23 #if defined(DEBUG) || defined (_DEBUG)
27 #include <spu_printf.h>
28 #define printf spu_printf
34 #define REL_ERROR2 btScalar(1.0e-6)
43 m_penetrationDepthSolver(penetrationDepthSolver),
44 m_simplexSolver(simplexSolver),
45 m_minkowskiA(objectA),
46 m_minkowskiB(objectB),
47 m_shapeTypeA(objectA->getShapeType()),
48 m_shapeTypeB(objectB->getShapeType()),
49 m_marginA(objectA->getMargin()),
50 m_marginB(objectB->getMargin()),
51 m_ignoreMargin(false),
53 m_catchDegeneracies(1),
54 m_fixContactNormalDirection(1)
59 m_penetrationDepthSolver(penetrationDepthSolver),
60 m_simplexSolver(simplexSolver),
61 m_minkowskiA(objectA),
62 m_minkowskiB(objectB),
63 m_shapeTypeA(shapeTypeA),
64 m_shapeTypeB(shapeTypeB),
67 m_ignoreMargin(false),
69 m_catchDegeneracies(1),
70 m_fixContactNormalDirection(1)
87 m_cachedSeparatingDistance = 0.f;
95 localTransA.
getOrigin() -= positionOffset;
96 localTransB.
getOrigin() -= positionOffset;
98 bool check2d = m_minkowskiA->isConvex2d() && m_minkowskiB->isConvex2d();
105 #ifdef DEBUG_SPU_COLLISION_DETECTION
113 #ifdef DEBUG_SPU_COLLISION_DETECTION
119 int gGjkMaxIter = 1000;
120 m_cachedSeparatingAxis.setValue(0,1,0);
122 bool isValid =
false;
123 bool checkSimplex =
false;
124 bool checkPenetration =
true;
125 m_degenerateSimplex = 0;
127 m_lastUsedMethod = -1;
133 btScalar margin = marginA + marginB;
137 m_simplexSolver->reset();
148 btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
149 btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
156 btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
157 btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
159 btVector3 pInA = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA);
160 btVector3 qInB = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB);
161 #ifdef TEST_NON_VIRTUAL
162 btVector3 pInAv = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA);
163 btVector3 qInBv = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB);
174 #ifdef DEBUG_SPU_COLLISION_DETECTION
175 spu_printf(
"got local supporting vertices\n");
185 delta = m_cachedSeparatingAxis.
dot(w);
190 m_degenerateSimplex = 10;
197 if (m_simplexSolver->inSimplex(w))
199 m_degenerateSimplex = 1;
204 btScalar f0 = squaredDistance - delta;
211 m_degenerateSimplex = 2;
214 m_degenerateSimplex = 11;
220 #ifdef DEBUG_SPU_COLLISION_DETECTION
224 m_simplexSolver->addVertex(w, pWorld, qWorld);
225 #ifdef DEBUG_SPU_COLLISION_DETECTION
231 if (!m_simplexSolver->closest(newCachedSeparatingAxis))
233 m_degenerateSimplex = 3;
240 m_cachedSeparatingAxis = newCachedSeparatingAxis;
241 m_degenerateSimplex = 6;
246 btScalar previousSquaredDistance = squaredDistance;
247 squaredDistance = newCachedSeparatingAxis.
length2();
249 if (squaredDistance>previousSquaredDistance)
252 m_degenerateSimplex = 7;
253 squaredDistance = previousSquaredDistance;
254 checkSimplex =
false;
263 if (previousSquaredDistance - squaredDistance <=
SIMD_EPSILON * previousSquaredDistance)
267 m_degenerateSimplex = 12;
272 m_cachedSeparatingAxis = newCachedSeparatingAxis;
275 if (m_curIter++ > gGjkMaxIter)
277 #if defined(DEBUG) || defined (_DEBUG) || defined (DEBUG_SPU_COLLISION_DETECTION)
279 printf(
"btGjkPairDetector maxIter exceeded:%i\n",m_curIter);
280 printf(
"sepAxis=(%f,%f,%f), squaredDistance = %f, shapeTypeA=%i,shapeTypeB=%i\n",
281 m_cachedSeparatingAxis.getX(),
282 m_cachedSeparatingAxis.getY(),
283 m_cachedSeparatingAxis.getZ(),
285 m_minkowskiA->getShapeType(),
286 m_minkowskiB->getShapeType());
294 bool check = (!m_simplexSolver->fullSimplex());
301 m_degenerateSimplex = 13;
308 m_simplexSolver->compute_points(pointOnA, pointOnB);
309 normalInB = m_cachedSeparatingAxis;
315 m_degenerateSimplex = 5;
324 pointOnA -= m_cachedSeparatingAxis * (marginA / s);
325 pointOnB += m_cachedSeparatingAxis * (marginB / s);
326 distance = ((
btScalar(1.)/rlen) - margin);
329 m_lastUsedMethod = 1;
332 m_lastUsedMethod = 2;
336 bool catchDegeneratePenetrationCase =
337 (m_catchDegeneracies && m_penetrationDepthSolver && m_degenerateSimplex && ((distance+margin) < 0.01));
340 if (checkPenetration && (!isValid || catchDegeneratePenetrationCase ))
345 if (m_penetrationDepthSolver)
351 m_cachedSeparatingAxis.setZero();
353 bool isValid2 = m_penetrationDepthSolver->calcPenDepth(
355 m_minkowskiA,m_minkowskiB,
356 localTransA,localTransB,
357 m_cachedSeparatingAxis, tmpPointOnA, tmpPointOnB,
364 btVector3 tmpNormalInB = tmpPointOnB-tmpPointOnA;
368 tmpNormalInB = m_cachedSeparatingAxis;
369 lenSqr = m_cachedSeparatingAxis.
length2();
372 if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON))
374 tmpNormalInB /=
btSqrt(lenSqr);
377 if (!isValid || (distance2 < distance))
379 distance = distance2;
380 pointOnA = tmpPointOnA;
381 pointOnB = tmpPointOnB;
382 normalInB = tmpNormalInB;
384 m_lastUsedMethod = 3;
387 m_lastUsedMethod = 8;
391 m_lastUsedMethod = 9;
403 if (m_cachedSeparatingAxis.length2() >
btScalar(0.))
407 if (!isValid || (distance2 < distance))
409 distance = distance2;
410 pointOnA = tmpPointOnA;
411 pointOnB = tmpPointOnB;
412 pointOnA -= m_cachedSeparatingAxis * marginA ;
413 pointOnB += m_cachedSeparatingAxis * marginB ;
414 normalInB = m_cachedSeparatingAxis;
417 m_lastUsedMethod = 6;
420 m_lastUsedMethod = 5;
438 printf(
"n = %2.3f,%2.3f,%2.3f. ",normalInB[0],normalInB[1],normalInB[2]);
439 printf(
"distance = %2.3f exit=%d deg=%d\n",distance,m_lastUsedMethod,m_degenerateSimplex);
443 if (m_fixContactNormalDirection)
454 m_minkowskiA->getAabb(localTransA,aabbMin,aabbMax);
457 m_minkowskiB->getAabb(localTransB,aabbMin,aabbMax);
461 if (diff.
dot(normalInB) < 0.f)
464 m_cachedSeparatingAxis = normalInB;
465 m_cachedSeparatingDistance = distance;
469 pointOnB+positionOffset,
btGjkPairDetector(const btConvexShape *objectA, const btConvexShape *objectB, btSimplexSolverInterface *simplexSolver, btConvexPenetrationDepthSolver *penetrationDepthSolver)
btScalar length(const btQuaternion &q)
Return the length of a quaternion.
ConvexPenetrationDepthSolver provides an interface for penetration depth calculation.
btScalar btSqrt(btScalar y)
btScalar dot(const btVector3 &v) const
Return the dot product.
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
The btConvexShape is an abstract shape interface, implemented by all convex shapes such as btBoxShape...
int gNumDeepPenetrationChecks
#define btSimplexSolverInterface
The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations...
btVector3 can be used to represent 3D points and vectors.
btScalar length2() const
Return the length of the vector squared.
virtual void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorld, btScalar depth)=0
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
virtual void getClosestPoints(const ClosestPointInput &input, Result &output, class btIDebugDraw *debugDraw, bool swapResults=false)
void getClosestPointsNonVirtual(const ClosestPointInput &input, Result &output, class btIDebugDraw *debugDraw)