Do not compute contacts if not necessary
This commit is contained in:
parent
8b82c4ac81
commit
b6ad69b278
|
@ -91,6 +91,8 @@ bool CapsuleVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo,
|
||||||
// If the segments were overlapping (the clip segment is valid)
|
// If the segments were overlapping (the clip segment is valid)
|
||||||
if (t1 > decimal(0.0) && t2 > decimal(0.0)) {
|
if (t1 > decimal(0.0) && t2 > decimal(0.0)) {
|
||||||
|
|
||||||
|
if (reportContacts) {
|
||||||
|
|
||||||
// Clip the inner segment of capsule 2
|
// Clip the inner segment of capsule 2
|
||||||
if (t1 > decimal(1.0)) t1 = decimal(1.0);
|
if (t1 > decimal(1.0)) t1 = decimal(1.0);
|
||||||
const Vector3 clipPointA = capsule2SegB - t1 * seg2;
|
const Vector3 clipPointA = capsule2SegB - t1 * seg2;
|
||||||
|
@ -119,6 +121,8 @@ bool CapsuleVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo,
|
||||||
narrowPhaseInfo->addContactPoint(normalWorld, penetrationDepth, contactPointACapsule1Local, contactPointACapsule2Local);
|
narrowPhaseInfo->addContactPoint(normalWorld, penetrationDepth, contactPointACapsule1Local, contactPointACapsule2Local);
|
||||||
narrowPhaseInfo->addContactPoint(normalWorld, penetrationDepth, contactPointBCapsule1Local, contactPointBCapsule2Local);
|
narrowPhaseInfo->addContactPoint(normalWorld, penetrationDepth, contactPointBCapsule1Local, contactPointBCapsule2Local);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,6 +141,8 @@ bool CapsuleVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo,
|
||||||
// If the collision shapes overlap
|
// If the collision shapes overlap
|
||||||
if (closestPointsDistanceSquare < sumRadius * sumRadius && closestPointsDistanceSquare > MACHINE_EPSILON) {
|
if (closestPointsDistanceSquare < sumRadius * sumRadius && closestPointsDistanceSquare > MACHINE_EPSILON) {
|
||||||
|
|
||||||
|
if (reportContacts) {
|
||||||
|
|
||||||
decimal closestPointsDistance = std::sqrt(closestPointsDistanceSquare);
|
decimal closestPointsDistance = std::sqrt(closestPointsDistanceSquare);
|
||||||
closestPointsSeg1ToSeg2 /= closestPointsDistance;
|
closestPointsSeg1ToSeg2 /= closestPointsDistance;
|
||||||
|
|
||||||
|
@ -150,6 +156,8 @@ bool CapsuleVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo,
|
||||||
// Create the contact info object
|
// Create the contact info object
|
||||||
narrowPhaseInfo->addContactPoint(normalWorld, penetrationDepth, contactPointCapsule1Local, contactPointCapsule2Local);
|
narrowPhaseInfo->addContactPoint(normalWorld, penetrationDepth, contactPointCapsule1Local, contactPointCapsule2Local);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,8 @@ bool CapsuleVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPh
|
||||||
// If we have found a contact point inside the margins (shallow penetration)
|
// If we have found a contact point inside the margins (shallow penetration)
|
||||||
if (result == GJKAlgorithm::GJKResult::COLLIDE_IN_MARGIN) {
|
if (result == GJKAlgorithm::GJKResult::COLLIDE_IN_MARGIN) {
|
||||||
|
|
||||||
|
if (reportContacts) {
|
||||||
|
|
||||||
// GJK has found a shallow contact. If the face of the polyhedron mesh is orthogonal to the
|
// GJK has found a shallow contact. If the face of the polyhedron mesh is orthogonal to the
|
||||||
// capsule inner segment and parallel to the contact point normal, we would like to create
|
// capsule inner segment and parallel to the contact point normal, we would like to create
|
||||||
// two contact points instead of a single one (as in the deep contact case with SAT algorithm)
|
// two contact points instead of a single one (as in the deep contact case with SAT algorithm)
|
||||||
|
@ -121,6 +123,8 @@ bool CapsuleVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
narrowPhaseInfo->overlappingPair->getLastFrameCollisionInfo().wasUsingSAT = false;
|
narrowPhaseInfo->overlappingPair->getLastFrameCollisionInfo().wasUsingSAT = false;
|
||||||
narrowPhaseInfo->overlappingPair->getLastFrameCollisionInfo().wasUsingGJK = false;
|
narrowPhaseInfo->overlappingPair->getLastFrameCollisionInfo().wasUsingGJK = false;
|
||||||
|
|
||||||
|
|
|
@ -83,8 +83,6 @@ class NarrowPhaseAlgorithm {
|
||||||
/// Deleted assignment operator
|
/// Deleted assignment operator
|
||||||
NarrowPhaseAlgorithm& operator=(const NarrowPhaseAlgorithm& algorithm) = delete;
|
NarrowPhaseAlgorithm& operator=(const NarrowPhaseAlgorithm& algorithm) = delete;
|
||||||
|
|
||||||
// TODO : Use the following reportContacts variable in all narrow-phase algorithms
|
|
||||||
|
|
||||||
/// Compute a contact info if the two bounding volume collide
|
/// Compute a contact info if the two bounding volume collide
|
||||||
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts)=0;
|
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts)=0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -139,6 +139,8 @@ bool SATAlgorithm::testCollisionSphereVsConvexPolyhedron(NarrowPhaseInfo* narrow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (reportContacts) {
|
||||||
|
|
||||||
const Vector3 minFaceNormal = polyhedron->getFaceNormal(minFaceIndex);
|
const Vector3 minFaceNormal = polyhedron->getFaceNormal(minFaceIndex);
|
||||||
Vector3 normalWorld = -(polyhedronToWorldTransform.getOrientation() * minFaceNormal);
|
Vector3 normalWorld = -(polyhedronToWorldTransform.getOrientation() * minFaceNormal);
|
||||||
const Vector3 contactPointSphereLocal = sphereToWorldTransform.getInverse().getOrientation() * normalWorld * sphere->getRadius();
|
const Vector3 contactPointSphereLocal = sphereToWorldTransform.getInverse().getOrientation() * normalWorld * sphere->getRadius();
|
||||||
|
@ -148,6 +150,7 @@ bool SATAlgorithm::testCollisionSphereVsConvexPolyhedron(NarrowPhaseInfo* narrow
|
||||||
narrowPhaseInfo->addContactPoint(normalWorld, minPenetrationDepth,
|
narrowPhaseInfo->addContactPoint(normalWorld, minPenetrationDepth,
|
||||||
isSphereShape1 ? contactPointSphereLocal : contactPointPolyhedronLocal,
|
isSphereShape1 ? contactPointSphereLocal : contactPointPolyhedronLocal,
|
||||||
isSphereShape1 ? contactPointPolyhedronLocal : contactPointSphereLocal);
|
isSphereShape1 ? contactPointPolyhedronLocal : contactPointSphereLocal);
|
||||||
|
}
|
||||||
|
|
||||||
lastFrameInfo.satMinAxisFaceIndex = minFaceIndex;
|
lastFrameInfo.satMinAxisFaceIndex = minFaceIndex;
|
||||||
|
|
||||||
|
@ -384,16 +387,21 @@ bool SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron(NarrowPhaseInfo* narro
|
||||||
// We need to clip the inner capsule segment with the adjacent faces of the separating face
|
// We need to clip the inner capsule segment with the adjacent faces of the separating face
|
||||||
if (isMinPenetrationFaceNormal) {
|
if (isMinPenetrationFaceNormal) {
|
||||||
|
|
||||||
|
if (reportContacts) {
|
||||||
|
|
||||||
computeCapsulePolyhedronFaceContactPoints(minFaceIndex, capsuleRadius, polyhedron, minPenetrationDepth,
|
computeCapsulePolyhedronFaceContactPoints(minFaceIndex, capsuleRadius, polyhedron, minPenetrationDepth,
|
||||||
polyhedronToCapsuleTransform, normalWorld, separatingAxisCapsuleSpace,
|
polyhedronToCapsuleTransform, normalWorld, separatingAxisCapsuleSpace,
|
||||||
capsuleSegAPolyhedronSpace, capsuleSegBPolyhedronSpace,
|
capsuleSegAPolyhedronSpace, capsuleSegBPolyhedronSpace,
|
||||||
narrowPhaseInfo, isCapsuleShape1);
|
narrowPhaseInfo, isCapsuleShape1);
|
||||||
|
}
|
||||||
|
|
||||||
lastFrameInfo.satIsAxisFacePolyhedron1 = true;
|
lastFrameInfo.satIsAxisFacePolyhedron1 = true;
|
||||||
lastFrameInfo.satMinAxisFaceIndex = minFaceIndex;
|
lastFrameInfo.satMinAxisFaceIndex = minFaceIndex;
|
||||||
}
|
}
|
||||||
else { // The separating axis is the cross product of a polyhedron edge and the inner capsule segment
|
else { // The separating axis is the cross product of a polyhedron edge and the inner capsule segment
|
||||||
|
|
||||||
|
if (reportContacts) {
|
||||||
|
|
||||||
// Compute the closest points between the inner capsule segment and the
|
// Compute the closest points between the inner capsule segment and the
|
||||||
// edge of the polyhedron in polyhedron local-space
|
// edge of the polyhedron in polyhedron local-space
|
||||||
Vector3 closestPointPolyhedronEdge, closestPointCapsuleInnerSegment;
|
Vector3 closestPointPolyhedronEdge, closestPointCapsuleInnerSegment;
|
||||||
|
@ -401,7 +409,6 @@ bool SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron(NarrowPhaseInfo* narro
|
||||||
separatingPolyhedronEdgeVertex1, separatingPolyhedronEdgeVertex2,
|
separatingPolyhedronEdgeVertex1, separatingPolyhedronEdgeVertex2,
|
||||||
closestPointCapsuleInnerSegment, closestPointPolyhedronEdge);
|
closestPointCapsuleInnerSegment, closestPointPolyhedronEdge);
|
||||||
|
|
||||||
|
|
||||||
// Project closest capsule inner segment point into the capsule bounds
|
// Project closest capsule inner segment point into the capsule bounds
|
||||||
const Vector3 contactPointCapsule = (polyhedronToCapsuleTransform * closestPointCapsuleInnerSegment) - separatingAxisCapsuleSpace * capsuleRadius;
|
const Vector3 contactPointCapsule = (polyhedronToCapsuleTransform * closestPointCapsuleInnerSegment) - separatingAxisCapsuleSpace * capsuleRadius;
|
||||||
|
|
||||||
|
@ -409,6 +416,7 @@ bool SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron(NarrowPhaseInfo* narro
|
||||||
narrowPhaseInfo->addContactPoint(normalWorld, minPenetrationDepth,
|
narrowPhaseInfo->addContactPoint(normalWorld, minPenetrationDepth,
|
||||||
isCapsuleShape1 ? contactPointCapsule : closestPointPolyhedronEdge,
|
isCapsuleShape1 ? contactPointCapsule : closestPointPolyhedronEdge,
|
||||||
isCapsuleShape1 ? closestPointPolyhedronEdge : contactPointCapsule);
|
isCapsuleShape1 ? closestPointPolyhedronEdge : contactPointCapsule);
|
||||||
|
}
|
||||||
|
|
||||||
lastFrameInfo.satIsAxisFacePolyhedron1 = false;
|
lastFrameInfo.satIsAxisFacePolyhedron1 = false;
|
||||||
lastFrameInfo.satMinEdge1Index = minEdgeIndex;
|
lastFrameInfo.satMinEdge1Index = minEdgeIndex;
|
||||||
|
@ -543,8 +551,7 @@ bool SATAlgorithm::isMinkowskiFaceCapsuleVsEdge(const Vector3& capsuleSegment, c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test collision between two convex polyhedrons
|
// Test collision between two convex polyhedrons
|
||||||
bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseInfo* narrowPhaseInfo,
|
bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) const {
|
||||||
bool reportContacts) const {
|
|
||||||
|
|
||||||
PROFILE("SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron()");
|
PROFILE("SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron()");
|
||||||
|
|
||||||
|
@ -787,6 +794,8 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn
|
||||||
// If the minimum separating axis is a face normal
|
// If the minimum separating axis is a face normal
|
||||||
if (isMinPenetrationFaceNormal) {
|
if (isMinPenetrationFaceNormal) {
|
||||||
|
|
||||||
|
if (reportContacts) {
|
||||||
|
|
||||||
const ConvexPolyhedronShape* referencePolyhedron = isMinPenetrationFaceNormalPolyhedron1 ? polyhedron1 : polyhedron2;
|
const ConvexPolyhedronShape* referencePolyhedron = isMinPenetrationFaceNormalPolyhedron1 ? polyhedron1 : polyhedron2;
|
||||||
const ConvexPolyhedronShape* incidentPolyhedron = isMinPenetrationFaceNormalPolyhedron1 ? polyhedron2 : polyhedron1;
|
const ConvexPolyhedronShape* incidentPolyhedron = isMinPenetrationFaceNormalPolyhedron1 ? polyhedron2 : polyhedron1;
|
||||||
const Transform& referenceToIncidentTransform = isMinPenetrationFaceNormalPolyhedron1 ? polyhedron1ToPolyhedron2 : polyhedron2ToPolyhedron1;
|
const Transform& referenceToIncidentTransform = isMinPenetrationFaceNormalPolyhedron1 ? polyhedron1ToPolyhedron2 : polyhedron2ToPolyhedron1;
|
||||||
|
@ -859,8 +868,7 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn
|
||||||
for (itPoints = clipPolygonVertices.begin(); itPoints != clipPolygonVertices.end(); ++itPoints) {
|
for (itPoints = clipPolygonVertices.begin(); itPoints != clipPolygonVertices.end(); ++itPoints) {
|
||||||
|
|
||||||
// If the clip point is bellow the reference face
|
// If the clip point is bellow the reference face
|
||||||
if (((*itPoints) - referenceFaceVertex).dot(axisReferenceSpace) < decimal(0.0))
|
if (((*itPoints) - referenceFaceVertex).dot(axisReferenceSpace) < decimal(0.0)) {
|
||||||
{
|
|
||||||
|
|
||||||
// Convert the clip incident polyhedron vertex into the incident polyhedron local-space
|
// Convert the clip incident polyhedron vertex into the incident polyhedron local-space
|
||||||
const Vector3 contactPointIncidentPolyhedron = referenceToIncidentTransform * (*itPoints);
|
const Vector3 contactPointIncidentPolyhedron = referenceToIncidentTransform * (*itPoints);
|
||||||
|
@ -874,6 +882,7 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn
|
||||||
isMinPenetrationFaceNormalPolyhedron1 ? contactPointIncidentPolyhedron : contactPointReferencePolyhedron);
|
isMinPenetrationFaceNormalPolyhedron1 ? contactPointIncidentPolyhedron : contactPointReferencePolyhedron);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lastFrameInfo.satIsAxisFacePolyhedron1 = isMinPenetrationFaceNormalPolyhedron1;
|
lastFrameInfo.satIsAxisFacePolyhedron1 = isMinPenetrationFaceNormalPolyhedron1;
|
||||||
lastFrameInfo.satIsAxisFacePolyhedron2 = !isMinPenetrationFaceNormalPolyhedron1;
|
lastFrameInfo.satIsAxisFacePolyhedron2 = !isMinPenetrationFaceNormalPolyhedron1;
|
||||||
|
@ -881,6 +890,8 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn
|
||||||
}
|
}
|
||||||
else { // If we have an edge vs edge contact
|
else { // If we have an edge vs edge contact
|
||||||
|
|
||||||
|
if (reportContacts) {
|
||||||
|
|
||||||
// Compute the closest points between the two edges (in the local-space of poylhedron 2)
|
// Compute the closest points between the two edges (in the local-space of poylhedron 2)
|
||||||
Vector3 closestPointPolyhedron1Edge, closestPointPolyhedron2Edge;
|
Vector3 closestPointPolyhedron1Edge, closestPointPolyhedron2Edge;
|
||||||
computeClosestPointBetweenTwoSegments(separatingEdge1A, separatingEdge1B, separatingEdge2A, separatingEdge2B,
|
computeClosestPointBetweenTwoSegments(separatingEdge1A, separatingEdge1B, separatingEdge2A, separatingEdge2B,
|
||||||
|
@ -895,6 +906,7 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn
|
||||||
// Create the contact point
|
// Create the contact point
|
||||||
narrowPhaseInfo->addContactPoint(normalWorld, minPenetrationDepth,
|
narrowPhaseInfo->addContactPoint(normalWorld, minPenetrationDepth,
|
||||||
closestPointPolyhedron1EdgeLocalSpace, closestPointPolyhedron2Edge);
|
closestPointPolyhedron1EdgeLocalSpace, closestPointPolyhedron2Edge);
|
||||||
|
}
|
||||||
|
|
||||||
lastFrameInfo.satIsAxisFacePolyhedron1 = false;
|
lastFrameInfo.satIsAxisFacePolyhedron1 = false;
|
||||||
lastFrameInfo.satIsAxisFacePolyhedron2 = false;
|
lastFrameInfo.satIsAxisFacePolyhedron2 = false;
|
||||||
|
|
|
@ -71,6 +71,8 @@ bool SphereVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, b
|
||||||
// If the collision shapes overlap
|
// If the collision shapes overlap
|
||||||
if (sphereSegmentDistanceSquare < sumRadius * sumRadius && sphereSegmentDistanceSquare > MACHINE_EPSILON) {
|
if (sphereSegmentDistanceSquare < sumRadius * sumRadius && sphereSegmentDistanceSquare > MACHINE_EPSILON) {
|
||||||
|
|
||||||
|
if (reportContacts) {
|
||||||
|
|
||||||
decimal sphereSegmentDistance = std::sqrt(sphereSegmentDistanceSquare);
|
decimal sphereSegmentDistance = std::sqrt(sphereSegmentDistanceSquare);
|
||||||
sphereCenterToSegment /= sphereSegmentDistance;
|
sphereCenterToSegment /= sphereSegmentDistance;
|
||||||
|
|
||||||
|
@ -89,6 +91,7 @@ bool SphereVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, b
|
||||||
narrowPhaseInfo->addContactPoint(normalWorld, penetrationDepth,
|
narrowPhaseInfo->addContactPoint(normalWorld, penetrationDepth,
|
||||||
isSphereShape1 ? contactPointSphereLocal : contactPointCapsuleLocal,
|
isSphereShape1 ? contactPointSphereLocal : contactPointCapsuleLocal,
|
||||||
isSphereShape1 ? contactPointCapsuleLocal : contactPointSphereLocal);
|
isSphereShape1 ? contactPointCapsuleLocal : contactPointSphereLocal);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,9 @@ bool SphereVsSphereAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bo
|
||||||
|
|
||||||
// If the sphere collision shapes intersect
|
// If the sphere collision shapes intersect
|
||||||
if (squaredDistanceBetweenCenters < sumRadius * sumRadius) {
|
if (squaredDistanceBetweenCenters < sumRadius * sumRadius) {
|
||||||
|
|
||||||
|
if (reportContacts) {
|
||||||
|
|
||||||
Vector3 centerSphere2InBody1LocalSpace = transform1.getInverse() * transform2.getPosition();
|
Vector3 centerSphere2InBody1LocalSpace = transform1.getInverse() * transform2.getPosition();
|
||||||
Vector3 centerSphere1InBody2LocalSpace = transform2.getInverse() * transform1.getPosition();
|
Vector3 centerSphere1InBody2LocalSpace = transform2.getInverse() * transform1.getPosition();
|
||||||
Vector3 intersectionOnBody1 = sphereShape1->getRadius() *
|
Vector3 intersectionOnBody1 = sphereShape1->getRadius() *
|
||||||
|
@ -63,6 +66,7 @@ bool SphereVsSphereAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bo
|
||||||
// Create the contact info object
|
// Create the contact info object
|
||||||
narrowPhaseInfo->addContactPoint(vectorBetweenCenters.getUnit(), penetrationDepth,
|
narrowPhaseInfo->addContactPoint(vectorBetweenCenters.getUnit(), penetrationDepth,
|
||||||
intersectionOnBody1, intersectionOnBody2);
|
intersectionOnBody1, intersectionOnBody2);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user