Blender V2.61 - r43446
|
00001 //Bullet Continuous Collision Detection and Physics Library 00002 //Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ 00003 00004 // 00005 // btAxisSweep3.h 00006 // 00007 // Copyright (c) 2006 Simon Hobbs 00008 // 00009 // 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. 00010 // 00011 // 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: 00012 // 00013 // 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. 00014 // 00015 // 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 00016 // 00017 // 3. This notice may not be removed or altered from any source distribution. 00018 00019 #ifndef AXIS_SWEEP_3_H 00020 #define AXIS_SWEEP_3_H 00021 00022 #include "LinearMath/btVector3.h" 00023 #include "btOverlappingPairCache.h" 00024 #include "btBroadphaseInterface.h" 00025 #include "btBroadphaseProxy.h" 00026 #include "btOverlappingPairCallback.h" 00027 #include "btDbvtBroadphase.h" 00028 00029 //#define DEBUG_BROADPHASE 1 00030 #define USE_OVERLAP_TEST_ON_REMOVES 1 00031 00035 template <typename BP_FP_INT_TYPE> 00036 class btAxisSweep3Internal : public btBroadphaseInterface 00037 { 00038 protected: 00039 00040 BP_FP_INT_TYPE m_bpHandleMask; 00041 BP_FP_INT_TYPE m_handleSentinel; 00042 00043 public: 00044 00045 BT_DECLARE_ALIGNED_ALLOCATOR(); 00046 00047 class Edge 00048 { 00049 public: 00050 BP_FP_INT_TYPE m_pos; // low bit is min/max 00051 BP_FP_INT_TYPE m_handle; 00052 00053 BP_FP_INT_TYPE IsMax() const {return static_cast<BP_FP_INT_TYPE>(m_pos & 1);} 00054 }; 00055 00056 public: 00057 class Handle : public btBroadphaseProxy 00058 { 00059 public: 00060 BT_DECLARE_ALIGNED_ALLOCATOR(); 00061 00062 // indexes into the edge arrays 00063 BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12 00064 // BP_FP_INT_TYPE m_uniqueId; 00065 btBroadphaseProxy* m_dbvtProxy;//for faster raycast 00066 //void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject 00067 00068 SIMD_FORCE_INLINE void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;} 00069 SIMD_FORCE_INLINE BP_FP_INT_TYPE GetNextFree() const {return m_minEdges[0];} 00070 }; // 24 bytes + 24 for Edge structures = 44 bytes total per entry 00071 00072 00073 protected: 00074 btVector3 m_worldAabbMin; // overall system bounds 00075 btVector3 m_worldAabbMax; // overall system bounds 00076 00077 btVector3 m_quantize; // scaling factor for quantization 00078 00079 BP_FP_INT_TYPE m_numHandles; // number of active handles 00080 BP_FP_INT_TYPE m_maxHandles; // max number of handles 00081 Handle* m_pHandles; // handles pool 00082 00083 BP_FP_INT_TYPE m_firstFreeHandle; // free handles list 00084 00085 Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries) 00086 void* m_pEdgesRawPtr[3]; 00087 00088 btOverlappingPairCache* m_pairCache; 00089 00091 btOverlappingPairCallback* m_userPairCallback; 00092 00093 bool m_ownsPairCache; 00094 00095 int m_invalidPair; 00096 00099 btDbvtBroadphase* m_raycastAccelerator; 00100 btOverlappingPairCache* m_nullPairCache; 00101 00102 00103 // allocation/deallocation 00104 BP_FP_INT_TYPE allocHandle(); 00105 void freeHandle(BP_FP_INT_TYPE handle); 00106 00107 00108 bool testOverlap2D(const Handle* pHandleA, const Handle* pHandleB,int axis0,int axis1); 00109 00110 #ifdef DEBUG_BROADPHASE 00111 void debugPrintAxis(int axis,bool checkCardinality=true); 00112 #endif //DEBUG_BROADPHASE 00113 00114 //Overlap* AddOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB); 00115 //void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB); 00116 00117 00118 00119 void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); 00120 void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); 00121 void sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); 00122 void sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); 00123 00124 public: 00125 00126 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); 00127 00128 virtual ~btAxisSweep3Internal(); 00129 00130 BP_FP_INT_TYPE getNumHandles() const 00131 { 00132 return m_numHandles; 00133 } 00134 00135 virtual void calculateOverlappingPairs(btDispatcher* dispatcher); 00136 00137 BP_FP_INT_TYPE addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy); 00138 void removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher); 00139 void updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); 00140 SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;} 00141 00142 virtual void resetPool(btDispatcher* dispatcher); 00143 00144 void processAllOverlappingPairs(btOverlapCallback* callback); 00145 00146 //Broadphase Interface 00147 virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy); 00148 virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); 00149 virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); 00150 virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; 00151 00152 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)); 00153 virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback); 00154 00155 00156 void quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const; 00158 void unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; 00159 00160 bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); 00161 00162 btOverlappingPairCache* getOverlappingPairCache() 00163 { 00164 return m_pairCache; 00165 } 00166 const btOverlappingPairCache* getOverlappingPairCache() const 00167 { 00168 return m_pairCache; 00169 } 00170 00171 void setOverlappingPairUserCallback(btOverlappingPairCallback* pairCallback) 00172 { 00173 m_userPairCallback = pairCallback; 00174 } 00175 const btOverlappingPairCallback* getOverlappingPairUserCallback() const 00176 { 00177 return m_userPairCallback; 00178 } 00179 00182 virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const 00183 { 00184 aabbMin = m_worldAabbMin; 00185 aabbMax = m_worldAabbMax; 00186 } 00187 00188 virtual void printStats() 00189 { 00190 /* printf("btAxisSweep3.h\n"); 00191 printf("numHandles = %d, maxHandles = %d\n",m_numHandles,m_maxHandles); 00192 printf("aabbMin=%f,%f,%f,aabbMax=%f,%f,%f\n",m_worldAabbMin.getX(),m_worldAabbMin.getY(),m_worldAabbMin.getZ(), 00193 m_worldAabbMax.getX(),m_worldAabbMax.getY(),m_worldAabbMax.getZ()); 00194 */ 00195 00196 } 00197 00198 }; 00199 00201 00202 00203 00204 00205 #ifdef DEBUG_BROADPHASE 00206 #include <stdio.h> 00207 00208 template <typename BP_FP_INT_TYPE> 00209 void btAxisSweep3<BP_FP_INT_TYPE>::debugPrintAxis(int axis, bool checkCardinality) 00210 { 00211 int numEdges = m_pHandles[0].m_maxEdges[axis]; 00212 printf("SAP Axis %d, numEdges=%d\n",axis,numEdges); 00213 00214 int i; 00215 for (i=0;i<numEdges+1;i++) 00216 { 00217 Edge* pEdge = m_pEdges[axis] + i; 00218 Handle* pHandlePrev = getHandle(pEdge->m_handle); 00219 int handleIndex = pEdge->IsMax()? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis]; 00220 char beginOrEnd; 00221 beginOrEnd=pEdge->IsMax()?'E':'B'; 00222 printf(" [%c,h=%d,p=%x,i=%d]\n",beginOrEnd,pEdge->m_handle,pEdge->m_pos,handleIndex); 00223 } 00224 00225 if (checkCardinality) 00226 btAssert(numEdges == m_numHandles*2+1); 00227 } 00228 #endif //DEBUG_BROADPHASE 00229 00230 template <typename BP_FP_INT_TYPE> 00231 btBroadphaseProxy* btAxisSweep3Internal<BP_FP_INT_TYPE>::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy) 00232 { 00233 (void)shapeType; 00234 BP_FP_INT_TYPE handleId = addHandle(aabbMin,aabbMax, userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,multiSapProxy); 00235 00236 Handle* handle = getHandle(handleId); 00237 00238 if (m_raycastAccelerator) 00239 { 00240 btBroadphaseProxy* rayProxy = m_raycastAccelerator->createProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,0); 00241 handle->m_dbvtProxy = rayProxy; 00242 } 00243 return handle; 00244 } 00245 00246 00247 00248 template <typename BP_FP_INT_TYPE> 00249 void btAxisSweep3Internal<BP_FP_INT_TYPE>::destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher) 00250 { 00251 Handle* handle = static_cast<Handle*>(proxy); 00252 if (m_raycastAccelerator) 00253 m_raycastAccelerator->destroyProxy(handle->m_dbvtProxy,dispatcher); 00254 removeHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), dispatcher); 00255 } 00256 00257 template <typename BP_FP_INT_TYPE> 00258 void btAxisSweep3Internal<BP_FP_INT_TYPE>::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher) 00259 { 00260 Handle* handle = static_cast<Handle*>(proxy); 00261 handle->m_aabbMin = aabbMin; 00262 handle->m_aabbMax = aabbMax; 00263 updateHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), aabbMin, aabbMax,dispatcher); 00264 if (m_raycastAccelerator) 00265 m_raycastAccelerator->setAabb(handle->m_dbvtProxy,aabbMin,aabbMax,dispatcher); 00266 00267 } 00268 00269 template <typename BP_FP_INT_TYPE> 00270 void btAxisSweep3Internal<BP_FP_INT_TYPE>::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax) 00271 { 00272 if (m_raycastAccelerator) 00273 { 00274 m_raycastAccelerator->rayTest(rayFrom,rayTo,rayCallback,aabbMin,aabbMax); 00275 } else 00276 { 00277 //choose axis? 00278 BP_FP_INT_TYPE axis = 0; 00279 //for each proxy 00280 for (BP_FP_INT_TYPE i=1;i<m_numHandles*2+1;i++) 00281 { 00282 if (m_pEdges[axis][i].IsMax()) 00283 { 00284 rayCallback.process(getHandle(m_pEdges[axis][i].m_handle)); 00285 } 00286 } 00287 } 00288 } 00289 00290 template <typename BP_FP_INT_TYPE> 00291 void btAxisSweep3Internal<BP_FP_INT_TYPE>::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) 00292 { 00293 if (m_raycastAccelerator) 00294 { 00295 m_raycastAccelerator->aabbTest(aabbMin,aabbMax,callback); 00296 } else 00297 { 00298 //choose axis? 00299 BP_FP_INT_TYPE axis = 0; 00300 //for each proxy 00301 for (BP_FP_INT_TYPE i=1;i<m_numHandles*2+1;i++) 00302 { 00303 if (m_pEdges[axis][i].IsMax()) 00304 { 00305 Handle* handle = getHandle(m_pEdges[axis][i].m_handle); 00306 if (TestAabbAgainstAabb2(aabbMin,aabbMax,handle->m_aabbMin,handle->m_aabbMax)) 00307 { 00308 callback.process(handle); 00309 } 00310 } 00311 } 00312 } 00313 } 00314 00315 00316 00317 template <typename BP_FP_INT_TYPE> 00318 void btAxisSweep3Internal<BP_FP_INT_TYPE>::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const 00319 { 00320 Handle* pHandle = static_cast<Handle*>(proxy); 00321 aabbMin = pHandle->m_aabbMin; 00322 aabbMax = pHandle->m_aabbMax; 00323 } 00324 00325 00326 template <typename BP_FP_INT_TYPE> 00327 void btAxisSweep3Internal<BP_FP_INT_TYPE>::unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const 00328 { 00329 Handle* pHandle = static_cast<Handle*>(proxy); 00330 00331 unsigned short vecInMin[3]; 00332 unsigned short vecInMax[3]; 00333 00334 vecInMin[0] = m_pEdges[0][pHandle->m_minEdges[0]].m_pos ; 00335 vecInMax[0] = m_pEdges[0][pHandle->m_maxEdges[0]].m_pos +1 ; 00336 vecInMin[1] = m_pEdges[1][pHandle->m_minEdges[1]].m_pos ; 00337 vecInMax[1] = m_pEdges[1][pHandle->m_maxEdges[1]].m_pos +1 ; 00338 vecInMin[2] = m_pEdges[2][pHandle->m_minEdges[2]].m_pos ; 00339 vecInMax[2] = m_pEdges[2][pHandle->m_maxEdges[2]].m_pos +1 ; 00340 00341 aabbMin.setValue((btScalar)(vecInMin[0]) / (m_quantize.getX()),(btScalar)(vecInMin[1]) / (m_quantize.getY()),(btScalar)(vecInMin[2]) / (m_quantize.getZ())); 00342 aabbMin += m_worldAabbMin; 00343 00344 aabbMax.setValue((btScalar)(vecInMax[0]) / (m_quantize.getX()),(btScalar)(vecInMax[1]) / (m_quantize.getY()),(btScalar)(vecInMax[2]) / (m_quantize.getZ())); 00345 aabbMax += m_worldAabbMin; 00346 } 00347 00348 00349 00350 00351 template <typename BP_FP_INT_TYPE> 00352 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) 00353 :m_bpHandleMask(handleMask), 00354 m_handleSentinel(handleSentinel), 00355 m_pairCache(pairCache), 00356 m_userPairCallback(0), 00357 m_ownsPairCache(false), 00358 m_invalidPair(0), 00359 m_raycastAccelerator(0) 00360 { 00361 BP_FP_INT_TYPE maxHandles = static_cast<BP_FP_INT_TYPE>(userMaxHandles+1);//need to add one sentinel handle 00362 00363 if (!m_pairCache) 00364 { 00365 void* ptr = btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16); 00366 m_pairCache = new(ptr) btHashedOverlappingPairCache(); 00367 m_ownsPairCache = true; 00368 } 00369 00370 if (!disableRaycastAccelerator) 00371 { 00372 m_nullPairCache = new (btAlignedAlloc(sizeof(btNullPairCache),16)) btNullPairCache(); 00373 m_raycastAccelerator = new (btAlignedAlloc(sizeof(btDbvtBroadphase),16)) btDbvtBroadphase(m_nullPairCache);//m_pairCache); 00374 m_raycastAccelerator->m_deferedcollide = true;//don't add/remove pairs 00375 } 00376 00377 //btAssert(bounds.HasVolume()); 00378 00379 // init bounds 00380 m_worldAabbMin = worldAabbMin; 00381 m_worldAabbMax = worldAabbMax; 00382 00383 btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin; 00384 00385 BP_FP_INT_TYPE maxInt = m_handleSentinel; 00386 00387 m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize; 00388 00389 // allocate handles buffer, using btAlignedAlloc, and put all handles on free list 00390 m_pHandles = new Handle[maxHandles]; 00391 00392 m_maxHandles = maxHandles; 00393 m_numHandles = 0; 00394 00395 // handle 0 is reserved as the null index, and is also used as the sentinel 00396 m_firstFreeHandle = 1; 00397 { 00398 for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < maxHandles; i++) 00399 m_pHandles[i].SetNextFree(static_cast<BP_FP_INT_TYPE>(i + 1)); 00400 m_pHandles[maxHandles - 1].SetNextFree(0); 00401 } 00402 00403 { 00404 // allocate edge buffers 00405 for (int i = 0; i < 3; i++) 00406 { 00407 m_pEdgesRawPtr[i] = btAlignedAlloc(sizeof(Edge)*maxHandles*2,16); 00408 m_pEdges[i] = new(m_pEdgesRawPtr[i]) Edge[maxHandles * 2]; 00409 } 00410 } 00411 //removed overlap management 00412 00413 // make boundary sentinels 00414 00415 m_pHandles[0].m_clientObject = 0; 00416 00417 for (int axis = 0; axis < 3; axis++) 00418 { 00419 m_pHandles[0].m_minEdges[axis] = 0; 00420 m_pHandles[0].m_maxEdges[axis] = 1; 00421 00422 m_pEdges[axis][0].m_pos = 0; 00423 m_pEdges[axis][0].m_handle = 0; 00424 m_pEdges[axis][1].m_pos = m_handleSentinel; 00425 m_pEdges[axis][1].m_handle = 0; 00426 #ifdef DEBUG_BROADPHASE 00427 debugPrintAxis(axis); 00428 #endif //DEBUG_BROADPHASE 00429 00430 } 00431 00432 } 00433 00434 template <typename BP_FP_INT_TYPE> 00435 btAxisSweep3Internal<BP_FP_INT_TYPE>::~btAxisSweep3Internal() 00436 { 00437 if (m_raycastAccelerator) 00438 { 00439 m_nullPairCache->~btOverlappingPairCache(); 00440 btAlignedFree(m_nullPairCache); 00441 m_raycastAccelerator->~btDbvtBroadphase(); 00442 btAlignedFree (m_raycastAccelerator); 00443 } 00444 00445 for (int i = 2; i >= 0; i--) 00446 { 00447 btAlignedFree(m_pEdgesRawPtr[i]); 00448 } 00449 delete [] m_pHandles; 00450 00451 if (m_ownsPairCache) 00452 { 00453 m_pairCache->~btOverlappingPairCache(); 00454 btAlignedFree(m_pairCache); 00455 } 00456 } 00457 00458 template <typename BP_FP_INT_TYPE> 00459 void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const 00460 { 00461 #ifdef OLD_CLAMPING_METHOD 00462 00463 00464 btVector3 clampedPoint(point); 00465 clampedPoint.setMax(m_worldAabbMin); 00466 clampedPoint.setMin(m_worldAabbMax); 00467 btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize; 00468 out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & m_bpHandleMask) | isMax); 00469 out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & m_bpHandleMask) | isMax); 00470 out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & m_bpHandleMask) | isMax); 00471 #else 00472 btVector3 v = (point - m_worldAabbMin) * m_quantize; 00473 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); 00474 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); 00475 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); 00476 #endif //OLD_CLAMPING_METHOD 00477 } 00478 00479 00480 template <typename BP_FP_INT_TYPE> 00481 BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::allocHandle() 00482 { 00483 btAssert(m_firstFreeHandle); 00484 00485 BP_FP_INT_TYPE handle = m_firstFreeHandle; 00486 m_firstFreeHandle = getHandle(handle)->GetNextFree(); 00487 m_numHandles++; 00488 00489 return handle; 00490 } 00491 00492 template <typename BP_FP_INT_TYPE> 00493 void btAxisSweep3Internal<BP_FP_INT_TYPE>::freeHandle(BP_FP_INT_TYPE handle) 00494 { 00495 btAssert(handle > 0 && handle < m_maxHandles); 00496 00497 getHandle(handle)->SetNextFree(m_firstFreeHandle); 00498 m_firstFreeHandle = handle; 00499 00500 m_numHandles--; 00501 } 00502 00503 00504 template <typename BP_FP_INT_TYPE> 00505 BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy) 00506 { 00507 // quantize the bounds 00508 BP_FP_INT_TYPE min[3], max[3]; 00509 quantize(min, aabbMin, 0); 00510 quantize(max, aabbMax, 1); 00511 00512 // allocate a handle 00513 BP_FP_INT_TYPE handle = allocHandle(); 00514 00515 00516 Handle* pHandle = getHandle(handle); 00517 00518 pHandle->m_uniqueId = static_cast<int>(handle); 00519 //pHandle->m_pOverlaps = 0; 00520 pHandle->m_clientObject = pOwner; 00521 pHandle->m_collisionFilterGroup = collisionFilterGroup; 00522 pHandle->m_collisionFilterMask = collisionFilterMask; 00523 pHandle->m_multiSapParentProxy = multiSapProxy; 00524 00525 // compute current limit of edge arrays 00526 BP_FP_INT_TYPE limit = static_cast<BP_FP_INT_TYPE>(m_numHandles * 2); 00527 00528 00529 // insert new edges just inside the max boundary edge 00530 for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++) 00531 { 00532 00533 m_pHandles[0].m_maxEdges[axis] += 2; 00534 00535 m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1]; 00536 00537 m_pEdges[axis][limit - 1].m_pos = min[axis]; 00538 m_pEdges[axis][limit - 1].m_handle = handle; 00539 00540 m_pEdges[axis][limit].m_pos = max[axis]; 00541 m_pEdges[axis][limit].m_handle = handle; 00542 00543 pHandle->m_minEdges[axis] = static_cast<BP_FP_INT_TYPE>(limit - 1); 00544 pHandle->m_maxEdges[axis] = limit; 00545 } 00546 00547 // now sort the new edges to their correct position 00548 sortMinDown(0, pHandle->m_minEdges[0], dispatcher,false); 00549 sortMaxDown(0, pHandle->m_maxEdges[0], dispatcher,false); 00550 sortMinDown(1, pHandle->m_minEdges[1], dispatcher,false); 00551 sortMaxDown(1, pHandle->m_maxEdges[1], dispatcher,false); 00552 sortMinDown(2, pHandle->m_minEdges[2], dispatcher,true); 00553 sortMaxDown(2, pHandle->m_maxEdges[2], dispatcher,true); 00554 00555 00556 return handle; 00557 } 00558 00559 00560 template <typename BP_FP_INT_TYPE> 00561 void btAxisSweep3Internal<BP_FP_INT_TYPE>::removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher) 00562 { 00563 00564 Handle* pHandle = getHandle(handle); 00565 00566 //explicitly remove the pairs containing the proxy 00567 //we could do it also in the sortMinUp (passing true) 00569 if (!m_pairCache->hasDeferredRemoval()) 00570 { 00571 m_pairCache->removeOverlappingPairsContainingProxy(pHandle,dispatcher); 00572 } 00573 00574 // compute current limit of edge arrays 00575 int limit = static_cast<int>(m_numHandles * 2); 00576 00577 int axis; 00578 00579 for (axis = 0;axis<3;axis++) 00580 { 00581 m_pHandles[0].m_maxEdges[axis] -= 2; 00582 } 00583 00584 // remove the edges by sorting them up to the end of the list 00585 for ( axis = 0; axis < 3; axis++) 00586 { 00587 Edge* pEdges = m_pEdges[axis]; 00588 BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis]; 00589 pEdges[max].m_pos = m_handleSentinel; 00590 00591 sortMaxUp(axis,max,dispatcher,false); 00592 00593 00594 BP_FP_INT_TYPE i = pHandle->m_minEdges[axis]; 00595 pEdges[i].m_pos = m_handleSentinel; 00596 00597 00598 sortMinUp(axis,i,dispatcher,false); 00599 00600 pEdges[limit-1].m_handle = 0; 00601 pEdges[limit-1].m_pos = m_handleSentinel; 00602 00603 #ifdef DEBUG_BROADPHASE 00604 debugPrintAxis(axis,false); 00605 #endif //DEBUG_BROADPHASE 00606 00607 00608 } 00609 00610 00611 // free the handle 00612 freeHandle(handle); 00613 00614 00615 } 00616 00617 template <typename BP_FP_INT_TYPE> 00618 void btAxisSweep3Internal<BP_FP_INT_TYPE>::resetPool(btDispatcher* dispatcher) 00619 { 00620 if (m_numHandles == 0) 00621 { 00622 m_firstFreeHandle = 1; 00623 { 00624 for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < m_maxHandles; i++) 00625 m_pHandles[i].SetNextFree(static_cast<BP_FP_INT_TYPE>(i + 1)); 00626 m_pHandles[m_maxHandles - 1].SetNextFree(0); 00627 } 00628 } 00629 } 00630 00631 00632 extern int gOverlappingPairs; 00633 //#include <stdio.h> 00634 00635 template <typename BP_FP_INT_TYPE> 00636 void btAxisSweep3Internal<BP_FP_INT_TYPE>::calculateOverlappingPairs(btDispatcher* dispatcher) 00637 { 00638 00639 if (m_pairCache->hasDeferredRemoval()) 00640 { 00641 00642 btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray(); 00643 00644 //perform a sort, to find duplicates and to sort 'invalid' pairs to the end 00645 overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); 00646 00647 overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); 00648 m_invalidPair = 0; 00649 00650 00651 int i; 00652 00653 btBroadphasePair previousPair; 00654 previousPair.m_pProxy0 = 0; 00655 previousPair.m_pProxy1 = 0; 00656 previousPair.m_algorithm = 0; 00657 00658 00659 for (i=0;i<overlappingPairArray.size();i++) 00660 { 00661 00662 btBroadphasePair& pair = overlappingPairArray[i]; 00663 00664 bool isDuplicate = (pair == previousPair); 00665 00666 previousPair = pair; 00667 00668 bool needsRemoval = false; 00669 00670 if (!isDuplicate) 00671 { 00673 bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1); 00674 00675 if (hasOverlap) 00676 { 00677 needsRemoval = false;//callback->processOverlap(pair); 00678 } else 00679 { 00680 needsRemoval = true; 00681 } 00682 } else 00683 { 00684 //remove duplicate 00685 needsRemoval = true; 00686 //should have no algorithm 00687 btAssert(!pair.m_algorithm); 00688 } 00689 00690 if (needsRemoval) 00691 { 00692 m_pairCache->cleanOverlappingPair(pair,dispatcher); 00693 00694 // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); 00695 // m_overlappingPairArray.pop_back(); 00696 pair.m_pProxy0 = 0; 00697 pair.m_pProxy1 = 0; 00698 m_invalidPair++; 00699 gOverlappingPairs--; 00700 } 00701 00702 } 00703 00705 #define CLEAN_INVALID_PAIRS 1 00706 #ifdef CLEAN_INVALID_PAIRS 00707 00708 //perform a sort, to sort 'invalid' pairs to the end 00709 overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); 00710 00711 overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); 00712 m_invalidPair = 0; 00713 #endif//CLEAN_INVALID_PAIRS 00714 00715 //printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size()); 00716 } 00717 00718 } 00719 00720 00721 template <typename BP_FP_INT_TYPE> 00722 bool btAxisSweep3Internal<BP_FP_INT_TYPE>::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) 00723 { 00724 const Handle* pHandleA = static_cast<Handle*>(proxy0); 00725 const Handle* pHandleB = static_cast<Handle*>(proxy1); 00726 00727 //optimization 1: check the array index (memory address), instead of the m_pos 00728 00729 for (int axis = 0; axis < 3; axis++) 00730 { 00731 if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || 00732 pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) 00733 { 00734 return false; 00735 } 00736 } 00737 return true; 00738 } 00739 00740 template <typename BP_FP_INT_TYPE> 00741 bool btAxisSweep3Internal<BP_FP_INT_TYPE>::testOverlap2D(const Handle* pHandleA, const Handle* pHandleB,int axis0,int axis1) 00742 { 00743 //optimization 1: check the array index (memory address), instead of the m_pos 00744 00745 if (pHandleA->m_maxEdges[axis0] < pHandleB->m_minEdges[axis0] || 00746 pHandleB->m_maxEdges[axis0] < pHandleA->m_minEdges[axis0] || 00747 pHandleA->m_maxEdges[axis1] < pHandleB->m_minEdges[axis1] || 00748 pHandleB->m_maxEdges[axis1] < pHandleA->m_minEdges[axis1]) 00749 { 00750 return false; 00751 } 00752 return true; 00753 } 00754 00755 template <typename BP_FP_INT_TYPE> 00756 void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher) 00757 { 00758 // btAssert(bounds.IsFinite()); 00759 //btAssert(bounds.HasVolume()); 00760 00761 Handle* pHandle = getHandle(handle); 00762 00763 // quantize the new bounds 00764 BP_FP_INT_TYPE min[3], max[3]; 00765 quantize(min, aabbMin, 0); 00766 quantize(max, aabbMax, 1); 00767 00768 // update changed edges 00769 for (int axis = 0; axis < 3; axis++) 00770 { 00771 BP_FP_INT_TYPE emin = pHandle->m_minEdges[axis]; 00772 BP_FP_INT_TYPE emax = pHandle->m_maxEdges[axis]; 00773 00774 int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos; 00775 int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos; 00776 00777 m_pEdges[axis][emin].m_pos = min[axis]; 00778 m_pEdges[axis][emax].m_pos = max[axis]; 00779 00780 // expand (only adds overlaps) 00781 if (dmin < 0) 00782 sortMinDown(axis, emin,dispatcher,true); 00783 00784 if (dmax > 0) 00785 sortMaxUp(axis, emax,dispatcher,true); 00786 00787 // shrink (only removes overlaps) 00788 if (dmin > 0) 00789 sortMinUp(axis, emin,dispatcher,true); 00790 00791 if (dmax < 0) 00792 sortMaxDown(axis, emax,dispatcher,true); 00793 00794 #ifdef DEBUG_BROADPHASE 00795 debugPrintAxis(axis); 00796 #endif //DEBUG_BROADPHASE 00797 } 00798 00799 00800 } 00801 00802 00803 00804 00805 // sorting a min edge downwards can only ever *add* overlaps 00806 template <typename BP_FP_INT_TYPE> 00807 void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* /* dispatcher */, bool updateOverlaps) 00808 { 00809 00810 Edge* pEdge = m_pEdges[axis] + edge; 00811 Edge* pPrev = pEdge - 1; 00812 Handle* pHandleEdge = getHandle(pEdge->m_handle); 00813 00814 while (pEdge->m_pos < pPrev->m_pos) 00815 { 00816 Handle* pHandlePrev = getHandle(pPrev->m_handle); 00817 00818 if (pPrev->IsMax()) 00819 { 00820 // if previous edge is a maximum check the bounds and add an overlap if necessary 00821 const int axis1 = (1 << axis) & 3; 00822 const int axis2 = (1 << axis1) & 3; 00823 if (updateOverlaps && testOverlap2D(pHandleEdge, pHandlePrev,axis1,axis2)) 00824 { 00825 m_pairCache->addOverlappingPair(pHandleEdge,pHandlePrev); 00826 if (m_userPairCallback) 00827 m_userPairCallback->addOverlappingPair(pHandleEdge,pHandlePrev); 00828 00829 //AddOverlap(pEdge->m_handle, pPrev->m_handle); 00830 00831 } 00832 00833 // update edge reference in other handle 00834 pHandlePrev->m_maxEdges[axis]++; 00835 } 00836 else 00837 pHandlePrev->m_minEdges[axis]++; 00838 00839 pHandleEdge->m_minEdges[axis]--; 00840 00841 // swap the edges 00842 Edge swap = *pEdge; 00843 *pEdge = *pPrev; 00844 *pPrev = swap; 00845 00846 // decrement 00847 pEdge--; 00848 pPrev--; 00849 } 00850 00851 #ifdef DEBUG_BROADPHASE 00852 debugPrintAxis(axis); 00853 #endif //DEBUG_BROADPHASE 00854 00855 } 00856 00857 // sorting a min edge upwards can only ever *remove* overlaps 00858 template <typename BP_FP_INT_TYPE> 00859 void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps) 00860 { 00861 Edge* pEdge = m_pEdges[axis] + edge; 00862 Edge* pNext = pEdge + 1; 00863 Handle* pHandleEdge = getHandle(pEdge->m_handle); 00864 00865 while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos)) 00866 { 00867 Handle* pHandleNext = getHandle(pNext->m_handle); 00868 00869 if (pNext->IsMax()) 00870 { 00871 Handle* handle0 = getHandle(pEdge->m_handle); 00872 Handle* handle1 = getHandle(pNext->m_handle); 00873 const int axis1 = (1 << axis) & 3; 00874 const int axis2 = (1 << axis1) & 3; 00875 00876 // if next edge is maximum remove any overlap between the two handles 00877 if (updateOverlaps 00878 #ifdef USE_OVERLAP_TEST_ON_REMOVES 00879 && testOverlap2D(handle0,handle1,axis1,axis2) 00880 #endif //USE_OVERLAP_TEST_ON_REMOVES 00881 ) 00882 { 00883 00884 00885 m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher); 00886 if (m_userPairCallback) 00887 m_userPairCallback->removeOverlappingPair(handle0,handle1,dispatcher); 00888 00889 } 00890 00891 00892 // update edge reference in other handle 00893 pHandleNext->m_maxEdges[axis]--; 00894 } 00895 else 00896 pHandleNext->m_minEdges[axis]--; 00897 00898 pHandleEdge->m_minEdges[axis]++; 00899 00900 // swap the edges 00901 Edge swap = *pEdge; 00902 *pEdge = *pNext; 00903 *pNext = swap; 00904 00905 // increment 00906 pEdge++; 00907 pNext++; 00908 } 00909 00910 00911 } 00912 00913 // sorting a max edge downwards can only ever *remove* overlaps 00914 template <typename BP_FP_INT_TYPE> 00915 void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps) 00916 { 00917 00918 Edge* pEdge = m_pEdges[axis] + edge; 00919 Edge* pPrev = pEdge - 1; 00920 Handle* pHandleEdge = getHandle(pEdge->m_handle); 00921 00922 while (pEdge->m_pos < pPrev->m_pos) 00923 { 00924 Handle* pHandlePrev = getHandle(pPrev->m_handle); 00925 00926 if (!pPrev->IsMax()) 00927 { 00928 // if previous edge was a minimum remove any overlap between the two handles 00929 Handle* handle0 = getHandle(pEdge->m_handle); 00930 Handle* handle1 = getHandle(pPrev->m_handle); 00931 const int axis1 = (1 << axis) & 3; 00932 const int axis2 = (1 << axis1) & 3; 00933 00934 if (updateOverlaps 00935 #ifdef USE_OVERLAP_TEST_ON_REMOVES 00936 && testOverlap2D(handle0,handle1,axis1,axis2) 00937 #endif //USE_OVERLAP_TEST_ON_REMOVES 00938 ) 00939 { 00940 //this is done during the overlappingpairarray iteration/narrowphase collision 00941 00942 00943 m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher); 00944 if (m_userPairCallback) 00945 m_userPairCallback->removeOverlappingPair(handle0,handle1,dispatcher); 00946 00947 00948 00949 } 00950 00951 // update edge reference in other handle 00952 pHandlePrev->m_minEdges[axis]++;; 00953 } 00954 else 00955 pHandlePrev->m_maxEdges[axis]++; 00956 00957 pHandleEdge->m_maxEdges[axis]--; 00958 00959 // swap the edges 00960 Edge swap = *pEdge; 00961 *pEdge = *pPrev; 00962 *pPrev = swap; 00963 00964 // decrement 00965 pEdge--; 00966 pPrev--; 00967 } 00968 00969 00970 #ifdef DEBUG_BROADPHASE 00971 debugPrintAxis(axis); 00972 #endif //DEBUG_BROADPHASE 00973 00974 } 00975 00976 // sorting a max edge upwards can only ever *add* overlaps 00977 template <typename BP_FP_INT_TYPE> 00978 void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* /* dispatcher */, bool updateOverlaps) 00979 { 00980 Edge* pEdge = m_pEdges[axis] + edge; 00981 Edge* pNext = pEdge + 1; 00982 Handle* pHandleEdge = getHandle(pEdge->m_handle); 00983 00984 while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos)) 00985 { 00986 Handle* pHandleNext = getHandle(pNext->m_handle); 00987 00988 const int axis1 = (1 << axis) & 3; 00989 const int axis2 = (1 << axis1) & 3; 00990 00991 if (!pNext->IsMax()) 00992 { 00993 // if next edge is a minimum check the bounds and add an overlap if necessary 00994 if (updateOverlaps && testOverlap2D(pHandleEdge, pHandleNext,axis1,axis2)) 00995 { 00996 Handle* handle0 = getHandle(pEdge->m_handle); 00997 Handle* handle1 = getHandle(pNext->m_handle); 00998 m_pairCache->addOverlappingPair(handle0,handle1); 00999 if (m_userPairCallback) 01000 m_userPairCallback->addOverlappingPair(handle0,handle1); 01001 } 01002 01003 // update edge reference in other handle 01004 pHandleNext->m_minEdges[axis]--; 01005 } 01006 else 01007 pHandleNext->m_maxEdges[axis]--; 01008 01009 pHandleEdge->m_maxEdges[axis]++; 01010 01011 // swap the edges 01012 Edge swap = *pEdge; 01013 *pEdge = *pNext; 01014 *pNext = swap; 01015 01016 // increment 01017 pEdge++; 01018 pNext++; 01019 } 01020 01021 } 01022 01023 01024 01026 01027 01031 class btAxisSweep3 : public btAxisSweep3Internal<unsigned short int> 01032 { 01033 public: 01034 01035 btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false); 01036 01037 }; 01038 01042 class bt32BitAxisSweep3 : public btAxisSweep3Internal<unsigned int> 01043 { 01044 public: 01045 01046 bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false); 01047 01048 }; 01049 01050 #endif 01051