Remove temporal coherence from SAT for sphere vs polyhedron and capsule vs polyhedron
This commit is contained in:
parent
9b89f66667
commit
673e487f14
|
@ -74,49 +74,6 @@ bool SATAlgorithm::testCollisionSphereVsConvexPolyhedron(NarrowPhaseInfo* narrow
|
|||
decimal minPenetrationDepth = DECIMAL_LARGEST;
|
||||
uint minFaceIndex = 0;
|
||||
|
||||
// True if the shapes were overlapping in the previous frame and are
|
||||
// still overlapping on the same axis in this frame
|
||||
bool isTemporalCoherenceValid = false;
|
||||
|
||||
LastFrameCollisionInfo& lastFrameInfo = narrowPhaseInfo->overlappingPair->getLastFrameCollisionInfo();
|
||||
|
||||
// If the shapes are not triangles (no temporal coherence for triangle collision because we do not store previous
|
||||
// frame collision data per triangle)
|
||||
if (polyhedron->getName() != CollisionShapeName::TRIANGLE) {
|
||||
|
||||
// If the last frame collision info is valid and was also using SAT algorithm
|
||||
if (lastFrameInfo.isValid && lastFrameInfo.wasUsingSAT) {
|
||||
|
||||
// We perform temporal coherence, we check if there is still an overlapping along the previous minimum separating
|
||||
// axis. If it is the case, we directly report the collision without executing the whole SAT algorithm again. If
|
||||
// the shapes are still separated along this axis, we directly exit with no collision.
|
||||
|
||||
// Compute the penetration depth of the shapes along the face normal direction
|
||||
decimal penetrationDepth = computePolyhedronFaceVsSpherePenetrationDepth(lastFrameInfo.satMinAxisFaceIndex, polyhedron,
|
||||
sphere, sphereCenter);
|
||||
|
||||
// If the previous axis is a separating axis
|
||||
if (penetrationDepth <= decimal(0.0)) {
|
||||
|
||||
// Return no collision
|
||||
return false;
|
||||
}
|
||||
|
||||
// The two shapes are overlapping as in the previous frame and on the same axis, therefore
|
||||
// we will skip the entire SAT algorithm because the minimum separating axis did not change
|
||||
isTemporalCoherenceValid = lastFrameInfo.wasColliding;
|
||||
|
||||
if (isTemporalCoherenceValid) {
|
||||
|
||||
minPenetrationDepth = penetrationDepth;
|
||||
minFaceIndex = lastFrameInfo.satMinAxisFaceIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We the shapes are still overlapping in the same axis as in
|
||||
// the previous frame, we skip the whole SAT algorithm
|
||||
if (!isTemporalCoherenceValid) {
|
||||
|
||||
// For each face of the convex mesh
|
||||
for (uint f = 0; f < polyhedron->getNbFaces(); f++) {
|
||||
|
@ -127,8 +84,6 @@ bool SATAlgorithm::testCollisionSphereVsConvexPolyhedron(NarrowPhaseInfo* narrow
|
|||
// If the penetration depth is negative, we have found a separating axis
|
||||
if (penetrationDepth <= decimal(0.0)) {
|
||||
|
||||
lastFrameInfo.satMinAxisFaceIndex = f;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -138,7 +93,6 @@ bool SATAlgorithm::testCollisionSphereVsConvexPolyhedron(NarrowPhaseInfo* narrow
|
|||
minFaceIndex = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reportContacts) {
|
||||
|
||||
|
@ -161,8 +115,6 @@ bool SATAlgorithm::testCollisionSphereVsConvexPolyhedron(NarrowPhaseInfo* narrow
|
|||
isSphereShape1 ? contactPointPolyhedronLocal : contactPointSphereLocal);
|
||||
}
|
||||
|
||||
lastFrameInfo.satMinAxisFaceIndex = minFaceIndex;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -217,97 +169,6 @@ bool SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron(NarrowPhaseInfo* narro
|
|||
Vector3 separatingPolyhedronEdgeVertex1;
|
||||
Vector3 separatingPolyhedronEdgeVertex2;
|
||||
|
||||
// True if the shapes were overlapping in the previous frame and are
|
||||
// still overlapping on the same axis in this frame
|
||||
bool isTemporalCoherenceValid = false;
|
||||
|
||||
LastFrameCollisionInfo& lastFrameInfo = narrowPhaseInfo->overlappingPair->getLastFrameCollisionInfo();
|
||||
|
||||
// If the shapes are not triangles (no temporal coherence for triangle collision because we do not store previous
|
||||
// frame collision data per triangle)
|
||||
if (polyhedron->getName() != CollisionShapeName::TRIANGLE) {
|
||||
|
||||
// If the last frame collision info is valid and was also using SAT algorithm
|
||||
if (lastFrameInfo.isValid && lastFrameInfo.wasUsingSAT) {
|
||||
|
||||
// We perform temporal coherence, we check if there is still an overlapping along the previous minimum separating
|
||||
// axis. If it is the case, we directly report the collision without executing the whole SAT algorithm again. If
|
||||
// the shapes are still separated along this axis, we directly exit with no collision.
|
||||
|
||||
// If the previous minimum separation axis was a face normal of the polyhedron
|
||||
if (lastFrameInfo.satIsAxisFacePolyhedron1) {
|
||||
|
||||
Vector3 outFaceNormalCapsuleSpace;
|
||||
|
||||
// Compute the penetration depth along the polyhedron face normal direction
|
||||
const decimal penetrationDepth = computePolyhedronFaceVsCapsulePenetrationDepth(lastFrameInfo.satMinAxisFaceIndex, polyhedron,
|
||||
capsuleShape, polyhedronToCapsuleTransform,
|
||||
outFaceNormalCapsuleSpace);
|
||||
|
||||
// If the previous axis is a separating axis
|
||||
if (penetrationDepth <= decimal(0.0)) {
|
||||
|
||||
// Return no collision
|
||||
return false;
|
||||
}
|
||||
|
||||
// The two shapes are overlapping as in the previous frame and on the same axis, therefore
|
||||
// we will skip the entire SAT algorithm because the minimum separating axis did not change
|
||||
isTemporalCoherenceValid = lastFrameInfo.wasColliding;
|
||||
|
||||
if (isTemporalCoherenceValid) {
|
||||
|
||||
minPenetrationDepth = penetrationDepth;
|
||||
minFaceIndex = lastFrameInfo.satMinAxisFaceIndex;
|
||||
isMinPenetrationFaceNormal = true;
|
||||
separatingAxisCapsuleSpace = outFaceNormalCapsuleSpace;
|
||||
}
|
||||
}
|
||||
else { // If the previous minimum separation axis the cross product of the capsule inner segment and an edge of the polyhedron
|
||||
|
||||
// Get an edge from the polyhedron (convert it into the capsule local-space)
|
||||
HalfEdgeStructure::Edge edge = polyhedron->getHalfEdge(lastFrameInfo.satMinEdge1Index);
|
||||
const Vector3 edgeVertex1 = polyhedron->getVertexPosition(edge.vertexIndex);
|
||||
const Vector3 edgeVertex2 = polyhedron->getVertexPosition(polyhedron->getHalfEdge(edge.nextEdgeIndex).vertexIndex);
|
||||
const Vector3 edgeDirectionCapsuleSpace = polyhedronToCapsuleTransform.getOrientation() * (edgeVertex2 - edgeVertex1);
|
||||
|
||||
Vector3 outAxis;
|
||||
|
||||
// Compute the penetration depth along this axis
|
||||
const decimal penetrationDepth = computeEdgeVsCapsuleInnerSegmentPenetrationDepth(polyhedron, capsuleShape,
|
||||
capsuleSegmentAxis, edgeVertex1,
|
||||
edgeDirectionCapsuleSpace,
|
||||
polyhedronToCapsuleTransform,
|
||||
outAxis);
|
||||
|
||||
// If the previous axis is a separating axis
|
||||
if (penetrationDepth <= decimal(0.0)) {
|
||||
|
||||
// Return no collision
|
||||
return false;
|
||||
}
|
||||
|
||||
// The two shapes are overlapping as in the previous frame and on the same axis, therefore
|
||||
// we will skip the entire SAT algorithm because the minimum separating axis did not change
|
||||
isTemporalCoherenceValid = lastFrameInfo.wasColliding;
|
||||
|
||||
if (isTemporalCoherenceValid) {
|
||||
|
||||
minPenetrationDepth = penetrationDepth;
|
||||
minEdgeIndex = lastFrameInfo.satMinEdge1Index;
|
||||
isMinPenetrationFaceNormal = false;
|
||||
separatingAxisCapsuleSpace = outAxis;
|
||||
separatingPolyhedronEdgeVertex1 = edgeVertex1;
|
||||
separatingPolyhedronEdgeVertex2 = edgeVertex2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the shapes are still overlapping in the same axis as in the previous frame
|
||||
// the previous frame, we skip the whole SAT algorithm
|
||||
if (!isTemporalCoherenceValid) {
|
||||
|
||||
// For each face of the convex mesh
|
||||
for (uint f = 0; f < polyhedron->getNbFaces(); f++) {
|
||||
|
||||
|
@ -321,9 +182,6 @@ bool SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron(NarrowPhaseInfo* narro
|
|||
// If the penetration depth is negative, we have found a separating axis
|
||||
if (penetrationDepth <= decimal(0.0)) {
|
||||
|
||||
lastFrameInfo.satIsAxisFacePolyhedron1 = true;
|
||||
lastFrameInfo.satMinAxisFaceIndex = f;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -364,9 +222,6 @@ bool SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron(NarrowPhaseInfo* narro
|
|||
// If the penetration depth is negative, we have found a separating axis
|
||||
if (penetrationDepth <= decimal(0.0)) {
|
||||
|
||||
lastFrameInfo.satIsAxisFacePolyhedron1 = false;
|
||||
lastFrameInfo.satMinEdge1Index = e;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -382,8 +237,6 @@ bool SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron(NarrowPhaseInfo* narro
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Convert the inner capsule segment points into the polyhedron local-space
|
||||
const Transform capsuleToPolyhedronTransform = polyhedronToCapsuleTransform.getInverse();
|
||||
const Vector3 capsuleSegAPolyhedronSpace = capsuleToPolyhedronTransform * capsuleSegA;
|
||||
|
@ -404,8 +257,6 @@ bool SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron(NarrowPhaseInfo* narro
|
|||
narrowPhaseInfo, isCapsuleShape1);
|
||||
}
|
||||
|
||||
lastFrameInfo.satIsAxisFacePolyhedron1 = true;
|
||||
lastFrameInfo.satMinAxisFaceIndex = minFaceIndex;
|
||||
}
|
||||
else { // The separating axis is the cross product of a polyhedron edge and the inner capsule segment
|
||||
|
||||
|
@ -433,9 +284,6 @@ bool SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron(NarrowPhaseInfo* narro
|
|||
isCapsuleShape1 ? contactPointCapsule : closestPointPolyhedronEdge,
|
||||
isCapsuleShape1 ? closestPointPolyhedronEdge : contactPointCapsule);
|
||||
}
|
||||
|
||||
lastFrameInfo.satIsAxisFacePolyhedron1 = false;
|
||||
lastFrameInfo.satMinEdge1Index = minEdgeIndex;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue
Block a user