Added trigger check for sphere vs convex polyhedron

This commit is contained in:
Diren D Bharwani 2023-01-01 03:32:59 +08:00
parent f3c0bdbcfd
commit 38764e79b3
1 changed files with 30 additions and 9 deletions

View File

@ -33,14 +33,37 @@ namespace SHADE
const SHVec3 CENTER = SPHERE.GetCenter(); const SHVec3 CENTER = SPHERE.GetCenter();
const float RADIUS = SPHERE.GetWorldRadius(); const float RADIUS = SPHERE.GetWorldRadius();
// Find closest face
const FaceQuery FACE_QUERY = findClosestFace(SPHERE, POLYHEDRON); const FaceQuery FACE_QUERY = findClosestFace(SPHERE, POLYHEDRON);
if (!FACE_QUERY.colliding) if (!FACE_QUERY.colliding)
return false; return false;
// If center of sphere is inside the polyhedron (below the face)
if (FACE_QUERY.bestDistance < SHMath::EPSILON) if (FACE_QUERY.bestDistance < SHMath::EPSILON)
return true; return true;
return false; // Find closest face of polygon to circle
const int32_t CLOSEST_POINT = findClosestPoint(SPHERE, POLYHEDRON, FACE_QUERY.closestFace);
const auto& FACE = POLYHEDRON.GetFace(FACE_QUERY.closestFace);
const SHVec3& FACE_NORMAL = POLYHEDRON.GetNormal(FACE_QUERY.closestFace);
const int32_t NUM_VERTICES = static_cast<int32_t>(FACE.vertexIndices.size());
// Get points and build tangents
const int32_t P2_INDEX = (CLOSEST_POINT + 1) % NUM_VERTICES;
const int32_t P3_INDEX = CLOSEST_POINT == 0 ? NUM_VERTICES - 1 : CLOSEST_POINT - 1;
const SHVec3 P1 = POLYHEDRON.GetVertex(FACE.vertexIndices[CLOSEST_POINT].index);
const SHVec3 P2 = POLYHEDRON.GetVertex(FACE.vertexIndices[P2_INDEX].index);
const SHVec3 P3 = POLYHEDRON.GetVertex(FACE.vertexIndices[P3_INDEX].index);
const SHVec3 TANGENT_1 = SHVec3::Normalise(P2 - P1);
const SHVec3 TANGENT_2 = SHVec3::Normalise(P3 - P1);
// Get the voronoi region it belongs in
const int32_t REGION = findVoronoiRegion(SPHERE, P1, FACE_NORMAL, TANGENT_1, TANGENT_2);
return REGION > 0;
} }
bool SHCollision::ConvexVsSphere(const SHCollisionShape& A, const SHCollisionShape& B) noexcept bool SHCollision::ConvexVsSphere(const SHCollisionShape& A, const SHCollisionShape& B) noexcept
@ -69,13 +92,12 @@ namespace SHADE
contact.featurePair.key = 0; contact.featurePair.key = 0;
// Check if center is inside polyhedron (below the face) // Check if center is inside polyhedron (below the face)
// TODO: Change to a point in polygon test.
if (FACE_QUERY.bestDistance < SHMath::EPSILON) if (FACE_QUERY.bestDistance < SHMath::EPSILON)
{ {
manifold.normal = -POLYHEDRON.GetNormal(FACE_QUERY.closestFace); manifold.normal = -POLYHEDRON.GetNormal(FACE_QUERY.closestFace);
contact.penetration = PENETRATION; contact.penetration = PENETRATION;
contact.position = SPHERE.GetCenter(); contact.position = SPHERE.GetCenter();
manifold.contacts[numContacts++] = contact; manifold.contacts[numContacts++] = contact;
manifold.numContacts = numContacts; manifold.numContacts = numContacts;
@ -86,10 +108,9 @@ namespace SHADE
// Find closest face of polygon to circle // Find closest face of polygon to circle
const int32_t CLOSEST_POINT = findClosestPoint(SPHERE, POLYHEDRON, FACE_QUERY.closestFace); const int32_t CLOSEST_POINT = findClosestPoint(SPHERE, POLYHEDRON, FACE_QUERY.closestFace);
const SHHalfEdgeStructure::Face& FACE = POLYHEDRON.GetFace(FACE_QUERY.closestFace); const auto& FACE = POLYHEDRON.GetFace(FACE_QUERY.closestFace);
const SHVec3& FACE_NORMAL = POLYHEDRON.GetNormal(FACE_QUERY.closestFace);
const SHVec3& FACE_NORMAL = POLYHEDRON.GetNormal(FACE_QUERY.closestFace); const int32_t NUM_VERTICES = static_cast<int32_t>(FACE.vertexIndices.size());
const int32_t NUM_VERTICES = static_cast<int32_t>(FACE.vertexIndices.size());
// Get points and build tangents // Get points and build tangents
const int32_t P2_INDEX = (CLOSEST_POINT + 1) % NUM_VERTICES; const int32_t P2_INDEX = (CLOSEST_POINT + 1) % NUM_VERTICES;
@ -238,7 +259,7 @@ namespace SHADE
static constexpr int NUM_TANGENTS = 2; static constexpr int NUM_TANGENTS = 2;
// Check against voronoi regions of the face to determine the type of the intersection test // Check against voronoi regions of the face to determine the type of the intersection test
// We have 3 voronoi regions to check: cp -> prev, cp -> next and cp -> center // We have 3 voronoi regions to check: 1 -> 2, 1 -> 3 and 1 -> center
// If none of these are true, the sphere is above the face but not separating // If none of these are true, the sphere is above the face but not separating
/* /*