btAxisSweep3Internal.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955
  1. //Bullet Continuous Collision Detection and Physics Library
  2. //Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
  3. //
  4. // btAxisSweep3.h
  5. //
  6. // Copyright (c) 2006 Simon Hobbs
  7. //
  8. // This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
  9. //
  10. // Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
  11. //
  12. // 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.
  13. //
  14. // 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  15. //
  16. // 3. This notice may not be removed or altered from any source distribution.
  17. #ifndef BT_AXIS_SWEEP_3_INTERNAL_H
  18. #define BT_AXIS_SWEEP_3_INTERNAL_H
  19. #include "LinearMath/btVector3.h"
  20. #include "btOverlappingPairCache.h"
  21. #include "btBroadphaseInterface.h"
  22. #include "btBroadphaseProxy.h"
  23. #include "btOverlappingPairCallback.h"
  24. #include "btDbvtBroadphase.h"
  25. //#define DEBUG_BROADPHASE 1
  26. #define USE_OVERLAP_TEST_ON_REMOVES 1
  27. /// The internal templace class btAxisSweep3Internal implements the sweep and prune broadphase.
  28. /// It uses quantized integers to represent the begin and end points for each of the 3 axis.
  29. /// Dont use this class directly, use btAxisSweep3 or bt32BitAxisSweep3 instead.
  30. template <typename BP_FP_INT_TYPE>
  31. class btAxisSweep3Internal : public btBroadphaseInterface
  32. {
  33. protected:
  34. BP_FP_INT_TYPE m_bpHandleMask;
  35. BP_FP_INT_TYPE m_handleSentinel;
  36. public:
  37. BT_DECLARE_ALIGNED_ALLOCATOR();
  38. class Edge
  39. {
  40. public:
  41. BP_FP_INT_TYPE m_pos; // low bit is min/max
  42. BP_FP_INT_TYPE m_handle;
  43. BP_FP_INT_TYPE IsMax() const { return static_cast<BP_FP_INT_TYPE>(m_pos & 1); }
  44. };
  45. public:
  46. class Handle : public btBroadphaseProxy
  47. {
  48. public:
  49. BT_DECLARE_ALIGNED_ALLOCATOR();
  50. // indexes into the edge arrays
  51. BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12
  52. // BP_FP_INT_TYPE m_uniqueId;
  53. btBroadphaseProxy* m_dbvtProxy; //for faster raycast
  54. //void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject
  55. SIMD_FORCE_INLINE void SetNextFree(BP_FP_INT_TYPE next) { m_minEdges[0] = next; }
  56. SIMD_FORCE_INLINE BP_FP_INT_TYPE GetNextFree() const { return m_minEdges[0]; }
  57. }; // 24 bytes + 24 for Edge structures = 44 bytes total per entry
  58. protected:
  59. btVector3 m_worldAabbMin; // overall system bounds
  60. btVector3 m_worldAabbMax; // overall system bounds
  61. btVector3 m_quantize; // scaling factor for quantization
  62. BP_FP_INT_TYPE m_numHandles; // number of active handles
  63. BP_FP_INT_TYPE m_maxHandles; // max number of handles
  64. Handle* m_pHandles; // handles pool
  65. BP_FP_INT_TYPE m_firstFreeHandle; // free handles list
  66. Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries)
  67. void* m_pEdgesRawPtr[3];
  68. btOverlappingPairCache* m_pairCache;
  69. ///btOverlappingPairCallback is an additional optional user callback for adding/removing overlapping pairs, similar interface to btOverlappingPairCache.
  70. btOverlappingPairCallback* m_userPairCallback;
  71. bool m_ownsPairCache;
  72. int m_invalidPair;
  73. ///additional dynamic aabb structure, used to accelerate ray cast queries.
  74. ///can be disabled using a optional argument in the constructor
  75. btDbvtBroadphase* m_raycastAccelerator;
  76. btOverlappingPairCache* m_nullPairCache;
  77. // allocation/deallocation
  78. BP_FP_INT_TYPE allocHandle();
  79. void freeHandle(BP_FP_INT_TYPE handle);
  80. bool testOverlap2D(const Handle* pHandleA, const Handle* pHandleB, int axis0, int axis1);
  81. #ifdef DEBUG_BROADPHASE
  82. void debugPrintAxis(int axis, bool checkCardinality = true);
  83. #endif //DEBUG_BROADPHASE
  84. //Overlap* AddOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
  85. //void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
  86. void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps);
  87. void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps);
  88. void sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps);
  89. void sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps);
  90. public:
  91. btAxisSweep3Internal(const btVector3& worldAabbMin, const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false);
  92. virtual ~btAxisSweep3Internal();
  93. BP_FP_INT_TYPE getNumHandles() const
  94. {
  95. return m_numHandles;
  96. }
  97. virtual void calculateOverlappingPairs(btDispatcher* dispatcher);
  98. BP_FP_INT_TYPE addHandle(const btVector3& aabbMin, const btVector3& aabbMax, void* pOwner, int collisionFilterGroup, int collisionFilterMask, btDispatcher* dispatcher);
  99. void removeHandle(BP_FP_INT_TYPE handle, btDispatcher* dispatcher);
  100. void updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin, const btVector3& aabbMax, btDispatcher* dispatcher);
  101. SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const { return m_pHandles + index; }
  102. virtual void resetPool(btDispatcher* dispatcher);
  103. void processAllOverlappingPairs(btOverlapCallback* callback);
  104. //Broadphase Interface
  105. virtual btBroadphaseProxy* createProxy(const btVector3& aabbMin, const btVector3& aabbMax, int shapeType, void* userPtr, int collisionFilterGroup, int collisionFilterMask, btDispatcher* dispatcher);
  106. virtual void destroyProxy(btBroadphaseProxy* proxy, btDispatcher* dispatcher);
  107. virtual void setAabb(btBroadphaseProxy* proxy, const btVector3& aabbMin, const btVector3& aabbMax, btDispatcher* dispatcher);
  108. virtual void getAabb(btBroadphaseProxy* proxy, btVector3& aabbMin, btVector3& aabbMax) const;
  109. virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin = btVector3(0, 0, 0), const btVector3& aabbMax = btVector3(0, 0, 0));
  110. virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback);
  111. void quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const;
  112. ///unQuantize should be conservative: aabbMin/aabbMax should be larger then 'getAabb' result
  113. void unQuantize(btBroadphaseProxy* proxy, btVector3& aabbMin, btVector3& aabbMax) const;
  114. bool testAabbOverlap(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1);
  115. btOverlappingPairCache* getOverlappingPairCache()
  116. {
  117. return m_pairCache;
  118. }
  119. const btOverlappingPairCache* getOverlappingPairCache() const
  120. {
  121. return m_pairCache;
  122. }
  123. void setOverlappingPairUserCallback(btOverlappingPairCallback* pairCallback)
  124. {
  125. m_userPairCallback = pairCallback;
  126. }
  127. const btOverlappingPairCallback* getOverlappingPairUserCallback() const
  128. {
  129. return m_userPairCallback;
  130. }
  131. ///getAabb returns the axis aligned bounding box in the 'global' coordinate frame
  132. ///will add some transform later
  133. virtual void getBroadphaseAabb(btVector3& aabbMin, btVector3& aabbMax) const
  134. {
  135. aabbMin = m_worldAabbMin;
  136. aabbMax = m_worldAabbMax;
  137. }
  138. virtual void printStats()
  139. {
  140. /* printf("btAxisSweep3.h\n");
  141. printf("numHandles = %d, maxHandles = %d\n",m_numHandles,m_maxHandles);
  142. printf("aabbMin=%f,%f,%f,aabbMax=%f,%f,%f\n",m_worldAabbMin.getX(),m_worldAabbMin.getY(),m_worldAabbMin.getZ(),
  143. m_worldAabbMax.getX(),m_worldAabbMax.getY(),m_worldAabbMax.getZ());
  144. */
  145. }
  146. };
  147. ////////////////////////////////////////////////////////////////////
  148. #ifdef DEBUG_BROADPHASE
  149. #include <stdio.h>
  150. template <typename BP_FP_INT_TYPE>
  151. void btAxisSweep3<BP_FP_INT_TYPE>::debugPrintAxis(int axis, bool checkCardinality)
  152. {
  153. int numEdges = m_pHandles[0].m_maxEdges[axis];
  154. printf("SAP Axis %d, numEdges=%d\n", axis, numEdges);
  155. int i;
  156. for (i = 0; i < numEdges + 1; i++)
  157. {
  158. Edge* pEdge = m_pEdges[axis] + i;
  159. Handle* pHandlePrev = getHandle(pEdge->m_handle);
  160. int handleIndex = pEdge->IsMax() ? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis];
  161. char beginOrEnd;
  162. beginOrEnd = pEdge->IsMax() ? 'E' : 'B';
  163. printf(" [%c,h=%d,p=%x,i=%d]\n", beginOrEnd, pEdge->m_handle, pEdge->m_pos, handleIndex);
  164. }
  165. if (checkCardinality)
  166. btAssert(numEdges == m_numHandles * 2 + 1);
  167. }
  168. #endif //DEBUG_BROADPHASE
  169. template <typename BP_FP_INT_TYPE>
  170. btBroadphaseProxy* btAxisSweep3Internal<BP_FP_INT_TYPE>::createProxy(const btVector3& aabbMin, const btVector3& aabbMax, int shapeType, void* userPtr, int collisionFilterGroup, int collisionFilterMask, btDispatcher* dispatcher)
  171. {
  172. (void)shapeType;
  173. BP_FP_INT_TYPE handleId = addHandle(aabbMin, aabbMax, userPtr, collisionFilterGroup, collisionFilterMask, dispatcher);
  174. Handle* handle = getHandle(handleId);
  175. if (m_raycastAccelerator)
  176. {
  177. btBroadphaseProxy* rayProxy = m_raycastAccelerator->createProxy(aabbMin, aabbMax, shapeType, userPtr, collisionFilterGroup, collisionFilterMask, dispatcher);
  178. handle->m_dbvtProxy = rayProxy;
  179. }
  180. return handle;
  181. }
  182. template <typename BP_FP_INT_TYPE>
  183. void btAxisSweep3Internal<BP_FP_INT_TYPE>::destroyProxy(btBroadphaseProxy* proxy, btDispatcher* dispatcher)
  184. {
  185. Handle* handle = static_cast<Handle*>(proxy);
  186. if (m_raycastAccelerator)
  187. m_raycastAccelerator->destroyProxy(handle->m_dbvtProxy, dispatcher);
  188. removeHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), dispatcher);
  189. }
  190. template <typename BP_FP_INT_TYPE>
  191. void btAxisSweep3Internal<BP_FP_INT_TYPE>::setAabb(btBroadphaseProxy* proxy, const btVector3& aabbMin, const btVector3& aabbMax, btDispatcher* dispatcher)
  192. {
  193. Handle* handle = static_cast<Handle*>(proxy);
  194. handle->m_aabbMin = aabbMin;
  195. handle->m_aabbMax = aabbMax;
  196. updateHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), aabbMin, aabbMax, dispatcher);
  197. if (m_raycastAccelerator)
  198. m_raycastAccelerator->setAabb(handle->m_dbvtProxy, aabbMin, aabbMax, dispatcher);
  199. }
  200. template <typename BP_FP_INT_TYPE>
  201. void btAxisSweep3Internal<BP_FP_INT_TYPE>::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin, const btVector3& aabbMax)
  202. {
  203. if (m_raycastAccelerator)
  204. {
  205. m_raycastAccelerator->rayTest(rayFrom, rayTo, rayCallback, aabbMin, aabbMax);
  206. }
  207. else
  208. {
  209. //choose axis?
  210. BP_FP_INT_TYPE axis = 0;
  211. //for each proxy
  212. for (BP_FP_INT_TYPE i = 1; i < m_numHandles * 2 + 1; i++)
  213. {
  214. if (m_pEdges[axis][i].IsMax())
  215. {
  216. rayCallback.process(getHandle(m_pEdges[axis][i].m_handle));
  217. }
  218. }
  219. }
  220. }
  221. template <typename BP_FP_INT_TYPE>
  222. void btAxisSweep3Internal<BP_FP_INT_TYPE>::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback)
  223. {
  224. if (m_raycastAccelerator)
  225. {
  226. m_raycastAccelerator->aabbTest(aabbMin, aabbMax, callback);
  227. }
  228. else
  229. {
  230. //choose axis?
  231. BP_FP_INT_TYPE axis = 0;
  232. //for each proxy
  233. for (BP_FP_INT_TYPE i = 1; i < m_numHandles * 2 + 1; i++)
  234. {
  235. if (m_pEdges[axis][i].IsMax())
  236. {
  237. Handle* handle = getHandle(m_pEdges[axis][i].m_handle);
  238. if (TestAabbAgainstAabb2(aabbMin, aabbMax, handle->m_aabbMin, handle->m_aabbMax))
  239. {
  240. callback.process(handle);
  241. }
  242. }
  243. }
  244. }
  245. }
  246. template <typename BP_FP_INT_TYPE>
  247. void btAxisSweep3Internal<BP_FP_INT_TYPE>::getAabb(btBroadphaseProxy* proxy, btVector3& aabbMin, btVector3& aabbMax) const
  248. {
  249. Handle* pHandle = static_cast<Handle*>(proxy);
  250. aabbMin = pHandle->m_aabbMin;
  251. aabbMax = pHandle->m_aabbMax;
  252. }
  253. template <typename BP_FP_INT_TYPE>
  254. void btAxisSweep3Internal<BP_FP_INT_TYPE>::unQuantize(btBroadphaseProxy* proxy, btVector3& aabbMin, btVector3& aabbMax) const
  255. {
  256. Handle* pHandle = static_cast<Handle*>(proxy);
  257. unsigned short vecInMin[3];
  258. unsigned short vecInMax[3];
  259. vecInMin[0] = m_pEdges[0][pHandle->m_minEdges[0]].m_pos;
  260. vecInMax[0] = m_pEdges[0][pHandle->m_maxEdges[0]].m_pos + 1;
  261. vecInMin[1] = m_pEdges[1][pHandle->m_minEdges[1]].m_pos;
  262. vecInMax[1] = m_pEdges[1][pHandle->m_maxEdges[1]].m_pos + 1;
  263. vecInMin[2] = m_pEdges[2][pHandle->m_minEdges[2]].m_pos;
  264. vecInMax[2] = m_pEdges[2][pHandle->m_maxEdges[2]].m_pos + 1;
  265. aabbMin.setValue((btScalar)(vecInMin[0]) / (m_quantize.getX()), (btScalar)(vecInMin[1]) / (m_quantize.getY()), (btScalar)(vecInMin[2]) / (m_quantize.getZ()));
  266. aabbMin += m_worldAabbMin;
  267. aabbMax.setValue((btScalar)(vecInMax[0]) / (m_quantize.getX()), (btScalar)(vecInMax[1]) / (m_quantize.getY()), (btScalar)(vecInMax[2]) / (m_quantize.getZ()));
  268. aabbMax += m_worldAabbMin;
  269. }
  270. template <typename BP_FP_INT_TYPE>
  271. btAxisSweep3Internal<BP_FP_INT_TYPE>::btAxisSweep3Internal(const btVector3& worldAabbMin, const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache, bool disableRaycastAccelerator)
  272. : m_bpHandleMask(handleMask),
  273. m_handleSentinel(handleSentinel),
  274. m_pairCache(pairCache),
  275. m_userPairCallback(0),
  276. m_ownsPairCache(false),
  277. m_invalidPair(0),
  278. m_raycastAccelerator(0)
  279. {
  280. BP_FP_INT_TYPE maxHandles = static_cast<BP_FP_INT_TYPE>(userMaxHandles + 1); //need to add one sentinel handle
  281. if (!m_pairCache)
  282. {
  283. void* ptr = btAlignedAlloc(sizeof(btHashedOverlappingPairCache), 16);
  284. m_pairCache = new (ptr) btHashedOverlappingPairCache();
  285. m_ownsPairCache = true;
  286. }
  287. if (!disableRaycastAccelerator)
  288. {
  289. m_nullPairCache = new (btAlignedAlloc(sizeof(btNullPairCache), 16)) btNullPairCache();
  290. m_raycastAccelerator = new (btAlignedAlloc(sizeof(btDbvtBroadphase), 16)) btDbvtBroadphase(m_nullPairCache); //m_pairCache);
  291. m_raycastAccelerator->m_deferedcollide = true; //don't add/remove pairs
  292. }
  293. //btAssert(bounds.HasVolume());
  294. // init bounds
  295. m_worldAabbMin = worldAabbMin;
  296. m_worldAabbMax = worldAabbMax;
  297. btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin;
  298. BP_FP_INT_TYPE maxInt = m_handleSentinel;
  299. m_quantize = btVector3(btScalar(maxInt), btScalar(maxInt), btScalar(maxInt)) / aabbSize;
  300. // allocate handles buffer, using btAlignedAlloc, and put all handles on free list
  301. m_pHandles = new Handle[maxHandles];
  302. m_maxHandles = maxHandles;
  303. m_numHandles = 0;
  304. // handle 0 is reserved as the null index, and is also used as the sentinel
  305. m_firstFreeHandle = 1;
  306. {
  307. for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < maxHandles; i++)
  308. m_pHandles[i].SetNextFree(static_cast<BP_FP_INT_TYPE>(i + 1));
  309. m_pHandles[maxHandles - 1].SetNextFree(0);
  310. }
  311. {
  312. // allocate edge buffers
  313. for (int i = 0; i < 3; i++)
  314. {
  315. m_pEdgesRawPtr[i] = btAlignedAlloc(sizeof(Edge) * maxHandles * 2, 16);
  316. m_pEdges[i] = new (m_pEdgesRawPtr[i]) Edge[maxHandles * 2];
  317. }
  318. }
  319. //removed overlap management
  320. // make boundary sentinels
  321. m_pHandles[0].m_clientObject = 0;
  322. for (int axis = 0; axis < 3; axis++)
  323. {
  324. m_pHandles[0].m_minEdges[axis] = 0;
  325. m_pHandles[0].m_maxEdges[axis] = 1;
  326. m_pEdges[axis][0].m_pos = 0;
  327. m_pEdges[axis][0].m_handle = 0;
  328. m_pEdges[axis][1].m_pos = m_handleSentinel;
  329. m_pEdges[axis][1].m_handle = 0;
  330. #ifdef DEBUG_BROADPHASE
  331. debugPrintAxis(axis);
  332. #endif //DEBUG_BROADPHASE
  333. }
  334. }
  335. template <typename BP_FP_INT_TYPE>
  336. btAxisSweep3Internal<BP_FP_INT_TYPE>::~btAxisSweep3Internal()
  337. {
  338. if (m_raycastAccelerator)
  339. {
  340. m_nullPairCache->~btOverlappingPairCache();
  341. btAlignedFree(m_nullPairCache);
  342. m_raycastAccelerator->~btDbvtBroadphase();
  343. btAlignedFree(m_raycastAccelerator);
  344. }
  345. for (int i = 2; i >= 0; i--)
  346. {
  347. btAlignedFree(m_pEdgesRawPtr[i]);
  348. }
  349. delete[] m_pHandles;
  350. if (m_ownsPairCache)
  351. {
  352. m_pairCache->~btOverlappingPairCache();
  353. btAlignedFree(m_pairCache);
  354. }
  355. }
  356. template <typename BP_FP_INT_TYPE>
  357. void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const
  358. {
  359. #ifdef OLD_CLAMPING_METHOD
  360. ///problem with this clamping method is that the floating point during quantization might still go outside the range [(0|isMax) .. (m_handleSentinel&m_bpHandleMask]|isMax]
  361. ///see http://code.google.com/p/bullet/issues/detail?id=87
  362. btVector3 clampedPoint(point);
  363. clampedPoint.setMax(m_worldAabbMin);
  364. clampedPoint.setMin(m_worldAabbMax);
  365. btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize;
  366. out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & m_bpHandleMask) | isMax);
  367. out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & m_bpHandleMask) | isMax);
  368. out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & m_bpHandleMask) | isMax);
  369. #else
  370. btVector3 v = (point - m_worldAabbMin) * m_quantize;
  371. out[0] = (v[0] <= 0) ? (BP_FP_INT_TYPE)isMax : (v[0] >= m_handleSentinel) ? (BP_FP_INT_TYPE)((m_handleSentinel & m_bpHandleMask) | isMax) : (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[0] & m_bpHandleMask) | isMax);
  372. out[1] = (v[1] <= 0) ? (BP_FP_INT_TYPE)isMax : (v[1] >= m_handleSentinel) ? (BP_FP_INT_TYPE)((m_handleSentinel & m_bpHandleMask) | isMax) : (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[1] & m_bpHandleMask) | isMax);
  373. out[2] = (v[2] <= 0) ? (BP_FP_INT_TYPE)isMax : (v[2] >= m_handleSentinel) ? (BP_FP_INT_TYPE)((m_handleSentinel & m_bpHandleMask) | isMax) : (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[2] & m_bpHandleMask) | isMax);
  374. #endif //OLD_CLAMPING_METHOD
  375. }
  376. template <typename BP_FP_INT_TYPE>
  377. BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::allocHandle()
  378. {
  379. btAssert(m_firstFreeHandle);
  380. BP_FP_INT_TYPE handle = m_firstFreeHandle;
  381. m_firstFreeHandle = getHandle(handle)->GetNextFree();
  382. m_numHandles++;
  383. return handle;
  384. }
  385. template <typename BP_FP_INT_TYPE>
  386. void btAxisSweep3Internal<BP_FP_INT_TYPE>::freeHandle(BP_FP_INT_TYPE handle)
  387. {
  388. btAssert(handle > 0 && handle < m_maxHandles);
  389. getHandle(handle)->SetNextFree(m_firstFreeHandle);
  390. m_firstFreeHandle = handle;
  391. m_numHandles--;
  392. }
  393. template <typename BP_FP_INT_TYPE>
  394. BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::addHandle(const btVector3& aabbMin, const btVector3& aabbMax, void* pOwner, int collisionFilterGroup, int collisionFilterMask, btDispatcher* dispatcher)
  395. {
  396. // quantize the bounds
  397. BP_FP_INT_TYPE min[3], max[3];
  398. quantize(min, aabbMin, 0);
  399. quantize(max, aabbMax, 1);
  400. // allocate a handle
  401. BP_FP_INT_TYPE handle = allocHandle();
  402. Handle* pHandle = getHandle(handle);
  403. pHandle->m_uniqueId = static_cast<int>(handle);
  404. //pHandle->m_pOverlaps = 0;
  405. pHandle->m_clientObject = pOwner;
  406. pHandle->m_collisionFilterGroup = collisionFilterGroup;
  407. pHandle->m_collisionFilterMask = collisionFilterMask;
  408. // compute current limit of edge arrays
  409. BP_FP_INT_TYPE limit = static_cast<BP_FP_INT_TYPE>(m_numHandles * 2);
  410. // insert new edges just inside the max boundary edge
  411. for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++)
  412. {
  413. m_pHandles[0].m_maxEdges[axis] += 2;
  414. m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1];
  415. m_pEdges[axis][limit - 1].m_pos = min[axis];
  416. m_pEdges[axis][limit - 1].m_handle = handle;
  417. m_pEdges[axis][limit].m_pos = max[axis];
  418. m_pEdges[axis][limit].m_handle = handle;
  419. pHandle->m_minEdges[axis] = static_cast<BP_FP_INT_TYPE>(limit - 1);
  420. pHandle->m_maxEdges[axis] = limit;
  421. }
  422. // now sort the new edges to their correct position
  423. sortMinDown(0, pHandle->m_minEdges[0], dispatcher, false);
  424. sortMaxDown(0, pHandle->m_maxEdges[0], dispatcher, false);
  425. sortMinDown(1, pHandle->m_minEdges[1], dispatcher, false);
  426. sortMaxDown(1, pHandle->m_maxEdges[1], dispatcher, false);
  427. sortMinDown(2, pHandle->m_minEdges[2], dispatcher, true);
  428. sortMaxDown(2, pHandle->m_maxEdges[2], dispatcher, true);
  429. return handle;
  430. }
  431. template <typename BP_FP_INT_TYPE>
  432. void btAxisSweep3Internal<BP_FP_INT_TYPE>::removeHandle(BP_FP_INT_TYPE handle, btDispatcher* dispatcher)
  433. {
  434. Handle* pHandle = getHandle(handle);
  435. //explicitly remove the pairs containing the proxy
  436. //we could do it also in the sortMinUp (passing true)
  437. ///@todo: compare performance
  438. if (!m_pairCache->hasDeferredRemoval())
  439. {
  440. m_pairCache->removeOverlappingPairsContainingProxy(pHandle, dispatcher);
  441. }
  442. // compute current limit of edge arrays
  443. int limit = static_cast<int>(m_numHandles * 2);
  444. int axis;
  445. for (axis = 0; axis < 3; axis++)
  446. {
  447. m_pHandles[0].m_maxEdges[axis] -= 2;
  448. }
  449. // remove the edges by sorting them up to the end of the list
  450. for (axis = 0; axis < 3; axis++)
  451. {
  452. Edge* pEdges = m_pEdges[axis];
  453. BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis];
  454. pEdges[max].m_pos = m_handleSentinel;
  455. sortMaxUp(axis, max, dispatcher, false);
  456. BP_FP_INT_TYPE i = pHandle->m_minEdges[axis];
  457. pEdges[i].m_pos = m_handleSentinel;
  458. sortMinUp(axis, i, dispatcher, false);
  459. pEdges[limit - 1].m_handle = 0;
  460. pEdges[limit - 1].m_pos = m_handleSentinel;
  461. #ifdef DEBUG_BROADPHASE
  462. debugPrintAxis(axis, false);
  463. #endif //DEBUG_BROADPHASE
  464. }
  465. // free the handle
  466. freeHandle(handle);
  467. }
  468. template <typename BP_FP_INT_TYPE>
  469. void btAxisSweep3Internal<BP_FP_INT_TYPE>::resetPool(btDispatcher* /*dispatcher*/)
  470. {
  471. if (m_numHandles == 0)
  472. {
  473. m_firstFreeHandle = 1;
  474. {
  475. for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < m_maxHandles; i++)
  476. m_pHandles[i].SetNextFree(static_cast<BP_FP_INT_TYPE>(i + 1));
  477. m_pHandles[m_maxHandles - 1].SetNextFree(0);
  478. }
  479. }
  480. }
  481. //#include <stdio.h>
  482. template <typename BP_FP_INT_TYPE>
  483. void btAxisSweep3Internal<BP_FP_INT_TYPE>::calculateOverlappingPairs(btDispatcher* dispatcher)
  484. {
  485. if (m_pairCache->hasDeferredRemoval())
  486. {
  487. btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray();
  488. //perform a sort, to find duplicates and to sort 'invalid' pairs to the end
  489. overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
  490. overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
  491. m_invalidPair = 0;
  492. int i;
  493. btBroadphasePair previousPair;
  494. previousPair.m_pProxy0 = 0;
  495. previousPair.m_pProxy1 = 0;
  496. previousPair.m_algorithm = 0;
  497. for (i = 0; i < overlappingPairArray.size(); i++)
  498. {
  499. btBroadphasePair& pair = overlappingPairArray[i];
  500. bool isDuplicate = (pair == previousPair);
  501. previousPair = pair;
  502. bool needsRemoval = false;
  503. if (!isDuplicate)
  504. {
  505. ///important to use an AABB test that is consistent with the broadphase
  506. bool hasOverlap = testAabbOverlap(pair.m_pProxy0, pair.m_pProxy1);
  507. if (hasOverlap)
  508. {
  509. needsRemoval = false; //callback->processOverlap(pair);
  510. }
  511. else
  512. {
  513. needsRemoval = true;
  514. }
  515. }
  516. else
  517. {
  518. //remove duplicate
  519. needsRemoval = true;
  520. //should have no algorithm
  521. btAssert(!pair.m_algorithm);
  522. }
  523. if (needsRemoval)
  524. {
  525. m_pairCache->cleanOverlappingPair(pair, dispatcher);
  526. // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
  527. // m_overlappingPairArray.pop_back();
  528. pair.m_pProxy0 = 0;
  529. pair.m_pProxy1 = 0;
  530. m_invalidPair++;
  531. }
  532. }
  533. ///if you don't like to skip the invalid pairs in the array, execute following code:
  534. #define CLEAN_INVALID_PAIRS 1
  535. #ifdef CLEAN_INVALID_PAIRS
  536. //perform a sort, to sort 'invalid' pairs to the end
  537. overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
  538. overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
  539. m_invalidPair = 0;
  540. #endif //CLEAN_INVALID_PAIRS
  541. //printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size());
  542. }
  543. }
  544. template <typename BP_FP_INT_TYPE>
  545. bool btAxisSweep3Internal<BP_FP_INT_TYPE>::testAabbOverlap(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
  546. {
  547. const Handle* pHandleA = static_cast<Handle*>(proxy0);
  548. const Handle* pHandleB = static_cast<Handle*>(proxy1);
  549. //optimization 1: check the array index (memory address), instead of the m_pos
  550. for (int axis = 0; axis < 3; axis++)
  551. {
  552. if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] ||
  553. pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis])
  554. {
  555. return false;
  556. }
  557. }
  558. return true;
  559. }
  560. template <typename BP_FP_INT_TYPE>
  561. bool btAxisSweep3Internal<BP_FP_INT_TYPE>::testOverlap2D(const Handle* pHandleA, const Handle* pHandleB, int axis0, int axis1)
  562. {
  563. //optimization 1: check the array index (memory address), instead of the m_pos
  564. if (pHandleA->m_maxEdges[axis0] < pHandleB->m_minEdges[axis0] ||
  565. pHandleB->m_maxEdges[axis0] < pHandleA->m_minEdges[axis0] ||
  566. pHandleA->m_maxEdges[axis1] < pHandleB->m_minEdges[axis1] ||
  567. pHandleB->m_maxEdges[axis1] < pHandleA->m_minEdges[axis1])
  568. {
  569. return false;
  570. }
  571. return true;
  572. }
  573. template <typename BP_FP_INT_TYPE>
  574. void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin, const btVector3& aabbMax, btDispatcher* dispatcher)
  575. {
  576. // btAssert(bounds.IsFinite());
  577. //btAssert(bounds.HasVolume());
  578. Handle* pHandle = getHandle(handle);
  579. // quantize the new bounds
  580. BP_FP_INT_TYPE min[3], max[3];
  581. quantize(min, aabbMin, 0);
  582. quantize(max, aabbMax, 1);
  583. // update changed edges
  584. for (int axis = 0; axis < 3; axis++)
  585. {
  586. BP_FP_INT_TYPE emin = pHandle->m_minEdges[axis];
  587. BP_FP_INT_TYPE emax = pHandle->m_maxEdges[axis];
  588. int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos;
  589. int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos;
  590. m_pEdges[axis][emin].m_pos = min[axis];
  591. m_pEdges[axis][emax].m_pos = max[axis];
  592. // expand (only adds overlaps)
  593. if (dmin < 0)
  594. sortMinDown(axis, emin, dispatcher, true);
  595. if (dmax > 0)
  596. sortMaxUp(axis, emax, dispatcher, true);
  597. // shrink (only removes overlaps)
  598. if (dmin > 0)
  599. sortMinUp(axis, emin, dispatcher, true);
  600. if (dmax < 0)
  601. sortMaxDown(axis, emax, dispatcher, true);
  602. #ifdef DEBUG_BROADPHASE
  603. debugPrintAxis(axis);
  604. #endif //DEBUG_BROADPHASE
  605. }
  606. }
  607. // sorting a min edge downwards can only ever *add* overlaps
  608. template <typename BP_FP_INT_TYPE>
  609. void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* /* dispatcher */, bool updateOverlaps)
  610. {
  611. Edge* pEdge = m_pEdges[axis] + edge;
  612. Edge* pPrev = pEdge - 1;
  613. Handle* pHandleEdge = getHandle(pEdge->m_handle);
  614. while (pEdge->m_pos < pPrev->m_pos)
  615. {
  616. Handle* pHandlePrev = getHandle(pPrev->m_handle);
  617. if (pPrev->IsMax())
  618. {
  619. // if previous edge is a maximum check the bounds and add an overlap if necessary
  620. const int axis1 = (1 << axis) & 3;
  621. const int axis2 = (1 << axis1) & 3;
  622. if (updateOverlaps && testOverlap2D(pHandleEdge, pHandlePrev, axis1, axis2))
  623. {
  624. m_pairCache->addOverlappingPair(pHandleEdge, pHandlePrev);
  625. if (m_userPairCallback)
  626. m_userPairCallback->addOverlappingPair(pHandleEdge, pHandlePrev);
  627. //AddOverlap(pEdge->m_handle, pPrev->m_handle);
  628. }
  629. // update edge reference in other handle
  630. pHandlePrev->m_maxEdges[axis]++;
  631. }
  632. else
  633. pHandlePrev->m_minEdges[axis]++;
  634. pHandleEdge->m_minEdges[axis]--;
  635. // swap the edges
  636. Edge swap = *pEdge;
  637. *pEdge = *pPrev;
  638. *pPrev = swap;
  639. // decrement
  640. pEdge--;
  641. pPrev--;
  642. }
  643. #ifdef DEBUG_BROADPHASE
  644. debugPrintAxis(axis);
  645. #endif //DEBUG_BROADPHASE
  646. }
  647. // sorting a min edge upwards can only ever *remove* overlaps
  648. template <typename BP_FP_INT_TYPE>
  649. void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps)
  650. {
  651. Edge* pEdge = m_pEdges[axis] + edge;
  652. Edge* pNext = pEdge + 1;
  653. Handle* pHandleEdge = getHandle(pEdge->m_handle);
  654. while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
  655. {
  656. Handle* pHandleNext = getHandle(pNext->m_handle);
  657. if (pNext->IsMax())
  658. {
  659. Handle* handle0 = getHandle(pEdge->m_handle);
  660. Handle* handle1 = getHandle(pNext->m_handle);
  661. const int axis1 = (1 << axis) & 3;
  662. const int axis2 = (1 << axis1) & 3;
  663. // if next edge is maximum remove any overlap between the two handles
  664. if (updateOverlaps
  665. #ifdef USE_OVERLAP_TEST_ON_REMOVES
  666. && testOverlap2D(handle0, handle1, axis1, axis2)
  667. #endif //USE_OVERLAP_TEST_ON_REMOVES
  668. )
  669. {
  670. m_pairCache->removeOverlappingPair(handle0, handle1, dispatcher);
  671. if (m_userPairCallback)
  672. m_userPairCallback->removeOverlappingPair(handle0, handle1, dispatcher);
  673. }
  674. // update edge reference in other handle
  675. pHandleNext->m_maxEdges[axis]--;
  676. }
  677. else
  678. pHandleNext->m_minEdges[axis]--;
  679. pHandleEdge->m_minEdges[axis]++;
  680. // swap the edges
  681. Edge swap = *pEdge;
  682. *pEdge = *pNext;
  683. *pNext = swap;
  684. // increment
  685. pEdge++;
  686. pNext++;
  687. }
  688. }
  689. // sorting a max edge downwards can only ever *remove* overlaps
  690. template <typename BP_FP_INT_TYPE>
  691. void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps)
  692. {
  693. Edge* pEdge = m_pEdges[axis] + edge;
  694. Edge* pPrev = pEdge - 1;
  695. Handle* pHandleEdge = getHandle(pEdge->m_handle);
  696. while (pEdge->m_pos < pPrev->m_pos)
  697. {
  698. Handle* pHandlePrev = getHandle(pPrev->m_handle);
  699. if (!pPrev->IsMax())
  700. {
  701. // if previous edge was a minimum remove any overlap between the two handles
  702. Handle* handle0 = getHandle(pEdge->m_handle);
  703. Handle* handle1 = getHandle(pPrev->m_handle);
  704. const int axis1 = (1 << axis) & 3;
  705. const int axis2 = (1 << axis1) & 3;
  706. if (updateOverlaps
  707. #ifdef USE_OVERLAP_TEST_ON_REMOVES
  708. && testOverlap2D(handle0, handle1, axis1, axis2)
  709. #endif //USE_OVERLAP_TEST_ON_REMOVES
  710. )
  711. {
  712. //this is done during the overlappingpairarray iteration/narrowphase collision
  713. m_pairCache->removeOverlappingPair(handle0, handle1, dispatcher);
  714. if (m_userPairCallback)
  715. m_userPairCallback->removeOverlappingPair(handle0, handle1, dispatcher);
  716. }
  717. // update edge reference in other handle
  718. pHandlePrev->m_minEdges[axis]++;
  719. ;
  720. }
  721. else
  722. pHandlePrev->m_maxEdges[axis]++;
  723. pHandleEdge->m_maxEdges[axis]--;
  724. // swap the edges
  725. Edge swap = *pEdge;
  726. *pEdge = *pPrev;
  727. *pPrev = swap;
  728. // decrement
  729. pEdge--;
  730. pPrev--;
  731. }
  732. #ifdef DEBUG_BROADPHASE
  733. debugPrintAxis(axis);
  734. #endif //DEBUG_BROADPHASE
  735. }
  736. // sorting a max edge upwards can only ever *add* overlaps
  737. template <typename BP_FP_INT_TYPE>
  738. void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* /* dispatcher */, bool updateOverlaps)
  739. {
  740. Edge* pEdge = m_pEdges[axis] + edge;
  741. Edge* pNext = pEdge + 1;
  742. Handle* pHandleEdge = getHandle(pEdge->m_handle);
  743. while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
  744. {
  745. Handle* pHandleNext = getHandle(pNext->m_handle);
  746. const int axis1 = (1 << axis) & 3;
  747. const int axis2 = (1 << axis1) & 3;
  748. if (!pNext->IsMax())
  749. {
  750. // if next edge is a minimum check the bounds and add an overlap if necessary
  751. if (updateOverlaps && testOverlap2D(pHandleEdge, pHandleNext, axis1, axis2))
  752. {
  753. Handle* handle0 = getHandle(pEdge->m_handle);
  754. Handle* handle1 = getHandle(pNext->m_handle);
  755. m_pairCache->addOverlappingPair(handle0, handle1);
  756. if (m_userPairCallback)
  757. m_userPairCallback->addOverlappingPair(handle0, handle1);
  758. }
  759. // update edge reference in other handle
  760. pHandleNext->m_minEdges[axis]--;
  761. }
  762. else
  763. pHandleNext->m_maxEdges[axis]--;
  764. pHandleEdge->m_maxEdges[axis]++;
  765. // swap the edges
  766. Edge swap = *pEdge;
  767. *pEdge = *pNext;
  768. *pNext = swap;
  769. // increment
  770. pEdge++;
  771. pNext++;
  772. }
  773. }
  774. #endif