Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp')
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp277
1 files changed, 218 insertions, 59 deletions
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
index 94385fed909..dd1f3e2490f 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
@@ -17,6 +17,7 @@ subject to the following restrictions:
///If you experience problems with capsule-capsule collision, try to define BT_DISABLE_CAPSULE_CAPSULE_COLLIDER and report it in the Bullet forums
///with reproduction case
//define BT_DISABLE_CAPSULE_CAPSULE_COLLIDER 1
+//#define ZERO_MARGIN
#include "btConvexConvexAlgorithm.h"
@@ -26,6 +27,8 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
+#include "BulletCollision/CollisionShapes/btTriangleShape.h"
+
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
@@ -48,7 +51,7 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
-
+#include "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h"
///////////
@@ -331,6 +334,8 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
#endif //BT_DISABLE_CAPSULE_CAPSULE_COLLIDER
+
+
#ifdef USE_SEPDISTANCE_UTIL2
if (dispatchInfo.m_useConvexConservativeDistanceUtil)
{
@@ -357,13 +362,14 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
} else
#endif //USE_SEPDISTANCE_UTIL2
{
- if (dispatchInfo.m_convexMaxDistanceUseCPT)
- {
- input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold();
- } else
- {
- input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
- }
+ //if (dispatchInfo.m_convexMaxDistanceUseCPT)
+ //{
+ // input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold();
+ //} else
+ //{
+ input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
+// }
+
input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
}
@@ -371,7 +377,7 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
input.m_transformA = body0->getWorldTransform();
input.m_transformB = body1->getWorldTransform();
- gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
+
@@ -389,6 +395,155 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
}
#endif //USE_SEPDISTANCE_UTIL2
+ if (min0->isPolyhedral() && min1->isPolyhedral())
+ {
+
+
+ struct btDummyResult : public btDiscreteCollisionDetectorInterface::Result
+ {
+ virtual void setShapeIdentifiersA(int partId0,int index0){}
+ virtual void setShapeIdentifiersB(int partId1,int index1){}
+ virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
+ {
+ }
+ };
+
+ btDummyResult dummy;
+
+
+ btPolyhedralConvexShape* polyhedronA = (btPolyhedralConvexShape*) min0;
+ btPolyhedralConvexShape* polyhedronB = (btPolyhedralConvexShape*) min1;
+ if (polyhedronA->getConvexPolyhedron() && polyhedronB->getConvexPolyhedron())
+ {
+
+
+
+
+ btScalar threshold = m_manifoldPtr->getContactBreakingThreshold();
+
+ btScalar minDist = -1e30f;
+ btVector3 sepNormalWorldSpace;
+ bool foundSepAxis = true;
+
+ if (dispatchInfo.m_enableSatConvex)
+ {
+ foundSepAxis = btPolyhedralContactClipping::findSeparatingAxis(
+ *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
+ body0->getWorldTransform(),
+ body1->getWorldTransform(),
+ sepNormalWorldSpace);
+ } else
+ {
+#ifdef ZERO_MARGIN
+ gjkPairDetector.setIgnoreMargin(true);
+ gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
+#else
+ //gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
+ gjkPairDetector.getClosestPoints(input,dummy,dispatchInfo.m_debugDraw);
+#endif //ZERO_MARGIN
+ btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2();
+ if (l2>SIMD_EPSILON)
+ {
+ sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2);
+ //minDist = -1e30f;//gjkPairDetector.getCachedSeparatingDistance();
+ minDist = gjkPairDetector.getCachedSeparatingDistance()-min0->getMargin()-min1->getMargin();
+
+#ifdef ZERO_MARGIN
+ foundSepAxis = true;//gjkPairDetector.getCachedSeparatingDistance()<0.f;
+#else
+ foundSepAxis = gjkPairDetector.getCachedSeparatingDistance()<(min0->getMargin()+min1->getMargin());
+#endif
+ }
+ }
+ if (foundSepAxis)
+ {
+// printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ());
+
+ btPolyhedralContactClipping::clipHullAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
+ body0->getWorldTransform(),
+ body1->getWorldTransform(), minDist-threshold, threshold, *resultOut);
+
+ }
+ if (m_ownManifold)
+ {
+ resultOut->refreshContactPoints();
+ }
+ return;
+
+ } else
+ {
+ //we can also deal with convex versus triangle (without connectivity data)
+ if (polyhedronA->getConvexPolyhedron() && polyhedronB->getShapeType()==TRIANGLE_SHAPE_PROXYTYPE)
+ {
+
+ btVertexArray vertices;
+ btTriangleShape* tri = (btTriangleShape*)polyhedronB;
+ vertices.push_back( body1->getWorldTransform()*tri->m_vertices1[0]);
+ vertices.push_back( body1->getWorldTransform()*tri->m_vertices1[1]);
+ vertices.push_back( body1->getWorldTransform()*tri->m_vertices1[2]);
+
+ //tri->initializePolyhedralFeatures();
+
+ btScalar threshold = m_manifoldPtr->getContactBreakingThreshold();
+
+ btVector3 sepNormalWorldSpace;
+ btScalar minDist =-1e30f;
+ btScalar maxDist = threshold;
+
+ bool foundSepAxis = false;
+ if (0)
+ {
+ polyhedronB->initializePolyhedralFeatures();
+ foundSepAxis = btPolyhedralContactClipping::findSeparatingAxis(
+ *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
+ body0->getWorldTransform(),
+ body1->getWorldTransform(),
+ sepNormalWorldSpace);
+ // printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ());
+
+ } else
+ {
+#ifdef ZERO_MARGIN
+ gjkPairDetector.setIgnoreMargin(true);
+ gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
+#else
+ gjkPairDetector.getClosestPoints(input,dummy,dispatchInfo.m_debugDraw);
+#endif//ZERO_MARGIN
+
+ btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2();
+ if (l2>SIMD_EPSILON)
+ {
+ sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2);
+ //minDist = gjkPairDetector.getCachedSeparatingDistance();
+ //maxDist = threshold;
+ minDist = gjkPairDetector.getCachedSeparatingDistance()-min0->getMargin()-min1->getMargin();
+ foundSepAxis = true;
+ }
+ }
+
+
+ if (foundSepAxis)
+ {
+ btPolyhedralContactClipping::clipFaceAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(),
+ body0->getWorldTransform(), vertices, minDist-threshold, maxDist, *resultOut);
+ }
+
+
+ if (m_ownManifold)
+ {
+ resultOut->refreshContactPoints();
+ }
+
+ return;
+ }
+
+ }
+
+
+ }
+
+ gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
+
//now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects
//perform perturbation when more then 'm_minimumPointsPerturbationThreshold' points
@@ -398,66 +553,70 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
int i;
btVector3 v0,v1;
btVector3 sepNormalWorldSpace;
+ btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2();
- sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis().normalized();
- btPlaneSpace1(sepNormalWorldSpace,v0,v1);
-
-
- bool perturbeA = true;
- const btScalar angleLimit = 0.125f * SIMD_PI;
- btScalar perturbeAngle;
- btScalar radiusA = min0->getAngularMotionDisc();
- btScalar radiusB = min1->getAngularMotionDisc();
- if (radiusA < radiusB)
- {
- perturbeAngle = gContactBreakingThreshold /radiusA;
- perturbeA = true;
- } else
+ if (l2>SIMD_EPSILON)
{
- perturbeAngle = gContactBreakingThreshold / radiusB;
- perturbeA = false;
- }
- if ( perturbeAngle > angleLimit )
- perturbeAngle = angleLimit;
+ sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2);
+
+ btPlaneSpace1(sepNormalWorldSpace,v0,v1);
- btTransform unPerturbedTransform;
- if (perturbeA)
- {
- unPerturbedTransform = input.m_transformA;
- } else
- {
- unPerturbedTransform = input.m_transformB;
- }
-
- for ( i=0;i<m_numPerturbationIterations;i++)
- {
- if (v0.length2()>SIMD_EPSILON)
+
+ bool perturbeA = true;
+ const btScalar angleLimit = 0.125f * SIMD_PI;
+ btScalar perturbeAngle;
+ btScalar radiusA = min0->getAngularMotionDisc();
+ btScalar radiusB = min1->getAngularMotionDisc();
+ if (radiusA < radiusB)
{
- btQuaternion perturbeRot(v0,perturbeAngle);
- btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
- btQuaternion rotq(sepNormalWorldSpace,iterationAngle);
-
-
+ perturbeAngle = gContactBreakingThreshold /radiusA;
+ perturbeA = true;
+ } else
+ {
+ perturbeAngle = gContactBreakingThreshold / radiusB;
+ perturbeA = false;
+ }
+ if ( perturbeAngle > angleLimit )
+ perturbeAngle = angleLimit;
+
+ btTransform unPerturbedTransform;
if (perturbeA)
{
- input.m_transformA.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0->getWorldTransform().getBasis());
- input.m_transformB = body1->getWorldTransform();
-#ifdef DEBUG_CONTACTS
- dispatchInfo.m_debugDraw->drawTransform(input.m_transformA,10.0);
-#endif //DEBUG_CONTACTS
+ unPerturbedTransform = input.m_transformA;
} else
{
- input.m_transformA = body0->getWorldTransform();
- input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1->getWorldTransform().getBasis());
-#ifdef DEBUG_CONTACTS
- dispatchInfo.m_debugDraw->drawTransform(input.m_transformB,10.0);
-#endif
+ unPerturbedTransform = input.m_transformB;
}
- btPerturbedContactResult perturbedResultOut(resultOut,input.m_transformA,input.m_transformB,unPerturbedTransform,perturbeA,dispatchInfo.m_debugDraw);
- gjkPairDetector.getClosestPoints(input,perturbedResultOut,dispatchInfo.m_debugDraw);
+ for ( i=0;i<m_numPerturbationIterations;i++)
+ {
+ if (v0.length2()>SIMD_EPSILON)
+ {
+ btQuaternion perturbeRot(v0,perturbeAngle);
+ btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
+ btQuaternion rotq(sepNormalWorldSpace,iterationAngle);
+
+
+ if (perturbeA)
+ {
+ input.m_transformA.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0->getWorldTransform().getBasis());
+ input.m_transformB = body1->getWorldTransform();
+ #ifdef DEBUG_CONTACTS
+ dispatchInfo.m_debugDraw->drawTransform(input.m_transformA,10.0);
+ #endif //DEBUG_CONTACTS
+ } else
+ {
+ input.m_transformA = body0->getWorldTransform();
+ input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1->getWorldTransform().getBasis());
+ #ifdef DEBUG_CONTACTS
+ dispatchInfo.m_debugDraw->drawTransform(input.m_transformB,10.0);
+ #endif
+ }
+
+ btPerturbedContactResult perturbedResultOut(resultOut,input.m_transformA,input.m_transformB,unPerturbedTransform,perturbeA,dispatchInfo.m_debugDraw);
+ gjkPairDetector.getClosestPoints(input,perturbedResultOut,dispatchInfo.m_debugDraw);
+ }
}
-
}
}
@@ -487,7 +646,7 @@ btScalar btConvexConvexAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,
{
(void)resultOut;
(void)dispatchInfo;
- ///rather than checking ALL pairs, only calculate TOI when motion exceeds threshold
+ ///Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold
///Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold
///col0->m_worldTransform,