aabb collides & cleanup.

This commit is contained in:
2024-03-13 07:35:20 -04:00
parent 22c3872cdb
commit 63e2de1730
7 changed files with 66 additions and 54 deletions

View File

@@ -13,6 +13,7 @@ enum class ColliderType : uint8_t {
class Collider : public VertexArray {
public:
ColliderType type;
void draw() override;
//Useful for everything except AABB.
Vector3 angle;
@@ -21,7 +22,9 @@ public:
namespace Collision {
Collider calculateOrientedBoundingBox(VertexArray* vArray, const Vector3& angle);
Collider calculateAxisAlignedBoundingBox(VertexArray vArray);
bool vertexInsideAxisAlignedBoundingBox(const Vector3& position, Collider boundingBox);
bool vertexInsideOrientedBoundingBox(const Vector3& position, const Collider& boundingBox);
bool orientedBoundingBoxCollides(const Collider& boundingBox, const Collider& boundingBox2);
bool axisAlignedBoundingBoxCollides(const Collider& boundingBox, const Collider& boundingBox2);
}

View File

@@ -44,6 +44,7 @@ public:
}
Vector3 angle = {0,0,0}; //Pitch Yaw Roll, The orientation of the entity in the world,
bool collidable = true; // Entities are solid by default.
GLuint getTextureID();
virtual VertexArray* getGeometry();
virtual Collider getCollider();
@@ -91,13 +92,7 @@ public:
void SetMatrix(const Matrix4x4& rhs);
bool draw = true;
bool occluded();
bool collidable = true;
void destruct() {
//TODO: Search entity list for this entity and remove it to avoid use-after-free.
// Non. This should be the concern of the object managing entities. Entity.h should JUST provide entity behavior.
}
bool isCollidingWith(Entity* entity);
virtual void pre_render() {}
virtual void post_render() {}
virtual void render();

View File

@@ -29,6 +29,6 @@ public:
void load(const std::string& filename);
static void erase(const VertexArray& vArray);
void drawWireframe();
void draw();
virtual void draw();
GLuint vbo = NULL;
};

View File

@@ -41,9 +41,7 @@ bool Collision::orientedBoundingBoxCollides(const Collider &boundingBox, const C
Vector3(0, 0, 1)
};
for (int i = 0; i < 3; i++) {
Vector3 axis = axes[i];
for (const auto& axis : axes) {
float projection1Min = FLT_MAX, projection1Max = -FLT_MAX;
float projection2Min = FLT_MAX, projection2Max = -FLT_MAX;
@@ -61,14 +59,11 @@ bool Collision::orientedBoundingBoxCollides(const Collider &boundingBox, const C
if (projection > projection2Max) projection2Max = projection;
}
if (projection1Max < projection2Min || projection2Max < projection1Min) {
if (projection1Max < projection2Min || projection2Max < projection1Min)
return false;
}
}
for (int i = 0; i < 3; i++) {
Vector3 axis = axes[i];
for (const auto& axis : axes) {
float projection1Min = FLT_MAX, projection1Max = -FLT_MAX;
float projection2Min = FLT_MAX, projection2Max = -FLT_MAX;
@@ -86,10 +81,42 @@ bool Collision::orientedBoundingBoxCollides(const Collider &boundingBox, const C
if (projection > projection2Max) projection2Max = projection;
}
if (projection1Max < projection2Min || projection2Max < projection1Min) {
return false; //OBBs not colliding.
}
if (projection1Max < projection2Min || projection2Max < projection1Min)
return false;
}
return true; //OBBs collide.
}
bool Collision::axisAlignedBoundingBoxCollides(const Collider &boundingBox, const Collider &boundingBox2) {
Vector3 aabb1Min = {boundingBox.vertices.front().x, boundingBox.vertices.front().y, boundingBox.vertices.front().z};
Vector3 aabb1Max = {boundingBox.vertices.back().x, boundingBox.vertices.back().y, boundingBox.vertices.back().z};
Vector3 aabb2Min = {boundingBox2.vertices.front().x, boundingBox2.vertices.front().y, boundingBox2.vertices.front().z};
Vector3 aabb2Max = {boundingBox2.vertices.back().x, boundingBox2.vertices.back().y, boundingBox2.vertices.back().z};
if (aabb1Max.x < aabb2Min.x || aabb2Max.x < aabb1Min.x)
return false;
if (aabb1Max.y < aabb2Min.y || aabb2Max.y < aabb1Min.y)
return false;
if (aabb1Max.z < aabb2Min.z || aabb2Max.z < aabb1Min.z)
return false;
return true; //AABBs Collide.
}
void Collider::draw() {
glBegin(GL_LINES);
for (int i = 0; i < 4; ++i) {
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
glVertex3f(vertices[(i + 1) % 4].x, vertices[(i + 1) % 4].y, vertices[(i + 1) % 4].z);
glVertex3f(vertices[i + 4].x, vertices[i + 4].y, vertices[i + 4].z);
glVertex3f(vertices[((i + 1) % 4) + 4].x, vertices[((i + 1) % 4) + 4].y, vertices[((i + 1) % 4) + 4].z);
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
glVertex3f(vertices[i + 4].x, vertices[i + 4].y, vertices[i + 4].z);
}
glEnd();
}

View File

@@ -2,9 +2,6 @@
#include <collision.h>
void Cube::pre_render() {
hVelocity = 1;
//this->angle.x -= 96*engine->frameDelta;
//this->angle.y -= 96*engine->frameDelta;
//this->angle.z -= 96*engine->frameDelta;
hMove(velAngle, hVelocity);
vMove(vVelocity);
@@ -16,10 +13,11 @@ void Cube::pre_render() {
if (moby == this)
return;
if (Collision::orientedBoundingBoxCollides(getCollider(), moby->getCollider())) {
if (collidable && moby->collidable && isCollidingWith(moby)) {
moby->velAngle = moby->lAngle();
velAngle = rAngle();
}
}
void Cube::update(float elapsed) {
@@ -37,7 +35,7 @@ void Cube::update(float elapsed) {
}
Collider Cube::getCollider() {
Collider collider = Collision::calculateOrientedBoundingBox(getGeometry(), angle);
Collider collider = Collision::calculateAxisAlignedBoundingBox(*getGeometry());
//Scale.
for (auto& vertex : collider.vertices) {

View File

@@ -166,25 +166,28 @@ void Entity::render() {
glColor3f(1, 0, 0);
glTranslatef(0, 0, 0);
getCollider().draw();
glColor3f(0, 0, 0);
glColor3f(1, 1, 1);
glPopMatrix();
}
if (engine->world->getGlobalFogMode() != NULL)
glEnable(GL_FOG);
//JGL::J2D::FillRect2D(JGL::Colors::Yellow, {0, 0}, {1, 1});
//JGL::J2D::DrawString2D(JGL::Colors::Blue, "ENTITY", 0, 0, 1/50.f);
}
bool Entity::isCollidingWith(Entity *entity) {
Collider thisCollider = getCollider();
Collider otherCollider = entity->getCollider();
if (thisCollider.type == ColliderType::OrientedBoundingBox && otherCollider.type == ColliderType::OrientedBoundingBox)
return Collision::orientedBoundingBoxCollides(thisCollider, otherCollider);
if (thisCollider.type == ColliderType::AxisAlignedBoundingBox && otherCollider.type == ColliderType::AxisAlignedBoundingBox)
return Collision::axisAlignedBoundingBoxCollides(thisCollider, otherCollider);
if ((thisCollider.type == ColliderType::AxisAlignedBoundingBox && otherCollider.type == ColliderType::OrientedBoundingBox) || (thisCollider.type == ColliderType::OrientedBoundingBox && otherCollider.type == ColliderType::AxisAlignedBoundingBox))
return Collision::orientedBoundingBoxCollides(thisCollider, otherCollider);
glPushMatrix();
JGL::J2D::FillRect2D(JGL::Colors::Yellow, {0, 0}, {1, 1});
JGL::J2D::DrawString2D(JGL::Colors::Blue, "ENTITY", 0, 0, 1/50.f);
glPopMatrix();
//glPushMatrix();
//glOrtho(0, 1024, 768, 0, -1, 1);
//JGL::J3D::DrawString3D(JGL::Colors::Blue, "ENTITY", position, 1.f);
//glPopMatrix();
}

View File

@@ -85,7 +85,7 @@ void VertexArray::draw() {
if (engine->useVBO) {
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexPointer(3, GL_FLOAT, 0, 0);
glVertexPointer(3, GL_FLOAT, 0, nullptr);
}
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, &indices[0]);
@@ -99,20 +99,6 @@ void VertexArray::draw() {
//This only works for *really* simple shapes.
//Primarily for the bounding box.
if (indices.empty()) {
glBegin(GL_LINES);
for (int i = 0; i < 4; ++i) {
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
glVertex3f(vertices[(i + 1) % 4].x, vertices[(i + 1) % 4].y, vertices[(i + 1) % 4].z);
glVertex3f(vertices[i + 4].x, vertices[i + 4].y, vertices[i + 4].z);
glVertex3f(vertices[((i + 1) % 4) + 4].x, vertices[((i + 1) % 4) + 4].y, vertices[((i + 1) % 4) + 4].z);
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
glVertex3f(vertices[i + 4].x, vertices[i + 4].y, vertices[i + 4].z);
}
glEnd();
}
}
void VertexArray::drawWireframe() {