summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErwin Coumans <erwin.coumans@gmail.com>2022-02-25 13:43:35 -0800
committerErwin Coumans <erwin.coumans@gmail.com>2022-02-25 13:43:35 -0800
commit28b951c128b53e1dcf26271dd47b88776148a940 (patch)
treee3360b85cdc97e3e9cc746e87e44b82161c8cdc0
parent9bfca83a8f730ddf2193cd58a78b44ea40cb12bf (diff)
downloadbullet3-28b951c128b53e1dcf26271dd47b88776148a940.tar.gz
add optimization for early out for convex versus triangle mesh. Helps getting closer to Jolt Physics Benchmark (at low number of threads)
-rw-r--r--src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp43
1 files changed, 42 insertions, 1 deletions
diff --git a/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
index 52fb6b43e..8d59ba95a 100644
--- a/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
+++ b/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
@@ -103,6 +103,44 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle, int partId,
if (m_convexBodyWrap->getCollisionShape()->isConvex())
{
+#ifndef BT_DISABLE_CONVEX_CONCAVE_EARLY_OUT
+ //an early out optimisation if the object is separated from the triangle
+ //projected on the triangle normal)
+ {
+ const btVector3 v0 = m_triBodyWrap->getWorldTransform()*triangle[0];
+ const btVector3 v1 = m_triBodyWrap->getWorldTransform()*triangle[1];
+ const btVector3 v2 = m_triBodyWrap->getWorldTransform()*triangle[2];
+
+ btVector3 triangle_normal_world = ( v1 - v0).cross(v2 - v0);
+ triangle_normal_world.normalize();
+
+ btConvexShape* convex = (btConvexShape*)m_convexBodyWrap->getCollisionShape();
+
+ btVector3 localPt = convex->localGetSupportingVertex(m_convexBodyWrap->getWorldTransform().getBasis().inverse()*triangle_normal_world);
+ btVector3 worldPt = m_convexBodyWrap->getWorldTransform()*localPt;
+ //now check if this is fully on one side of the triangle
+ btScalar proj_distPt = triangle_normal_world.dot(worldPt);
+ btScalar proj_distTr = triangle_normal_world.dot(v0);
+ btScalar contact_threshold = m_manifoldPtr->getContactBreakingThreshold()+ m_resultOut->m_closestPointDistanceThreshold;
+ btScalar dist = proj_distTr - proj_distPt;
+ if (dist > contact_threshold)
+ return;
+
+ //also check the other side of the triangle
+ triangle_normal_world*=-1;
+
+ localPt = convex->localGetSupportingVertex(m_convexBodyWrap->getWorldTransform().getBasis().inverse()*triangle_normal_world);
+ worldPt = m_convexBodyWrap->getWorldTransform()*localPt;
+ //now check if this is fully on one side of the triangle
+ proj_distPt = triangle_normal_world.dot(worldPt);
+ proj_distTr = triangle_normal_world.dot(v0);
+
+ dist = proj_distTr - proj_distPt;
+ if (dist > contact_threshold)
+ return;
+ }
+#endif //BT_DISABLE_CONVEX_CONCAVE_EARLY_OUT
+
btTriangleShape tm(triangle[0], triangle[1], triangle[2]);
tm.setMargin(m_collisionMarginTriangle);
@@ -132,7 +170,10 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle, int partId,
m_resultOut->setShapeIdentifiersB(partId, triangleIndex);
}
- colAlgo->processCollision(m_convexBodyWrap, &triObWrap, *m_dispatchInfoPtr, m_resultOut);
+ {
+ BT_PROFILE("processCollision (GJK?)");
+ colAlgo->processCollision(m_convexBodyWrap, &triObWrap, *m_dispatchInfoPtr, m_resultOut);
+ }
if (m_resultOut->getBody0Internal() == m_triBodyWrap->getCollisionObject())
{