diff --git a/resources/Schema/Entities/ModelCollisionTest.xml b/resources/Schema/Entities/ModelCollisionTest.xml
new file mode 100644
index 00000000..46746264
--- /dev/null
+++ b/resources/Schema/Entities/ModelCollisionTest.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ../assets/Models/Core/UnitCube.obj
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ../assets/Models/Core/UnitCube.obj
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp
index b30ae927..c351d9fa 100644
--- a/src/Engine/Collision/Collision.cpp
+++ b/src/Engine/Collision/Collision.cpp
@@ -199,30 +199,93 @@ bool RayVsModel(const Ray& ray,
return hit;
}
-bool AABBvsTriangles(const AABB& box, const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& outResolutionVector)
+bool AABBvsTriangle(const AABB& box, const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, glm::vec3& outResolutionVector)
{
- bool hit = false;
-
const glm::vec3& origin = box.Origin();
const glm::vec3& min = box.MinCorner();
const glm::vec3& max = box.MaxCorner();
+ const glm::vec3& half = box.HalfSize();
- outResolutionVector.x = INFINITY;
+ const glm::vec3 triPos[] = {
+ v0, v1, v2
+ };
- for (int i = 0; i < modelIndices.size(); ++i) {
- glm::vec3 p = modelVertices[i].Position;
+ for (int ax = 0; ax < 3; ++ax) {
+ auto outsideMinPlane = glm::tvec3(false);
+ auto outsideMaxPlane = glm::tvec3(false);
+ for (int pos = 0; pos < 3; ++pos) {
+ outsideMinPlane[pos] = (min[ax] > triPos[pos][ax]);
+ outsideMaxPlane[pos] = (triPos[pos][ax] > max[ax]);
+ }
+ if (glm::all(outsideMinPlane) || glm::all(outsideMaxPlane)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool AABBvsTriangles(const AABB& box, const std::vector& modelVertices, const std::vector& modelIndices, const glm::mat4& modelMatrix, glm::vec3& outResolutionVector)
+{
+ bool hit = false;
+ for (int i = 0; i < modelIndices.size(); i += 3) {
+ glm::vec3 resVec;
+ hit = AABBvsTriangle(
+ box,
+ modelVertices[modelIndices[i]].Position,
+ modelVertices[modelIndices[i + 1]].Position,
+ modelVertices[modelIndices[i + 2]].Position,
+ resVec
+ );
+ if (hit) {
+ break;
+ }
+ }
+ return hit;
+ //TODO: Remove old code.
+
+ /*
+ auto hit = glm::tvec3(false);
+ const glm::vec3& origin = box.Origin();
+ const glm::vec3& min = box.MinCorner();
+ const glm::vec3& max = box.MaxCorner();
+ const glm::vec3& half = box.HalfSize();
+
+ float minResolution = INFINITY;
+ outResolutionVector = glm::vec3(0.f);
+ //TODO: Don't need indices? Remove?
+ for (const auto& v : modelVertices) {
+ glm::vec3 p = v.Position;
p = glm::vec3(modelMatrix * glm::vec4(p.x, p.y, p.z, 1));
- float distFromOrigin = glm::abs(origin.x - p.x);
- float penetration = box.HalfSize().x - distFromOrigin;
- if (penetration > 0 && penetration < glm::abs(outResolutionVector.x)) {
- if (p.x > origin.x) {
- outResolutionVector.x = -penetration;
- } else {
- outResolutionVector.x = penetration;
+ const glm::vec3 diffO = origin - p;
+ const glm::vec3 distO = glm::abs(diffO);
+ for (int axis = 0; axis < 3; ++axis) {
+ float penetration = half[axis] - distO[axis];
+ if (penetration > 0){
+ if (penetration < minResolution) {
+ minResolution = penetration;
+ outResolutionVector = glm::vec3(0.f);
+ if (p[axis] > origin[axis]) {
+ outResolutionVector[axis] = -penetration;
+ } else {
+ outResolutionVector[axis] = penetration;
+ }
+ }
+ hit[axis] = true;
}
- hit = true;
}
+
+ //float distFromOrigin = glm::abs(origin.x - p.x);
+ //float penetration = box.HalfSize().x - distFromOrigin;
+ //if (penetration > 0 && penetration < glm::abs(outResolutionVector.x)) {
+ // if (p.x > origin.x) {
+ // outResolutionVector.x = -penetration;
+ // } else {
+ // outResolutionVector.x = penetration;
+ // }
+ // hit = true;
+ //}
+
//glm::vec3 pLocal = origin - p;
//for (int axis = 0; axis < 3; ++axis) {
// if (p[axis] < min[axis] || p[axis] > max[axis]) {
@@ -236,7 +299,13 @@ bool AABBvsTriangles(const AABB& box, const std::vector& model
//}
}
- return hit;
+ //for (int axis = 0; axis < 3; ++axis) {
+ // if (glm::isinf(outResolutionVector[axis])) {
+ // outResolutionVector[axis] = 0.f;
+ // }
+ //}
+
+ return glm::all(hit);*/
}
bool IsSameBoxProbably(const AABB& first, const AABB& second, const float epsilon)
diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp
index d841c75e..58e48357 100644
--- a/src/Engine/Collision/CollisionSystem.cpp
+++ b/src/Engine/Collision/CollisionSystem.cpp
@@ -1,6 +1,7 @@
#include "Collision/Collision.h"
#include "Collision/CollisionSystem.h"
#include "Core/AABB.h"
+#include "Rendering/Model.h"
void CollisionSystem::UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt)
{
@@ -22,40 +23,42 @@ void CollisionSystem::UpdateComponent(World* world, EntityWrapper& entity, Compo
}
// Collide against octree
- std::vector octreeResult;
- m_Octree->BoxesInSameRegion(*boundingBox, octreeResult);
- for (auto& boxB : octreeResult) {
- glm::vec3 resolutionVector;
- if (Collision::IsSameBoxProbably(boxA, boxB)) {
- continue;
- }
- if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) {
- (glm::vec3&)cTransform["Position"] += resolutionVector;
- cPhysics["Velocity"] = glm::vec3(0, 0, 0);
- }
- }
-
- // HACK: Temporarily collide against all collidable models since they're not in the octree yet
- //auto otherCollidables = world->GetComponents("Model");
- //for (auto& cModel : *otherCollidables) {
- // if (cModel.EntityID == entity) {
- // continue;
- // }
- // if (!world->HasComponent(cModel.EntityID, "Collidable")) {
- // continue;
- // }
-
- // auto absPosition = RenderQueueFactory::AbsolutePosition(world, cModel.EntityID);
- // auto absOrientation = RenderQueueFactory::AbsoluteOrientation(world, cModel.EntityID);
- // auto absScale = RenderQueueFactory::AbsoluteScale(world, cModel.EntityID);
- // glm::mat4 modelMatrix = glm::translate(absPosition); // *glm::toMat4(absOrientation) * glm::scale(absScale);
-
- // auto model = ResourceManager::Load(cModel["Resource"]);
+ //std::vector octreeResult;
+ //m_Octree->BoxesInSameRegion(*boundingBox, octreeResult);
+ //for (auto& boxB : octreeResult) {
// glm::vec3 resolutionVector;
- // if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, resolutionVector)) {
+ // if (Collision::IsSameBoxProbably(boxA, boxB)) {
+ // continue;
+ // }
+ // if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) {
// (glm::vec3&)cTransform["Position"] += resolutionVector;
+ // cPhysics["Velocity"] = glm::vec3(0, 0, 0);
// }
//}
+
+ // HACK: Temporarily collide against all collidable models since they're not in the octree yet
+ auto otherCollidables = world->GetComponents("Model");
+ for (auto& cModel : *otherCollidables) {
+ if (cModel.EntityID == EntityID(entity)) {
+ continue;
+ }
+ if (!world->HasComponent(cModel.EntityID, "Collidable")) {
+ continue;
+ }
+
+ auto absPosition = Transform::AbsolutePosition(world, cModel.EntityID);
+ auto absOrientation = Transform::AbsoluteOrientation(world, cModel.EntityID);
+ auto absScale = Transform::AbsoluteScale(world, cModel.EntityID);
+ glm::mat4 modelMatrix = glm::translate(absPosition); // *glm::toMat4(absOrientation) * glm::scale(absScale);
+
+ RawModel* model = ResourceManager::Load(cModel["Resource"]);
+ glm::vec3 resolutionVector;
+ if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, resolutionVector)) {
+ //TODO: remove Temp.
+ (glm::vec3&)cTransform["Position"] = glm::vec3(2, 2, 2);
+ //(glm::vec3&)cTransform["Position"] += resolutionVector;
+ }
+ }
}
bool CollisionSystem::OnKeyUp(const Events::KeyUp & event)