Skip to content

Commit

Permalink
Fix issue with missing collision between capsule and triangle edge if…
Browse files Browse the repository at this point in the history
… edge is parallel to capsule segment
  • Loading branch information
DanielChappuis committed Feb 5, 2024
1 parent 4ec3899 commit abfa55a
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
- Issue [#237](https://github.com/DanielChappuis/reactphysics3d/issues/237) Wrong assert has been removed
- Issue [#239](https://github.com/DanielChappuis/reactphysics3d/issues/239) Memory allocation alignment
- Issue [#240](https://github.com/DanielChappuis/reactphysics3d/issues/240) Uninitialized variable
- Issue [#347](https://github.com/DanielChappuis/reactphysics3d/issues/347) Missing collision between capsule and triangle edge in some case
- Issue with edge vs edge collision detection for BoxShape, ConvexMeshShape, ConcaveMeshShape and HeightFieldShape (SAT algorithm)
- Compilation error on Clang 19

Expand Down
23 changes: 5 additions & 18 deletions src/collision/narrowphase/CapsuleVsConvexPolyhedronAlgorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,8 @@ bool CapsuleVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfoBatch& nar
// If we need to report contacts
if (narrowPhaseInfoBatch.narrowPhaseInfos[batchIndex].reportContacts) {

bool noContact = false;

// 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
// GJK has found a shallow contact. If the normal of face of the polyhedron mesh is orthogonal to the
// capsule inner segment (the face normal is 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)

// Get the contact point created by GJK
Expand Down Expand Up @@ -116,13 +114,13 @@ bool CapsuleVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfoBatch& nar
bool isFaceNormalInDirectionOfContactNormal = faceNormalWorld.dot(contactPoint.normal) > decimal(0.0);
bool isFaceNormalInContactDirection = (isCapsuleShape1 && !isFaceNormalInDirectionOfContactNormal) || (!isCapsuleShape1 && isFaceNormalInDirectionOfContactNormal);

// If the polyhedron face normal is orthogonal to the capsule inner segment and parallel to the contact point normal and the face normal
// If the polyhedron face normal is orthogonal to the capsule inner segment (the face normal is parallel to the contact point normal) and the face normal
// is in direction of the contact normal (from the polyhedron point of view).
if (isFaceNormalInContactDirection && areOrthogonalVectors(faceNormalWorld, capsuleInnerSegmentDirection)
&& areParallelVectors(faceNormalWorld, contactPoint.normal)) {

// Remove the previous contact point computed by GJK
narrowPhaseInfoBatch.resetContactPoints(batchIndex);
//narrowPhaseInfoBatch.resetContactPoints(batchIndex);

const Transform capsuleToWorld = isCapsuleShape1 ? narrowPhaseInfoBatch.narrowPhaseInfos[batchIndex].shape1ToWorldTransform : narrowPhaseInfoBatch.narrowPhaseInfos[batchIndex].shape2ToWorldTransform;
const Transform polyhedronToCapsuleTransform = capsuleToWorld.getInverse() * polyhedronToWorld;
Expand All @@ -147,24 +145,13 @@ bool CapsuleVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfoBatch& nar
polyhedronToCapsuleTransform, faceNormalWorld, separatingAxisCapsuleSpace,
capsuleSegAPolyhedronSpace, capsuleSegBPolyhedronSpace,
narrowPhaseInfoBatch, batchIndex, isCapsuleShape1);
if (!contactsFound) {
noContact = true;
narrowPhaseInfoBatch.narrowPhaseInfos[batchIndex].isColliding = false;
if (contactsFound) {
break;
}

break;
}
}

if (noContact) {
continue;
}
}

lastFrameCollisionInfo->wasUsingSAT = false;
lastFrameCollisionInfo->wasUsingGJK = false;

// Colision found
narrowPhaseInfoBatch.narrowPhaseInfos[batchIndex].isColliding = true;
isCollisionFound = true;
Expand Down
4 changes: 4 additions & 0 deletions src/collision/narrowphase/SAT/SATAlgorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,10 @@ bool SATAlgorithm::computeCapsulePolyhedronFaceContactPoints(uint32 referenceFac
// If the clipped point is one that produce this penetration depth, we keep it
if (clipPointPenDepth > penetrationDepth - capsuleRadius - decimal(0.001)) {

if (!contactFound) {
narrowPhaseInfoBatch.resetContactPoints(batchIndex);
}

contactFound = true;

Vector3 contactPointPolyhedron = clipSegment[i] + delta;
Expand Down

0 comments on commit abfa55a

Please sign in to comment.