390
433
concaveShape->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
393
// BT_PROFILE("rayTestCompound");
394
///@todo: use AABB tree or other BVH acceleration structure, see btDbvt
436
// BT_PROFILE("rayTestCompound");
395
437
if (collisionShape->isCompound())
439
struct LocalInfoAdder2 : public RayResultCallback
441
RayResultCallback* m_userCallback;
444
LocalInfoAdder2 (int i, RayResultCallback *user)
445
: m_userCallback(user), m_i(i)
447
m_closestHitFraction = m_userCallback->m_closestHitFraction;
449
virtual bool needsCollision(btBroadphaseProxy* p) const
451
return m_userCallback->needsCollision(p);
454
virtual btScalar addSingleResult (btCollisionWorld::LocalRayResult &r, bool b)
456
btCollisionWorld::LocalShapeInfo shapeInfo;
457
shapeInfo.m_shapePart = -1;
458
shapeInfo.m_triangleIndex = m_i;
459
if (r.m_localShapeInfo == NULL)
460
r.m_localShapeInfo = &shapeInfo;
462
const btScalar result = m_userCallback->addSingleResult(r, b);
463
m_closestHitFraction = m_userCallback->m_closestHitFraction;
468
struct RayTester : btDbvt::ICollide
470
btCollisionObject* m_collisionObject;
471
const btCompoundShape* m_compoundShape;
472
const btTransform& m_colObjWorldTransform;
473
const btTransform& m_rayFromTrans;
474
const btTransform& m_rayToTrans;
475
RayResultCallback& m_resultCallback;
477
RayTester(btCollisionObject* collisionObject,
478
const btCompoundShape* compoundShape,
479
const btTransform& colObjWorldTransform,
480
const btTransform& rayFromTrans,
481
const btTransform& rayToTrans,
482
RayResultCallback& resultCallback):
483
m_collisionObject(collisionObject),
484
m_compoundShape(compoundShape),
485
m_colObjWorldTransform(colObjWorldTransform),
486
m_rayFromTrans(rayFromTrans),
487
m_rayToTrans(rayToTrans),
488
m_resultCallback(resultCallback)
495
const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(i);
496
const btTransform& childTrans = m_compoundShape->getChildTransform(i);
497
btTransform childWorldTrans = m_colObjWorldTransform * childTrans;
499
// replace collision shape so that callback can determine the triangle
500
btCollisionShape* saveCollisionShape = m_collisionObject->getCollisionShape();
501
m_collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
503
LocalInfoAdder2 my_cb(i, &m_resultCallback);
514
m_collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
517
void Process(const btDbvtNode* leaf)
519
Process(leaf->dataAsInt);
397
523
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
399
for (i=0;i<compoundShape->getNumChildShapes();i++)
401
btTransform childTrans = compoundShape->getChildTransform(i);
402
const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
403
btTransform childWorldTrans = colObjWorldTransform * childTrans;
404
// replace collision shape so that callback can determine the triangle
405
btCollisionShape* saveCollisionShape = collisionObject->getCollisionShape();
406
collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
407
rayTestSingle(rayFromTrans,rayToTrans,
413
collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
524
const btDbvt* dbvt = compoundShape->getDynamicAabbTree();
530
colObjWorldTransform,
534
#ifndef DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
537
btVector3 localRayFrom = colObjWorldTransform.inverseTimes(rayFromTrans).getOrigin();
538
btVector3 localRayTo = colObjWorldTransform.inverseTimes(rayToTrans).getOrigin();
539
btDbvt::rayTest(dbvt->m_root, localRayFrom , localRayTo, rayCB);
542
#endif //DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
544
for (int i = 0, n = compoundShape->getNumChildShapes(); i < n; ++i)
826
992
objectQuerySingle(castShape, convexFromTrans,convexToTrans,
828
collisionObject->getCollisionShape(),
829
collisionObject->getWorldTransform(),
831
allowedCcdPenetration);
994
collisionObject->getCollisionShape(),
995
collisionObject->getWorldTransform(),
997
allowedCcdPenetration);
835
1001
#endif //USE_BRUTEFORCE_RAYBROADPHASE
1006
struct btBridgedManifoldResult : public btManifoldResult
1009
btCollisionWorld::ContactResultCallback& m_resultCallback;
1011
btBridgedManifoldResult( btCollisionObject* obj0,btCollisionObject* obj1,btCollisionWorld::ContactResultCallback& resultCallback )
1012
:btManifoldResult(obj0,obj1),
1013
m_resultCallback(resultCallback)
1017
virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
1019
bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
1020
btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
1025
localA = m_rootTransB.invXform(pointA );
1026
localB = m_rootTransA.invXform(pointInWorld);
1029
localA = m_rootTransA.invXform(pointA );
1030
localB = m_rootTransB.invXform(pointInWorld);
1033
btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
1034
newPt.m_positionWorldOnA = pointA;
1035
newPt.m_positionWorldOnB = pointInWorld;
1037
//BP mod, store contact triangles.
1040
newPt.m_partId0 = m_partId1;
1041
newPt.m_partId1 = m_partId0;
1042
newPt.m_index0 = m_index1;
1043
newPt.m_index1 = m_index0;
1046
newPt.m_partId0 = m_partId0;
1047
newPt.m_partId1 = m_partId1;
1048
newPt.m_index0 = m_index0;
1049
newPt.m_index1 = m_index1;
1052
//experimental feature info, for per-triangle material etc.
1053
btCollisionObject* obj0 = isSwapped? m_body1 : m_body0;
1054
btCollisionObject* obj1 = isSwapped? m_body0 : m_body1;
1055
m_resultCallback.addSingleResult(newPt,obj0,newPt.m_partId0,newPt.m_index0,obj1,newPt.m_partId1,newPt.m_index1);
1063
struct btSingleContactCallback : public btBroadphaseAabbCallback
1066
btCollisionObject* m_collisionObject;
1067
btCollisionWorld* m_world;
1068
btCollisionWorld::ContactResultCallback& m_resultCallback;
1071
btSingleContactCallback(btCollisionObject* collisionObject, btCollisionWorld* world,btCollisionWorld::ContactResultCallback& resultCallback)
1072
:m_collisionObject(collisionObject),
1074
m_resultCallback(resultCallback)
1078
virtual bool process(const btBroadphaseProxy* proxy)
1080
btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
1081
if (collisionObject == m_collisionObject)
1084
//only perform raycast if filterMask matches
1085
if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
1087
btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(m_collisionObject,collisionObject);
1090
btBridgedManifoldResult contactPointResult(m_collisionObject,collisionObject, m_resultCallback);
1091
//discrete collision detection query
1092
algorithm->processCollision(m_collisionObject,collisionObject, m_world->getDispatchInfo(),&contactPointResult);
1094
algorithm->~btCollisionAlgorithm();
1095
m_world->getDispatcher()->freeCollisionAlgorithm(algorithm);
1103
///contactTest performs a discrete collision test against all objects in the btCollisionWorld, and calls the resultCallback.
1104
///it reports one or more contact points for every overlapping object (including the one with deepest penetration)
1105
void btCollisionWorld::contactTest( btCollisionObject* colObj, ContactResultCallback& resultCallback)
1107
btVector3 aabbMin,aabbMax;
1108
colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(),aabbMin,aabbMax);
1109
btSingleContactCallback contactCB(colObj,this,resultCallback);
1111
m_broadphasePairCache->aabbTest(aabbMin,aabbMax,contactCB);
1115
///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected.
1116
///it reports one or more contact points (including the one with deepest penetration)
1117
void btCollisionWorld::contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback)
1119
btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(colObjA,colObjB);
1122
btBridgedManifoldResult contactPointResult(colObjA,colObjB, resultCallback);
1123
//discrete collision detection query
1124
algorithm->processCollision(colObjA,colObjB, getDispatchInfo(),&contactPointResult);
1126
algorithm->~btCollisionAlgorithm();
1127
getDispatcher()->freeCollisionAlgorithm(algorithm);
1135
class DebugDrawcallback : public btTriangleCallback, public btInternalTriangleIndexCallback
1137
btIDebugDraw* m_debugDrawer;
1139
btTransform m_worldTrans;
1143
DebugDrawcallback(btIDebugDraw* debugDrawer,const btTransform& worldTrans,const btVector3& color) :
1144
m_debugDrawer(debugDrawer),
1146
m_worldTrans(worldTrans)
1150
virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
1152
processTriangle(triangle,partId,triangleIndex);
1155
virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex)
1158
(void)triangleIndex;
1160
btVector3 wv0,wv1,wv2;
1161
wv0 = m_worldTrans*triangle[0];
1162
wv1 = m_worldTrans*triangle[1];
1163
wv2 = m_worldTrans*triangle[2];
1164
btVector3 center = (wv0+wv1+wv2)*btScalar(1./3.);
1166
btVector3 normal = (wv1-wv0).cross(wv2-wv0);
1168
btVector3 normalColor(1,1,0);
1169
m_debugDrawer->drawLine(center,center+normal,normalColor);
1174
m_debugDrawer->drawLine(wv0,wv1,m_color);
1175
m_debugDrawer->drawLine(wv1,wv2,m_color);
1176
m_debugDrawer->drawLine(wv2,wv0,m_color);
1181
void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color)
1183
// Draw a small simplex at the center of the object
1184
getDebugDrawer()->drawTransform(worldTransform,1);
1186
if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
1188
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
1189
for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--)
1191
btTransform childTrans = compoundShape->getChildTransform(i);
1192
const btCollisionShape* colShape = compoundShape->getChildShape(i);
1193
debugDrawObject(worldTransform*childTrans,colShape,color);
1198
switch (shape->getShapeType())
1201
case BOX_SHAPE_PROXYTYPE:
1203
const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
1204
btVector3 halfExtents = boxShape->getHalfExtentsWithMargin();
1205
getDebugDrawer()->drawBox(-halfExtents,halfExtents,worldTransform,color);
1209
case SPHERE_SHAPE_PROXYTYPE:
1211
const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
1212
btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
1214
getDebugDrawer()->drawSphere(radius, worldTransform, color);
1217
case MULTI_SPHERE_SHAPE_PROXYTYPE:
1219
const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
1221
btTransform childTransform;
1222
childTransform.setIdentity();
1224
for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
1226
childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
1227
getDebugDrawer()->drawSphere(multiSphereShape->getSphereRadius(i), worldTransform*childTransform, color);
1232
case CAPSULE_SHAPE_PROXYTYPE:
1234
const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
1236
btScalar radius = capsuleShape->getRadius();
1237
btScalar halfHeight = capsuleShape->getHalfHeight();
1239
int upAxis = capsuleShape->getUpAxis();
1240
getDebugDrawer()->drawCapsule(radius, halfHeight, upAxis, worldTransform, color);
1243
case CONE_SHAPE_PROXYTYPE:
1245
const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
1246
btScalar radius = coneShape->getRadius();//+coneShape->getMargin();
1247
btScalar height = coneShape->getHeight();//+coneShape->getMargin();
1249
int upAxis= coneShape->getConeUpIndex();
1250
getDebugDrawer()->drawCone(radius, height, upAxis, worldTransform, color);
1254
case CYLINDER_SHAPE_PROXYTYPE:
1256
const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
1257
int upAxis = cylinder->getUpAxis();
1258
btScalar radius = cylinder->getRadius();
1259
btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
1260
getDebugDrawer()->drawCylinder(radius, halfHeight, upAxis, worldTransform, color);
1264
case STATIC_PLANE_PROXYTYPE:
1266
const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
1267
btScalar planeConst = staticPlaneShape->getPlaneConstant();
1268
const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
1269
getDebugDrawer()->drawPlane(planeNormal, planeConst,worldTransform, color);
1276
if (shape->isConcave())
1278
btConcaveShape* concaveMesh = (btConcaveShape*) shape;
1280
///@todo pass camera, for some culling? no -> we are not a graphics lib
1281
btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
1282
btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
1284
DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
1285
concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
1289
if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE)
1291
btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape;
1292
//todo: pass camera for some culling
1293
btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
1294
btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
1295
//DebugDrawcallback drawCallback;
1296
DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
1297
convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
1301
/// for polyhedral shapes
1302
if (shape->isPolyhedral())
1304
btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
1307
for (i=0;i<polyshape->getNumEdges();i++)
1310
polyshape->getEdge(i,a,b);
1311
btVector3 wa = worldTransform * a;
1312
btVector3 wb = worldTransform * b;
1313
getDebugDrawer()->drawLine(wa,wb,color);
1325
void btCollisionWorld::debugDrawWorld()
1327
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
1329
int numManifolds = getDispatcher()->getNumManifolds();
1330
btVector3 color(0,0,0);
1331
for (int i=0;i<numManifolds;i++)
1333
btPersistentManifold* contactManifold = getDispatcher()->getManifoldByIndexInternal(i);
1334
//btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
1335
//btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
1337
int numContacts = contactManifold->getNumContacts();
1338
for (int j=0;j<numContacts;j++)
1340
btManifoldPoint& cp = contactManifold->getContactPoint(j);
1341
getDebugDrawer()->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
1346
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb))
1350
for ( i=0;i<m_collisionObjects.size();i++)
1352
btCollisionObject* colObj = m_collisionObjects[i];
1353
if ((colObj->getCollisionFlags() & btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT)==0)
1355
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
1357
btVector3 color(btScalar(1.),btScalar(1.),btScalar(1.));
1358
switch(colObj->getActivationState())
1361
color = btVector3(btScalar(1.),btScalar(1.),btScalar(1.)); break;
1362
case ISLAND_SLEEPING:
1363
color = btVector3(btScalar(0.),btScalar(1.),btScalar(0.));break;
1364
case WANTS_DEACTIVATION:
1365
color = btVector3(btScalar(0.),btScalar(1.),btScalar(1.));break;
1366
case DISABLE_DEACTIVATION:
1367
color = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));break;
1368
case DISABLE_SIMULATION:
1369
color = btVector3(btScalar(1.),btScalar(1.),btScalar(0.));break;
1372
color = btVector3(btScalar(1),btScalar(0.),btScalar(0.));
1376
debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color);
1378
if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
1380
btVector3 minAabb,maxAabb;
1381
btVector3 colorvec(1,0,0);
1382
colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
1383
btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);
1384
minAabb -= contactThreshold;
1385
maxAabb += contactThreshold;
1387
btVector3 minAabb2,maxAabb2;
1389
colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
1390
minAabb2 -= contactThreshold;
1391
maxAabb2 += contactThreshold;
1393
minAabb.setMin(minAabb2);
1394
maxAabb.setMax(maxAabb2);
1396
m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
1405
void btCollisionWorld::serializeCollisionObjects(btSerializer* serializer)
1408
//serialize all collision objects
1409
for (i=0;i<m_collisionObjects.size();i++)
1411
btCollisionObject* colObj = m_collisionObjects[i];
1412
if (colObj->getInternalType() == btCollisionObject::CO_COLLISION_OBJECT)
1414
colObj->serializeSingleObject(serializer);
1418
///keep track of shapes already serialized
1419
btHashMap<btHashPtr,btCollisionShape*> serializedShapes;
1421
for (i=0;i<m_collisionObjects.size();i++)
1423
btCollisionObject* colObj = m_collisionObjects[i];
1424
btCollisionShape* shape = colObj->getCollisionShape();
1426
if (!serializedShapes.find(shape))
1428
serializedShapes.insert(shape,shape);
1429
shape->serializeSingleShape(serializer);
1436
void btCollisionWorld::serialize(btSerializer* serializer)
1439
serializer->startSerialization();
1441
serializeCollisionObjects(serializer);
1443
serializer->finishSerialization();