Improved collision logic, still not perfect since it updates before PlayerSystem.

This commit is contained in:
William Moberg
2015-12-16 16:34:27 +01:00
parent cf0ff9bfe5
commit 6d1cbd928e
3 changed files with 46 additions and 8 deletions
+3
View File
@@ -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].
+34
View File
@@ -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<bool, glm::highp>(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<RawModel::Vertex>& modelVertices,
const std::vector<unsigned int>& modelIndices)
+9 -8
View File
@@ -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;
}
}
}