RealTimeBullet3CollisionSdk.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. #define BLAAT
  2. #include "RealTimeBullet3CollisionSdk.h"
  3. #include "Bullet3Common/b3AlignedObjectArray.h"
  4. #include "Bullet3Collision/NarrowPhaseCollision/shared/b3Collidable.h"
  5. #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h"
  6. #include "Bullet3Collision/BroadPhaseCollision/shared/b3Aabb.h"
  7. //convert the opaque pointer to int
  8. struct RTB3_ColliderOpaque2Int
  9. {
  10. union
  11. {
  12. plCollisionObjectHandle m_ptrValue;
  13. int m_intValue;
  14. };
  15. };
  16. struct RTB3_ShapeOpaque2Int
  17. {
  18. union
  19. {
  20. plCollisionShapeHandle m_ptrValue;
  21. int m_intValue;
  22. };
  23. };
  24. enum RTB3ShapeTypes
  25. {
  26. RTB3_SHAPE_SPHERE=0,
  27. RTB3_SHAPE_PLANE,
  28. RTB3_SHAPE_CAPSULE,
  29. MAX_NUM_SINGLE_SHAPE_TYPES,
  30. RTB3_SHAPE_COMPOUND_INTERNAL,
  31. };
  32. //we start at 1, so that the 0 index is 'invalid' just like a nullptr
  33. #define START_COLLIDABLE_INDEX 1
  34. #define START_SHAPE_INDEX 1
  35. struct RTB3CollisionWorld
  36. {
  37. b3AlignedObjectArray<void*> m_collidableUserPointers;
  38. b3AlignedObjectArray<int> m_collidableUserIndices;
  39. b3AlignedObjectArray<b3Float4> m_collidablePositions;
  40. b3AlignedObjectArray<b3Quaternion> m_collidableOrientations;
  41. b3AlignedObjectArray<b3Transform> m_collidableTransforms;
  42. b3AlignedObjectArray<b3Collidable> m_collidables;
  43. b3AlignedObjectArray<b3GpuChildShape> m_childShapes;
  44. b3AlignedObjectArray<b3Aabb> m_localSpaceAabbs;
  45. b3AlignedObjectArray<b3Aabb> m_worldSpaceAabbs;
  46. b3AlignedObjectArray<b3GpuFace> m_planeFaces;
  47. b3AlignedObjectArray<b3CompoundOverlappingPair> m_compoundOverlappingPairs;
  48. int m_nextFreeShapeIndex;
  49. int m_nextFreeCollidableIndex;
  50. int m_nextFreePlaneFaceIndex;
  51. RTB3CollisionWorld()
  52. :m_nextFreeCollidableIndex(START_COLLIDABLE_INDEX),
  53. m_nextFreeShapeIndex(START_SHAPE_INDEX),
  54. m_nextFreePlaneFaceIndex(0)//this value is never exposed to the user, so we can start from 0
  55. {
  56. }
  57. };
  58. struct RealTimeBullet3CollisionSdkInternalData
  59. {
  60. b3AlignedObjectArray<RTB3CollisionWorld*> m_collisionWorlds;
  61. };
  62. RealTimeBullet3CollisionSdk::RealTimeBullet3CollisionSdk()
  63. {
  64. // int szCol = sizeof(b3Collidable);
  65. // int szShap = sizeof(b3GpuChildShape);
  66. // int szComPair = sizeof(b3CompoundOverlappingPair);
  67. m_internalData = new RealTimeBullet3CollisionSdkInternalData;
  68. }
  69. RealTimeBullet3CollisionSdk::~RealTimeBullet3CollisionSdk()
  70. {
  71. delete m_internalData;
  72. m_internalData=0;
  73. }
  74. plCollisionWorldHandle RealTimeBullet3CollisionSdk::createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity)
  75. {
  76. RTB3CollisionWorld* world = new RTB3CollisionWorld();
  77. world->m_collidables.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
  78. world->m_collidablePositions.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
  79. world->m_collidableOrientations.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
  80. world->m_collidableTransforms.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
  81. world->m_collidableUserPointers.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
  82. world->m_collidableUserIndices.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX);
  83. world->m_childShapes.resize(maxNumShapesCapacity+START_SHAPE_INDEX);
  84. world->m_planeFaces.resize(maxNumShapesCapacity);
  85. world->m_compoundOverlappingPairs.resize(maxNumPairsCapacity);
  86. m_internalData->m_collisionWorlds.push_back(world);
  87. return (plCollisionWorldHandle) world;
  88. }
  89. void RealTimeBullet3CollisionSdk::deleteCollisionWorld(plCollisionWorldHandle worldHandle)
  90. {
  91. RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
  92. int loc = m_internalData->m_collisionWorlds.findLinearSearch(world);
  93. b3Assert(loc >=0 && loc<m_internalData->m_collisionWorlds.size());
  94. if (loc >=0 && loc<m_internalData->m_collisionWorlds.size())
  95. {
  96. m_internalData->m_collisionWorlds.remove(world);
  97. delete world;
  98. }
  99. }
  100. plCollisionShapeHandle RealTimeBullet3CollisionSdk::createSphereShape(plCollisionWorldHandle worldHandle, plReal radius)
  101. {
  102. RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
  103. b3Assert(world->m_nextFreeShapeIndex<world->m_childShapes.size());
  104. if (world->m_nextFreeShapeIndex<world->m_childShapes.size())
  105. {
  106. b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
  107. shape.m_childPosition.setZero();
  108. shape.m_childOrientation.setValue(0,0,0,1);
  109. shape.m_radius = radius;
  110. shape.m_shapeType = RTB3_SHAPE_SPHERE;
  111. return (plCollisionShapeHandle) world->m_nextFreeShapeIndex++;
  112. }
  113. return 0;
  114. }
  115. plCollisionShapeHandle RealTimeBullet3CollisionSdk::createPlaneShape(plCollisionWorldHandle worldHandle,
  116. plReal planeNormalX,
  117. plReal planeNormalY,
  118. plReal planeNormalZ,
  119. plReal planeConstant)
  120. {
  121. RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
  122. b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size());
  123. if (world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size())
  124. {
  125. b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
  126. shape.m_childPosition.setZero();
  127. shape.m_childOrientation.setValue(0,0,0,1);
  128. world->m_planeFaces[world->m_nextFreePlaneFaceIndex].m_plane = b3MakeVector4(planeNormalX,planeNormalY,planeNormalZ,planeConstant);
  129. shape.m_shapeIndex = world->m_nextFreePlaneFaceIndex++;
  130. shape.m_shapeType = RTB3_SHAPE_PLANE;
  131. return (plCollisionShapeHandle) world->m_nextFreeShapeIndex++;
  132. }
  133. return 0;
  134. }
  135. plCollisionShapeHandle RealTimeBullet3CollisionSdk::createCapsuleShape(plCollisionWorldHandle worldHandle,
  136. plReal radius,
  137. plReal height,
  138. int capsuleAxis)
  139. {
  140. RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
  141. b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size());
  142. if (world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size())
  143. {
  144. b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
  145. shape.m_childPosition.setZero();
  146. shape.m_childOrientation.setValue(0,0,0,1);
  147. shape.m_radius = radius;
  148. shape.m_height = height;
  149. shape.m_shapeIndex = capsuleAxis;
  150. shape.m_shapeType = RTB3_SHAPE_CAPSULE;
  151. return (plCollisionShapeHandle) world->m_nextFreeShapeIndex++;
  152. }
  153. return 0;
  154. }
  155. plCollisionShapeHandle RealTimeBullet3CollisionSdk::createCompoundShape(plCollisionWorldHandle worldHandle)
  156. {
  157. RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
  158. b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size());
  159. if (world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size())
  160. {
  161. b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
  162. shape.m_childPosition.setZero();
  163. shape.m_childOrientation.setValue(0,0,0,1);
  164. shape.m_numChildShapes = 0;
  165. shape.m_shapeType = RTB3_SHAPE_COMPOUND_INTERNAL;
  166. return (plCollisionShapeHandle) world->m_nextFreeShapeIndex++;
  167. }
  168. return 0;
  169. }
  170. void RealTimeBullet3CollisionSdk::addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape,plVector3 childPos,plQuaternion childOrn)
  171. {
  172. }
  173. void RealTimeBullet3CollisionSdk::deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape)
  174. {
  175. ///todo
  176. //deleting shapes would involve a garbage collection phase, and mess up all user indices
  177. //this would be solved by one more in-direction, at some performance penalty for certain operations
  178. //for now, we don't delete and eventually run out-of-shapes
  179. }
  180. void RealTimeBullet3CollisionSdk::addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object)
  181. {
  182. ///createCollisionObject already adds it to the world
  183. }
  184. void RealTimeBullet3CollisionSdk::removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object)
  185. {
  186. ///todo, see deleteShape
  187. }
  188. plCollisionObjectHandle RealTimeBullet3CollisionSdk::createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer,
  189. int userIndex, plCollisionShapeHandle shapeHandle ,
  190. plVector3 startPosition,plQuaternion startOrientation )
  191. {
  192. RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
  193. b3Assert(world->m_nextFreeCollidableIndex < world->m_collidables.size());
  194. if (world->m_nextFreeCollidableIndex < world->m_collidables.size())
  195. {
  196. b3Collidable& collidable = world->m_collidables[world->m_nextFreeCollidableIndex];
  197. world->m_collidablePositions[world->m_nextFreeCollidableIndex].setValue(startPosition[0],startPosition[1],startPosition[2]);
  198. world->m_collidableOrientations[world->m_nextFreeCollidableIndex].setValue(startOrientation[0],startOrientation[1],startOrientation[2],startOrientation[3]);
  199. world->m_collidableTransforms[world->m_nextFreeCollidableIndex].setOrigin(world->m_collidablePositions[world->m_nextFreeCollidableIndex]);
  200. world->m_collidableTransforms[world->m_nextFreeCollidableIndex].setRotation(world->m_collidableOrientations[world->m_nextFreeCollidableIndex]);
  201. world->m_collidableUserPointers[world->m_nextFreeCollidableIndex] = userPointer;
  202. world->m_collidableUserIndices[world->m_nextFreeCollidableIndex] = userIndex;
  203. RTB3_ShapeOpaque2Int caster;
  204. caster.m_ptrValue = shapeHandle;
  205. int shapeIndex = caster.m_intValue;
  206. collidable.m_shapeIndex = shapeIndex;
  207. b3GpuChildShape& shape = world->m_childShapes[shapeIndex];
  208. collidable.m_shapeType = shape.m_shapeType;
  209. collidable.m_numChildShapes = 1;
  210. switch (collidable.m_shapeType)
  211. {
  212. case RTB3_SHAPE_SPHERE:
  213. {
  214. break;
  215. }
  216. case RTB3_SHAPE_PLANE:
  217. {
  218. break;
  219. }
  220. case RTB3_SHAPE_COMPOUND_INTERNAL:
  221. {
  222. break;
  223. }
  224. default:
  225. {
  226. b3Assert(0);
  227. }
  228. }
  229. /*case SHAPE_COMPOUND_OF_CONVEX_HULLS:
  230. case SHAPE_COMPOUND_OF_SPHERES:
  231. case SHAPE_COMPOUND_OF_CAPSULES:
  232. {
  233. collidable.m_numChildShapes = shape.m_numChildShapes;
  234. collidable.m_shapeIndex = shape.m_shapeIndex;
  235. break;
  236. */
  237. return (plCollisionObjectHandle)world->m_nextFreeCollidableIndex++;
  238. }
  239. return 0;
  240. }
  241. void RealTimeBullet3CollisionSdk::deleteCollisionObject(plCollisionObjectHandle body)
  242. {
  243. ///todo, see deleteShape
  244. }
  245. void RealTimeBullet3CollisionSdk::setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body,
  246. plVector3 position,plQuaternion orientation )
  247. {
  248. }
  249. struct plContactCache
  250. {
  251. lwContactPoint* pointsOut;
  252. int pointCapacity;
  253. int numAddedPoints;
  254. };
  255. typedef void (*plDetectCollisionFunc)(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB,
  256. plContactCache* contactCache);
  257. void detectCollisionDummy(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB,
  258. plContactCache* contactCache)
  259. {
  260. (void)world;
  261. (void)colA,(void)colB;
  262. (void)contactCache;
  263. }
  264. void plVecCopy(float* dst,const b3Vector3& src)
  265. {
  266. dst[0] = src.x;
  267. dst[1] = src.y;
  268. dst[2] = src.z;
  269. }
  270. void plVecCopy(double* dst,const b3Vector3& src)
  271. {
  272. dst[0] = src.x;
  273. dst[1] = src.y;
  274. dst[2] = src.z;
  275. }
  276. void ComputeClosestPointsPlaneSphere(const b3Vector3& planeNormalWorld, b3Scalar planeConstant, const b3Vector3& spherePosWorld,b3Scalar sphereRadius, plContactCache* contactCache)
  277. {
  278. if (contactCache->numAddedPoints < contactCache->pointCapacity)
  279. {
  280. lwContactPoint& pointOut = contactCache->pointsOut[contactCache->numAddedPoints];
  281. b3Scalar t = -(spherePosWorld.dot(-planeNormalWorld)+planeConstant);
  282. b3Vector3 intersectionPoint = spherePosWorld+t*-planeNormalWorld;
  283. b3Scalar distance = t-sphereRadius;
  284. if (distance<=0)
  285. {
  286. pointOut.m_distance = distance;
  287. plVecCopy(pointOut.m_ptOnBWorld,intersectionPoint);
  288. plVecCopy(pointOut.m_ptOnAWorld,spherePosWorld+sphereRadius*-planeNormalWorld);
  289. plVecCopy(pointOut.m_normalOnB,planeNormalWorld);
  290. contactCache->numAddedPoints++;
  291. }
  292. }
  293. }
  294. void ComputeClosestPointsSphereSphere(b3Scalar sphereARadius, const b3Vector3& sphereAPosWorld, b3Scalar sphereBRadius, const b3Vector3& sphereBPosWorld, plContactCache* contactCache) {
  295. if (contactCache->numAddedPoints < contactCache->pointCapacity)
  296. {
  297. lwContactPoint& pointOut = contactCache->pointsOut[contactCache->numAddedPoints];
  298. b3Vector3 diff = sphereAPosWorld-sphereBPosWorld;
  299. b3Scalar len = diff.length();
  300. pointOut.m_distance = len - (sphereARadius+sphereBRadius);
  301. if (pointOut.m_distance<=0)
  302. {
  303. b3Vector3 normOnB = b3MakeVector3(1,0,0);
  304. if (len > B3_EPSILON) {
  305. normOnB = diff / len;
  306. }
  307. plVecCopy(pointOut.m_normalOnB,normOnB);
  308. b3Vector3 ptAWorld = sphereAPosWorld - sphereARadius*normOnB;
  309. plVecCopy(pointOut.m_ptOnAWorld,ptAWorld);
  310. plVecCopy(pointOut.m_ptOnBWorld,ptAWorld-normOnB*pointOut.m_distance);
  311. contactCache->numAddedPoints++;
  312. }
  313. }
  314. }
  315. B3_FORCE_INLINE void detectCollisionSphereSphere(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB,
  316. plContactCache* contactCache)
  317. {
  318. const b3Scalar radiusA = world->m_childShapes[shapeIndexA].m_radius;
  319. const b3Scalar radiusB = world->m_childShapes[shapeIndexB].m_radius;
  320. const b3Transform& trA = world->m_collidableTransforms[colA];
  321. const b3Vector3& sphereALocalPos = world->m_childShapes[shapeIndexA].m_childPosition;
  322. b3Vector3 spherePosAWorld = trA(sphereALocalPos);
  323. //b3Vector3 spherePosAWorld = b3QuatRotate( world->m_collidableOrientations[colA], sphereALocalPos ) + (world->m_collidablePositions[colA]);
  324. const b3Transform& trB = world->m_collidableTransforms[colB];
  325. const b3Vector3& sphereBLocalPos = world->m_childShapes[shapeIndexB].m_childPosition;
  326. b3Vector3 spherePosBWorld = trB(sphereBLocalPos);
  327. //b3Vector3 spherePosBWorld = b3QuatRotate( world->m_collidableOrientations[colB], sphereBLocalPos ) + (world->m_collidablePositions[colB]);
  328. ComputeClosestPointsSphereSphere(radiusA,spherePosAWorld,radiusB,spherePosBWorld,contactCache);
  329. }
  330. void detectCollisionSpherePlane(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB,
  331. plContactCache* contactCache)
  332. {
  333. const b3Transform& trA = world->m_collidableTransforms[colA];
  334. const b3Vector3& sphereALocalPos = world->m_childShapes[shapeIndexA].m_childPosition;
  335. b3Vector3 spherePosAWorld = trA(sphereALocalPos);
  336. int planeFaceIndex = world->m_childShapes[shapeIndexB].m_shapeIndex;
  337. b3Vector3 planeNormal = world->m_planeFaces[planeFaceIndex].m_plane;
  338. b3Scalar planeConstant = planeNormal[3];
  339. planeNormal[3] = 0.f;
  340. ComputeClosestPointsPlaneSphere(planeNormal, planeConstant, spherePosAWorld,world->m_childShapes[shapeIndexA].m_radius, contactCache);
  341. }
  342. void detectCollisionPlaneSphere(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB,
  343. plContactCache* contactCache)
  344. {
  345. (void)world;
  346. (void)colA,(void)shapeIndexA,(void)colB,(void)shapeIndexB;
  347. (void)contactCache;
  348. }
  349. #ifdef RTB3_SHAPE_CAPSULE
  350. plDetectCollisionFunc funcTbl_detectCollision[MAX_NUM_SINGLE_SHAPE_TYPES,][MAX_NUM_SINGLE_SHAPE_TYPES,] = {
  351. {detectCollisionSphereSphere ,detectCollisionSpherePlane ,detectCollisionSphereCapsule},
  352. {detectCollisionPlaneSphere ,detectCollisionDummy ,detectCollisionPlaneCapsule},
  353. {detectCollisionCapsuleSphere ,detectCollisionCapsulePlane ,detectCollisionCapsuleCapsule},
  354. };
  355. #else
  356. plDetectCollisionFunc funcTbl_detectCollision[MAX_NUM_SINGLE_SHAPE_TYPES][MAX_NUM_SINGLE_SHAPE_TYPES] = {
  357. {detectCollisionSphereSphere ,detectCollisionSpherePlane},
  358. {detectCollisionPlaneSphere ,detectCollisionDummy },
  359. };
  360. #endif
  361. int RealTimeBullet3CollisionSdk::collide(plCollisionWorldHandle worldHandle,plCollisionObjectHandle colAHandle, plCollisionObjectHandle colBHandle,
  362. lwContactPoint* pointsOutOrg, int pointCapacity)
  363. {
  364. RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
  365. RTB3_ColliderOpaque2Int caster;
  366. caster.m_ptrValue =colAHandle;
  367. int colAIndex = caster.m_intValue;
  368. caster.m_ptrValue = colBHandle;
  369. int colBIndex = caster.m_intValue;
  370. const b3Collidable& colA = world->m_collidables[colAIndex];
  371. const b3Collidable& colB = world->m_collidables[colBIndex];
  372. plContactCache contactCache;
  373. contactCache.pointCapacity = pointCapacity;
  374. contactCache.pointsOut = pointsOutOrg;
  375. contactCache.numAddedPoints = 0;
  376. for (int i=0;i<colA.m_numChildShapes;i++)
  377. {
  378. for (int j=0;j<colB.m_numChildShapes;j++)
  379. {
  380. if (contactCache.numAddedPoints<pointCapacity)
  381. {
  382. //funcTbl_detectCollision[world->m_childShapes[colA.m_shapeIndex+i].m_shapeType]
  383. // [world->m_childShapes[colB.m_shapeIndex+j].m_shapeType](world,colAIndex,colA.m_shapeIndex+i,colBIndex,colB.m_shapeIndex+j,&contactCache);
  384. }
  385. }
  386. return contactCache.numAddedPoints;
  387. }
  388. return 0;
  389. }
  390. void RealTimeBullet3CollisionSdk::collideWorld( plCollisionWorldHandle worldHandle,
  391. plNearCallback filter, void* userData)
  392. {
  393. RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle;
  394. if (filter)
  395. {
  396. RTB3_ColliderOpaque2Int caster;
  397. plCollisionObjectHandle colA;
  398. plCollisionObjectHandle colB;
  399. for (int i=START_COLLIDABLE_INDEX;i<world->m_nextFreeCollidableIndex;i++)
  400. {
  401. for (int j=i+1;j<world->m_nextFreeCollidableIndex;j++)
  402. {
  403. caster.m_intValue = i;
  404. colA = caster.m_ptrValue;
  405. caster.m_intValue = j;
  406. colB = caster.m_ptrValue;
  407. filter((plCollisionSdkHandle)this,worldHandle,userData,colA,colB);
  408. }
  409. }
  410. }
  411. }
  412. plCollisionSdkHandle RealTimeBullet3CollisionSdk::createRealTimeBullet3CollisionSdkHandle()
  413. {
  414. return (plCollisionSdkHandle) new RealTimeBullet3CollisionSdk();
  415. }