From 3955e1d60c1d388b39599c5eaa3c343d064bac85 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Fri, 22 Jan 2016 13:46:09 +0100 Subject: [PATCH] Can resolve collision when AABB corners cut through triangle. At least two more cases left to resolve. --- .../Schema/Entities/ModelCollisionTest.xml | 35 ++++++++++++++----- src/Engine/Collision/Collision.cpp | 8 ++--- src/Engine/Collision/CollisionSystem.cpp | 8 ++++- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/resources/Schema/Entities/ModelCollisionTest.xml b/resources/Schema/Entities/ModelCollisionTest.xml index fd26f0c5..f7a547f5 100644 --- a/resources/Schema/Entities/ModelCollisionTest.xml +++ b/resources/Schema/Entities/ModelCollisionTest.xml @@ -2,7 +2,9 @@ - + + + @@ -11,8 +13,8 @@ - - + + @@ -21,25 +23,40 @@ - ../assets/Models/Core/UnitCube.obj - + ../assets/Models/Core/UnitQuad.obj + - + + + - + + + + + ../assets/Models/Core/UnitQuad.obj + + + + + + + + + - ../assets/Models/Core/UnitCube.obj + - + diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index d643e8cc..d174eb86 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -299,7 +299,7 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, c //closest to being perpendicular to the plane of the polygon. triNormal = glm::normalize(triNormal); - glm::vec3 diagonal = signNonZero(triNormal) * half; + glm::vec3 diagonal = -signNonZero(triNormal) * half; #define EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK #ifdef EARLY_OUT_OR_MAYBE_JUST_EXTRA_WORK //The triangle plane contains all points P in dot(triNormal, P) == dot(triNormal, v0) @@ -323,9 +323,9 @@ bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, c return false; } #endif - float dist = glm::dot(triNormal, origin + diagonal - v0); - outResolutionVector = dist * triNormal; - LOG_DEBUG("Triangle collision corner"); + //Distance between triangle plane, and the diagonal corner, multiplied by the normal. + //Signed distance, positive if on the same side as the normal. + outResolutionVector = -glm::dot(triNormal, origin + diagonal - v0) * triNormal; return true; } return false; diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index 657cc90b..11d2a836 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -51,7 +51,13 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c auto absScale = Transform::AbsoluteScale(m_World, cModel.EntityID); glm::mat4 modelMatrix = glm::translate(absPosition) * glm::toMat4(absOrientation) * glm::scale(absScale); - RawModel* model = ResourceManager::Load(cModel["Resource"]); + RawModel* model; + try { + model = ResourceManager::Load(cModel["Resource"]); + } catch (const std::exception&) { + continue; + } + glm::vec3 resolutionVector; if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, resolutionVector)) { (glm::vec3&)cTransform["Position"] += resolutionVector;