2
Bullet Continuous Collision Detection and Physics Library
3
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
5
This software is provided 'as-is', without any express or implied warranty.
6
In no event will the authors be held liable for any damages arising from the use of this software.
7
Permission is granted to anyone to use this software for any purpose,
8
including commercial applications, and to alter it and redistribute it freely,
9
subject to the following restrictions:
11
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13
3. This notice may not be removed or altered from any source distribution.
16
#include "btMinkowskiPenetrationDepthSolver.h"
17
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
18
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
19
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
20
#include "BulletCollision/CollisionShapes/btConvexShape.h"
22
#define NUM_UNITSPHERE_POINTS 42
25
bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& simplexSolver,
26
const btConvexShape* convexA,const btConvexShape* convexB,
27
const btTransform& transA,const btTransform& transB,
28
btVector3& v, btVector3& pa, btVector3& pb,
29
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
36
bool check2d= convexA->isConvex2d() && convexB->isConvex2d();
38
struct btIntermediateResult : public btDiscreteCollisionDetectorInterface::Result
41
btIntermediateResult():m_hasResult(false)
45
btVector3 m_normalOnBInWorld;
46
btVector3 m_pointInWorld;
50
virtual void setShapeIdentifiersA(int partId0,int index0)
55
virtual void setShapeIdentifiersB(int partId1,int index1)
60
void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
62
m_normalOnBInWorld = normalOnBInWorld;
63
m_pointInWorld = pointInWorld;
69
//just take fixed number of orientation, and sample the penetration depth in that direction
70
btScalar minProj = btScalar(BT_LARGE_FLOAT);
71
btVector3 minNorm(btScalar(0.), btScalar(0.), btScalar(0.));
73
btVector3 seperatingAxisInA,seperatingAxisInB;
74
btVector3 pInA,qInB,pWorld,qWorld,w;
77
#define USE_BATCHED_SUPPORT 1
79
#ifdef USE_BATCHED_SUPPORT
81
btVector3 supportVerticesABatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2];
82
btVector3 supportVerticesBBatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2];
83
btVector3 seperatingAxisInABatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2];
84
btVector3 seperatingAxisInBBatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2];
87
int numSampleDirections = NUM_UNITSPHERE_POINTS;
89
for (i=0;i<numSampleDirections;i++)
91
btVector3 norm = getPenetrationDirections()[i];
92
seperatingAxisInABatch[i] = (-norm) * transA.getBasis() ;
93
seperatingAxisInBBatch[i] = norm * transB.getBasis() ;
97
int numPDA = convexA->getNumPreferredPenetrationDirections();
100
for (int i=0;i<numPDA;i++)
103
convexA->getPreferredPenetrationDirection(i,norm);
104
norm = transA.getBasis() * norm;
105
getPenetrationDirections()[numSampleDirections] = norm;
106
seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis();
107
seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis();
108
numSampleDirections++;
114
int numPDB = convexB->getNumPreferredPenetrationDirections();
117
for (int i=0;i<numPDB;i++)
120
convexB->getPreferredPenetrationDirection(i,norm);
121
norm = transB.getBasis() * norm;
122
getPenetrationDirections()[numSampleDirections] = norm;
123
seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis();
124
seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis();
125
numSampleDirections++;
133
convexA->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInABatch,supportVerticesABatch,numSampleDirections);
134
convexB->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInBBatch,supportVerticesBBatch,numSampleDirections);
136
for (i=0;i<numSampleDirections;i++)
138
btVector3 norm = getPenetrationDirections()[i];
143
if (norm.length2()>0.01)
146
seperatingAxisInA = seperatingAxisInABatch[i];
147
seperatingAxisInB = seperatingAxisInBBatch[i];
149
pInA = supportVerticesABatch[i];
150
qInB = supportVerticesBBatch[i];
152
pWorld = transA(pInA);
153
qWorld = transB(qInB);
161
btScalar delta = norm.dot(w);
162
//find smallest delta
174
int numSampleDirections = NUM_UNITSPHERE_POINTS;
178
int numPDA = convexA->getNumPreferredPenetrationDirections();
181
for (int i=0;i<numPDA;i++)
184
convexA->getPreferredPenetrationDirection(i,norm);
185
norm = transA.getBasis() * norm;
186
getPenetrationDirections()[numSampleDirections] = norm;
187
numSampleDirections++;
193
int numPDB = convexB->getNumPreferredPenetrationDirections();
196
for (int i=0;i<numPDB;i++)
199
convexB->getPreferredPenetrationDirection(i,norm);
200
norm = transB.getBasis() * norm;
201
getPenetrationDirections()[numSampleDirections] = norm;
202
numSampleDirections++;
208
for (int i=0;i<numSampleDirections;i++)
210
const btVector3& norm = getPenetrationDirections()[i];
211
seperatingAxisInA = (-norm)* transA.getBasis();
212
seperatingAxisInB = norm* transB.getBasis();
213
pInA = convexA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
214
qInB = convexB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
215
pWorld = transA(pInA);
216
qWorld = transB(qInB);
218
btScalar delta = norm.dot(w);
219
//find smallest delta
228
#endif //USE_BATCHED_SUPPORT
232
minA += minNorm*convexA->getMarginNonVirtual();
233
minB -= minNorm*convexB->getMarginNonVirtual();
235
if (minProj < btScalar(0.))
238
btScalar extraSeparation = 0.5f;///scale dependent
239
minProj += extraSeparation+(convexA->getMarginNonVirtual() + convexB->getMarginNonVirtual());
245
//#define DEBUG_DRAW 1
249
btVector3 color(0,1,0);
250
debugDraw->drawLine(minA,minB,color);
251
color = btVector3 (1,1,1);
252
btVector3 vec = minB-minA;
253
btScalar prj2 = minNorm.dot(vec);
254
debugDraw->drawLine(minA,minA+(minNorm*minProj),color);
261
btGjkPairDetector gjkdet(convexA,convexB,&simplexSolver,0);
263
btScalar offsetDist = minProj;
264
btVector3 offset = minNorm * offsetDist;
268
btGjkPairDetector::ClosestPointInput input;
270
btVector3 newOrg = transA.getOrigin() + offset;
272
btTransform displacedTrans = transA;
273
displacedTrans.setOrigin(newOrg);
275
input.m_transformA = displacedTrans;
276
input.m_transformB = transB;
277
input.m_maximumDistanceSquared = btScalar(BT_LARGE_FLOAT);//minProj;
279
btIntermediateResult res;
280
gjkdet.setCachedSeperatingAxis(-minNorm);
281
gjkdet.getClosestPoints(input,res,debugDraw);
283
btScalar correctedMinNorm = minProj - res.m_depth;
286
//the penetration depth is over-estimated, relax it
287
btScalar penetration_relaxation= btScalar(1.);
288
minNorm*=penetration_relaxation;
294
pa = res.m_pointInWorld - minNorm * correctedMinNorm;
295
pb = res.m_pointInWorld;
301
btVector3 color(1,0,0);
302
debugDraw->drawLine(pa,pb,color);
308
return res.m_hasResult;
311
btVector3* btMinkowskiPenetrationDepthSolver::getPenetrationDirections()
313
static btVector3 sPenetrationDirections[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2] =
315
btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)),
316
btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)),
317
btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)),
318
btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)),
319
btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)),
320
btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)),
321
btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)),
322
btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)),
323
btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)),
324
btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)),
325
btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)),
326
btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)),
327
btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)),
328
btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)),
329
btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)),
330
btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)),
331
btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)),
332
btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)),
333
btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)),
334
btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)),
335
btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)),
336
btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)),
337
btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)),
338
btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)),
339
btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)),
340
btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)),
341
btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)),
342
btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)),
343
btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)),
344
btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)),
345
btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)),
346
btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)),
347
btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)),
348
btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)),
349
btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)),
350
btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)),
351
btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)),
352
btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)),
353
btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)),
354
btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)),
355
btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)),
356
btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654))
359
return sPenetrationDirections;