Bullet2CollisionSdk.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. #include "Bullet2CollisionSdk.h"
  2. #include "btBulletCollisionCommon.h"
  3. struct Bullet2CollisionSdkInternalData
  4. {
  5. btCollisionConfiguration* m_collisionConfig;
  6. btCollisionDispatcher* m_dispatcher;
  7. btBroadphaseInterface* m_aabbBroadphase;
  8. btCollisionWorld* m_collisionWorld;
  9. Bullet2CollisionSdkInternalData()
  10. :m_aabbBroadphase(0),
  11. m_dispatcher(0),
  12. m_collisionWorld(0)
  13. {
  14. }
  15. };
  16. Bullet2CollisionSdk::Bullet2CollisionSdk()
  17. {
  18. m_internalData = new Bullet2CollisionSdkInternalData;
  19. }
  20. Bullet2CollisionSdk::~Bullet2CollisionSdk()
  21. {
  22. delete m_internalData;
  23. m_internalData = 0;
  24. }
  25. plCollisionWorldHandle Bullet2CollisionSdk::createCollisionWorld(int /*maxNumObjsCapacity*/, int /*maxNumShapesCapacity*/, int /*maxNumPairsCapacity*/)
  26. {
  27. m_internalData->m_collisionConfig = new btDefaultCollisionConfiguration;
  28. m_internalData->m_dispatcher = new btCollisionDispatcher(m_internalData->m_collisionConfig);
  29. m_internalData->m_aabbBroadphase = new btDbvtBroadphase();
  30. m_internalData->m_collisionWorld = new btCollisionWorld(m_internalData->m_dispatcher,
  31. m_internalData->m_aabbBroadphase,
  32. m_internalData->m_collisionConfig);
  33. return (plCollisionWorldHandle) m_internalData->m_collisionWorld;
  34. }
  35. void Bullet2CollisionSdk::deleteCollisionWorld(plCollisionWorldHandle worldHandle)
  36. {
  37. btCollisionWorld* world = (btCollisionWorld*) worldHandle;
  38. btAssert(m_internalData->m_collisionWorld == world);
  39. if (m_internalData->m_collisionWorld == world)
  40. {
  41. delete m_internalData->m_collisionWorld;
  42. m_internalData->m_collisionWorld=0;
  43. delete m_internalData->m_aabbBroadphase;
  44. m_internalData->m_aabbBroadphase=0;
  45. delete m_internalData->m_dispatcher;
  46. m_internalData->m_dispatcher=0;
  47. delete m_internalData->m_collisionConfig;
  48. m_internalData->m_collisionConfig=0;
  49. }
  50. }
  51. plCollisionShapeHandle Bullet2CollisionSdk::createSphereShape(plCollisionWorldHandle /*worldHandle*/, plReal radius)
  52. {
  53. btSphereShape* sphereShape = new btSphereShape(radius);
  54. return (plCollisionShapeHandle) sphereShape;
  55. }
  56. plCollisionShapeHandle Bullet2CollisionSdk::createPlaneShape(plCollisionWorldHandle worldHandle,
  57. plReal planeNormalX,
  58. plReal planeNormalY,
  59. plReal planeNormalZ,
  60. plReal planeConstant)
  61. {
  62. btStaticPlaneShape* planeShape = new btStaticPlaneShape(btVector3(planeNormalX,planeNormalY,planeNormalZ),planeConstant);
  63. return (plCollisionShapeHandle) planeShape;
  64. }
  65. plCollisionShapeHandle Bullet2CollisionSdk::createCapsuleShape(plCollisionWorldHandle worldHandle,
  66. plReal radius,
  67. plReal height,
  68. int capsuleAxis)
  69. {
  70. btCapsuleShape* capsule = 0;
  71. switch (capsuleAxis)
  72. {
  73. case 0:
  74. {
  75. capsule = new btCapsuleShapeX(radius,height);
  76. break;
  77. }
  78. case 1:
  79. {
  80. capsule = new btCapsuleShape(radius,height);
  81. break;
  82. }
  83. case 2:
  84. {
  85. capsule = new btCapsuleShapeZ(radius,height);
  86. break;
  87. }
  88. default:
  89. {
  90. btAssert(0);
  91. }
  92. }
  93. return (plCollisionShapeHandle)capsule;
  94. }
  95. plCollisionShapeHandle Bullet2CollisionSdk::createCompoundShape(plCollisionWorldHandle worldHandle)
  96. {
  97. return (plCollisionShapeHandle) new btCompoundShape();
  98. }
  99. void Bullet2CollisionSdk::addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShapeHandle, plCollisionShapeHandle childShapeHandle,plVector3 childPos,plQuaternion childOrn)
  100. {
  101. btCompoundShape* compound = (btCompoundShape*) compoundShapeHandle;
  102. btCollisionShape* childShape = (btCollisionShape*) childShapeHandle;
  103. btTransform localTrans;
  104. localTrans.setOrigin(btVector3(childPos[0],childPos[1],childPos[2]));
  105. localTrans.setRotation(btQuaternion(childOrn[0],childOrn[1],childOrn[2],childOrn[3]));
  106. compound->addChildShape(localTrans,childShape);
  107. }
  108. void Bullet2CollisionSdk::deleteShape(plCollisionWorldHandle /*worldHandle*/, plCollisionShapeHandle shapeHandle)
  109. {
  110. btCollisionShape* shape = (btCollisionShape*) shapeHandle;
  111. delete shape;
  112. }
  113. void Bullet2CollisionSdk::addCollisionObject(plCollisionWorldHandle worldHandle, plCollisionObjectHandle objectHandle)
  114. {
  115. btCollisionWorld* world = (btCollisionWorld*) worldHandle;
  116. btCollisionObject* colObj = (btCollisionObject*) objectHandle;
  117. btAssert(world && colObj);
  118. if (world == m_internalData->m_collisionWorld && colObj)
  119. {
  120. world->addCollisionObject(colObj);
  121. }
  122. }
  123. void Bullet2CollisionSdk::removeCollisionObject(plCollisionWorldHandle worldHandle, plCollisionObjectHandle objectHandle)
  124. {
  125. btCollisionWorld* world = (btCollisionWorld*) worldHandle;
  126. btCollisionObject* colObj = (btCollisionObject*) objectHandle;
  127. btAssert(world && colObj);
  128. if (world == m_internalData->m_collisionWorld && colObj)
  129. {
  130. world->removeCollisionObject(colObj);
  131. }
  132. }
  133. plCollisionObjectHandle Bullet2CollisionSdk::createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle shapeHandle ,
  134. plVector3 startPosition,plQuaternion startOrientation )
  135. {
  136. btCollisionShape* colShape = (btCollisionShape*) shapeHandle;
  137. btAssert(colShape);
  138. if (colShape)
  139. {
  140. btCollisionObject* colObj= new btCollisionObject;
  141. colObj->setUserIndex(userIndex);
  142. colObj->setUserPointer(userPointer);
  143. colObj->setCollisionShape(colShape);
  144. btTransform tr;
  145. tr.setOrigin(btVector3(startPosition[0],startPosition[1],startPosition[2]));
  146. tr.setRotation(btQuaternion(startOrientation[0],startOrientation[1],startOrientation[2],startOrientation[3]));
  147. colObj->setWorldTransform(tr);
  148. return (plCollisionObjectHandle) colObj;
  149. }
  150. return 0;
  151. }
  152. void Bullet2CollisionSdk::deleteCollisionObject(plCollisionObjectHandle bodyHandle)
  153. {
  154. btCollisionObject* colObj = (btCollisionObject*) bodyHandle;
  155. delete colObj;
  156. }
  157. void Bullet2CollisionSdk::setCollisionObjectTransform(plCollisionWorldHandle /*worldHandle*/, plCollisionObjectHandle bodyHandle,
  158. plVector3 position,plQuaternion orientation )
  159. {
  160. btCollisionObject* colObj = (btCollisionObject*) bodyHandle;
  161. btTransform tr;
  162. tr.setOrigin(btVector3(position[0],position[1],position[2]));
  163. tr.setRotation(btQuaternion(orientation[0],orientation[1],orientation[2],orientation[3]));
  164. colObj->setWorldTransform(tr);
  165. }
  166. struct Bullet2ContactResultCallback : public btCollisionWorld::ContactResultCallback
  167. {
  168. int m_numContacts;
  169. lwContactPoint* m_pointsOut;
  170. int m_pointCapacity;
  171. Bullet2ContactResultCallback(lwContactPoint* pointsOut, int pointCapacity) :
  172. m_numContacts(0),
  173. m_pointsOut(pointsOut),
  174. m_pointCapacity(pointCapacity)
  175. {
  176. }
  177. virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
  178. {
  179. if (m_numContacts<m_pointCapacity)
  180. {
  181. lwContactPoint& ptOut = m_pointsOut[m_numContacts];
  182. ptOut.m_distance = cp.m_distance1;
  183. ptOut.m_normalOnB[0] = cp.m_normalWorldOnB.getX();
  184. ptOut.m_normalOnB[1] = cp.m_normalWorldOnB.getY();
  185. ptOut.m_normalOnB[2] = cp.m_normalWorldOnB.getZ();
  186. ptOut.m_ptOnAWorld[0] = cp.m_positionWorldOnA[0];
  187. ptOut.m_ptOnAWorld[1] = cp.m_positionWorldOnA[1];
  188. ptOut.m_ptOnAWorld[2] = cp.m_positionWorldOnA[2];
  189. ptOut.m_ptOnBWorld[0] = cp.m_positionWorldOnB[0];
  190. ptOut.m_ptOnBWorld[1] = cp.m_positionWorldOnB[1];
  191. ptOut.m_ptOnBWorld[2] = cp.m_positionWorldOnB[2];
  192. m_numContacts++;
  193. }
  194. return 1.f;
  195. }
  196. };
  197. int Bullet2CollisionSdk::collide(plCollisionWorldHandle worldHandle,plCollisionObjectHandle colA, plCollisionObjectHandle colB,
  198. lwContactPoint* pointsOut, int pointCapacity)
  199. {
  200. btCollisionWorld* world = (btCollisionWorld*) worldHandle;
  201. btCollisionObject* colObjA = (btCollisionObject*) colA;
  202. btCollisionObject* colObjB = (btCollisionObject*) colB;
  203. btAssert(world && colObjA && colObjB);
  204. if (world == m_internalData->m_collisionWorld && colObjA && colObjB)
  205. {
  206. Bullet2ContactResultCallback cb(pointsOut,pointCapacity);
  207. world->contactPairTest(colObjA,colObjB,cb);
  208. return cb.m_numContacts;
  209. }
  210. return 0;
  211. }
  212. static plNearCallback gTmpFilter;
  213. static int gNearCallbackCount = 0;
  214. static plCollisionSdkHandle gCollisionSdk = 0;
  215. static plCollisionWorldHandle gCollisionWorldHandle = 0;
  216. static void* gUserData = 0;
  217. void Bullet2NearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo)
  218. {
  219. btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
  220. btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
  221. plCollisionObjectHandle obA =(plCollisionObjectHandle) colObj0;
  222. plCollisionObjectHandle obB =(plCollisionObjectHandle) colObj1;
  223. if(gTmpFilter)
  224. {
  225. gTmpFilter(gCollisionSdk,gCollisionWorldHandle, gUserData,obA,obB);
  226. gNearCallbackCount++;
  227. }
  228. }
  229. void Bullet2CollisionSdk::collideWorld( plCollisionWorldHandle worldHandle,
  230. plNearCallback filter, void* userData)
  231. {
  232. btCollisionWorld* world = (btCollisionWorld*) worldHandle;
  233. //chain the near-callback
  234. gTmpFilter = filter;
  235. gNearCallbackCount = 0;
  236. gUserData = userData;
  237. gCollisionSdk = (plCollisionSdkHandle)this;
  238. gCollisionWorldHandle = worldHandle;
  239. m_internalData->m_dispatcher->setNearCallback(Bullet2NearCallback);
  240. world->performDiscreteCollisionDetection();
  241. gTmpFilter = 0;
  242. }
  243. plCollisionSdkHandle Bullet2CollisionSdk::createBullet2SdkHandle()
  244. {
  245. return (plCollisionSdkHandle) new Bullet2CollisionSdk;
  246. }