diff --git a/resources/Schema/Entities/CollisionTestLevel.xml b/resources/Schema/Entities/CollisionTestLevel.xml
index d5e932c2..76a3b6e6 100644
--- a/resources/Schema/Entities/CollisionTestLevel.xml
+++ b/resources/Schema/Entities/CollisionTestLevel.xml
@@ -1,122 +1,66 @@
-
+
+
-
-
-
-
-
-
- Models/DummyScene.obj
-
-
-
-
-
-
-
-
-
-
- Models/Core/UnitSphere.obj
-
-
-
-
-
-
-
-
-
-
- Models/RotationWidgetX.obj
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Models/Core/UnitCube.obj
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Models/Core/UnitRaptor.obj
-
-
-
-
-
-
-
-
-
-
-
- 20
-
-
-
-
-
-
-
-
-
-
-
-
- Models/Core/UnitCube.obj
-
-
-
-
-
-
-
-
-
-
-
-
- Models/Core/UnitCube.obj
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+ ../assets\Models\Test/ObstacleCourse.obj
+
+
+
+
+
+
+
+
+
+
+ 0.46000027656555176
+
+
+
+
+
+
+
+
+
+
+
+
+ ../assets\Models\Core\UnitCube.obj
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ../assets\Models\Core\colorbox.obj
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp
index f040ccd5..d134a5d8 100644
--- a/src/Engine/Collision/Collision.cpp
+++ b/src/Engine/Collision/Collision.cpp
@@ -4,6 +4,7 @@
#include "Engine/GLM.h"
#include "Core/World.h"
#include "Rendering/Model.h"
+#include "imgui/imgui.h"
namespace Collision
{
@@ -248,12 +249,21 @@ bool vectorHasLength(const glm::vec3& vec)
return glm::any(glm::greaterThan(glm::abs(vec), glm::vec3(0.0001f, 0.0001f, 0.0001f)));
}
+enum BoxTriHit
+{
+ Line0 = 0,
+ Line1,
+ Line2,
+ Ground,
+ Corner
+};
+
bool AABBvsTriangle(const AABB& box,
const glm::vec3& v0,
const glm::vec3& v1,
const glm::vec3& v2,
glm::vec3& outVector,
- int& lineHit)
+ BoxTriHit& outHit)
{
//Check so we don't have a zero area triangle when calculating the normal.
glm::vec3 triNormal = glm::cross(v1 - v0, v2 - v0);
@@ -266,6 +276,23 @@ bool AABBvsTriangle(const AABB& box,
const glm::vec3& min = box.MinCorner();
const glm::vec3& max = box.MaxCorner();
+ //Check if normal faces upwards, and if so, just push the box upwards on collision.
+ triNormal = glm::normalize(triNormal);
+ if (triNormal.y > 0.5f || true) {
+ //TODO: Optimize calculation since x, z is 0.
+ //Ray ray(glm::vec3(origin.x, origin.y + half.y, origin.z), glm::vec3(0, -1, 0));
+ //float dist = INFINITY, u, v;
+ //if (RayVsTriangle(ray, v0, v1, v2, dist, u, v) && dist < 2.0f * half.y) {
+ Ray ray(origin, glm::vec3(0, -1, 0));
+ float dist = INFINITY, u, v;
+ if (RayVsTriangle(ray, v0, v1, v2, dist, u, v) && dist < half.y) {
+ outVector = glm::vec3(0, half.y - dist, 0);
+ outHit = Ground;
+ return true;
+ }
+ //return false; //TODO: Uncomment?
+ }
+
const glm::vec3 triPos[] = {
v0, v1, v2
};
@@ -291,7 +318,6 @@ bool AABBvsTriangle(const AABB& box,
return false; //If a triangle is completely inside the box, we call it a non-intersection.
}
- triNormal = glm::normalize(triNormal);
Ray ray;
//All triangle edges.
//Check if any edge on the triangle intersects the box.
@@ -302,7 +328,7 @@ bool AABBvsTriangle(const AABB& box,
float dist;
if (RayVsAABB(ray, box, dist) && dist <= glm::length(edge)) {
outVector = triNormal;
- lineHit = l;
+ outHit = (BoxTriHit)l;
return true;
}
}
@@ -341,6 +367,7 @@ bool AABBvsTriangle(const AABB& box,
//Distance between triangle plane, and the diagonal corner, multiplied by the normal.
//Signed distance, positive if on the same side as the normal.
outVector = -glm::dot(triNormal, origin + diagonal - v0) * triNormal;
+ outHit = Corner;
return true;
}
return false;
@@ -348,6 +375,7 @@ bool AABBvsTriangle(const AABB& box,
bool AABBvsTriangles(const AABB& box, const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& outResolutionVector)
{
+ AABB newBox = box;
struct Triangle
{
glm::vec3 v0, v1, v2;
@@ -362,45 +390,61 @@ bool AABBvsTriangles(const AABB& box, const std::vector& model
glm::vec3 v0 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix);
glm::vec3 v1 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix);
glm::vec3 v2 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix);
- int lineHit = -1;
- if (AABBvsTriangle(box, v0, v1, v2, outVec, lineHit))
+ BoxTriHit hitCase;
+ if (AABBvsTriangle(newBox, v0, v1, v2, outVec, hitCase))
{
hit = true;
- if (lineHit == -1) {
- outResolutionVector += outVec;
- //TODO: We might be able to return here instead, having only convex geometry.
- cornerHitTODO = true;
- //return true;
- }
- else {
- const glm::vec3 triPos[] = {
- v0, v1, v2
- };
- glm::vec3 edge = triPos[(lineHit + 1) % 3] - triPos[lineHit];
+ switch (hitCase) {
+ case Collision::Line0:
+ case Collision::Line1:
+ case Collision::Line2:
+ //TODO: Resolve.
+ //const glm::vec3 triPos[] = {
+ // v0, v1, v2
+ //};
+ //glm::vec3 edge = triPos[(hitCase + 1) % 3] - triPos[hitCase];
hitTriangles.push_back({v0, v1, v2});
hitNormals.push_back(outVec);
+ ImGui::Text("triangle edge collision.");
+ break;
+ case Collision::Corner:
+ //TODO: We might be able to return here instead, having only convex geometry.
+ cornerHitTODO = true;
+ //outResolutionVector += outVec;
+ //return true;
+ ImGui::Text("triangle corner collision.");
+ outResolutionVector += outVec;
+ newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size());
+ break;
+ case Collision::Ground:
+ default:
+ outResolutionVector += outVec;
+ newBox = AABB::FromOriginSize(newBox.Origin() + outVec, newBox.Size());
+ ImGui::Text("triangle ground collision.");
+ break;
}
}
}
if (hitTriangles.size() > 0) {
if (cornerHitTODO) {
- LOG_DEBUG("Both edges and corners was hit on the same model.");
+ ImGui::Text("Both edges and corners was hit on the same model.");
return true;
}
+ glm::vec3 lineResolve(0.f);
for (const glm::vec3& norm : hitNormals) {
- outResolutionVector += norm;
+ lineResolve += norm;
}
//Normalize.
- outResolutionVector /= hitNormals.size();
- const glm::vec3& origin = box.Origin();
- const glm::vec3& half = box.HalfSize();
+ lineResolve /= hitNormals.size();
+ const glm::vec3& origin = newBox.Origin();
+ const glm::vec3& half = newBox.HalfSize();
float maxDist = -10;
for (const Triangle& tri : hitTriangles) {
- float d = glm::dot(outResolutionVector, 0.333f * (tri.v0 + tri.v1 + tri.v2) - origin);
+ float d = glm::dot(lineResolve, 0.333f * (tri.v0 + tri.v1 + tri.v2) - origin);
maxDist = std::max(maxDist, d);
}
- glm::vec3 tmp = glm::clamp(2.0f * outResolutionVector, glm::vec3(-1, -1, -1), glm::vec3(1, 1, 1));
- outResolutionVector *= maxDist + glm::length(tmp * half);
+ glm::vec3 tmp = glm::clamp(2.0f * lineResolve, glm::vec3(-1, -1, -1), glm::vec3(1, 1, 1));
+ outResolutionVector += lineResolve * (maxDist + glm::length(tmp * half));
}
return hit;
}
diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp
index 452a73ef..20854c12 100644
--- a/src/Engine/Collision/CollisionSystem.cpp
+++ b/src/Engine/Collision/CollisionSystem.cpp
@@ -56,6 +56,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
glm::vec3 resolutionVector;
if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, resolutionVector)) {
(glm::vec3&)cTransform["Position"] += resolutionVector;
+ cPhysics["Velocity"] = glm::vec3(0, 0, 0);
}
}
}