Reverts last WIP since it probably added code without improving anything.

Revert "WIP, should take shortest resolution even if forced upwards because of slopes, not solving the jittering problem though. + debug code."

This reverts commit db5170c699.
This commit is contained in:
William Moberg
2016-02-29 15:38:36 +01:00
parent db5170c699
commit 8e21c5a5e4
2 changed files with 45 additions and 113 deletions
+45 -111
View File
@@ -380,11 +380,11 @@ bool AABBvsTriangle(const AABB& box,
enum BoxTriResolveCase enum BoxTriResolveCase
{ {
EResolveDimX, ResolveDimX,
EResolveDimY, ResolveDimY,
EResolveDimZ, ResolveDimZ,
ELine, //Box edge colliding with triangle line. Line, //Box edge colliding with triangle line.
ECorner //Box corner colliding with the triangle face. Corner //Box corner colliding with the triangle face.
}; };
struct Resolution struct Resolution
{ {
@@ -396,55 +396,10 @@ bool AABBvsTriangle(const AABB& box,
float DistanceSq; float DistanceSq;
glm::vec3 Vector; glm::vec3 Vector;
}; };
struct CaseResolutions
{
Resolution Vertex;
Resolution Line;
Resolution Corner;
Resolution* Shortest = &Vertex;
void AddResolution(BoxTriResolveCase resCase, float distanceSq, const glm::vec3& resVec)
{
switch (resCase) {
case EResolveDimY:
case EResolveDimX:
case EResolveDimZ:
if (distanceSq < Vertex.DistanceSq) {
Vertex.Vector = resVec;
Vertex.DistanceSq = distanceSq;
Vertex.Case = resCase;
if (distanceSq < Line.DistanceSq) {
Shortest = &Vertex;
}
}
break;
case ELine:
if (distanceSq < Vertex.DistanceSq && distanceSq < Line.DistanceSq) {
Line.Vector = resVec;
Line.DistanceSq = distanceSq;
Line.Case = resCase;
Shortest = &Line;
}
break;
case ECorner:
//NOTE: It is assumed that the Corner is less than the
//added resolution, since only one corner should be added per triangle.
if (distanceSq < Vertex.DistanceSq && distanceSq < Line.DistanceSq) {
Corner.Vector = resVec;
Corner.DistanceSq = distanceSq;
Corner.Case = resCase;
Shortest = &Corner;
}
break;
default:
break;
}
}
};
//The smallest resolution that solves the collision. //The smallest resolution that solves the collision.
CaseResolutions resolveShortest; Resolution resolveShortest;
//The smallest resolution that solves the collision, that resolves upwards. //The smallest resolution that solves the collision, that resolves upwards.
CaseResolutions resolveUpwards; Resolution resolveUpwards;
//If player stands on the ground and collides with a ground triangle, //If player stands on the ground and collides with a ground triangle,
//we might step up onto it if the step is small enough. //we might step up onto it if the step is small enough.
bool canStairStepUp = isOnGround && FaceIsGround(triNormal.y); bool canStairStepUp = isOnGround && FaceIsGround(triNormal.y);
@@ -466,27 +421,34 @@ bool AABBvsTriangle(const AABB& box,
//Project box. //Project box.
glm::vec2 boxMin(min[dim.first], min[dim.second]); glm::vec2 boxMin(min[dim.first], min[dim.second]);
glm::vec2 boxMax(max[dim.first], max[dim.second]); glm::vec2 boxMax(max[dim.first], max[dim.second]);
glm::vec2 resolutionVector2D; glm::vec2 resolutionVector;
float resolutionDistSq; float resolutionDist;
bool pushedFromTriangleLine; bool pushedFromTriangleLine;
//if projections don't overlap, return false. //if projections don't overlap, return false.
if (!rectangleVsTriangle(boxMin, boxMax, t2D, resolutionVector2D, resolutionDistSq, pushedFromTriangleLine)) { if (!rectangleVsTriangle(boxMin, boxMax, t2D, resolutionVector, resolutionDist, pushedFromTriangleLine)) {
return false; return false;
} else if (resolveCollision) { } else if (resolveCollision) {
glm::vec3 resolve3D = glm::vec3(0.f);
resolve3D[dim.first] = resolutionVector2D.x;
resolve3D[dim.second] = resolutionVector2D.y;
//If we pushed away from triangle line (edge), or if we
//move the player along one coordinate axis (pick the dimension that isn't zero).
BoxTriResolveCase resCase = pushedFromTriangleLine ? ELine : static_cast<BoxTriResolveCase>((abs(resolve3D[dim.first]) < 0.0001f) ? dim.second : dim.first);
//Overwrite the smallest resolution if this is smaller. //Overwrite the smallest resolution if this is smaller.
resolveShortest.AddResolution(resCase, resolutionDistSq, resolve3D); if (resolutionDist < resolveShortest.DistanceSq) {
resolveShortest.Vector = glm::vec3(0.f);
resolveShortest.Vector[dim.first] = resolutionVector.x;
resolveShortest.Vector[dim.second] = resolutionVector.y;
resolveShortest.DistanceSq = resolutionDist;
//If we pushed away from triangle line (edge), or if we
//move the player along one coordinate axis (pick the dimension that isn't zero).
resolveShortest.Case = pushedFromTriangleLine ? Line : static_cast<BoxTriResolveCase>((abs(resolveShortest.Vector[dim.first]) < 0.0001f) ? dim.second : dim.first);
}
//Overwrite the smallest upward resolution if this is smaller, and resolves upwards. //Overwrite the smallest upward resolution if this is smaller, and resolves upwards.
constexpr int yAxis = 1; constexpr int yAxis = 1;
bool resIsUpwardsIn3D = dim.first == yAxis && resolutionVector2D.x > 0 || dim.second == yAxis && resolutionVector2D.y > 0; bool resIsUpwardsIn3D = dim.first == yAxis && resolutionVector.x > 0 || dim.second == yAxis && resolutionVector.y > 0;
if (canStairStepUp && resIsUpwardsIn3D) { if (canStairStepUp && resIsUpwardsIn3D && resolutionDist < resolveUpwards.DistanceSq) {
resolveUpwards.AddResolution(resCase, resolutionDistSq, resolve3D); resolveUpwards.Vector = glm::vec3(0.f);
resolveUpwards.Vector[dim.first] = resolutionVector.x;
resolveUpwards.Vector[dim.second] = resolutionVector.y;
resolveUpwards.DistanceSq = resolutionDist;
//If we pushed away from triangle line (edge), or if we
//move the player along one coordinate axis (pick the dimension that isn't zero).
resolveUpwards.Case = pushedFromTriangleLine ? Line : static_cast<BoxTriResolveCase>((abs(resolveUpwards.Vector[dim.first]) < 0.0001f) ? dim.second : dim.first);
} }
} }
} }
@@ -510,40 +472,37 @@ bool AABBvsTriangle(const AABB& box,
glm::vec3 cornerResolution = (1+t) * diagonal; glm::vec3 cornerResolution = (1+t) * diagonal;
//Overwrite the smallest resolution if cornerResolution is smaller. //Overwrite the smallest resolution if cornerResolution is smaller.
float lenSq = glm::length2(cornerResolution); float lenSq = glm::length2(cornerResolution);
resolveShortest.AddResolution(ECorner, lenSq, cornerResolution); if (lenSq < resolveShortest.DistanceSq) {
if (canStairStepUp && cornerResolution.y > 0) { resolveShortest.Vector = cornerResolution;
resolveUpwards.AddResolution(ECorner, lenSq, cornerResolution); resolveShortest.Case = Corner;
}
if (canStairStepUp && cornerResolution.y > 0 && lenSq < resolveUpwards.DistanceSq) {
resolveUpwards.Vector = cornerResolution;
resolveUpwards.Case = Corner;
resolveUpwards.DistanceSq = lenSq;
} }
//Force the resolution upwards if it is smaller than the threshold verticalStepHeight. //Force the resolution upwards if it is smaller than the threshold verticalStepHeight.
//Else take the shortest resolution. //Else take the shortest resolution.
bool takeUp = resolveUpwards.Shortest->Vector.y > 0 && resolveUpwards.Shortest->Vector.y < verticalStepHeight; bool takeUp = resolveUpwards.Vector.y > 0 && resolveUpwards.Vector.y < verticalStepHeight;
CaseResolutions& bestResolve = takeUp ? resolveUpwards : resolveShortest; Resolution& bestResolve = takeUp ? resolveUpwards : resolveShortest;
outResolution = bestResolve.Shortest->Vector; outResolution = bestResolve.Vector;
std::string dbgString = "";
glm::vec3 projNorm; glm::vec3 projNorm;
switch (bestResolve.Shortest->Case) { switch (bestResolve.Case) {
case EResolveDimY: case ResolveDimY:
boxVelocity.y = 0.f; boxVelocity.y = 0.f;
if (outResolution.y > 0) if (outResolution.y > 0)
isOnGround = true; isOnGround = true;
case EResolveDimX: case ResolveDimX:
case EResolveDimZ: case ResolveDimZ:
//If we get here, the resolution is along one coordinate axis. //If we get here, the resolution is along one coordinate axis.
//set velocity to 0 in y if it is along y-axis. //set velocity to 0 in y if it is along y-axis.
dbgString = "Vertex Collision";
dbgString += isOnGround ? " Ground" : " Air";
dbgString += takeUp ? " Force up" : " Normal";
std::cout << (dbgString.c_str()) << std::endl;
ImGui::Text(dbgString.c_str());
return true; return true;
case ELine: case Line:
dbgString = "Line Collision";
projNorm = glm::normalize(outResolution); projNorm = glm::normalize(outResolution);
break; break;
case ECorner: case Corner:
dbgString = "Corner Collision";
projNorm = triNormal; projNorm = triNormal;
break; break;
default: default:
@@ -560,23 +519,6 @@ bool AABBvsTriangle(const AABB& box,
outResolution.y = len / glm::sin(ang); outResolution.y = len / glm::sin(ang);
outResolution.z = 0; outResolution.z = 0;
} }
float y;
if (bestResolve.Shortest->Case == ECorner) {
len = glm::length(bestResolve.Line.Vector);
ang = glm::half_pi<float>() - glm::acos(bestResolve.Line.Vector.y / len);
if (len > 0.0000001f && ang > 0.0000001f) {
y = len / glm::sin(ang);
if (y < outResolution.y) {
outResolution.x = 0;
outResolution.y = y;
outResolution.z = 0;
}
}
}
y = bestResolve.Vertex.Vector.y;
if (bestResolve.Vertex.Case == EResolveDimY && y < outResolution.y) {
outResolution.y = y;
}
//Also zero the vertical velocity, if it is positive, else project it onto the normal. //Also zero the vertical velocity, if it is positive, else project it onto the normal.
//Project the velocity onto the normal of the hit line/face. //Project the velocity onto the normal of the hit line/face.
//w = v - <v,n>*n, |n|==1. //w = v - <v,n>*n, |n|==1.
@@ -591,10 +533,6 @@ bool AABBvsTriangle(const AABB& box,
boxVelocity = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm; boxVelocity = boxVelocity - glm::dot(boxVelocity, projNorm) * projNorm;
} }
} }
dbgString += isOnGround ? " Ground" : " Air";
dbgString += takeUp ? " Force up" : " Normal";
std::cout << (dbgString.c_str()) << std::endl;
ImGui::Text(dbgString.c_str());
return true; return true;
} }
@@ -608,7 +546,6 @@ bool AABBvsTriangles(const AABB& box,
glm::vec3& outResolutionVector, glm::vec3& outResolutionVector,
bool resolveCollision) bool resolveCollision)
{ {
std::cout << ("---->>>--AABBvsTriangles--------") << std::endl;
bool hit = false; bool hit = false;
bool everHitTheGround = false; bool everHitTheGround = false;
@@ -636,9 +573,6 @@ bool AABBvsTriangles(const AABB& box,
if (!everHitTheGround) { if (!everHitTheGround) {
isOnGround = false; isOnGround = false;
} }
std::cout << (isOnGround ? "Hit Ground" : "In Air") << std::endl;
ImGui::Text(isOnGround ? "Hit Ground" : "In Air");
std::cout << ("--------AABBvsTriangles---->>>--") << std::endl;
return hit; return hit;
} }
-2
View File
@@ -12,7 +12,6 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
if (!boundingBox) { if (!boundingBox) {
return; return;
} }
std::cout << "---->>>--Start Update--------" << std::endl;
ComponentWrapper& cTransform = entity["Transform"]; ComponentWrapper& cTransform = entity["Transform"];
EntityAABB& boxA = *boundingBox; EntityAABB& boxA = *boundingBox;
bool everHitTheGround = false; bool everHitTheGround = false;
@@ -116,5 +115,4 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
} }
m_PrevPositions[entity] = boxA.Origin(); m_PrevPositions[entity] = boxA.Origin();
std::cout << "--------End Update---->>>--" << std::endl;
} }