From 6d1cbd928ed2f84445d9390efdfcb992e0beb493 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Wed, 16 Dec 2015 16:34:27 +0100 Subject: [PATCH] Improved collision logic, still not perfect since it updates before PlayerSystem. --- include/Engine/Collision/Collision.h | 3 +++ src/Engine/Collision/Collision.cpp | 34 ++++++++++++++++++++++++ src/Engine/Collision/CollisionSystem.cpp | 17 ++++++------ 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index 1fcb910e..64bf2d2c 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -41,6 +41,9 @@ bool RayVsModel(const Ray& ray, //Return true if the boxes are intersecting. bool AABBVsAABB(const AABB& a, const AABB& b); +//Return true if the boxes are intersecting. +//Also outputs the minimum translation that box [a] would need in order to resolve collision. +bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation); bool IsSameBoxProbably(const AABB& first, const AABB& second, const float epsilon = 0.0001f); //Returns true if the entity has a boundingbox. Outputs the aabb in [outBox]. diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index 500d59bc..d9cf8a0e 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -81,6 +81,40 @@ namespace Collision return (abs(aCenter[1] - bCenter[1]) <= (aHSize[1] + bHSize[1])); } + bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation) + { + minimumTranslation = glm::vec3(0, 0, 0); + const glm::vec3& aMax = a.MaxCorner(); + const glm::vec3& bMax = b.MaxCorner(); + const glm::vec3& aMin = a.MinCorner(); + const glm::vec3& bMin = b.MinCorner(); + const glm::vec3& bSize = b.Size(); + const glm::vec3& aSize = a.Size(); + float minOffset = INFINITY; + float off; + auto axisesIntersecting = glm::tvec3(false, false, false); + for (int i = 0; i < 3; ++i) { + off = bMax[i] - aMin[i]; + if (off > 0 && off < bSize[i] + aSize[i]) { + if (off < minOffset) { + minimumTranslation = glm::vec3(); + minimumTranslation[i] = minOffset = off; + } + axisesIntersecting[i] = true; + } + off = aMax[i] - bMin[i]; + if (off > 0 && off < bSize[i] + aSize[i]) { + if (off < minOffset) { + minOffset = off; + minimumTranslation = glm::vec3(); + minimumTranslation[i] = -off; + } + axisesIntersecting[i] = true; + } + } + return glm::all(axisesIntersecting); + } + bool RayVsModel(const Ray& ray, const std::vector& modelVertices, const std::vector& modelIndices) diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index ee5d4d29..dec33a20 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -4,15 +4,18 @@ void CollisionSystem::UpdateComponent(World * world, ComponentWrapper & cAABB, double dt) { - //cAABB is any entity that should be collideable. + //TODO: Update CollisionSystem system after PlayerSystem. + + //Right now, cAABB is a component attached to any entity that should be collideable. AABB thisBox; if (!Collision::GetEntityBox(world, cAABB, thisBox)) { return; } - //Here c should be an object that moves, currently only players. + //Press 'Z' to enable/disable collision. if (zPress) { return; } + //Here, mover should be an object that moves, currently only players. for (auto& mover : *world->GetComponents("Player")) { if (cAABB.EntityID == mover.EntityID) { continue; @@ -21,13 +24,11 @@ void CollisionSystem::UpdateComponent(World * world, ComponentWrapper & cAABB, d if (!Collision::GetEntityBox(world, mover.EntityID, otherBox)) { continue; } - if (Collision::AABBVsAABB(thisBox, otherBox)) { + glm::vec3 resolveTranslation; + if (Collision::AABBVsAABB(otherBox, thisBox, resolveTranslation)) { ComponentWrapper& trans = world->GetComponent(mover.EntityID, "Transform"); - //TODO: Move entity to correct position on collision instead of this. Special treatment if both are movers. - glm::vec3 newPos = trans["Position"]; - float moveSpeed = 0.12f; - newPos += moveSpeed * glm::normalize(newPos - thisBox.Center()); - trans["Position"] = newPos; + //TODO: Special treatment if both are movers. + trans["Position"] = (glm::vec3)trans["Position"] + resolveTranslation; } } }