Physics.cpp
unknown
c_cpp
2 years ago
3.5 kB
12
Indexable
#include "Physics.h"
namespace Drizzle3D {
Physics::Physics(std::shared_ptr<App> ap) : app(ap) {
app->dispatcher()->AddEventListener(Drizzle3D::EventType::ObjectMoved, [](GLFWwindow* window, std::unique_ptr<Drizzle3D::Event> ev, std::any a) {
Physics* al = std::any_cast<Physics*>(a);
al->calculateAABB(dynamic_cast<Drizzle3D::ObjectMovedEvent*>(ev.get())->GetObjectName());
if (al->CheckColliders(dynamic_cast<Drizzle3D::ObjectMovedEvent*>(ev.get())->GetObjectName())) {
std::cout << "Object Collided!";
exit(-1993);
}
}, this);
app->dispatcher()->AddEventListener(Drizzle3D::EventType::AppUpdate, [](GLFWwindow* window, std::unique_ptr<Drizzle3D::Event> ev, std::any a) {
Physics* al = std::any_cast<Physics*>(a);
al->UpdateColliders();
}, this);
}
void Physics::calculateAABB(std::string name) {
if (name == "Skybox")
return;
glm::vec3 min_bound = glm::vec3(std::numeric_limits<float>::max());
glm::vec3 max_bound = glm::vec3(std::numeric_limits<float>::lowest());
// Assuming vertices are stored as x, y, z, x, y, z, ...
auto Objects = app->GetRenderingLayer()->getObjects();
std::vector<float> vertices;
for (int i = 0; i < Objects->size(); i++) {
if (Objects->at(i).name == name) {
vertices = Objects->at(i).vertices;
}
}
for (size_t i = 0; i < vertices.size(); i += 3) {
glm::vec3 vertex(vertices[i], vertices[i + 1], vertices[i + 2]);
min_bound = glm::min(min_bound, vertex);
max_bound = glm::max(max_bound, vertex);
}
std::cout << "min: " << min_bound.x << ", " << min_bound.y << ", " << min_bound.z << "\n";
std::cout << "max: " << max_bound.x << ", " << max_bound.y << ", " << max_bound.z << "\n";
// Update collider's AABB if it exists for the specified object
for (auto& collider : colliders) {
if (std::get<0>(collider) == name) {
std::get<2>(collider).min = min_bound;
std::get<2>(collider).max = max_bound;
break;
}
}
}
void Physics::addCollider(std::string name, bool isCollider) {
for (auto& collider : colliders) {
if (std::get<0>(collider) == name) {
std::get<1>(collider) = isCollider;
break;
}
}
}
void Physics::UpdateColliders() {
for (auto& obj : *app->GetRenderingLayer()->getObjects()) {
bool found = false;
for (auto& collider : colliders) {
if (std::get<0>(collider) == obj.name) {
found = true;
break;
}
}
if (!found && obj.name != "Skybox") {
colliders.push_back(std::make_tuple(obj.name, false, AABB(glm::vec3(0, 0, 0), glm::vec3(0, 0, 0))));
calculateAABB(obj.name);
}
}
}
bool Physics::CheckColliders(std::string name) {
glm::vec3 objectMin;
glm::vec3 objectMax;
bool isCollider = false;
for (const auto& collider : colliders) {
if (std::get<0>(collider) == name) {
objectMin = std::get<2>(collider).min;
objectMax = std::get<2>(collider).max;
isCollider = std::get<1>(collider);
break;
}
}
for (const auto& otherCollider : colliders) {
if (std::get<0>(otherCollider) == name || !std::get<1>(otherCollider))
continue;
glm::vec3 otherMin = std::get<2>(otherCollider).min;
glm::vec3 otherMax = std::get<2>(otherCollider).max;
if (objectMin.x <= otherMax.x && objectMax.x >= otherMin.x &&
objectMin.y <= otherMax.y && objectMax.y >= otherMin.y &&
objectMin.z <= otherMax.z && objectMax.z >= otherMin.z) {
return true;
}
}
return false;
}
}Editor is loading...
Leave a Comment