MCPcopy Create free account
hub / github.com/DanielChappuis/reactphysics3d / reduceContactPoints

Method reduceContactPoints

src/systems/CollisionDetectionSystem.cpp:1483–1662  ·  view source on GitHub ↗

Reduce the number of contact points of a potential contact manifold This is based on the technique described by Dirk Gregorius in his "Contacts Creation" GDC presentation. This method will reduce the number of contact points to a maximum of 4 points (but it can be less).

Source from the content-addressed store, hash-verified

1481// "Contacts Creation" GDC presentation. This method will reduce the number of
1482// contact points to a maximum of 4 points (but it can be less).
1483void CollisionDetectionSystem::reduceContactPoints(ContactManifoldInfo& manifold, const Transform& shape1ToWorldTransform,
1484 const Array<ContactPointInfo>& potentialContactPoints) const {
1485
1486 assert(manifold.nbPotentialContactPoints > MAX_CONTACT_POINTS_IN_MANIFOLD);
1487
1488 // The following algorithm only works to reduce to a maximum of 4 contact points
1489 assert(MAX_CONTACT_POINTS_IN_MANIFOLD == 4);
1490
1491 // Array of the candidate contact points indices in the manifold. Every time that we have found a
1492 // point we want to keep, we will remove it from this array
1493 uint candidatePointsIndices[NB_MAX_CONTACT_POINTS_IN_POTENTIAL_MANIFOLD];
1494 uint8 nbCandidatePoints = manifold.nbPotentialContactPoints;
1495 for (uint8 i=0 ; i < manifold.nbPotentialContactPoints; i++) {
1496 candidatePointsIndices[i] = manifold.potentialContactPointsIndices[i];
1497 }
1498
1499 int8 nbReducedPoints = 0;
1500
1501 uint32 pointsToKeepIndices[MAX_CONTACT_POINTS_IN_MANIFOLD];
1502 for (int8 i=0; i<MAX_CONTACT_POINTS_IN_MANIFOLD; i++) {
1503 pointsToKeepIndices[i] = 0;
1504 }
1505
1506 // Compute the initial contact point we need to keep.
1507 // The first point we keep is always the point in a given
1508 // constant direction (in order to always have same contact points
1509 // between frames for better stability)
1510
1511 const Transform worldToShape1Transform = shape1ToWorldTransform.getInverse();
1512
1513 // Compute the contact normal of the manifold (we use the first contact point)
1514 // in the local-space of the first collision shape
1515 const Vector3 contactNormalShape1Space = worldToShape1Transform.getOrientation() * potentialContactPoints[candidatePointsIndices[0]].normal;
1516
1517 // Compute a search direction
1518 const Vector3 searchDirection(1, 1, 1);
1519 decimal maxDotProduct = DECIMAL_SMALLEST;
1520 uint32 elementIndexToKeep = 0;
1521 for (uint32 i=0; i < nbCandidatePoints; i++) {
1522
1523 const ContactPointInfo& element = potentialContactPoints[candidatePointsIndices[i]];
1524 decimal dotProduct = searchDirection.dot(element.localPoint1);
1525 if (dotProduct > maxDotProduct) {
1526 maxDotProduct = dotProduct;
1527 elementIndexToKeep = i;
1528 nbReducedPoints = 1;
1529 }
1530 }
1531 pointsToKeepIndices[0] = candidatePointsIndices[elementIndexToKeep];
1532 removeItemAtInArray(candidatePointsIndices, elementIndexToKeep, nbCandidatePoints);
1533 //candidatePointsIndices.removeAt(elementIndexToKeep);
1534 assert(nbReducedPoints == 1);
1535
1536 // Compute the second contact point we need to keep.
1537 // The second point we keep is the one farthest away from the first point.
1538
1539 decimal maxDistance = decimal(0.0);
1540 elementIndexToKeep = 0;

Callers

nothing calls this directly

Calls 4

getInverseMethod · 0.45
dotMethod · 0.45
lengthSquareMethod · 0.45
crossMethod · 0.45

Tested by

no test coverage detected