Improved collision logic, still not perfect since it updates before PlayerSystem.
This commit is contained in:
@@ -41,6 +41,9 @@ bool RayVsModel(const Ray& ray,
|
|||||||
|
|
||||||
//Return true if the boxes are intersecting.
|
//Return true if the boxes are intersecting.
|
||||||
bool AABBVsAABB(const AABB& a, const AABB& b);
|
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);
|
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].
|
//Returns true if the entity has a boundingbox. Outputs the aabb in [outBox].
|
||||||
|
|||||||
@@ -81,6 +81,40 @@ namespace Collision
|
|||||||
return (abs(aCenter[1] - bCenter[1]) <= (aHSize[1] + bHSize[1]));
|
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,
|
bool RayVsModel(const Ray& ray,
|
||||||
const std::vector<RawModel::Vertex>& modelVertices,
|
const std::vector<RawModel::Vertex>& modelVertices,
|
||||||
const std::vector<unsigned int>& modelIndices)
|
const std::vector<unsigned int>& modelIndices)
|
||||||
|
|||||||
@@ -4,15 +4,18 @@
|
|||||||
|
|
||||||
void CollisionSystem::UpdateComponent(World * world, ComponentWrapper & cAABB, double dt)
|
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;
|
AABB thisBox;
|
||||||
if (!Collision::GetEntityBox(world, cAABB, thisBox)) {
|
if (!Collision::GetEntityBox(world, cAABB, thisBox)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Here c should be an object that moves, currently only players.
|
//Press 'Z' to enable/disable collision.
|
||||||
if (zPress) {
|
if (zPress) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//Here, mover should be an object that moves, currently only players.
|
||||||
for (auto& mover : *world->GetComponents("Player")) {
|
for (auto& mover : *world->GetComponents("Player")) {
|
||||||
if (cAABB.EntityID == mover.EntityID) {
|
if (cAABB.EntityID == mover.EntityID) {
|
||||||
continue;
|
continue;
|
||||||
@@ -21,13 +24,11 @@ void CollisionSystem::UpdateComponent(World * world, ComponentWrapper & cAABB, d
|
|||||||
if (!Collision::GetEntityBox(world, mover.EntityID, otherBox)) {
|
if (!Collision::GetEntityBox(world, mover.EntityID, otherBox)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (Collision::AABBVsAABB(thisBox, otherBox)) {
|
glm::vec3 resolveTranslation;
|
||||||
|
if (Collision::AABBVsAABB(otherBox, thisBox, resolveTranslation)) {
|
||||||
ComponentWrapper& trans = world->GetComponent(mover.EntityID, "Transform");
|
ComponentWrapper& trans = world->GetComponent(mover.EntityID, "Transform");
|
||||||
//TODO: Move entity to correct position on collision instead of this. Special treatment if both are movers.
|
//TODO: Special treatment if both are movers.
|
||||||
glm::vec3 newPos = trans["Position"];
|
trans["Position"] = (glm::vec3)trans["Position"] + resolveTranslation;
|
||||||
float moveSpeed = 0.12f;
|
|
||||||
newPos += moveSpeed * glm::normalize(newPos - thisBox.Center());
|
|
||||||
trans["Position"] = newPos;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user