00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00065 #ifndef COLLISION_WORLD_H
00066 #define COLLISION_WORLD_H
00067
00068 class btStackAlloc;
00069 class btCollisionShape;
00070 class btConvexShape;
00071 class btBroadphaseInterface;
00072 class btSerializer;
00073
00074 #include "LinearMath/btVector3.h"
00075 #include "LinearMath/btTransform.h"
00076 #include "btCollisionObject.h"
00077 #include "btCollisionDispatcher.h"
00078 #include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
00079 #include "LinearMath/btAlignedObjectArray.h"
00080
00082 class btCollisionWorld
00083 {
00084
00085
00086 protected:
00087
00088 btAlignedObjectArray<btCollisionObject*> m_collisionObjects;
00089
00090 btDispatcher* m_dispatcher1;
00091
00092 btDispatcherInfo m_dispatchInfo;
00093
00094 btStackAlloc* m_stackAlloc;
00095
00096 btBroadphaseInterface* m_broadphasePairCache;
00097
00098 btIDebugDraw* m_debugDrawer;
00099
00102 bool m_forceUpdateAllAabbs;
00103
00104 void serializeCollisionObjects(btSerializer* serializer);
00105
00106 public:
00107
00108
00109 btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphasePairCache, btCollisionConfiguration* collisionConfiguration);
00110
00111 virtual ~btCollisionWorld();
00112
00113 void setBroadphase(btBroadphaseInterface* pairCache)
00114 {
00115 m_broadphasePairCache = pairCache;
00116 }
00117
00118 const btBroadphaseInterface* getBroadphase() const
00119 {
00120 return m_broadphasePairCache;
00121 }
00122
00123 btBroadphaseInterface* getBroadphase()
00124 {
00125 return m_broadphasePairCache;
00126 }
00127
00128 btOverlappingPairCache* getPairCache()
00129 {
00130 return m_broadphasePairCache->getOverlappingPairCache();
00131 }
00132
00133
00134 btDispatcher* getDispatcher()
00135 {
00136 return m_dispatcher1;
00137 }
00138
00139 const btDispatcher* getDispatcher() const
00140 {
00141 return m_dispatcher1;
00142 }
00143
00144 void updateSingleAabb(btCollisionObject* colObj);
00145
00146 virtual void updateAabbs();
00147
00148 virtual void setDebugDrawer(btIDebugDraw* debugDrawer)
00149 {
00150 m_debugDrawer = debugDrawer;
00151 }
00152
00153 virtual btIDebugDraw* getDebugDrawer()
00154 {
00155 return m_debugDrawer;
00156 }
00157
00158 virtual void debugDrawWorld();
00159
00160 virtual void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color);
00161
00162
00165 struct LocalShapeInfo
00166 {
00167 int m_shapePart;
00168 int m_triangleIndex;
00169
00170
00171
00172 };
00173
00174 struct LocalRayResult
00175 {
00176 LocalRayResult(btCollisionObject* collisionObject,
00177 LocalShapeInfo* localShapeInfo,
00178 const btVector3& hitNormalLocal,
00179 btScalar hitFraction)
00180 :m_collisionObject(collisionObject),
00181 m_localShapeInfo(localShapeInfo),
00182 m_hitNormalLocal(hitNormalLocal),
00183 m_hitFraction(hitFraction)
00184 {
00185 }
00186
00187 btCollisionObject* m_collisionObject;
00188 LocalShapeInfo* m_localShapeInfo;
00189 btVector3 m_hitNormalLocal;
00190 btScalar m_hitFraction;
00191
00192 };
00193
00195 struct RayResultCallback
00196 {
00197 btScalar m_closestHitFraction;
00198 btCollisionObject* m_collisionObject;
00199 short int m_collisionFilterGroup;
00200 short int m_collisionFilterMask;
00201
00202 unsigned int m_flags;
00203
00204 virtual ~RayResultCallback()
00205 {
00206 }
00207 bool hasHit() const
00208 {
00209 return (m_collisionObject != 0);
00210 }
00211
00212 RayResultCallback()
00213 :m_closestHitFraction(btScalar(1.)),
00214 m_collisionObject(0),
00215 m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
00216 m_collisionFilterMask(btBroadphaseProxy::AllFilter),
00217
00218 m_flags(0)
00219 {
00220 }
00221
00222 virtual bool needsCollision(btBroadphaseProxy* proxy0) const
00223 {
00224 bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0;
00225 collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask);
00226 return collides;
00227 }
00228
00229
00230 virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) = 0;
00231 };
00232
00233 struct ClosestRayResultCallback : public RayResultCallback
00234 {
00235 ClosestRayResultCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld)
00236 :m_rayFromWorld(rayFromWorld),
00237 m_rayToWorld(rayToWorld)
00238 {
00239 }
00240
00241 btVector3 m_rayFromWorld;
00242 btVector3 m_rayToWorld;
00243
00244 btVector3 m_hitNormalWorld;
00245 btVector3 m_hitPointWorld;
00246
00247 virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace)
00248 {
00249
00250 btAssert(rayResult.m_hitFraction <= m_closestHitFraction);
00251
00252 m_closestHitFraction = rayResult.m_hitFraction;
00253 m_collisionObject = rayResult.m_collisionObject;
00254 if (normalInWorldSpace)
00255 {
00256 m_hitNormalWorld = rayResult.m_hitNormalLocal;
00257 } else
00258 {
00260 m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal;
00261 }
00262 m_hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction);
00263 return rayResult.m_hitFraction;
00264 }
00265 };
00266
00267
00268 struct LocalConvexResult
00269 {
00270 LocalConvexResult(btCollisionObject* hitCollisionObject,
00271 LocalShapeInfo* localShapeInfo,
00272 const btVector3& hitNormalLocal,
00273 const btVector3& hitPointLocal,
00274 btScalar hitFraction
00275 )
00276 :m_hitCollisionObject(hitCollisionObject),
00277 m_localShapeInfo(localShapeInfo),
00278 m_hitNormalLocal(hitNormalLocal),
00279 m_hitPointLocal(hitPointLocal),
00280 m_hitFraction(hitFraction)
00281 {
00282 }
00283
00284 btCollisionObject* m_hitCollisionObject;
00285 LocalShapeInfo* m_localShapeInfo;
00286 btVector3 m_hitNormalLocal;
00287 btVector3 m_hitPointLocal;
00288 btScalar m_hitFraction;
00289 };
00290
00292 struct ConvexResultCallback
00293 {
00294 btScalar m_closestHitFraction;
00295 short int m_collisionFilterGroup;
00296 short int m_collisionFilterMask;
00297
00298 ConvexResultCallback()
00299 :m_closestHitFraction(btScalar(1.)),
00300 m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
00301 m_collisionFilterMask(btBroadphaseProxy::AllFilter)
00302 {
00303 }
00304
00305 virtual ~ConvexResultCallback()
00306 {
00307 }
00308
00309 bool hasHit() const
00310 {
00311 return (m_closestHitFraction < btScalar(1.));
00312 }
00313
00314
00315
00316 virtual bool needsCollision(btBroadphaseProxy* proxy0) const
00317 {
00318 bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0;
00319 collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask);
00320 return collides;
00321 }
00322
00323 virtual btScalar addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace) = 0;
00324 };
00325
00326 struct ClosestConvexResultCallback : public ConvexResultCallback
00327 {
00328 ClosestConvexResultCallback(const btVector3& convexFromWorld,const btVector3& convexToWorld)
00329 :m_convexFromWorld(convexFromWorld),
00330 m_convexToWorld(convexToWorld),
00331 m_hitCollisionObject(0)
00332 {
00333 }
00334
00335 btVector3 m_convexFromWorld;
00336 btVector3 m_convexToWorld;
00337
00338 btVector3 m_hitNormalWorld;
00339 btVector3 m_hitPointWorld;
00340 btCollisionObject* m_hitCollisionObject;
00341
00342 virtual btScalar addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace)
00343 {
00344
00345 btAssert(convexResult.m_hitFraction <= m_closestHitFraction);
00346
00347 m_closestHitFraction = convexResult.m_hitFraction;
00348 m_hitCollisionObject = convexResult.m_hitCollisionObject;
00349 if (normalInWorldSpace)
00350 {
00351 m_hitNormalWorld = convexResult.m_hitNormalLocal;
00352 } else
00353 {
00355 m_hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal;
00356 }
00357 m_hitPointWorld = convexResult.m_hitPointLocal;
00358 return convexResult.m_hitFraction;
00359 }
00360 };
00361
00363 struct ContactResultCallback
00364 {
00365 short int m_collisionFilterGroup;
00366 short int m_collisionFilterMask;
00367
00368 ContactResultCallback()
00369 :m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
00370 m_collisionFilterMask(btBroadphaseProxy::AllFilter)
00371 {
00372 }
00373
00374 virtual ~ContactResultCallback()
00375 {
00376 }
00377
00378 virtual bool needsCollision(btBroadphaseProxy* proxy0) const
00379 {
00380 bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0;
00381 collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask);
00382 return collides;
00383 }
00384
00385 virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) = 0;
00386 };
00387
00388
00389
00390 int getNumCollisionObjects() const
00391 {
00392 return int(m_collisionObjects.size());
00393 }
00394
00397 virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const;
00398
00401 void convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = btScalar(0.)) const;
00402
00405 void contactTest(btCollisionObject* colObj, ContactResultCallback& resultCallback);
00406
00409 void contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback);
00410
00411
00415 static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
00416 btCollisionObject* collisionObject,
00417 const btCollisionShape* collisionShape,
00418 const btTransform& colObjWorldTransform,
00419 RayResultCallback& resultCallback);
00420
00422 static void objectQuerySingle(const btConvexShape* castShape, const btTransform& rayFromTrans,const btTransform& rayToTrans,
00423 btCollisionObject* collisionObject,
00424 const btCollisionShape* collisionShape,
00425 const btTransform& colObjWorldTransform,
00426 ConvexResultCallback& resultCallback, btScalar allowedPenetration);
00427
00428 virtual void addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter);
00429
00430 btCollisionObjectArray& getCollisionObjectArray()
00431 {
00432 return m_collisionObjects;
00433 }
00434
00435 const btCollisionObjectArray& getCollisionObjectArray() const
00436 {
00437 return m_collisionObjects;
00438 }
00439
00440
00441 virtual void removeCollisionObject(btCollisionObject* collisionObject);
00442
00443 virtual void performDiscreteCollisionDetection();
00444
00445 btDispatcherInfo& getDispatchInfo()
00446 {
00447 return m_dispatchInfo;
00448 }
00449
00450 const btDispatcherInfo& getDispatchInfo() const
00451 {
00452 return m_dispatchInfo;
00453 }
00454
00455 bool getForceUpdateAllAabbs() const
00456 {
00457 return m_forceUpdateAllAabbs;
00458 }
00459 void setForceUpdateAllAabbs( bool forceUpdateAllAabbs)
00460 {
00461 m_forceUpdateAllAabbs = forceUpdateAllAabbs;
00462 }
00463
00465 virtual void serialize(btSerializer* serializer);
00466
00467 };
00468
00469
00470 #endif //COLLISION_WORLD_H