- Timestamp:
- Oct 20, 2008, 5:40:38 PM (16 years ago)
- Location:
- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp
r1963 r1972 22 22 #include <assert.h> 23 23 24 btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache , bool disableRaycastAccelerator)25 :btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache ,disableRaycastAccelerator)24 btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache) 25 :btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache) 26 26 { 27 27 // 1 handle is reserved as sentinel … … 31 31 32 32 33 bt32BitAxisSweep3::bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache , bool disableRaycastAccelerator)34 :btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache ,disableRaycastAccelerator)33 bt32BitAxisSweep3::bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache ) 34 :btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache) 35 35 { 36 36 // 1 handle is reserved as sentinel -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.h
r1963 r1972 26 26 #include "btBroadphaseProxy.h" 27 27 #include "btOverlappingPairCallback.h" 28 #include "btDbvtBroadphase.h"29 28 30 29 //#define DEBUG_BROADPHASE 1 … … 63 62 BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12 64 63 // BP_FP_INT_TYPE m_uniqueId; 65 btBroadphaseProxy* m_dbvtProxy;//for faster raycast 64 BP_FP_INT_TYPE m_pad; 65 66 66 //void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject 67 67 … … 95 95 int m_invalidPair; 96 96 97 ///additional dynamic aabb structure, used to accelerate ray cast queries.98 ///can be disabled using a optional argument in the constructor99 btDbvtBroadphase* m_raycastAccelerator;100 101 102 97 // allocation/deallocation 103 98 BP_FP_INT_TYPE allocHandle(); … … 114 109 //void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB); 115 110 116 111 void quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const; 117 112 118 113 void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); … … 123 118 public: 124 119 125 btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0 ,bool disableRaycastAccelerator = false);120 btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0); 126 121 127 122 virtual ~btAxisSweep3Internal(); … … 145 140 virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); 146 141 virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); 147 virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;148 149 virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback);150 151 void quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const;152 ///unQuantize should be conservative: aabbMin/aabbMax should be larger then 'getAabb' result153 void unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;154 142 155 143 bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); … … 230 218 231 219 Handle* handle = getHandle(handleId); 232 233 if (m_raycastAccelerator) 234 { 235 btBroadphaseProxy* rayProxy = m_raycastAccelerator->createProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,0); 236 handle->m_dbvtProxy = rayProxy; 237 } 220 238 221 return handle; 239 222 } … … 245 228 { 246 229 Handle* handle = static_cast<Handle*>(proxy); 247 if (m_raycastAccelerator)248 m_raycastAccelerator->destroyProxy(handle->m_dbvtProxy,dispatcher);249 230 removeHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), dispatcher); 250 231 } … … 254 235 { 255 236 Handle* handle = static_cast<Handle*>(proxy); 256 handle->m_aabbMin = aabbMin;257 handle->m_aabbMax = aabbMax;258 237 updateHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), aabbMin, aabbMax,dispatcher); 259 if (m_raycastAccelerator) 260 m_raycastAccelerator->setAabb(handle->m_dbvtProxy,aabbMin,aabbMax,dispatcher); 261 262 } 263 264 template <typename BP_FP_INT_TYPE> 265 266 void btAxisSweep3Internal<BP_FP_INT_TYPE>::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback) 267 { 268 if (m_raycastAccelerator) 269 { 270 m_raycastAccelerator->rayTest(rayFrom,rayTo,rayCallback); 271 } else 272 { 273 //choose axis? 274 BP_FP_INT_TYPE axis = 0; 275 //for each proxy 276 for (BP_FP_INT_TYPE i=1;i<m_numHandles*2+1;i++) 277 { 278 if (m_pEdges[axis][i].IsMax()) 279 { 280 rayCallback.process(getHandle(m_pEdges[axis][i].m_handle)); 281 } 282 } 283 } 284 } 285 286 287 template <typename BP_FP_INT_TYPE> 288 void btAxisSweep3Internal<BP_FP_INT_TYPE>::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const 289 { 290 Handle* pHandle = static_cast<Handle*>(proxy); 291 aabbMin = pHandle->m_aabbMin; 292 aabbMax = pHandle->m_aabbMax; 293 } 294 295 296 template <typename BP_FP_INT_TYPE> 297 void btAxisSweep3Internal<BP_FP_INT_TYPE>::unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const 298 { 299 Handle* pHandle = static_cast<Handle*>(proxy); 300 301 unsigned short vecInMin[3]; 302 unsigned short vecInMax[3]; 303 304 vecInMin[0] = m_pEdges[0][pHandle->m_minEdges[0]].m_pos ; 305 vecInMax[0] = m_pEdges[0][pHandle->m_maxEdges[0]].m_pos +1 ; 306 vecInMin[1] = m_pEdges[1][pHandle->m_minEdges[1]].m_pos ; 307 vecInMax[1] = m_pEdges[1][pHandle->m_maxEdges[1]].m_pos +1 ; 308 vecInMin[2] = m_pEdges[2][pHandle->m_minEdges[2]].m_pos ; 309 vecInMax[2] = m_pEdges[2][pHandle->m_maxEdges[2]].m_pos +1 ; 310 311 aabbMin.setValue((btScalar)(vecInMin[0]) / (m_quantize.getX()),(btScalar)(vecInMin[1]) / (m_quantize.getY()),(btScalar)(vecInMin[2]) / (m_quantize.getZ())); 312 aabbMin += m_worldAabbMin; 313 314 aabbMax.setValue((btScalar)(vecInMax[0]) / (m_quantize.getX()),(btScalar)(vecInMax[1]) / (m_quantize.getY()),(btScalar)(vecInMax[2]) / (m_quantize.getZ())); 315 aabbMax += m_worldAabbMin; 316 } 317 318 319 320 321 template <typename BP_FP_INT_TYPE> 322 btAxisSweep3Internal<BP_FP_INT_TYPE>::btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache , bool disableRaycastAccelerator) 238 239 } 240 241 242 243 244 245 template <typename BP_FP_INT_TYPE> 246 btAxisSweep3Internal<BP_FP_INT_TYPE>::btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache ) 323 247 :m_bpHandleMask(handleMask), 324 248 m_handleSentinel(handleSentinel), … … 326 250 m_userPairCallback(0), 327 251 m_ownsPairCache(false), 328 m_invalidPair(0), 329 m_raycastAccelerator(0) 252 m_invalidPair(0) 330 253 { 331 254 BP_FP_INT_TYPE maxHandles = static_cast<BP_FP_INT_TYPE>(userMaxHandles+1);//need to add one sentinel handle … … 336 259 m_pairCache = new(ptr) btHashedOverlappingPairCache(); 337 260 m_ownsPairCache = true; 338 }339 340 if (!disableRaycastAccelerator)341 {342 m_raycastAccelerator = new (btAlignedAlloc(sizeof(btDbvtBroadphase),16)) btDbvtBroadphase();//m_pairCache);343 m_raycastAccelerator->m_deferedcollide = true;//don't add/remove pairs344 261 } 345 262 … … 404 321 btAxisSweep3Internal<BP_FP_INT_TYPE>::~btAxisSweep3Internal() 405 322 { 406 if (m_raycastAccelerator) 407 btAlignedFree (m_raycastAccelerator); 408 323 409 324 for (int i = 2; i >= 0; i--) 410 325 { … … 985 900 public: 986 901 987 btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0 , bool disableRaycastAccelerator = false);902 btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0); 988 903 989 904 }; … … 996 911 public: 997 912 998 bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0 , bool disableRaycastAccelerator = false);913 bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0); 999 914 1000 915 }; -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
r1963 r1972 24 24 class btOverlappingPairCache; 25 25 26 struct btBroadphaseRayCallback27 {28 virtual ~btBroadphaseRayCallback() {}29 virtual bool process(const btBroadphaseProxy* proxy) = 0;30 };31 32 26 #include "LinearMath/btVector3.h" 33 27 … … 43 37 virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)=0; 44 38 virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)=0; 45 virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const =0; 46 47 virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback) = 0; 48 39 49 40 ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb 50 41 virtual void calculateOverlappingPairs(btDispatcher* dispatcher)=0; -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
r1963 r1972 18 18 19 19 #include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE 20 #include "LinearMath/btVector3.h"21 20 #include "LinearMath/btAlignedAllocator.h" 22 21 … … 92 91 }; 93 92 94 btVector3 m_aabbMin;95 btVector3 m_aabbMax;96 97 93 //Usually the client btCollisionObject or Rigidbody class 98 94 void* m_clientObject; … … 116 112 } 117 113 118 btBroadphaseProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0) 119 :m_aabbMin(aabbMin), 120 m_aabbMax(aabbMax), 121 m_clientObject(userPtr), 114 btBroadphaseProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0) 115 :m_clientObject(userPtr), 122 116 m_collisionFilterGroup(collisionFilterGroup), 123 117 m_collisionFilterMask(collisionFilterMask) -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp
r1963 r1972 24 24 struct btDbvtNodeEnumerator : btDbvt::ICollide 25 25 { 26 27 26 tConstNodeArray nodes; 27 void Process(const btDbvtNode* n) { nodes.push_back(n); } 28 28 }; 29 29 … … 31 31 static DBVT_INLINE int indexof(const btDbvtNode* node) 32 32 { 33 33 return(node->parent->childs[1]==node); 34 34 } 35 35 36 36 // 37 37 static DBVT_INLINE btDbvtVolume merge( const btDbvtVolume& a, 38 38 const btDbvtVolume& b) 39 39 { 40 40 #if DBVT_MERGE_IMPL==DBVT_IMPL_SSE 41 42 41 DBVT_ALIGN char locals[sizeof(btDbvtAabbMm)]; 42 btDbvtVolume& res=*(btDbvtVolume*)locals; 43 43 #else 44 44 btDbvtVolume res; 45 45 #endif 46 47 46 Merge(a,b,res); 47 return(res); 48 48 } 49 49 … … 51 51 static DBVT_INLINE btScalar size(const btDbvtVolume& a) 52 52 { 53 54 53 const btVector3 edges=a.Lengths(); 54 return( edges.x()*edges.y()*edges.z()+ 55 55 edges.x()+edges.y()+edges.z()); 56 56 } … … 59 59 static void getmaxdepth(const btDbvtNode* node,int depth,int& maxdepth) 60 60 { 61 62 { 63 64 61 if(node->isinternal()) 62 { 63 getmaxdepth(node->childs[0],depth+1,maxdepth); 64 getmaxdepth(node->childs[0],depth+1,maxdepth); 65 65 } else maxdepth=btMax(maxdepth,depth); 66 66 } … … 68 68 // 69 69 static DBVT_INLINE void deletenode( btDbvt* pdbvt, 70 71 { 72 73 74 } 75 70 btDbvtNode* node) 71 { 72 btAlignedFree(pdbvt->m_free); 73 pdbvt->m_free=node; 74 } 75 76 76 // 77 77 static void recursedeletenode( btDbvt* pdbvt, 78 79 { 80 81 { 82 83 84 } 85 86 78 btDbvtNode* node) 79 { 80 if(!node->isleaf()) 81 { 82 recursedeletenode(pdbvt,node->childs[0]); 83 recursedeletenode(pdbvt,node->childs[1]); 84 } 85 if(node==pdbvt->m_root) pdbvt->m_root=0; 86 deletenode(pdbvt,node); 87 87 } 88 88 89 89 // 90 90 static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt, 91 92 93 { 94 95 91 btDbvtNode* parent, 92 void* data) 93 { 94 btDbvtNode* node; 95 if(pdbvt->m_free) 96 96 { node=pdbvt->m_free;pdbvt->m_free=0; } 97 97 else 98 98 { node=new(btAlignedAlloc(sizeof(btDbvtNode),16)) btDbvtNode(); } 99 100 101 102 99 node->parent = parent; 100 node->data = data; 101 node->childs[1] = 0; 102 return(node); 103 103 } 104 104 105 105 // 106 106 static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt, 107 108 109 110 { 111 112 113 107 btDbvtNode* parent, 108 const btDbvtVolume& volume, 109 void* data) 110 { 111 btDbvtNode* node=createnode(pdbvt,parent,data); 112 node->volume=volume; 113 return(node); 114 114 } 115 115 116 116 // 117 117 static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt, 118 119 120 121 122 { 123 124 125 118 btDbvtNode* parent, 119 const btDbvtVolume& volume0, 120 const btDbvtVolume& volume1, 121 void* data) 122 { 123 btDbvtNode* node=createnode(pdbvt,parent,data); 124 Merge(volume0,volume1,node->volume); 125 return(node); 126 126 } 127 127 128 128 // 129 129 static void insertleaf( btDbvt* pdbvt, 130 131 132 { 133 134 { 135 136 130 btDbvtNode* root, 131 btDbvtNode* leaf) 132 { 133 if(!pdbvt->m_root) 134 { 135 pdbvt->m_root = leaf; 136 leaf->parent = 0; 137 137 } 138 138 else 139 139 { 140 141 { 142 143 144 root->childs[0]->volume,145 root->childs[1]->volume)];140 if(!root->isleaf()) 141 { 142 do { 143 root=root->childs[Select( leaf->volume, 144 root->childs[0]->volume, 145 root->childs[1]->volume)]; 146 146 } while(!root->isleaf()); 147 147 } 148 149 150 151 { 152 153 154 155 156 157 148 btDbvtNode* prev=root->parent; 149 btDbvtNode* node=createnode(pdbvt,prev,leaf->volume,root->volume,0); 150 if(prev) 151 { 152 prev->childs[indexof(root)] = node; 153 node->childs[0] = root;root->parent=node; 154 node->childs[1] = leaf;leaf->parent=node; 155 do { 156 if(!prev->volume.Contain(node->volume)) 157 Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume); 158 158 else 159 160 159 break; 160 node=prev; 161 161 } while(0!=(prev=node->parent)); 162 162 } 163 163 else 164 164 { 165 166 167 168 } 169 } 170 } 171 165 node->childs[0] = root;root->parent=node; 166 node->childs[1] = leaf;leaf->parent=node; 167 pdbvt->m_root = node; 168 } 169 } 170 } 171 172 172 // 173 173 static btDbvtNode* removeleaf( btDbvt* pdbvt, 174 175 { 176 177 { 178 179 174 btDbvtNode* leaf) 175 { 176 if(leaf==pdbvt->m_root) 177 { 178 pdbvt->m_root=0; 179 return(0); 180 180 } 181 181 else 182 182 { 183 184 185 186 187 { 188 189 190 191 192 { 193 194 195 183 btDbvtNode* parent=leaf->parent; 184 btDbvtNode* prev=parent->parent; 185 btDbvtNode* sibling=parent->childs[1-indexof(leaf)]; 186 if(prev) 187 { 188 prev->childs[indexof(parent)]=sibling; 189 sibling->parent=prev; 190 deletenode(pdbvt,parent); 191 while(prev) 192 { 193 const btDbvtVolume pb=prev->volume; 194 Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume); 195 if(NotEqual(pb,prev->volume)) 196 196 { 197 197 prev=prev->parent; 198 198 } else break; 199 199 } 200 200 return(prev?prev:pdbvt->m_root); 201 201 } 202 202 else 203 203 { 204 205 206 207 204 pdbvt->m_root=sibling; 205 sibling->parent=0; 206 deletenode(pdbvt,parent); 207 return(pdbvt->m_root); 208 208 } 209 209 } … … 216 216 int depth=-1) 217 217 { 218 219 { 220 221 222 218 if(root->isinternal()&&depth) 219 { 220 fetchleaves(pdbvt,root->childs[0],leaves,depth-1); 221 fetchleaves(pdbvt,root->childs[1],leaves,depth-1); 222 deletenode(pdbvt,root); 223 223 } 224 224 else 225 225 { 226 226 leaves.push_back(root); 227 227 } 228 228 } … … 230 230 // 231 231 static void split( const tNodeArray& leaves, 232 233 234 235 236 { 237 238 239 240 { 241 242 232 tNodeArray& left, 233 tNodeArray& right, 234 const btVector3& org, 235 const btVector3& axis) 236 { 237 left.resize(0); 238 right.resize(0); 239 for(int i=0,ni=leaves.size();i<ni;++i) 240 { 241 if(dot(axis,leaves[i]->volume.Center()-org)<0) 242 left.push_back(leaves[i]); 243 243 else 244 244 right.push_back(leaves[i]); 245 245 } 246 246 } … … 250 250 { 251 251 #if DBVT_MERGE_IMPL==DBVT_IMPL_SSE 252 253 254 252 DBVT_ALIGN char locals[sizeof(btDbvtVolume)]; 253 btDbvtVolume& volume=*(btDbvtVolume*)locals; 254 volume=leaves[0]->volume; 255 255 #else 256 256 btDbvtVolume volume=leaves[0]->volume; 257 257 #endif 258 259 { 260 261 } 262 258 for(int i=1,ni=leaves.size();i<ni;++i) 259 { 260 Merge(volume,leaves[i]->volume,volume); 261 } 262 return(volume); 263 263 } 264 264 265 265 // 266 266 static void bottomup( btDbvt* pdbvt, 267 268 { 269 270 { 271 272 273 274 { 275 276 { 277 278 267 tNodeArray& leaves) 268 { 269 while(leaves.size()>1) 270 { 271 btScalar minsize=SIMD_INFINITY; 272 int minidx[2]={-1,-1}; 273 for(int i=0;i<leaves.size();++i) 274 { 275 for(int j=i+1;j<leaves.size();++j) 276 { 277 const btScalar sz=size(merge(leaves[i]->volume,leaves[j]->volume)); 278 if(sz<minsize) 279 279 { 280 281 282 280 minsize = sz; 281 minidx[0] = i; 282 minidx[1] = j; 283 283 } 284 284 } 285 285 } 286 287 288 289 290 291 292 293 294 286 btDbvtNode* n[] = {leaves[minidx[0]],leaves[minidx[1]]}; 287 btDbvtNode* p = createnode(pdbvt,0,n[0]->volume,n[1]->volume,0); 288 p->childs[0] = n[0]; 289 p->childs[1] = n[1]; 290 n[0]->parent = p; 291 n[1]->parent = p; 292 leaves[minidx[0]] = p; 293 leaves.swap(minidx[1],leaves.size()-1); 294 leaves.pop_back(); 295 295 } 296 296 } … … 301 301 int bu_treshold) 302 302 { 303 304 btVector3(0,1,0),305 btVector3(0,0,1)};306 307 { 308 309 { 310 311 312 313 314 315 316 317 318 { 319 320 303 static const btVector3 axis[]={btVector3(1,0,0), 304 btVector3(0,1,0), 305 btVector3(0,0,1)}; 306 if(leaves.size()>1) 307 { 308 if(leaves.size()>bu_treshold) 309 { 310 const btDbvtVolume vol=bounds(leaves); 311 const btVector3 org=vol.Center(); 312 tNodeArray sets[2]; 313 int bestaxis=-1; 314 int bestmidp=leaves.size(); 315 int splitcount[3][2]={{0,0},{0,0},{0,0}}; 316 int i; 317 for( i=0;i<leaves.size();++i) 318 { 319 const btVector3 x=leaves[i]->volume.Center()-org; 320 for(int j=0;j<3;++j) 321 321 { 322 322 ++splitcount[j][dot(x,axis[j])>0?1:0]; 323 323 } 324 324 } 325 326 { 327 325 for( i=0;i<3;++i) 326 { 327 if((splitcount[i][0]>0)&&(splitcount[i][1]>0)) 328 328 { 329 330 329 const int midp=(int)btFabs(btScalar(splitcount[i][0]-splitcount[i][1])); 330 if(midp<bestmidp) 331 331 { 332 333 332 bestaxis=i; 333 bestmidp=midp; 334 334 } 335 335 } 336 336 } 337 338 { 339 340 341 337 if(bestaxis>=0) 338 { 339 sets[0].reserve(splitcount[bestaxis][0]); 340 sets[1].reserve(splitcount[bestaxis][1]); 341 split(leaves,sets[0],sets[1],org,axis[bestaxis]); 342 342 } 343 343 else 344 344 { 345 346 347 345 sets[0].reserve(leaves.size()/2+1); 346 sets[1].reserve(leaves.size()/2); 347 for(int i=0,ni=leaves.size();i<ni;++i) 348 348 { 349 349 sets[i&1].push_back(leaves[i]); 350 350 } 351 351 } 352 353 354 355 356 357 352 btDbvtNode* node=createnode(pdbvt,0,vol,0); 353 node->childs[0]=topdown(pdbvt,sets[0],bu_treshold); 354 node->childs[1]=topdown(pdbvt,sets[1],bu_treshold); 355 node->childs[0]->parent=node; 356 node->childs[1]->parent=node; 357 return(node); 358 358 } 359 359 else 360 360 { 361 362 363 } 364 } 365 361 bottomup(pdbvt,leaves); 362 return(leaves[0]); 363 } 364 } 365 return(leaves[0]); 366 366 } 367 367 … … 369 369 static DBVT_INLINE btDbvtNode* sort(btDbvtNode* n,btDbvtNode*& r) 370 370 { 371 372 373 374 { 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 } 393 371 btDbvtNode* p=n->parent; 372 btAssert(n->isinternal()); 373 if(p>n) 374 { 375 const int i=indexof(n); 376 const int j=1-i; 377 btDbvtNode* s=p->childs[j]; 378 btDbvtNode* q=p->parent; 379 btAssert(n==p->childs[i]); 380 if(q) q->childs[indexof(p)]=n; else r=n; 381 s->parent=n; 382 p->parent=n; 383 n->parent=q; 384 p->childs[0]=n->childs[0]; 385 p->childs[1]=n->childs[1]; 386 n->childs[0]->parent=p; 387 n->childs[1]->parent=p; 388 n->childs[i]=p; 389 n->childs[j]=s; 390 btSwap(p->volume,n->volume); 391 return(p); 392 } 393 return(n); 394 394 } 395 395 … … 397 397 static DBVT_INLINE btDbvtNode* walkup(btDbvtNode* n,int count) 398 398 { 399 400 399 while(n&&(count--)) n=n->parent; 400 return(n); 401 401 } 402 402 … … 406 406 407 407 // 408 btDbvt::btDbvt()409 { 410 411 412 413 414 415 } 416 417 // 418 btDbvt::~btDbvt()419 { 420 408 btDbvt::btDbvt() 409 { 410 m_root = 0; 411 m_free = 0; 412 m_lkhd = -1; 413 m_leaves = 0; 414 m_opath = 0; 415 } 416 417 // 418 btDbvt::~btDbvt() 419 { 420 clear(); 421 421 } 422 422 … … 424 424 void btDbvt::clear() 425 425 { 426 427 428 426 if(m_root) recursedeletenode(this,m_root); 427 btAlignedFree(m_free); 428 m_free=0; 429 429 } 430 430 … … 432 432 void btDbvt::optimizeBottomUp() 433 433 { 434 435 { 436 437 438 439 440 434 if(m_root) 435 { 436 tNodeArray leaves; 437 leaves.reserve(m_leaves); 438 fetchleaves(this,m_root,leaves); 439 bottomup(this,leaves); 440 m_root=leaves[0]; 441 441 } 442 442 } … … 445 445 void btDbvt::optimizeTopDown(int bu_treshold) 446 446 { 447 448 { 449 450 451 452 447 if(m_root) 448 { 449 tNodeArray leaves; 450 leaves.reserve(m_leaves); 451 fetchleaves(this,m_root,leaves); 452 m_root=topdown(this,leaves,bu_treshold); 453 453 } 454 454 } … … 457 457 void btDbvt::optimizeIncremental(int passes) 458 458 { 459 460 461 { 462 463 464 465 466 { 467 468 469 } 470 471 459 if(passes<0) passes=m_leaves; 460 if(m_root&&(passes>0)) 461 { 462 do { 463 btDbvtNode* node=m_root; 464 unsigned bit=0; 465 while(node->isinternal()) 466 { 467 node=sort(node,m_root)->childs[(m_opath>>bit)&1]; 468 bit=(bit+1)&(sizeof(unsigned)*8-1); 469 } 470 update(node); 471 ++m_opath; 472 472 } while(--passes); 473 473 } … … 477 477 btDbvtNode* btDbvt::insert(const btDbvtVolume& volume,void* data) 478 478 { 479 480 481 482 479 btDbvtNode* leaf=createnode(this,0,volume,data); 480 insertleaf(this,m_root,leaf); 481 ++m_leaves; 482 return(leaf); 483 483 } 484 484 … … 486 486 void btDbvt::update(btDbvtNode* leaf,int lookahead) 487 487 { 488 489 490 { 491 492 { 493 494 { 495 488 btDbvtNode* root=removeleaf(this,leaf); 489 if(root) 490 { 491 if(lookahead>=0) 492 { 493 for(int i=0;(i<lookahead)&&root->parent;++i) 494 { 495 root=root->parent; 496 496 } 497 497 } else root=m_root; 498 498 } 499 499 insertleaf(this,root,leaf); 500 500 } 501 501 … … 503 503 void btDbvt::update(btDbvtNode* leaf,const btDbvtVolume& volume) 504 504 { 505 506 507 { 508 509 { 510 511 { 512 505 btDbvtNode* root=removeleaf(this,leaf); 506 if(root) 507 { 508 if(m_lkhd>=0) 509 { 510 for(int i=0;(i<m_lkhd)&&root->parent;++i) 511 { 512 root=root->parent; 513 513 } 514 514 } else root=m_root; 515 515 } 516 517 516 leaf->volume=volume; 517 insertleaf(this,root,leaf); 518 518 } 519 519 … … 521 521 bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity,btScalar margin) 522 522 { 523 524 525 526 527 523 if(leaf->volume.Contain(volume)) return(false); 524 volume.Expand(btVector3(margin,margin,margin)); 525 volume.SignedExpand(velocity); 526 update(leaf,volume); 527 return(true); 528 528 } 529 529 … … 531 531 bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity) 532 532 { 533 534 535 536 533 if(leaf->volume.Contain(volume)) return(false); 534 volume.SignedExpand(velocity); 535 update(leaf,volume); 536 return(true); 537 537 } 538 538 … … 540 540 bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume volume,btScalar margin) 541 541 { 542 543 544 545 542 if(leaf->volume.Contain(volume)) return(false); 543 volume.Expand(btVector3(margin,margin,margin)); 544 update(leaf,volume); 545 return(true); 546 546 } 547 547 … … 549 549 void btDbvt::remove(btDbvtNode* leaf) 550 550 { 551 552 553 551 removeleaf(this,leaf); 552 deletenode(this,leaf); 553 --m_leaves; 554 554 } 555 555 … … 557 557 void btDbvt::write(IWriter* iwriter) const 558 558 { 559 560 561 562 563 564 { 565 566 567 568 569 { 570 571 572 559 btDbvtNodeEnumerator nodes; 560 nodes.nodes.reserve(m_leaves*2); 561 enumNodes(m_root,nodes); 562 iwriter->Prepare(m_root,nodes.nodes.size()); 563 for(int i=0;i<nodes.nodes.size();++i) 564 { 565 const btDbvtNode* n=nodes.nodes[i]; 566 int p=-1; 567 if(n->parent) p=nodes.nodes.findLinearSearch(n->parent); 568 if(n->isinternal()) 569 { 570 const int c0=nodes.nodes.findLinearSearch(n->childs[0]); 571 const int c1=nodes.nodes.findLinearSearch(n->childs[1]); 572 iwriter->WriteNode(n,i,p,c0,c1); 573 573 } 574 574 else 575 575 { 576 576 iwriter->WriteLeaf(n,i,p); 577 577 } 578 578 } … … 582 582 void btDbvt::clone(btDbvt& dest,IClone* iclone) const 583 583 { 584 585 584 dest.clear(); 585 if(m_root!=0) 586 586 { 587 588 589 590 591 592 593 594 595 596 587 btAlignedObjectArray<sStkCLN> stack; 588 stack.reserve(m_leaves); 589 stack.push_back(sStkCLN(m_root,0)); 590 do { 591 const int i=stack.size()-1; 592 const sStkCLN e=stack[i]; 593 btDbvtNode* n=createnode(&dest,e.parent,e.node->volume,e.node->data); 594 stack.pop_back(); 595 if(e.parent!=0) 596 e.parent->childs[i&1]=n; 597 597 else 598 599 600 { 601 602 598 dest.m_root=n; 599 if(e.node->isinternal()) 600 { 601 stack.push_back(sStkCLN(e.node->childs[0],n)); 602 stack.push_back(sStkCLN(e.node->childs[1],n)); 603 603 } 604 604 else 605 605 { 606 606 iclone->CloneLeaf(n); 607 607 } 608 608 } while(stack.size()>0); … … 613 613 int btDbvt::maxdepth(const btDbvtNode* node) 614 614 { 615 616 617 615 int depth=0; 616 if(node) getmaxdepth(node,1,depth); 617 return(depth); 618 618 } 619 619 … … 621 621 int btDbvt::countLeaves(const btDbvtNode* node) 622 622 { 623 624 623 if(node->isinternal()) 624 return(countLeaves(node->childs[0])+countLeaves(node->childs[1])); 625 625 else 626 626 return(1); 627 627 } 628 628 … … 630 630 void btDbvt::extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves) 631 631 { 632 633 { 634 635 632 if(node->isinternal()) 633 { 634 extractLeaves(node->childs[0],leaves); 635 extractLeaves(node->childs[1],leaves); 636 636 } 637 637 else 638 638 { 639 639 leaves.push_back(node); 640 640 } 641 641 } … … 658 658 659 659 Benchmarking dbvt... 660 World scale: 100.000000661 Extents base: 1.000000662 Extents range: 4.000000663 Leaves: 8192664 sizeof(btDbvtVolume): 32 bytes665 sizeof(btDbvtNode): 44 bytes660 World scale: 100.000000 661 Extents base: 1.000000 662 Extents range: 4.000000 663 Leaves: 8192 664 sizeof(btDbvtVolume): 32 bytes 665 sizeof(btDbvtNode): 44 bytes 666 666 [1] btDbvtVolume intersections: 3499 ms (-1%) 667 667 [2] btDbvtVolume merges: 1934 ms (0%) … … 670 670 [5] btDbvt::collideTT xform: 7379 ms (-1%) 671 671 [6] btDbvt::collideTT xform,self: 7270 ms (-2%) 672 [7] btDbvt:: rayTest: 6314 ms (0%),(332143 r/s)672 [7] btDbvt::collideRAY: 6314 ms (0%),(332143 r/s) 673 673 [8] insert/remove: 2093 ms (0%),(1001983 ir/s) 674 674 [9] updates (teleport): 1879 ms (-3%),(1116100 u/s) … … 685 685 struct btDbvtBenchmark 686 686 { 687 688 { 689 690 691 692 693 { 694 695 687 struct NilPolicy : btDbvt::ICollide 688 { 689 NilPolicy() : m_pcount(0),m_depth(-SIMD_INFINITY),m_checksort(true) {} 690 void Process(const btDbvtNode*,const btDbvtNode*) { ++m_pcount; } 691 void Process(const btDbvtNode*) { ++m_pcount; } 692 void Process(const btDbvtNode*,btScalar depth) 693 { 694 ++m_pcount; 695 if(m_checksort) 696 696 { if(depth>=m_depth) m_depth=depth; else printf("wrong depth: %f (should be >= %f)\r\n",depth,m_depth); } 697 697 } 698 699 700 698 int m_pcount; 699 btScalar m_depth; 700 bool m_checksort; 701 701 }; 702 703 { 704 705 { 706 707 702 struct P14 : btDbvt::ICollide 703 { 704 struct Node 705 { 706 const btDbvtNode* leaf; 707 btScalar depth; 708 708 }; 709 710 { 711 712 713 714 } 715 716 { 717 718 719 720 } 721 709 void Process(const btDbvtNode* leaf,btScalar depth) 710 { 711 Node n; 712 n.leaf = leaf; 713 n.depth = depth; 714 } 715 static int sortfnc(const Node& a,const Node& b) 716 { 717 if(a.depth<b.depth) return(+1); 718 if(a.depth>b.depth) return(-1); 719 return(0); 720 } 721 btAlignedObjectArray<Node> m_nodes; 722 722 }; 723 724 { 725 726 { 727 728 723 struct P15 : btDbvt::ICollide 724 { 725 struct Node 726 { 727 const btDbvtNode* leaf; 728 btScalar depth; 729 729 }; 730 731 { 732 733 734 735 } 736 737 { 738 739 740 741 } 742 743 730 void Process(const btDbvtNode* leaf) 731 { 732 Node n; 733 n.leaf = leaf; 734 n.depth = dot(leaf->volume.Center(),m_axis); 735 } 736 static int sortfnc(const Node& a,const Node& b) 737 { 738 if(a.depth<b.depth) return(+1); 739 if(a.depth>b.depth) return(-1); 740 return(0); 741 } 742 btAlignedObjectArray<Node> m_nodes; 743 btVector3 m_axis; 744 744 }; 745 746 { 747 748 } 749 750 { 751 752 } 753 754 { 755 756 } 757 758 { 759 760 } 761 762 { 763 764 765 766 767 } 768 769 { 770 771 772 { 773 745 static btScalar RandUnit() 746 { 747 return(rand()/(btScalar)RAND_MAX); 748 } 749 static btVector3 RandVector3() 750 { 751 return(btVector3(RandUnit(),RandUnit(),RandUnit())); 752 } 753 static btVector3 RandVector3(btScalar cs) 754 { 755 return(RandVector3()*cs-btVector3(cs,cs,cs)/2); 756 } 757 static btDbvtVolume RandVolume(btScalar cs,btScalar eb,btScalar es) 758 { 759 return(btDbvtVolume::FromCE(RandVector3(cs),btVector3(eb,eb,eb)+RandVector3()*es)); 760 } 761 static btTransform RandTransform(btScalar cs) 762 { 763 btTransform t; 764 t.setOrigin(RandVector3(cs)); 765 t.setRotation(btQuaternion(RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2).normalized()); 766 return(t); 767 } 768 static void RandTree(btScalar cs,btScalar eb,btScalar es,int leaves,btDbvt& dbvt) 769 { 770 dbvt.clear(); 771 for(int i=0;i<leaves;++i) 772 { 773 dbvt.insert(RandVolume(cs,eb,es),0); 774 774 } 775 775 } … … 778 778 void btDbvt::benchmark() 779 779 { 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 //[7] btDbvt::rayTest 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 780 static const btScalar cfgVolumeCenterScale = 100; 781 static const btScalar cfgVolumeExentsBase = 1; 782 static const btScalar cfgVolumeExentsScale = 4; 783 static const int cfgLeaves = 8192; 784 static const bool cfgEnable = true; 785 786 //[1] btDbvtVolume intersections 787 bool cfgBenchmark1_Enable = cfgEnable; 788 static const int cfgBenchmark1_Iterations = 8; 789 static const int cfgBenchmark1_Reference = 3499; 790 //[2] btDbvtVolume merges 791 bool cfgBenchmark2_Enable = cfgEnable; 792 static const int cfgBenchmark2_Iterations = 4; 793 static const int cfgBenchmark2_Reference = 1945; 794 //[3] btDbvt::collideTT 795 bool cfgBenchmark3_Enable = cfgEnable; 796 static const int cfgBenchmark3_Iterations = 512; 797 static const int cfgBenchmark3_Reference = 5485; 798 //[4] btDbvt::collideTT self 799 bool cfgBenchmark4_Enable = cfgEnable; 800 static const int cfgBenchmark4_Iterations = 512; 801 static const int cfgBenchmark4_Reference = 2814; 802 //[5] btDbvt::collideTT xform 803 bool cfgBenchmark5_Enable = cfgEnable; 804 static const int cfgBenchmark5_Iterations = 512; 805 static const btScalar cfgBenchmark5_OffsetScale = 2; 806 static const int cfgBenchmark5_Reference = 7379; 807 //[6] btDbvt::collideTT xform,self 808 bool cfgBenchmark6_Enable = cfgEnable; 809 static const int cfgBenchmark6_Iterations = 512; 810 static const btScalar cfgBenchmark6_OffsetScale = 2; 811 static const int cfgBenchmark6_Reference = 7270; 812 //[7] btDbvt::collideRAY 813 bool cfgBenchmark7_Enable = cfgEnable; 814 static const int cfgBenchmark7_Passes = 32; 815 static const int cfgBenchmark7_Iterations = 65536; 816 static const int cfgBenchmark7_Reference = 6307; 817 //[8] insert/remove 818 bool cfgBenchmark8_Enable = cfgEnable; 819 static const int cfgBenchmark8_Passes = 32; 820 static const int cfgBenchmark8_Iterations = 65536; 821 static const int cfgBenchmark8_Reference = 2105; 822 //[9] updates (teleport) 823 bool cfgBenchmark9_Enable = cfgEnable; 824 static const int cfgBenchmark9_Passes = 32; 825 static const int cfgBenchmark9_Iterations = 65536; 826 static const int cfgBenchmark9_Reference = 1879; 827 //[10] updates (jitter) 828 bool cfgBenchmark10_Enable = cfgEnable; 829 static const btScalar cfgBenchmark10_Scale = cfgVolumeCenterScale/10000; 830 static const int cfgBenchmark10_Passes = 32; 831 static const int cfgBenchmark10_Iterations = 65536; 832 static const int cfgBenchmark10_Reference = 1244; 833 //[11] optimize (incremental) 834 bool cfgBenchmark11_Enable = cfgEnable; 835 static const int cfgBenchmark11_Passes = 64; 836 static const int cfgBenchmark11_Iterations = 65536; 837 static const int cfgBenchmark11_Reference = 2510; 838 //[12] btDbvtVolume notequal 839 bool cfgBenchmark12_Enable = cfgEnable; 840 static const int cfgBenchmark12_Iterations = 32; 841 static const int cfgBenchmark12_Reference = 3677; 842 //[13] culling(OCL+fullsort) 843 bool cfgBenchmark13_Enable = cfgEnable; 844 static const int cfgBenchmark13_Iterations = 1024; 845 static const int cfgBenchmark13_Reference = 2231; 846 //[14] culling(OCL+qsort) 847 bool cfgBenchmark14_Enable = cfgEnable; 848 static const int cfgBenchmark14_Iterations = 8192; 849 static const int cfgBenchmark14_Reference = 3500; 850 //[15] culling(KDOP+qsort) 851 bool cfgBenchmark15_Enable = cfgEnable; 852 static const int cfgBenchmark15_Iterations = 8192; 853 static const int cfgBenchmark15_Reference = 1151; 854 //[16] insert/remove batch 855 bool cfgBenchmark16_Enable = cfgEnable; 856 static const int cfgBenchmark16_BatchCount = 256; 857 static const int cfgBenchmark16_Passes = 16384; 858 static const int cfgBenchmark16_Reference = 5138; 859 //[17] select 860 bool cfgBenchmark17_Enable = cfgEnable; 861 static const int cfgBenchmark17_Iterations = 4; 862 static const int cfgBenchmark17_Reference = 3390; 863 864 btClock wallclock; 865 printf("Benchmarking dbvt...\r\n"); 866 printf("\tWorld scale: %f\r\n",cfgVolumeCenterScale); 867 printf("\tExtents base: %f\r\n",cfgVolumeExentsBase); 868 printf("\tExtents range: %f\r\n",cfgVolumeExentsScale); 869 printf("\tLeaves: %u\r\n",cfgLeaves); 870 printf("\tsizeof(btDbvtVolume): %u bytes\r\n",sizeof(btDbvtVolume)); 871 printf("\tsizeof(btDbvtNode): %u bytes\r\n",sizeof(btDbvtNode)); 872 if(cfgBenchmark1_Enable) 873 873 {// Benchmark 1 874 875 876 877 878 879 880 { 881 882 } 883 884 885 886 { 887 888 { 889 874 srand(380843); 875 btAlignedObjectArray<btDbvtVolume> volumes; 876 btAlignedObjectArray<bool> results; 877 volumes.resize(cfgLeaves); 878 results.resize(cfgLeaves); 879 for(int i=0;i<cfgLeaves;++i) 880 { 881 volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale); 882 } 883 printf("[1] btDbvtVolume intersections: "); 884 wallclock.reset(); 885 for(int i=0;i<cfgBenchmark1_Iterations;++i) 886 { 887 for(int j=0;j<cfgLeaves;++j) 888 { 889 for(int k=0;k<cfgLeaves;++k) 890 890 { 891 891 results[k]=Intersect(volumes[j],volumes[k]); 892 892 } 893 893 } 894 894 } 895 896 897 } 898 895 const int time=(int)wallclock.getTimeMilliseconds(); 896 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark1_Reference)*100/time); 897 } 898 if(cfgBenchmark2_Enable) 899 899 {// Benchmark 2 900 901 902 903 904 905 906 { 907 908 } 909 910 911 912 { 913 914 { 915 900 srand(380843); 901 btAlignedObjectArray<btDbvtVolume> volumes; 902 btAlignedObjectArray<btDbvtVolume> results; 903 volumes.resize(cfgLeaves); 904 results.resize(cfgLeaves); 905 for(int i=0;i<cfgLeaves;++i) 906 { 907 volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale); 908 } 909 printf("[2] btDbvtVolume merges: "); 910 wallclock.reset(); 911 for(int i=0;i<cfgBenchmark2_Iterations;++i) 912 { 913 for(int j=0;j<cfgLeaves;++j) 914 { 915 for(int k=0;k<cfgLeaves;++k) 916 916 { 917 917 Merge(volumes[j],volumes[k],results[k]); 918 918 } 919 919 } 920 920 } 921 922 923 } 924 921 const int time=(int)wallclock.getTimeMilliseconds(); 922 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark2_Reference)*100/time); 923 } 924 if(cfgBenchmark3_Enable) 925 925 {// Benchmark 3 926 927 928 929 930 931 932 933 934 935 936 { 937 938 } 939 940 941 } 942 926 srand(380843); 927 btDbvt dbvt[2]; 928 btDbvtBenchmark::NilPolicy policy; 929 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]); 930 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]); 931 dbvt[0].optimizeTopDown(); 932 dbvt[1].optimizeTopDown(); 933 printf("[3] btDbvt::collideTT: "); 934 wallclock.reset(); 935 for(int i=0;i<cfgBenchmark3_Iterations;++i) 936 { 937 btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,policy); 938 } 939 const int time=(int)wallclock.getTimeMilliseconds(); 940 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark3_Reference)*100/time); 941 } 942 if(cfgBenchmark4_Enable) 943 943 {// Benchmark 4 944 945 946 947 948 949 950 951 952 { 953 954 } 955 956 957 } 958 944 srand(380843); 945 btDbvt dbvt; 946 btDbvtBenchmark::NilPolicy policy; 947 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 948 dbvt.optimizeTopDown(); 949 printf("[4] btDbvt::collideTT self: "); 950 wallclock.reset(); 951 for(int i=0;i<cfgBenchmark4_Iterations;++i) 952 { 953 btDbvt::collideTT(dbvt.m_root,dbvt.m_root,policy); 954 } 955 const int time=(int)wallclock.getTimeMilliseconds(); 956 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark4_Reference)*100/time); 957 } 958 if(cfgBenchmark5_Enable) 959 959 {// Benchmark 5 960 961 962 963 964 965 966 { 967 968 } 969 970 971 972 973 974 975 976 { 977 978 } 979 980 981 } 982 960 srand(380843); 961 btDbvt dbvt[2]; 962 btAlignedObjectArray<btTransform> transforms; 963 btDbvtBenchmark::NilPolicy policy; 964 transforms.resize(cfgBenchmark5_Iterations); 965 for(int i=0;i<transforms.size();++i) 966 { 967 transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark5_OffsetScale); 968 } 969 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]); 970 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]); 971 dbvt[0].optimizeTopDown(); 972 dbvt[1].optimizeTopDown(); 973 printf("[5] btDbvt::collideTT xform: "); 974 wallclock.reset(); 975 for(int i=0;i<cfgBenchmark5_Iterations;++i) 976 { 977 btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,transforms[i],policy); 978 } 979 const int time=(int)wallclock.getTimeMilliseconds(); 980 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark5_Reference)*100/time); 981 } 982 if(cfgBenchmark6_Enable) 983 983 {// Benchmark 6 984 985 986 987 988 989 990 { 991 992 } 993 994 995 996 997 998 { 999 1000 } 1001 1002 1003 } 1004 984 srand(380843); 985 btDbvt dbvt; 986 btAlignedObjectArray<btTransform> transforms; 987 btDbvtBenchmark::NilPolicy policy; 988 transforms.resize(cfgBenchmark6_Iterations); 989 for(int i=0;i<transforms.size();++i) 990 { 991 transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark6_OffsetScale); 992 } 993 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 994 dbvt.optimizeTopDown(); 995 printf("[6] btDbvt::collideTT xform,self: "); 996 wallclock.reset(); 997 for(int i=0;i<cfgBenchmark6_Iterations;++i) 998 { 999 btDbvt::collideTT(dbvt.m_root,dbvt.m_root,transforms[i],policy); 1000 } 1001 const int time=(int)wallclock.getTimeMilliseconds(); 1002 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark6_Reference)*100/time); 1003 } 1004 if(cfgBenchmark7_Enable) 1005 1005 {// Benchmark 7 1006 1007 1008 1009 1010 1011 1012 1013 1014 { 1015 1016 1017 } 1018 1019 1020 printf("[7] btDbvt::rayTest: ");1021 1022 1023 { 1024 1025 { 1026 btDbvt::rayTest(dbvt.m_root,rayorg[j],rayorg[j]+raydir[j],policy);1027 } 1028 } 1029 1030 1031 1032 } 1033 1006 srand(380843); 1007 btDbvt dbvt; 1008 btAlignedObjectArray<btVector3> rayorg; 1009 btAlignedObjectArray<btVector3> raydir; 1010 btDbvtBenchmark::NilPolicy policy; 1011 rayorg.resize(cfgBenchmark7_Iterations); 1012 raydir.resize(cfgBenchmark7_Iterations); 1013 for(int i=0;i<rayorg.size();++i) 1014 { 1015 rayorg[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2); 1016 raydir[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2); 1017 } 1018 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 1019 dbvt.optimizeTopDown(); 1020 printf("[7] btDbvt::collideRAY: "); 1021 wallclock.reset(); 1022 for(int i=0;i<cfgBenchmark7_Passes;++i) 1023 { 1024 for(int j=0;j<cfgBenchmark7_Iterations;++j) 1025 { 1026 btDbvt::collideRAY(dbvt.m_root,rayorg[j],raydir[j],policy); 1027 } 1028 } 1029 const int time=(int)wallclock.getTimeMilliseconds(); 1030 unsigned rays=cfgBenchmark7_Passes*cfgBenchmark7_Iterations; 1031 printf("%u ms (%i%%),(%u r/s)\r\n",time,(time-cfgBenchmark7_Reference)*100/time,(rays*1000)/time); 1032 } 1033 if(cfgBenchmark8_Enable) 1034 1034 {// Benchmark 8 1035 1036 1037 1038 1039 1040 1041 1042 { 1043 1044 { 1045 1046 } 1047 } 1048 1049 1050 1051 } 1052 1035 srand(380843); 1036 btDbvt dbvt; 1037 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 1038 dbvt.optimizeTopDown(); 1039 printf("[8] insert/remove: "); 1040 wallclock.reset(); 1041 for(int i=0;i<cfgBenchmark8_Passes;++i) 1042 { 1043 for(int j=0;j<cfgBenchmark8_Iterations;++j) 1044 { 1045 dbvt.remove(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0)); 1046 } 1047 } 1048 const int time=(int)wallclock.getTimeMilliseconds(); 1049 const int ir=cfgBenchmark8_Passes*cfgBenchmark8_Iterations; 1050 printf("%u ms (%i%%),(%u ir/s)\r\n",time,(time-cfgBenchmark8_Reference)*100/time,ir*1000/time); 1051 } 1052 if(cfgBenchmark9_Enable) 1053 1053 {// Benchmark 9 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 { 1064 1065 { 1066 1067 btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale));1068 } 1069 } 1070 1071 1072 1073 } 1074 1054 srand(380843); 1055 btDbvt dbvt; 1056 btAlignedObjectArray<const btDbvtNode*> leaves; 1057 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 1058 dbvt.optimizeTopDown(); 1059 dbvt.extractLeaves(dbvt.m_root,leaves); 1060 printf("[9] updates (teleport): "); 1061 wallclock.reset(); 1062 for(int i=0;i<cfgBenchmark9_Passes;++i) 1063 { 1064 for(int j=0;j<cfgBenchmark9_Iterations;++j) 1065 { 1066 dbvt.update(const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]), 1067 btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale)); 1068 } 1069 } 1070 const int time=(int)wallclock.getTimeMilliseconds(); 1071 const int up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations; 1072 printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time); 1073 } 1074 if(cfgBenchmark10_Enable) 1075 1075 {// Benchmark 10 1076 1077 1078 1079 1080 1081 1082 { 1083 1084 } 1085 1086 1087 1088 1089 1090 1091 1092 { 1093 1076 srand(380843); 1077 btDbvt dbvt; 1078 btAlignedObjectArray<const btDbvtNode*> leaves; 1079 btAlignedObjectArray<btVector3> vectors; 1080 vectors.resize(cfgBenchmark10_Iterations); 1081 for(int i=0;i<vectors.size();++i) 1082 { 1083 vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1))*cfgBenchmark10_Scale; 1084 } 1085 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 1086 dbvt.optimizeTopDown(); 1087 dbvt.extractLeaves(dbvt.m_root,leaves); 1088 printf("[10] updates (jitter): "); 1089 wallclock.reset(); 1090 1091 for(int i=0;i<cfgBenchmark10_Passes;++i) 1092 { 1093 for(int j=0;j<cfgBenchmark10_Iterations;++j) 1094 1094 { 1095 1096 1097 1098 1099 } 1100 } 1101 1102 1103 1104 } 1105 1095 const btVector3& d=vectors[j]; 1096 btDbvtNode* l=const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]); 1097 btDbvtVolume v=btDbvtVolume::FromMM(l->volume.Mins()+d,l->volume.Maxs()+d); 1098 dbvt.update(l,v); 1099 } 1100 } 1101 const int time=(int)wallclock.getTimeMilliseconds(); 1102 const int up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations; 1103 printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time); 1104 } 1105 if(cfgBenchmark11_Enable) 1106 1106 {// Benchmark 11 1107 1108 1109 1110 1111 1112 1113 1114 { 1115 1116 } 1117 1118 1119 1120 } 1121 1107 srand(380843); 1108 btDbvt dbvt; 1109 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 1110 dbvt.optimizeTopDown(); 1111 printf("[11] optimize (incremental): "); 1112 wallclock.reset(); 1113 for(int i=0;i<cfgBenchmark11_Passes;++i) 1114 { 1115 dbvt.optimizeIncremental(cfgBenchmark11_Iterations); 1116 } 1117 const int time=(int)wallclock.getTimeMilliseconds(); 1118 const int op=cfgBenchmark11_Passes*cfgBenchmark11_Iterations; 1119 printf("%u ms (%i%%),(%u o/s)\r\n",time,(time-cfgBenchmark11_Reference)*100/time,op/time*1000); 1120 } 1121 if(cfgBenchmark12_Enable) 1122 1122 {// Benchmark 12 1123 1124 1125 1126 1127 1128 1129 { 1130 1131 } 1132 1133 1134 1135 { 1136 1137 { 1138 1123 srand(380843); 1124 btAlignedObjectArray<btDbvtVolume> volumes; 1125 btAlignedObjectArray<bool> results; 1126 volumes.resize(cfgLeaves); 1127 results.resize(cfgLeaves); 1128 for(int i=0;i<cfgLeaves;++i) 1129 { 1130 volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale); 1131 } 1132 printf("[12] btDbvtVolume notequal: "); 1133 wallclock.reset(); 1134 for(int i=0;i<cfgBenchmark12_Iterations;++i) 1135 { 1136 for(int j=0;j<cfgLeaves;++j) 1137 { 1138 for(int k=0;k<cfgLeaves;++k) 1139 1139 { 1140 1140 results[k]=NotEqual(volumes[j],volumes[k]); 1141 1141 } 1142 1142 } 1143 1143 } 1144 1145 1146 } 1147 1144 const int time=(int)wallclock.getTimeMilliseconds(); 1145 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark12_Reference)*100/time); 1146 } 1147 if(cfgBenchmark13_Enable) 1148 1148 {// Benchmark 13 1149 1150 1151 1152 1153 1154 1155 { 1156 1157 } 1158 1159 1160 1161 1162 1163 { 1164 1165 1166 1167 } 1168 1169 1170 1171 } 1172 1149 srand(380843); 1150 btDbvt dbvt; 1151 btAlignedObjectArray<btVector3> vectors; 1152 btDbvtBenchmark::NilPolicy policy; 1153 vectors.resize(cfgBenchmark13_Iterations); 1154 for(int i=0;i<vectors.size();++i) 1155 { 1156 vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized(); 1157 } 1158 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 1159 dbvt.optimizeTopDown(); 1160 printf("[13] culling(OCL+fullsort): "); 1161 wallclock.reset(); 1162 for(int i=0;i<cfgBenchmark13_Iterations;++i) 1163 { 1164 static const btScalar offset=0; 1165 policy.m_depth=-SIMD_INFINITY; 1166 dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy); 1167 } 1168 const int time=(int)wallclock.getTimeMilliseconds(); 1169 const int t=cfgBenchmark13_Iterations; 1170 printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark13_Reference)*100/time,(t*1000)/time); 1171 } 1172 if(cfgBenchmark14_Enable) 1173 1173 {// Benchmark 14 1174 1175 1176 1177 1178 1179 1180 { 1181 1182 } 1183 1184 1185 1186 1187 1188 1189 { 1190 1191 1192 1193 1194 } 1195 1196 1197 1198 } 1199 1174 srand(380843); 1175 btDbvt dbvt; 1176 btAlignedObjectArray<btVector3> vectors; 1177 btDbvtBenchmark::P14 policy; 1178 vectors.resize(cfgBenchmark14_Iterations); 1179 for(int i=0;i<vectors.size();++i) 1180 { 1181 vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized(); 1182 } 1183 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 1184 dbvt.optimizeTopDown(); 1185 policy.m_nodes.reserve(cfgLeaves); 1186 printf("[14] culling(OCL+qsort): "); 1187 wallclock.reset(); 1188 for(int i=0;i<cfgBenchmark14_Iterations;++i) 1189 { 1190 static const btScalar offset=0; 1191 policy.m_nodes.resize(0); 1192 dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy,false); 1193 policy.m_nodes.quickSort(btDbvtBenchmark::P14::sortfnc); 1194 } 1195 const int time=(int)wallclock.getTimeMilliseconds(); 1196 const int t=cfgBenchmark14_Iterations; 1197 printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark14_Reference)*100/time,(t*1000)/time); 1198 } 1199 if(cfgBenchmark15_Enable) 1200 1200 {// Benchmark 15 1201 1202 1203 1204 1205 1206 1207 { 1208 1209 } 1210 1211 1212 1213 1214 1215 1216 { 1217 1218 1219 1220 1221 1222 } 1223 1224 1225 1226 } 1227 1201 srand(380843); 1202 btDbvt dbvt; 1203 btAlignedObjectArray<btVector3> vectors; 1204 btDbvtBenchmark::P15 policy; 1205 vectors.resize(cfgBenchmark15_Iterations); 1206 for(int i=0;i<vectors.size();++i) 1207 { 1208 vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized(); 1209 } 1210 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 1211 dbvt.optimizeTopDown(); 1212 policy.m_nodes.reserve(cfgLeaves); 1213 printf("[15] culling(KDOP+qsort): "); 1214 wallclock.reset(); 1215 for(int i=0;i<cfgBenchmark15_Iterations;++i) 1216 { 1217 static const btScalar offset=0; 1218 policy.m_nodes.resize(0); 1219 policy.m_axis=vectors[i]; 1220 dbvt.collideKDOP(dbvt.m_root,&vectors[i],&offset,1,policy); 1221 policy.m_nodes.quickSort(btDbvtBenchmark::P15::sortfnc); 1222 } 1223 const int time=(int)wallclock.getTimeMilliseconds(); 1224 const int t=cfgBenchmark15_Iterations; 1225 printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark15_Reference)*100/time,(t*1000)/time); 1226 } 1227 if(cfgBenchmark16_Enable) 1228 1228 {// Benchmark 16 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 { 1239 1240 { 1241 1242 } 1243 1244 { 1245 1246 } 1247 1248 } 1249 1250 1251 1252 } 1253 1229 srand(380843); 1230 btDbvt dbvt; 1231 btAlignedObjectArray<btDbvtNode*> batch; 1232 btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); 1233 dbvt.optimizeTopDown(); 1234 batch.reserve(cfgBenchmark16_BatchCount); 1235 printf("[16] insert/remove batch(%u): ",cfgBenchmark16_BatchCount); 1236 wallclock.reset(); 1237 for(int i=0;i<cfgBenchmark16_Passes;++i) 1238 { 1239 for(int j=0;j<cfgBenchmark16_BatchCount;++j) 1240 { 1241 batch.push_back(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0)); 1242 } 1243 for(int j=0;j<cfgBenchmark16_BatchCount;++j) 1244 { 1245 dbvt.remove(batch[j]); 1246 } 1247 batch.resize(0); 1248 } 1249 const int time=(int)wallclock.getTimeMilliseconds(); 1250 const int ir=cfgBenchmark16_Passes*cfgBenchmark16_BatchCount; 1251 printf("%u ms (%i%%),(%u bir/s)\r\n",time,(time-cfgBenchmark16_Reference)*100/time,int(ir*1000.0/time)); 1252 } 1253 if(cfgBenchmark17_Enable) 1254 1254 {// Benchmark 17 1255 1256 1257 1258 1259 1260 1261 1262 1263 { 1264 1265 1266 } 1267 1268 { 1269 1270 } 1271 1272 1273 1274 { 1275 1276 { 1277 1255 srand(380843); 1256 btAlignedObjectArray<btDbvtVolume> volumes; 1257 btAlignedObjectArray<int> results; 1258 btAlignedObjectArray<int> indices; 1259 volumes.resize(cfgLeaves); 1260 results.resize(cfgLeaves); 1261 indices.resize(cfgLeaves); 1262 for(int i=0;i<cfgLeaves;++i) 1263 { 1264 indices[i]=i; 1265 volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale); 1266 } 1267 for(int i=0;i<cfgLeaves;++i) 1268 { 1269 btSwap(indices[i],indices[rand()%cfgLeaves]); 1270 } 1271 printf("[17] btDbvtVolume select: "); 1272 wallclock.reset(); 1273 for(int i=0;i<cfgBenchmark17_Iterations;++i) 1274 { 1275 for(int j=0;j<cfgLeaves;++j) 1276 { 1277 for(int k=0;k<cfgLeaves;++k) 1278 1278 { 1279 1280 1279 const int idx=indices[k]; 1280 results[idx]=Select(volumes[idx],volumes[j],volumes[k]); 1281 1281 } 1282 1282 } 1283 1283 } 1284 1285 1286 } 1287 1284 const int time=(int)wallclock.getTimeMilliseconds(); 1285 printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark17_Reference)*100/time); 1286 } 1287 printf("\r\n\r\n"); 1288 1288 } 1289 1289 #endif -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvt.h
r1963 r1972 21 21 #include "LinearMath/btVector3.h" 22 22 #include "LinearMath/btTransform.h" 23 #include "LinearMath/btAabbUtil2.h"24 23 25 24 // … … 34 33 // Template implementation of ICollide 35 34 #ifdef WIN32 36 #if (defined (_MSC_VER) && _MSC_VER >= 1400)37 #define DBVT_USE_TEMPLATE 138 #else39 #define DBVT_USE_TEMPLATE 035 #if (defined (_MSC_VER) && _MSC_VER >= 1400) 36 #define DBVT_USE_TEMPLATE 1 37 #else 38 #define DBVT_USE_TEMPLATE 0 40 39 #endif 41 40 #else … … 136 135 struct btDbvtAabbMm 137 136 { 138 DBVT_INLINE btVector3 Center() const { return((mi+mx)/2); } 139 DBVT_INLINE btVector3 Lengths() const { return(mx-mi); } 140 DBVT_INLINE btVector3 Extents() const { return((mx-mi)/2); } 141 DBVT_INLINE const btVector3& Mins() const { return(mi); } 142 DBVT_INLINE const btVector3& Maxs() const { return(mx); } 143 static inline btDbvtAabbMm FromCE(const btVector3& c,const btVector3& e); 144 static inline btDbvtAabbMm FromCR(const btVector3& c,btScalar r); 145 static inline btDbvtAabbMm FromMM(const btVector3& mi,const btVector3& mx); 146 static inline btDbvtAabbMm FromPoints(const btVector3* pts,int n); 147 static inline btDbvtAabbMm FromPoints(const btVector3** ppts,int n); 148 DBVT_INLINE void Expand(const btVector3& e); 149 DBVT_INLINE void SignedExpand(const btVector3& e); 150 DBVT_INLINE bool Contain(const btDbvtAabbMm& a) const; 151 DBVT_INLINE int Classify(const btVector3& n,btScalar o,int s) const; 152 DBVT_INLINE btScalar ProjectMinimum(const btVector3& v,unsigned signs) const; 153 DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, 154 const btDbvtAabbMm& b); 155 DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, 156 const btDbvtAabbMm& b, 157 const btTransform& xform); 158 DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, 159 const btVector3& b); 160 161 DBVT_INLINE friend btScalar Proximity( const btDbvtAabbMm& a, 162 const btDbvtAabbMm& b); 163 DBVT_INLINE friend int Select( const btDbvtAabbMm& o, 164 const btDbvtAabbMm& a, 165 const btDbvtAabbMm& b); 166 DBVT_INLINE friend void Merge( const btDbvtAabbMm& a, 167 const btDbvtAabbMm& b, 168 btDbvtAabbMm& r); 169 DBVT_INLINE friend bool NotEqual( const btDbvtAabbMm& a, 170 const btDbvtAabbMm& b); 137 DBVT_INLINE btVector3 Center() const { return((mi+mx)/2); } 138 DBVT_INLINE btVector3 Lengths() const { return(mx-mi); } 139 DBVT_INLINE btVector3 Extents() const { return((mx-mi)/2); } 140 DBVT_INLINE const btVector3& Mins() const { return(mi); } 141 DBVT_INLINE const btVector3& Maxs() const { return(mx); } 142 static inline btDbvtAabbMm FromCE(const btVector3& c,const btVector3& e); 143 static inline btDbvtAabbMm FromCR(const btVector3& c,btScalar r); 144 static inline btDbvtAabbMm FromMM(const btVector3& mi,const btVector3& mx); 145 static inline btDbvtAabbMm FromPoints(const btVector3* pts,int n); 146 static inline btDbvtAabbMm FromPoints(const btVector3** ppts,int n); 147 DBVT_INLINE void Expand(const btVector3& e); 148 DBVT_INLINE void SignedExpand(const btVector3& e); 149 DBVT_INLINE bool Contain(const btDbvtAabbMm& a) const; 150 DBVT_INLINE int Classify(const btVector3& n,btScalar o,int s) const; 151 DBVT_INLINE btScalar ProjectMinimum(const btVector3& v,unsigned signs) const; 152 DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, 153 const btDbvtAabbMm& b); 154 DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, 155 const btDbvtAabbMm& b, 156 const btTransform& xform); 157 DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, 158 const btVector3& b); 159 DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, 160 const btVector3& org, 161 const btVector3& invdir, 162 const unsigned* signs); 163 DBVT_INLINE friend btScalar Proximity( const btDbvtAabbMm& a, 164 const btDbvtAabbMm& b); 165 DBVT_INLINE friend int Select( const btDbvtAabbMm& o, 166 const btDbvtAabbMm& a, 167 const btDbvtAabbMm& b); 168 DBVT_INLINE friend void Merge( const btDbvtAabbMm& a, 169 const btDbvtAabbMm& b, 170 btDbvtAabbMm& r); 171 DBVT_INLINE friend bool NotEqual( const btDbvtAabbMm& a, 172 const btDbvtAabbMm& b); 171 173 private: 172 174 DBVT_INLINE void AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const; 173 175 private: 174 176 btVector3 mi,mx; 175 177 }; 176 178 … … 186 188 DBVT_INLINE bool isinternal() const { return(!isleaf()); } 187 189 union { 188 btDbvtNode* childs[2];189 void* data;190 int dataAsInt;191 };190 btDbvtNode* childs[2]; 191 void* data; 192 int dataAsInt; 193 }; 192 194 }; 193 195 … … 196 198 ///Unlike the btQuantizedBvh, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure. 197 199 struct btDbvt 198 {200 { 199 201 /* Stack element */ 200 202 struct sStkNN 201 {203 { 202 204 const btDbvtNode* a; 203 205 const btDbvtNode* b; 204 206 sStkNN() {} 205 207 sStkNN(const btDbvtNode* na,const btDbvtNode* nb) : a(na),b(nb) {} 206 };208 }; 207 209 struct sStkNP 208 {210 { 209 211 const btDbvtNode* node; 210 212 int mask; 211 213 sStkNP(const btDbvtNode* n,unsigned m) : node(n),mask(m) {} 212 };214 }; 213 215 struct sStkNPS 214 {216 { 215 217 const btDbvtNode* node; 216 218 int mask; … … 218 220 sStkNPS() {} 219 221 sStkNPS(const btDbvtNode* n,unsigned m,btScalar v) : node(n),mask(m),value(v) {} 220 };222 }; 221 223 struct sStkCLN 222 {224 { 223 225 const btDbvtNode* node; 224 226 btDbvtNode* parent; 225 227 sStkCLN(const btDbvtNode* n,btDbvtNode* p) : node(n),parent(p) {} 226 };228 }; 227 229 // Policies/Interfaces 228 230 229 231 /* ICollide */ 230 232 struct ICollide 231 {233 { 232 234 DBVT_VIRTUAL_DTOR(ICollide) 233 235 DBVT_VIRTUAL void Process(const btDbvtNode*,const btDbvtNode*) {} 234 236 DBVT_VIRTUAL void Process(const btDbvtNode*) {} 235 237 DBVT_VIRTUAL void Process(const btDbvtNode* n,btScalar) { Process(n); } 236 238 DBVT_VIRTUAL bool Descent(const btDbvtNode*) { return(true); } 237 239 DBVT_VIRTUAL bool AllLeaves(const btDbvtNode*) { return(true); } 238 };240 }; 239 241 /* IWriter */ 240 242 struct IWriter 241 {243 { 242 244 virtual ~IWriter() {} 243 245 virtual void Prepare(const btDbvtNode* root,int numnodes)=0; 244 246 virtual void WriteNode(const btDbvtNode*,int index,int parent,int child0,int child1)=0; 245 247 virtual void WriteLeaf(const btDbvtNode*,int index,int parent)=0; 246 };248 }; 247 249 /* IClone */ 248 250 struct IClone 249 {251 { 250 252 virtual ~IClone() {} 251 253 virtual void CloneLeaf(btDbvtNode*) {} 252 };253 254 }; 255 254 256 // Constants 255 257 enum { 256 SIMPLE_STACKSIZE = 64,257 DOUBLE_STACKSIZE = SIMPLE_STACKSIZE*2258 };259 258 SIMPLE_STACKSIZE = 64, 259 DOUBLE_STACKSIZE = SIMPLE_STACKSIZE*2 260 }; 261 260 262 // Fields 261 263 btDbvtNode* m_root; … … 265 267 unsigned m_opath; 266 268 // Methods 267 btDbvt();268 ~btDbvt();269 btDbvt(); 270 ~btDbvt(); 269 271 void clear(); 270 272 bool empty() const { return(0==m_root); } … … 284 286 static int countLeaves(const btDbvtNode* node); 285 287 static void extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves); 286 #if DBVT_ENABLE_BENCHMARK288 #if DBVT_ENABLE_BENCHMARK 287 289 static void benchmark(); 288 #else290 #else 289 291 static void benchmark(){} 290 #endif292 #endif 291 293 // DBVT_IPOLICY must support ICollide policy/interface 292 294 DBVT_PREFIX 293 294 DBVT_IPOLICY);295 static void enumNodes( const btDbvtNode* root, 296 DBVT_IPOLICY); 295 297 DBVT_PREFIX 296 297 DBVT_IPOLICY);298 static void enumLeaves( const btDbvtNode* root, 299 DBVT_IPOLICY); 298 300 DBVT_PREFIX 299 300 const btDbvtNode* root1,301 DBVT_IPOLICY);301 static void collideTT( const btDbvtNode* root0, 302 const btDbvtNode* root1, 303 DBVT_IPOLICY); 302 304 DBVT_PREFIX 303 304 const btDbvtNode* root1,305 const btTransform& xform,306 DBVT_IPOLICY);305 static void collideTT( const btDbvtNode* root0, 306 const btDbvtNode* root1, 307 const btTransform& xform, 308 DBVT_IPOLICY); 307 309 DBVT_PREFIX 308 309 const btTransform& xform0,310 const btDbvtNode* root1,311 const btTransform& xform1,312 DBVT_IPOLICY);310 static void collideTT( const btDbvtNode* root0, 311 const btTransform& xform0, 312 const btDbvtNode* root1, 313 const btTransform& xform1, 314 DBVT_IPOLICY); 313 315 DBVT_PREFIX 314 315 const btDbvtVolume& volume,316 DBVT_IPOLICY);316 static void collideTV( const btDbvtNode* root, 317 const btDbvtVolume& volume, 318 DBVT_IPOLICY); 317 319 DBVT_PREFIX 318 static void rayTest( const btDbvtNode* root,319 const btVector3& rayFrom,320 const btVector3& rayTo,321 DBVT_IPOLICY);320 static void collideRAY( const btDbvtNode* root, 321 const btVector3& origin, 322 const btVector3& direction, 323 DBVT_IPOLICY); 322 324 DBVT_PREFIX 323 324 const btVector3* normals,325 const btScalar* offsets,326 int count,327 DBVT_IPOLICY);325 static void collideKDOP(const btDbvtNode* root, 326 const btVector3* normals, 327 const btScalar* offsets, 328 int count, 329 DBVT_IPOLICY); 328 330 DBVT_PREFIX 329 330 const btVector3* normals,331 const btScalar* offsets,332 const btVector3& sortaxis,333 int count,334 DBVT_IPOLICY,335 bool fullsort=true);331 static void collideOCL( const btDbvtNode* root, 332 const btVector3* normals, 333 const btScalar* offsets, 334 const btVector3& sortaxis, 335 int count, 336 DBVT_IPOLICY, 337 bool fullsort=true); 336 338 DBVT_PREFIX 337 338 DBVT_IPOLICY);339 static void collideTU( const btDbvtNode* root, 340 DBVT_IPOLICY); 339 341 // Helpers 340 342 static DBVT_INLINE int nearest(const int* i,const btDbvt::sStkNPS* a,btScalar v,int l,int h) 341 {343 { 342 344 int m=0; 343 345 while(l<h) 344 {346 { 345 347 m=(l+h)>>1; 346 348 if(a[i[m]].value>=v) l=m+1; else h=m; 349 } 350 return(h); 347 351 } 348 return(h);349 }350 352 static DBVT_INLINE int allocate( btAlignedObjectArray<int>& ifree, 351 btAlignedObjectArray<sStkNPS>& stock,352 const sStkNPS& value)353 {353 btAlignedObjectArray<sStkNPS>& stock, 354 const sStkNPS& value) 355 { 354 356 int i; 355 357 if(ifree.size()>0) 356 { i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; }357 else358 { i=stock.size();stock.push_back(value); }358 { i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; } 359 else 360 { i=stock.size();stock.push_back(value); } 359 361 return(i); 360 }362 } 361 363 // 362 private:363 btDbvt(const btDbvt&) {}364 };364 private: 365 btDbvt(const btDbvt&) {} 366 }; 365 367 366 368 // … … 371 373 inline btDbvtAabbMm btDbvtAabbMm::FromCE(const btVector3& c,const btVector3& e) 372 374 { 373 374 375 376 } 377 375 btDbvtAabbMm box; 376 box.mi=c-e;box.mx=c+e; 377 return(box); 378 } 379 378 380 // 379 381 inline btDbvtAabbMm btDbvtAabbMm::FromCR(const btVector3& c,btScalar r) 380 382 { 381 382 } 383 383 return(FromCE(c,btVector3(r,r,r))); 384 } 385 384 386 // 385 387 inline btDbvtAabbMm btDbvtAabbMm::FromMM(const btVector3& mi,const btVector3& mx) 386 388 { 387 388 389 390 } 391 389 btDbvtAabbMm box; 390 box.mi=mi;box.mx=mx; 391 return(box); 392 } 393 392 394 // 393 395 inline btDbvtAabbMm btDbvtAabbMm::FromPoints(const btVector3* pts,int n) 394 396 { 395 396 397 398 { 399 400 401 } 402 397 btDbvtAabbMm box; 398 box.mi=box.mx=pts[0]; 399 for(int i=1;i<n;++i) 400 { 401 box.mi.setMin(pts[i]); 402 box.mx.setMax(pts[i]); 403 } 404 return(box); 403 405 } 404 406 … … 406 408 inline btDbvtAabbMm btDbvtAabbMm::FromPoints(const btVector3** ppts,int n) 407 409 { 408 409 410 411 { 412 413 414 } 415 410 btDbvtAabbMm box; 411 box.mi=box.mx=*ppts[0]; 412 for(int i=1;i<n;++i) 413 { 414 box.mi.setMin(*ppts[i]); 415 box.mx.setMax(*ppts[i]); 416 } 417 return(box); 416 418 } 417 419 … … 419 421 DBVT_INLINE void btDbvtAabbMm::Expand(const btVector3& e) 420 422 { 421 422 } 423 423 mi-=e;mx+=e; 424 } 425 424 426 // 425 427 DBVT_INLINE void btDbvtAabbMm::SignedExpand(const btVector3& e) 426 428 { 427 428 429 430 } 431 429 if(e.x()>0) mx.setX(mx.x()+e[0]); else mi.setX(mi.x()+e[0]); 430 if(e.y()>0) mx.setY(mx.y()+e[1]); else mi.setY(mi.y()+e[1]); 431 if(e.z()>0) mx.setZ(mx.z()+e[2]); else mi.setZ(mi.z()+e[2]); 432 } 433 432 434 // 433 435 DBVT_INLINE bool btDbvtAabbMm::Contain(const btDbvtAabbMm& a) const 434 436 { 435 437 return( (mi.x()<=a.mi.x())&& 436 438 (mi.y()<=a.mi.y())&& 437 439 (mi.z()<=a.mi.z())&& … … 444 446 DBVT_INLINE int btDbvtAabbMm::Classify(const btVector3& n,btScalar o,int s) const 445 447 { 446 447 448 btVector3 pi,px; 449 switch(s) 448 450 { 449 451 case (0+0+0): px=btVector3(mi.x(),mi.y(),mi.z()); 450 pi=btVector3(mx.x(),mx.y(),mx.z());break;452 pi=btVector3(mx.x(),mx.y(),mx.z());break; 451 453 case (1+0+0): px=btVector3(mx.x(),mi.y(),mi.z()); 452 pi=btVector3(mi.x(),mx.y(),mx.z());break;454 pi=btVector3(mi.x(),mx.y(),mx.z());break; 453 455 case (0+2+0): px=btVector3(mi.x(),mx.y(),mi.z()); 454 pi=btVector3(mx.x(),mi.y(),mx.z());break;456 pi=btVector3(mx.x(),mi.y(),mx.z());break; 455 457 case (1+2+0): px=btVector3(mx.x(),mx.y(),mi.z()); 456 pi=btVector3(mi.x(),mi.y(),mx.z());break;458 pi=btVector3(mi.x(),mi.y(),mx.z());break; 457 459 case (0+0+4): px=btVector3(mi.x(),mi.y(),mx.z()); 458 pi=btVector3(mx.x(),mx.y(),mi.z());break;460 pi=btVector3(mx.x(),mx.y(),mi.z());break; 459 461 case (1+0+4): px=btVector3(mx.x(),mi.y(),mx.z()); 460 pi=btVector3(mi.x(),mx.y(),mi.z());break;462 pi=btVector3(mi.x(),mx.y(),mi.z());break; 461 463 case (0+2+4): px=btVector3(mi.x(),mx.y(),mx.z()); 462 pi=btVector3(mx.x(),mi.y(),mi.z());break;464 pi=btVector3(mx.x(),mi.y(),mi.z());break; 463 465 case (1+2+4): px=btVector3(mx.x(),mx.y(),mx.z()); 464 pi=btVector3(mi.x(),mi.y(),mi.z());break;465 } 466 467 468 466 pi=btVector3(mi.x(),mi.y(),mi.z());break; 467 } 468 if((dot(n,px)+o)<0) return(-1); 469 if((dot(n,pi)+o)>=0) return(+1); 470 return(0); 469 471 } 470 472 … … 472 474 DBVT_INLINE btScalar btDbvtAabbMm::ProjectMinimum(const btVector3& v,unsigned signs) const 473 475 { 474 475 476 b[(signs>>1)&1]->y(),477 b[(signs>>2)&1]->z());478 476 const btVector3* b[]={&mx,&mi}; 477 const btVector3 p( b[(signs>>0)&1]->x(), 478 b[(signs>>1)&1]->y(), 479 b[(signs>>2)&1]->z()); 480 return(dot(p,v)); 479 481 } 480 482 … … 482 484 DBVT_INLINE void btDbvtAabbMm::AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const 483 485 { 484 485 { 486 486 for(int i=0;i<3;++i) 487 { 488 if(d[i]<0) 487 489 { smi+=mx[i]*d[i];smx+=mi[i]*d[i]; } 488 490 else … … 490 492 } 491 493 } 492 494 493 495 // 494 496 DBVT_INLINE bool Intersect( const btDbvtAabbMm& a, 495 497 const btDbvtAabbMm& b) 496 498 { 497 499 #if DBVT_INT0_IMPL == DBVT_IMPL_SSE 498 499 _mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi))));500 501 500 const __m128 rt(_mm_or_ps( _mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)), 501 _mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi)))); 502 const __int32* pu((const __int32*)&rt); 503 return((pu[0]|pu[1]|pu[2])==0); 502 504 #else 503 505 return( (a.mi.x()<=b.mx.x())&& 504 506 (a.mx.x()>=b.mi.x())&& 505 507 (a.mi.y()<=b.mx.y())&& … … 512 514 // 513 515 DBVT_INLINE bool Intersect( const btDbvtAabbMm& a, 514 515 516 { 517 518 519 520 521 522 523 524 525 516 const btDbvtAabbMm& b, 517 const btTransform& xform) 518 { 519 const btVector3 d0=xform*b.Center()-a.Center(); 520 const btVector3 d1=d0*xform.getBasis(); 521 btScalar s0[2]={0,0}; 522 btScalar s1[2]={dot(xform.getOrigin(),d0),s1[0]}; 523 a.AddSpan(d0,s0[0],s0[1]); 524 b.AddSpan(d1,s1[0],s1[1]); 525 if(s0[0]>(s1[1])) return(false); 526 if(s0[1]<(s1[0])) return(false); 527 return(true); 526 528 } 527 529 528 530 // 529 531 DBVT_INLINE bool Intersect( const btDbvtAabbMm& a, 530 531 { 532 532 const btVector3& b) 533 { 534 return( (b.x()>=a.mi.x())&& 533 535 (b.y()>=a.mi.y())&& 534 536 (b.z()>=a.mi.z())&& … … 538 540 } 539 541 540 541 542 543 544 ////////////////////////////////////// 545 546 542 // 543 DBVT_INLINE bool Intersect( const btDbvtAabbMm& a, 544 const btVector3& org, 545 const btVector3& invdir, 546 const unsigned* signs) 547 { 548 #if 0 549 const btVector3 b0((a.mi-org)*invdir); 550 const btVector3 b1((a.mx-org)*invdir); 551 const btVector3 tmin(btMin(b0[0],b1[0]),btMin(b0[1],b1[1]),btMin(b0[2],b1[2])); 552 const btVector3 tmax(btMax(b0[0],b1[0]),btMax(b0[1],b1[1]),btMax(b0[2],b1[2])); 553 const btScalar tin=btMax(tmin[0],btMax(tmin[1],tmin[2])); 554 const btScalar tout=btMin(tmax[0],btMin(tmax[1],tmax[2])); 555 return(tin<tout); 556 #else 557 const btVector3* bounds[2]={&a.mi,&a.mx}; 558 btScalar txmin=(bounds[ signs[0]]->x()-org[0])*invdir[0]; 559 btScalar txmax=(bounds[1-signs[0]]->x()-org[0])*invdir[0]; 560 const btScalar tymin=(bounds[ signs[1]]->y()-org[1])*invdir[1]; 561 const btScalar tymax=(bounds[1-signs[1]]->y()-org[1])*invdir[1]; 562 if((txmin>tymax)||(tymin>txmax)) return(false); 563 if(tymin>txmin) txmin=tymin; 564 if(tymax<txmax) txmax=tymax; 565 const btScalar tzmin=(bounds[ signs[2]]->z()-org[2])*invdir[2]; 566 const btScalar tzmax=(bounds[1-signs[2]]->z()-org[2])*invdir[2]; 567 if((txmin>tzmax)||(tzmin>txmax)) return(false); 568 if(tzmin>txmin) txmin=tzmin; 569 if(tzmax<txmax) txmax=tzmax; 570 return(txmax>0); 571 #endif 572 } 573 547 574 // 548 575 DBVT_INLINE btScalar Proximity( const btDbvtAabbMm& a, 549 550 { 551 552 576 const btDbvtAabbMm& b) 577 { 578 const btVector3 d=(a.mi+a.mx)-(b.mi+b.mx); 579 return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z())); 553 580 } 554 581 555 582 // 556 583 DBVT_INLINE int Select( const btDbvtAabbMm& o, 557 558 584 const btDbvtAabbMm& a, 585 const btDbvtAabbMm& b) 559 586 { 560 587 #if DBVT_SELECT_IMPL == DBVT_IMPL_SSE 561 588 static DBVT_ALIGN const unsigned __int32 mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff}; 562 589 // TODO: the intrinsic version is 11% slower 563 #if DBVT_USE_INTRINSIC_SSE590 #if DBVT_USE_INTRINSIC_SSE 564 591 __m128 omi(_mm_load_ps(o.mi)); 565 592 omi=_mm_add_ps(omi,_mm_load_ps(o.mx)); … … 579 606 bmi=_mm_add_ss(bmi,_mm_shuffle_ps(bmi,bmi,1)); 580 607 return(_mm_cmple_ss(bmi,ami).m128_u32[0]&1); 581 #else608 #else 582 609 DBVT_ALIGN __int32 r[1]; 583 610 __asm 584 {611 { 585 612 mov eax,o 586 587 588 613 mov ecx,a 614 mov edx,b 615 movaps xmm0,[eax] 589 616 movaps xmm5,mask 590 617 addps xmm0,[eax+16] 591 618 movaps xmm1,[ecx] 592 619 movaps xmm2,[edx] … … 594 621 addps xmm2,[edx+16] 595 622 subps xmm1,xmm0 596 597 598 599 600 601 602 603 604 605 606 607 608 609 }623 subps xmm2,xmm0 624 andps xmm1,xmm5 625 andps xmm2,xmm5 626 movhlps xmm3,xmm1 627 movhlps xmm4,xmm2 628 addps xmm1,xmm3 629 addps xmm2,xmm4 630 pshufd xmm3,xmm1,1 631 pshufd xmm4,xmm2,1 632 addss xmm1,xmm3 633 addss xmm2,xmm4 634 cmpless xmm2,xmm1 635 movss r,xmm2 636 } 610 637 return(r[0]&1); 611 #endif638 #endif 612 639 #else 613 640 return(Proximity(o,a)<Proximity(o,b)?0:1); 614 641 #endif 615 642 } … … 617 644 // 618 645 DBVT_INLINE void Merge( const btDbvtAabbMm& a, 619 620 646 const btDbvtAabbMm& b, 647 btDbvtAabbMm& r) 621 648 { 622 649 #if DBVT_MERGE_IMPL==DBVT_IMPL_SSE 623 624 625 626 627 628 629 630 650 __m128 ami(_mm_load_ps(a.mi)); 651 __m128 amx(_mm_load_ps(a.mx)); 652 __m128 bmi(_mm_load_ps(b.mi)); 653 __m128 bmx(_mm_load_ps(b.mx)); 654 ami=_mm_min_ps(ami,bmi); 655 amx=_mm_max_ps(amx,bmx); 656 _mm_store_ps(r.mi,ami); 657 _mm_store_ps(r.mx,amx); 631 658 #else 632 633 { 634 635 659 for(int i=0;i<3;++i) 660 { 661 if(a.mi[i]<b.mi[i]) r.mi[i]=a.mi[i]; else r.mi[i]=b.mi[i]; 662 if(a.mx[i]>b.mx[i]) r.mx[i]=a.mx[i]; else r.mx[i]=b.mx[i]; 636 663 } 637 664 #endif … … 640 667 // 641 668 DBVT_INLINE bool NotEqual( const btDbvtAabbMm& a, 642 643 { 644 669 const btDbvtAabbMm& b) 670 { 671 return( (a.mi.x()!=b.mi.x())|| 645 672 (a.mi.y()!=b.mi.y())|| 646 673 (a.mi.z()!=b.mi.z())|| … … 657 684 DBVT_PREFIX 658 685 inline void btDbvt::enumNodes( const btDbvtNode* root, 659 660 { 661 662 663 664 { 665 666 686 DBVT_IPOLICY) 687 { 688 DBVT_CHECKTYPE 689 policy.Process(root); 690 if(root->isinternal()) 691 { 692 enumNodes(root->childs[0],policy); 693 enumNodes(root->childs[1],policy); 667 694 } 668 695 } … … 671 698 DBVT_PREFIX 672 699 inline void btDbvt::enumLeaves( const btDbvtNode* root, 673 674 { 675 676 677 678 679 680 681 682 683 684 700 DBVT_IPOLICY) 701 { 702 DBVT_CHECKTYPE 703 if(root->isinternal()) 704 { 705 enumLeaves(root->childs[0],policy); 706 enumLeaves(root->childs[1],policy); 707 } 708 else 709 { 710 policy.Process(root); 711 } 685 712 } 686 713 … … 688 715 DBVT_PREFIX 689 716 inline void btDbvt::collideTT( const btDbvtNode* root0, 690 const btDbvtNode* root1, 691 DBVT_IPOLICY) 692 { 693 DBVT_CHECKTYPE 694 if(root0&&root1) 695 { 696 btAlignedObjectArray<sStkNN> stack; 697 int depth=1; 698 int treshold=DOUBLE_STACKSIZE-4; 699 stack.resize(DOUBLE_STACKSIZE); 700 stack[0]=sStkNN(root0,root1); 701 do { 702 sStkNN p=stack[--depth]; 703 if(depth>treshold) 704 { 705 stack.resize(stack.size()*2); 706 treshold=stack.size()-4; 707 } 708 if(p.a==p.b) 709 { 710 if(p.a->isinternal()) 717 const btDbvtNode* root1, 718 DBVT_IPOLICY) 719 { 720 DBVT_CHECKTYPE 721 if(root0&&root1) 722 { 723 btAlignedObjectArray<sStkNN> stack; 724 int depth=1; 725 int treshold=DOUBLE_STACKSIZE-4; 726 stack.resize(DOUBLE_STACKSIZE); 727 stack[0]=sStkNN(root0,root1); 728 do { 729 sStkNN p=stack[--depth]; 730 if(depth>treshold) 731 { 732 stack.resize(stack.size()*2); 733 treshold=stack.size()-4; 734 } 735 if(p.a==p.b) 736 { 737 if(p.a->isinternal()) 738 { 739 stack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]); 740 stack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]); 741 stack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]); 742 } 743 } 744 else if(Intersect(p.a->volume,p.b->volume)) 745 { 746 if(p.a->isinternal()) 747 { 748 if(p.b->isinternal()) 711 749 { 712 stack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]); 713 stack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]); 714 stack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]); 715 } 716 } 717 else if(Intersect(p.a->volume,p.b->volume)) 718 { 719 if(p.a->isinternal()) 720 { 721 if(p.b->isinternal()) 722 { 723 stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]); 724 stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]); 725 stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]); 726 stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]); 727 } 728 else 729 { 730 stack[depth++]=sStkNN(p.a->childs[0],p.b); 731 stack[depth++]=sStkNN(p.a->childs[1],p.b); 732 } 750 stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]); 751 stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]); 752 stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]); 753 stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]); 733 754 } 734 755 else 735 756 { 736 if(p.b->isinternal()) 737 { 738 stack[depth++]=sStkNN(p.a,p.b->childs[0]); 739 stack[depth++]=sStkNN(p.a,p.b->childs[1]); 740 } 741 else 742 { 743 policy.Process(p.a,p.b); 744 } 757 stack[depth++]=sStkNN(p.a->childs[0],p.b); 758 stack[depth++]=sStkNN(p.a->childs[1],p.b); 745 759 } 746 760 } 747 } while(depth); 748 } 749 } 750 751 // 752 DBVT_PREFIX 753 inline void btDbvt::collideTT( const btDbvtNode* root0, 754 const btDbvtNode* root1, 755 const btTransform& xform, 756 DBVT_IPOLICY) 757 { 758 DBVT_CHECKTYPE 759 if(root0&&root1) 760 { 761 btAlignedObjectArray<sStkNN> stack; 762 int depth=1; 763 int treshold=DOUBLE_STACKSIZE-4; 764 stack.resize(DOUBLE_STACKSIZE); 765 stack[0]=sStkNN(root0,root1); 766 do { 767 sStkNN p=stack[--depth]; 768 if(Intersect(p.a->volume,p.b->volume,xform)) 769 { 770 if(depth>treshold) 761 else 762 { 763 if(p.b->isinternal()) 771 764 { 772 stack.resize(stack.size()*2); 773 treshold=stack.size()-4; 774 } 775 if(p.a->isinternal()) 776 { 777 if(p.b->isinternal()) 778 { 779 stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]); 780 stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]); 781 stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]); 782 stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]); 783 } 784 else 785 { 786 stack[depth++]=sStkNN(p.a->childs[0],p.b); 787 stack[depth++]=sStkNN(p.a->childs[1],p.b); 788 } 765 stack[depth++]=sStkNN(p.a,p.b->childs[0]); 766 stack[depth++]=sStkNN(p.a,p.b->childs[1]); 789 767 } 790 768 else 791 769 { 792 if(p.b->isinternal()) 793 { 794 stack[depth++]=sStkNN(p.a,p.b->childs[0]); 795 stack[depth++]=sStkNN(p.a,p.b->childs[1]); 796 } 797 else 798 { 799 policy.Process(p.a,p.b); 800 } 770 policy.Process(p.a,p.b); 801 771 } 802 772 } 803 } while(depth); 804 } 773 } 774 } while(depth); 775 } 805 776 } 806 777 … … 808 779 DBVT_PREFIX 809 780 inline void btDbvt::collideTT( const btDbvtNode* root0, 810 const btTransform& xform0, 811 const btDbvtNode* root1, 812 const btTransform& xform1, 813 DBVT_IPOLICY) 814 { 815 const btTransform xform=xform0.inverse()*xform1; 816 collideTT(root0,root1,xform,policy); 817 } 818 819 // 820 DBVT_PREFIX 821 inline void btDbvt::collideTV( const btDbvtNode* root, 822 const btDbvtVolume& vol, 823 DBVT_IPOLICY) 824 { 825 DBVT_CHECKTYPE 826 if(root) 827 { 828 ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol); 829 btAlignedObjectArray<const btDbvtNode*> stack; 830 stack.reserve(SIMPLE_STACKSIZE); 831 stack.push_back(root); 832 do { 833 const btDbvtNode* n=stack[stack.size()-1]; 834 stack.pop_back(); 835 if(Intersect(n->volume,volume)) 836 { 837 if(n->isinternal()) 838 { 839 stack.push_back(n->childs[0]); 840 stack.push_back(n->childs[1]); 781 const btDbvtNode* root1, 782 const btTransform& xform, 783 DBVT_IPOLICY) 784 { 785 DBVT_CHECKTYPE 786 if(root0&&root1) 787 { 788 btAlignedObjectArray<sStkNN> stack; 789 int depth=1; 790 int treshold=DOUBLE_STACKSIZE-4; 791 stack.resize(DOUBLE_STACKSIZE); 792 stack[0]=sStkNN(root0,root1); 793 do { 794 sStkNN p=stack[--depth]; 795 if(Intersect(p.a->volume,p.b->volume,xform)) 796 { 797 if(depth>treshold) 798 { 799 stack.resize(stack.size()*2); 800 treshold=stack.size()-4; 801 } 802 if(p.a->isinternal()) 803 { 804 if(p.b->isinternal()) 805 { 806 stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]); 807 stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]); 808 stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]); 809 stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]); 841 810 } 842 811 else 843 812 { 844 policy.Process(n); 813 stack[depth++]=sStkNN(p.a->childs[0],p.b); 814 stack[depth++]=sStkNN(p.a->childs[1],p.b); 845 815 } 846 816 } 847 } while(stack.size()>0); 848 } 849 } 850 851 852 // 853 DBVT_PREFIX 854 inline void btDbvt::rayTest( const btDbvtNode* root, 855 const btVector3& rayFrom, 856 const btVector3& rayTo, 857 DBVT_IPOLICY) 858 { 859 DBVT_CHECKTYPE 860 if(root) 861 { 862 btVector3 rayDir = (rayTo-rayFrom); 863 rayDir.normalize (); 864 865 ///what about division by zero? --> just set rayDirection[i] to INF/1e30 866 btVector3 rayDirectionInverse; 867 rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0]; 868 rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1]; 869 rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2]; 870 unsigned int signs[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0}; 871 872 873 btVector3 resultNormal; 874 875 876 btAlignedObjectArray<const btDbvtNode*> stack; 877 stack.reserve(SIMPLE_STACKSIZE); 878 stack.push_back(root); 879 do { 880 const btDbvtNode* node=stack[stack.size()-1]; 881 stack.pop_back(); 882 883 btVector3 bounds[2] = {node->volume.Mins(),node->volume.Maxs()}; 884 btScalar lambda_max = rayDir.dot(rayTo-rayFrom); 885 btScalar tmin=1.f,lambda_min=0.f; 886 bool result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max); 887 888 #ifdef COMPARE_BTRAY_AABB2 889 btScalar param=1.f; 890 bool result2 = btRayAabb(rayFrom,rayTo,node->volume.Mins(),node->volume.Maxs(),param,resultNormal); 891 btAssert(result1 == result2); 892 #endif //TEST_BTRAY_AABB2 893 894 if(result1) 895 { 896 if(node->isinternal()) 817 else 818 { 819 if(p.b->isinternal()) 897 820 { 898 stack.push_back(node->childs[0]);899 stack.push_back(node->childs[1]);821 stack[depth++]=sStkNN(p.a,p.b->childs[0]); 822 stack[depth++]=sStkNN(p.a,p.b->childs[1]); 900 823 } 901 824 else 902 825 { 903 policy.Process(node);826 policy.Process(p.a,p.b); 904 827 } 905 828 } 906 } while(stack.size()); 907 } 829 } 830 } while(depth); 831 } 832 } 833 834 // 835 DBVT_PREFIX 836 inline void btDbvt::collideTT( const btDbvtNode* root0, 837 const btTransform& xform0, 838 const btDbvtNode* root1, 839 const btTransform& xform1, 840 DBVT_IPOLICY) 841 { 842 const btTransform xform=xform0.inverse()*xform1; 843 collideTT(root0,root1,xform,policy); 844 } 845 846 // 847 DBVT_PREFIX 848 inline void btDbvt::collideTV( const btDbvtNode* root, 849 const btDbvtVolume& vol, 850 DBVT_IPOLICY) 851 { 852 DBVT_CHECKTYPE 853 if(root) 854 { 855 ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol); 856 btAlignedObjectArray<const btDbvtNode*> stack; 857 stack.reserve(SIMPLE_STACKSIZE); 858 stack.push_back(root); 859 do { 860 const btDbvtNode* n=stack[stack.size()-1]; 861 stack.pop_back(); 862 if(Intersect(n->volume,volume)) 863 { 864 if(n->isinternal()) 865 { 866 stack.push_back(n->childs[0]); 867 stack.push_back(n->childs[1]); 868 } 869 else 870 { 871 policy.Process(n); 872 } 873 } 874 } while(stack.size()>0); 875 } 876 } 877 878 // 879 DBVT_PREFIX 880 inline void btDbvt::collideRAY( const btDbvtNode* root, 881 const btVector3& origin, 882 const btVector3& direction, 883 DBVT_IPOLICY) 884 { 885 DBVT_CHECKTYPE 886 if(root) 887 { 888 const btVector3 normal=direction.normalized(); 889 const btVector3 invdir( 1/normal.x(), 890 1/normal.y(), 891 1/normal.z()); 892 const unsigned signs[]={ direction.x()<0, 893 direction.y()<0, 894 direction.z()<0}; 895 btAlignedObjectArray<const btDbvtNode*> stack; 896 stack.reserve(SIMPLE_STACKSIZE); 897 stack.push_back(root); 898 do { 899 const btDbvtNode* node=stack[stack.size()-1]; 900 stack.pop_back(); 901 if(Intersect(node->volume,origin,invdir,signs)) 902 { 903 if(node->isinternal()) 904 { 905 stack.push_back(node->childs[0]); 906 stack.push_back(node->childs[1]); 907 } 908 else 909 { 910 policy.Process(node); 911 } 912 } 913 } while(stack.size()); 914 } 908 915 } 909 916 … … 916 923 DBVT_IPOLICY) 917 924 { 918 DBVT_CHECKTYPE 919 if(root) 925 DBVT_CHECKTYPE 926 if(root) 927 { 928 const int inside=(1<<count)-1; 929 btAlignedObjectArray<sStkNP> stack; 930 int signs[sizeof(unsigned)*8]; 931 btAssert(count<int (sizeof(signs)/sizeof(signs[0]))); 932 for(int i=0;i<count;++i) 920 933 { 921 const int inside=(1<<count)-1; 922 btAlignedObjectArray<sStkNP> stack; 923 int signs[sizeof(unsigned)*8]; 924 btAssert(count<int (sizeof(signs)/sizeof(signs[0]))); 925 for(int i=0;i<count;++i) 926 { 927 signs[i]= ((normals[i].x()>=0)?1:0)+ 934 signs[i]= ((normals[i].x()>=0)?1:0)+ 928 935 ((normals[i].y()>=0)?2:0)+ 929 936 ((normals[i].z()>=0)?4:0); 937 } 938 stack.reserve(SIMPLE_STACKSIZE); 939 stack.push_back(sStkNP(root,0)); 940 do { 941 sStkNP se=stack[stack.size()-1]; 942 bool out=false; 943 stack.pop_back(); 944 for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1) 945 { 946 if(0==(se.mask&j)) 947 { 948 const int side=se.node->volume.Classify(normals[i],offsets[i],signs[i]); 949 switch(side) 950 { 951 case -1: out=true;break; 952 case +1: se.mask|=j;break; 953 } 954 } 930 955 } 931 stack.reserve(SIMPLE_STACKSIZE); 932 stack.push_back(sStkNP(root,0)); 933 do { 934 sStkNP se=stack[stack.size()-1]; 935 bool out=false; 936 stack.pop_back(); 937 for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1) 938 { 939 if(0==(se.mask&j)) 956 if(!out) 957 { 958 if((se.mask!=inside)&&(se.node->isinternal())) 959 { 960 stack.push_back(sStkNP(se.node->childs[0],se.mask)); 961 stack.push_back(sStkNP(se.node->childs[1],se.mask)); 962 } 963 else 964 { 965 if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy); 966 } 967 } 968 } while(stack.size()); 969 } 970 } 971 972 // 973 DBVT_PREFIX 974 inline void btDbvt::collideOCL( const btDbvtNode* root, 975 const btVector3* normals, 976 const btScalar* offsets, 977 const btVector3& sortaxis, 978 int count, 979 DBVT_IPOLICY, 980 bool fsort) 981 { 982 DBVT_CHECKTYPE 983 if(root) 984 { 985 const unsigned srtsgns=(sortaxis[0]>=0?1:0)+ 986 (sortaxis[1]>=0?2:0)+ 987 (sortaxis[2]>=0?4:0); 988 const int inside=(1<<count)-1; 989 btAlignedObjectArray<sStkNPS> stock; 990 btAlignedObjectArray<int> ifree; 991 btAlignedObjectArray<int> stack; 992 int signs[sizeof(unsigned)*8]; 993 btAssert(count<int (sizeof(signs)/sizeof(signs[0]))); 994 for(int i=0;i<count;++i) 995 { 996 signs[i]= ((normals[i].x()>=0)?1:0)+ 997 ((normals[i].y()>=0)?2:0)+ 998 ((normals[i].z()>=0)?4:0); 999 } 1000 stock.reserve(SIMPLE_STACKSIZE); 1001 stack.reserve(SIMPLE_STACKSIZE); 1002 ifree.reserve(SIMPLE_STACKSIZE); 1003 stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns)))); 1004 do { 1005 const int id=stack[stack.size()-1]; 1006 sStkNPS se=stock[id]; 1007 stack.pop_back();ifree.push_back(id); 1008 if(se.mask!=inside) 1009 { 1010 bool out=false; 1011 for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1) 1012 { 1013 if(0==(se.mask&j)) 940 1014 { 941 942 1015 const int side=se.node->volume.Classify(normals[i],offsets[i],signs[i]); 1016 switch(side) 943 1017 { 944 1018 case -1: out=true;break; … … 947 1021 } 948 1022 } 949 if(!out) 950 { 951 if((se.mask!=inside)&&(se.node->isinternal())) 1023 if(out) continue; 1024 } 1025 if(policy.Descent(se.node)) 1026 { 1027 if(se.node->isinternal()) 1028 { 1029 const btDbvtNode* pns[]={ se.node->childs[0],se.node->childs[1]}; 1030 sStkNPS nes[]={ sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)), 1031 sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))}; 1032 const int q=nes[0].value<nes[1].value?1:0; 1033 int j=stack.size(); 1034 if(fsort&&(j>0)) 952 1035 { 953 stack.push_back(sStkNP(se.node->childs[0],se.mask)); 954 stack.push_back(sStkNP(se.node->childs[1],se.mask)); 1036 /* Insert 0 */ 1037 j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size()); 1038 stack.push_back(0); 1039 #if DBVT_USE_MEMMOVE 1040 memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1)); 1041 #else 1042 for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1]; 1043 #endif 1044 stack[j]=allocate(ifree,stock,nes[q]); 1045 /* Insert 1 */ 1046 j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size()); 1047 stack.push_back(0); 1048 #if DBVT_USE_MEMMOVE 1049 memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1)); 1050 #else 1051 for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1]; 1052 #endif 1053 stack[j]=allocate(ifree,stock,nes[1-q]); 955 1054 } 956 1055 else 957 1056 { 958 if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy); 1057 stack.push_back(allocate(ifree,stock,nes[q])); 1058 stack.push_back(allocate(ifree,stock,nes[1-q])); 959 1059 } 960 1060 } 961 } while(stack.size()); 962 } 963 } 964 965 // 966 DBVT_PREFIX 967 inline void btDbvt::collideOCL( const btDbvtNode* root, 968 const btVector3* normals, 969 const btScalar* offsets, 970 const btVector3& sortaxis, 971 int count, 972 DBVT_IPOLICY, 973 bool fsort) 974 { 975 DBVT_CHECKTYPE 976 if(root) 977 { 978 const unsigned srtsgns=(sortaxis[0]>=0?1:0)+ 979 (sortaxis[1]>=0?2:0)+ 980 (sortaxis[2]>=0?4:0); 981 const int inside=(1<<count)-1; 982 btAlignedObjectArray<sStkNPS> stock; 983 btAlignedObjectArray<int> ifree; 984 btAlignedObjectArray<int> stack; 985 int signs[sizeof(unsigned)*8]; 986 btAssert(count<int (sizeof(signs)/sizeof(signs[0]))); 987 for(int i=0;i<count;++i) 988 { 989 signs[i]= ((normals[i].x()>=0)?1:0)+ 990 ((normals[i].y()>=0)?2:0)+ 991 ((normals[i].z()>=0)?4:0); 1061 else 1062 { 1063 policy.Process(se.node,se.value); 1064 } 992 1065 } 993 stock.reserve(SIMPLE_STACKSIZE); 994 stack.reserve(SIMPLE_STACKSIZE); 995 ifree.reserve(SIMPLE_STACKSIZE); 996 stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns)))); 997 do { 998 const int id=stack[stack.size()-1]; 999 sStkNPS se=stock[id]; 1000 stack.pop_back();ifree.push_back(id); 1001 if(se.mask!=inside) 1002 { 1003 bool out=false; 1004 for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1) 1005 { 1006 if(0==(se.mask&j)) 1007 { 1008 const int side=se.node->volume.Classify(normals[i],offsets[i],signs[i]); 1009 switch(side) 1010 { 1011 case -1: out=true;break; 1012 case +1: se.mask|=j;break; 1013 } 1014 } 1015 } 1016 if(out) continue; 1017 } 1018 if(policy.Descent(se.node)) 1019 { 1020 if(se.node->isinternal()) 1021 { 1022 const btDbvtNode* pns[]={ se.node->childs[0],se.node->childs[1]}; 1023 sStkNPS nes[]={ sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)), 1024 sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))}; 1025 const int q=nes[0].value<nes[1].value?1:0; 1026 int j=stack.size(); 1027 if(fsort&&(j>0)) 1028 { 1029 /* Insert 0 */ 1030 j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size()); 1031 stack.push_back(0); 1032 #if DBVT_USE_MEMMOVE 1033 memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1)); 1034 #else 1035 for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1]; 1036 #endif 1037 stack[j]=allocate(ifree,stock,nes[q]); 1038 /* Insert 1 */ 1039 j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size()); 1040 stack.push_back(0); 1041 #if DBVT_USE_MEMMOVE 1042 memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1)); 1043 #else 1044 for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1]; 1045 #endif 1046 stack[j]=allocate(ifree,stock,nes[1-q]); 1047 } 1048 else 1049 { 1050 stack.push_back(allocate(ifree,stock,nes[q])); 1051 stack.push_back(allocate(ifree,stock,nes[1-q])); 1052 } 1053 } 1054 else 1055 { 1056 policy.Process(se.node,se.value); 1057 } 1058 } 1059 } while(stack.size()); 1060 } 1066 } while(stack.size()); 1067 } 1061 1068 } 1062 1069 … … 1064 1071 DBVT_PREFIX 1065 1072 inline void btDbvt::collideTU( const btDbvtNode* root, 1066 1067 { 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1073 DBVT_IPOLICY) 1074 { 1075 DBVT_CHECKTYPE 1076 if(root) 1077 { 1078 btAlignedObjectArray<const btDbvtNode*> stack; 1079 stack.reserve(SIMPLE_STACKSIZE); 1080 stack.push_back(root); 1081 do { 1082 const btDbvtNode* n=stack[stack.size()-1]; 1083 stack.pop_back(); 1084 if(policy.Descent(n)) 1085 { 1086 if(n->isinternal()) 1087 { stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); } 1088 else 1089 { policy.Process(n); } 1090 } 1091 } while(stack.size()>0); 1092 } 1086 1093 } 1087 1094 -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp
r1963 r1972 27 27 #if DBVT_BP_PROFILE 28 28 struct ProfileScope 29 {29 { 30 30 __forceinline ProfileScope(btClock& clock,unsigned long& value) : 31 m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds())32 {33 }31 m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds()) 32 { 33 } 34 34 __forceinline ~ProfileScope() 35 {35 { 36 36 (*m_value)+=m_clock->getTimeMicroseconds()-m_base; 37 }37 } 38 38 btClock* m_clock; 39 39 unsigned long* m_value; 40 40 unsigned long m_base; 41 };41 }; 42 42 #define SPC(_value_) ProfileScope spc_scope(m_clock,_value_) 43 43 #else … … 53 53 static inline void listappend(T* item,T*& list) 54 54 { 55 56 57 58 55 item->links[0]=0; 56 item->links[1]=list; 57 if(list) list->links[0]=item; 58 list=item; 59 59 } 60 60 … … 63 63 static inline void listremove(T* item,T*& list) 64 64 { 65 66 65 if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1]; 66 if(item->links[1]) item->links[1]->links[0]=item->links[0]; 67 67 } 68 68 … … 71 71 static inline int listcount(T* root) 72 72 { 73 74 75 73 int n=0; 74 while(root) { ++n;root=root->links[1]; } 75 return(n); 76 76 } 77 77 … … 80 80 static inline void clear(T& value) 81 81 { 82 83 82 static const struct ZeroDummy : T {} zerodummy; 83 value=zerodummy; 84 84 } 85 85 … … 91 91 struct btDbvtTreeCollider : btDbvt::ICollide 92 92 { 93 94 95 btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {}96 97 { 98 99 { 100 101 102 #if DBVT_BP_SORTPAIRS103 104 #endif105 106 107 } 108 } 109 110 { 111 93 btDbvtBroadphase* pbp; 94 btDbvtProxy* proxy; 95 btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {} 96 void Process(const btDbvtNode* na,const btDbvtNode* nb) 97 { 98 if(na!=nb) 99 { 100 btDbvtProxy* pa=(btDbvtProxy*)na->data; 101 btDbvtProxy* pb=(btDbvtProxy*)nb->data; 102 #if DBVT_BP_SORTPAIRS 103 if(pa>pb) btSwap(pa,pb); 104 #endif 105 pbp->m_paircache->addOverlappingPair(pa,pb); 106 ++pbp->m_newpairs; 107 } 108 } 109 void Process(const btDbvtNode* n) 110 { 111 Process(n,proxy->leaf); 112 112 } 113 113 }; … … 120 120 btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache* paircache) 121 121 { 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 paircache :137 new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();138 139 140 141 142 { 143 122 m_deferedcollide = false; 123 m_needcleanup = true; 124 m_releasepaircache = (paircache!=0)?false:true; 125 m_prediction = 1/(btScalar)2; 126 m_stageCurrent = 0; 127 m_fixedleft = 0; 128 m_fupdates = 1; 129 m_dupdates = 0; 130 m_cupdates = 10; 131 m_newpairs = 1; 132 m_updates_call = 0; 133 m_updates_done = 0; 134 m_updates_ratio = 0; 135 m_paircache = paircache? 136 paircache : 137 new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache(); 138 m_gid = 0; 139 m_pid = 0; 140 m_cid = 0; 141 for(int i=0;i<=STAGECOUNT;++i) 142 { 143 m_stageRoots[i]=0; 144 144 } 145 145 #if DBVT_BP_PROFILE 146 146 clear(m_profiling); 147 147 #endif 148 148 } … … 151 151 btDbvtBroadphase::~btDbvtBroadphase() 152 152 { 153 154 155 156 157 153 if(m_releasepaircache) 154 { 155 m_paircache->~btOverlappingPairCache(); 156 btAlignedFree(m_paircache); 157 } 158 158 } 159 159 160 160 // 161 161 btBroadphaseProxy* btDbvtBroadphase::createProxy( const btVector3& aabbMin, 162 const btVector3& aabbMax, 163 int /*shapeType*/, 164 void* userPtr, 165 short int collisionFilterGroup, 166 short int collisionFilterMask, 167 btDispatcher* /*dispatcher*/, 168 void* /*multiSapProxy*/) 169 { 170 btDbvtProxy* proxy=new(btAlignedAlloc(sizeof(btDbvtProxy),16)) btDbvtProxy( aabbMin,aabbMax,userPtr, 171 collisionFilterGroup, 172 collisionFilterMask); 173 174 btDbvtAabbMm aabb = btDbvtVolume::FromMM(aabbMin,aabbMax); 175 176 //bproxy->aabb = btDbvtVolume::FromMM(aabbMin,aabbMax); 177 proxy->stage = m_stageCurrent; 178 proxy->m_uniqueId = ++m_gid; 179 proxy->leaf = m_sets[0].insert(aabb,proxy); 180 listappend(proxy,m_stageRoots[m_stageCurrent]); 181 if(!m_deferedcollide) 182 { 183 btDbvtTreeCollider collider(this); 184 collider.proxy=proxy; 185 btDbvt::collideTV(m_sets[0].m_root,aabb,collider); 186 btDbvt::collideTV(m_sets[1].m_root,aabb,collider); 187 } 188 return(proxy); 162 const btVector3& aabbMax, 163 int /*shapeType*/, 164 void* userPtr, 165 short int collisionFilterGroup, 166 short int collisionFilterMask, 167 btDispatcher* /*dispatcher*/, 168 void* /*multiSapProxy*/) 169 { 170 btDbvtProxy* proxy=new(btAlignedAlloc(sizeof(btDbvtProxy),16)) btDbvtProxy( userPtr, 171 collisionFilterGroup, 172 collisionFilterMask); 173 proxy->aabb = btDbvtVolume::FromMM(aabbMin,aabbMax); 174 proxy->stage = m_stageCurrent; 175 proxy->m_uniqueId = ++m_gid; 176 proxy->leaf = m_sets[0].insert(proxy->aabb,proxy); 177 listappend(proxy,m_stageRoots[m_stageCurrent]); 178 if(!m_deferedcollide) 179 { 180 btDbvtTreeCollider collider(this); 181 collider.proxy=proxy; 182 btDbvt::collideTV(m_sets[0].m_root,proxy->aabb,collider); 183 btDbvt::collideTV(m_sets[1].m_root,proxy->aabb,collider); 184 } 185 return(proxy); 189 186 } 190 187 191 188 // 192 189 void btDbvtBroadphase::destroyProxy( btBroadphaseProxy* absproxy, 193 btDispatcher* dispatcher) 194 { 195 btDbvtProxy* proxy=(btDbvtProxy*)absproxy; 190 btDispatcher* dispatcher) 191 { 192 btDbvtProxy* proxy=(btDbvtProxy*)absproxy; 193 if(proxy->stage==STAGECOUNT) 194 m_sets[1].remove(proxy->leaf); 195 else 196 m_sets[0].remove(proxy->leaf); 197 listremove(proxy,m_stageRoots[proxy->stage]); 198 m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher); 199 btAlignedFree(proxy); 200 m_needcleanup=true; 201 } 202 203 // 204 void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy, 205 const btVector3& aabbMin, 206 const btVector3& aabbMax, 207 btDispatcher* /*dispatcher*/) 208 { 209 btDbvtProxy* proxy=(btDbvtProxy*)absproxy; 210 ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax); 211 #if DBVT_BP_PREVENTFALSEUPDATE 212 if(NotEqual(aabb,proxy->leaf->volume)) 213 #endif 214 { 215 bool docollide=false; 196 216 if(proxy->stage==STAGECOUNT) 217 {/* fixed -> dynamic set */ 197 218 m_sets[1].remove(proxy->leaf); 198 else 199 m_sets[0].remove(proxy->leaf); 200 listremove(proxy,m_stageRoots[proxy->stage]); 201 m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher); 202 btAlignedFree(proxy); 203 m_needcleanup=true; 204 } 205 206 void btDbvtBroadphase::getAabb(btBroadphaseProxy* absproxy,btVector3& aabbMin, btVector3& aabbMax ) const 207 { 208 btDbvtProxy* proxy=(btDbvtProxy*)absproxy; 209 aabbMin = proxy->m_aabbMin; 210 aabbMax = proxy->m_aabbMax; 211 } 212 213 void btDbvtBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback) 214 { 215 216 struct BroadphaseRayTester : btDbvt::ICollide 217 { 218 btBroadphaseRayCallback& m_rayCallback; 219 BroadphaseRayTester(btBroadphaseRayCallback& orgCallback) 220 :m_rayCallback(orgCallback) 221 { 222 } 223 void Process(const btDbvtNode* leaf) 224 { 225 btDbvtProxy* proxy=(btDbvtProxy*)leaf->data; 226 m_rayCallback.process(proxy); 227 } 228 }; 229 230 BroadphaseRayTester callback(rayCallback); 231 232 m_sets[0].rayTest( m_sets[0].m_root, 233 rayFrom, 234 rayTo, 235 callback); 236 237 m_sets[1].rayTest( m_sets[1].m_root, 238 rayFrom, 239 rayTo, 240 callback); 241 242 } 243 244 // 245 void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy, 246 const btVector3& aabbMin, 247 const btVector3& aabbMax, 248 btDispatcher* /*dispatcher*/) 249 { 250 btDbvtProxy* proxy=(btDbvtProxy*)absproxy; 251 ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax); 252 #if DBVT_BP_PREVENTFALSEUPDATE 253 if(NotEqual(aabb,proxy->leaf->volume)) 254 #endif 255 { 256 bool docollide=false; 257 if(proxy->stage==STAGECOUNT) 258 {/* fixed -> dynamic set */ 259 m_sets[1].remove(proxy->leaf); 260 proxy->leaf=m_sets[0].insert(aabb,proxy); 261 docollide=true; 219 proxy->leaf=m_sets[0].insert(aabb,proxy); 220 docollide=true; 262 221 } 263 222 else 264 223 {/* dynamic set */ 265 266 224 ++m_updates_call; 225 if(Intersect(proxy->leaf->volume,aabb)) 267 226 {/* Moving */ 268 269 const btVector3 delta=aabbMin-proxy->m_aabbMin; 270 btVector3 velocity(((proxy->m_aabbMax-proxy->m_aabbMin)/2)*m_prediction); 271 if(delta[0]<0) velocity[0]=-velocity[0]; 272 if(delta[1]<0) velocity[1]=-velocity[1]; 273 if(delta[2]<0) velocity[2]=-velocity[2]; 274 if ( 275 #ifdef DBVT_BP_MARGIN 276 m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN) 277 #else 278 m_sets[0].update(proxy->leaf,aabb,velocity) 279 #endif 280 ) 227 const btVector3 delta=aabbMin-proxy->aabb.Mins(); 228 btVector3 velocity(aabb.Extents()*m_prediction); 229 if(delta[0]<0) velocity[0]=-velocity[0]; 230 if(delta[1]<0) velocity[1]=-velocity[1]; 231 if(delta[2]<0) velocity[2]=-velocity[2]; 232 if ( 233 #ifdef DBVT_BP_MARGIN 234 m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN) 235 #else 236 m_sets[0].update(proxy->leaf,aabb,velocity) 237 #endif 238 ) 281 239 { 282 283 240 ++m_updates_done; 241 docollide=true; 284 242 } 285 243 } 286 244 else 287 245 {/* Teleporting */ 288 289 290 246 m_sets[0].update(proxy->leaf,aabb); 247 ++m_updates_done; 248 docollide=true; 291 249 } 292 250 } 293 listremove(proxy,m_stageRoots[proxy->stage]); 294 proxy->m_aabbMin = aabbMin; 295 proxy->m_aabbMax = aabbMax; 296 proxy->stage = m_stageCurrent; 297 listappend(proxy,m_stageRoots[m_stageCurrent]); 298 if(docollide) 299 { 300 m_needcleanup=true; 301 if(!m_deferedcollide) 251 listremove(proxy,m_stageRoots[proxy->stage]); 252 proxy->aabb = aabb; 253 proxy->stage = m_stageCurrent; 254 listappend(proxy,m_stageRoots[m_stageCurrent]); 255 if(docollide) 256 { 257 m_needcleanup=true; 258 if(!m_deferedcollide) 302 259 { 303 304 305 260 btDbvtTreeCollider collider(this); 261 btDbvt::collideTT(m_sets[1].m_root,proxy->leaf,collider); 262 btDbvt::collideTT(m_sets[0].m_root,proxy->leaf,collider); 306 263 } 307 264 } … … 312 269 void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) 313 270 { 314 271 collide(dispatcher); 315 272 #if DBVT_BP_PROFILE 316 273 if(0==(m_pid%DBVT_BP_PROFILING_RATE)) 317 274 { 318 319 320 321 322 323 324 325 326 m_profiling.m_fdcollide+327 m_profiling.m_cleanup;328 329 330 331 275 printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leaves,m_sets[0].m_leaves,m_paircache->getNumOverlappingPairs()); 276 unsigned int total=m_profiling.m_total; 277 if(total<=0) total=1; 278 printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE); 279 printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE); 280 printf("cleanup: %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE); 281 printf("total: %uus\r\n",total/DBVT_BP_PROFILING_RATE); 282 const unsigned long sum=m_profiling.m_ddcollide+ 283 m_profiling.m_fdcollide+ 284 m_profiling.m_cleanup; 285 printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE); 286 printf("job counts: %u%%\r\n",(m_profiling.m_jobcount*100)/((m_sets[0].m_leaves+m_sets[1].m_leaves)*DBVT_BP_PROFILING_RATE)); 287 clear(m_profiling); 288 m_clock.reset(); 332 289 } 333 290 #endif … … 337 294 void btDbvtBroadphase::collide(btDispatcher* dispatcher) 338 295 { 339 SPC(m_profiling.m_total); 340 /* optimize */ 341 m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100); 342 if(m_fixedleft) 343 { 344 const int count=1+(m_sets[1].m_leaves*m_fupdates)/100; 345 m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100); 346 m_fixedleft=btMax<int>(0,m_fixedleft-count); 347 } 348 /* dynamic -> fixed set */ 349 m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT; 350 btDbvtProxy* current=m_stageRoots[m_stageCurrent]; 351 if(current) 352 { 353 btDbvtTreeCollider collider(this); 354 do { 355 btDbvtProxy* next=current->links[1]; 356 listremove(current,m_stageRoots[current->stage]); 357 listappend(current,m_stageRoots[STAGECOUNT]); 358 #if DBVT_BP_ACCURATESLEEPING 359 m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher); 360 collider.proxy=current; 361 btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider); 362 btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider); 363 #endif 364 m_sets[0].remove(current->leaf); 365 ATTRIBUTE_ALIGNED16(btDbvtVolume) curAabb=btDbvtVolume::FromMM(current->m_aabbMin,current->m_aabbMax); 366 current->leaf = m_sets[1].insert(curAabb,current); 367 current->stage = STAGECOUNT; 368 current = next; 296 SPC(m_profiling.m_total); 297 /* optimize */ 298 m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100); 299 if(m_fixedleft) 300 { 301 const int count=1+(m_sets[1].m_leaves*m_fupdates)/100; 302 m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100); 303 m_fixedleft=btMax<int>(0,m_fixedleft-count); 304 } 305 /* dynamic -> fixed set */ 306 m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT; 307 btDbvtProxy* current=m_stageRoots[m_stageCurrent]; 308 if(current) 309 { 310 btDbvtTreeCollider collider(this); 311 do { 312 btDbvtProxy* next=current->links[1]; 313 listremove(current,m_stageRoots[current->stage]); 314 listappend(current,m_stageRoots[STAGECOUNT]); 315 #if DBVT_BP_ACCURATESLEEPING 316 m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher); 317 collider.proxy=current; 318 btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider); 319 btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider); 320 #endif 321 m_sets[0].remove(current->leaf); 322 current->leaf = m_sets[1].insert(current->aabb,current); 323 current->stage = STAGECOUNT; 324 current = next; 369 325 } while(current); 370 371 372 } 373 374 { 375 376 377 { 378 379 380 } 381 382 { 383 384 385 } 386 } 387 388 389 { 390 391 392 393 { 394 395 396 326 m_fixedleft=m_sets[1].m_leaves; 327 m_needcleanup=true; 328 } 329 /* collide dynamics */ 330 { 331 btDbvtTreeCollider collider(this); 332 if(m_deferedcollide) 333 { 334 SPC(m_profiling.m_fdcollide); 335 btDbvt::collideTT(m_sets[0].m_root,m_sets[1].m_root,collider); 336 } 337 if(m_deferedcollide) 338 { 339 SPC(m_profiling.m_ddcollide); 340 btDbvt::collideTT(m_sets[0].m_root,m_sets[0].m_root,collider); 341 } 342 } 343 /* clean up */ 344 if(m_needcleanup) 345 { 346 SPC(m_profiling.m_cleanup); 347 btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray(); 348 if(pairs.size()>0) 349 { 350 const int ci=pairs.size(); 351 int ni=btMin(ci,btMax<int>(m_newpairs,(ci*m_cupdates)/100)); 352 for(int i=0;i<ni;++i) 397 353 { 398 399 400 401 354 btBroadphasePair& p=pairs[(m_cid+i)%ci]; 355 btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0; 356 btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1; 357 if(!Intersect(pa->leaf->volume,pb->leaf->volume)) 402 358 { 403 #if DBVT_BP_SORTPAIRS404 405 #endif406 407 359 #if DBVT_BP_SORTPAIRS 360 if(pa>pb) btSwap(pa,pb); 361 #endif 362 m_paircache->removeOverlappingPair(pa,pb,dispatcher); 363 --ni;--i; 408 364 } 409 365 } 410 411 } 412 } 413 414 415 416 366 if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0; 367 } 368 } 369 ++m_pid; 370 m_newpairs=1; 371 m_needcleanup=false; 372 if(m_updates_call>0) 417 373 { m_updates_ratio=m_updates_done/(btScalar)m_updates_call; } 418 374 else 419 375 { m_updates_ratio=0; } 420 421 376 m_updates_done/=2; 377 m_updates_call/=2; 422 378 } 423 379 … … 425 381 void btDbvtBroadphase::optimize() 426 382 { 427 428 383 m_sets[0].optimizeTopDown(); 384 m_sets[1].optimizeTopDown(); 429 385 } 430 386 … … 432 388 btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() 433 389 { 434 390 return(m_paircache); 435 391 } 436 392 … … 438 394 const btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() const 439 395 { 440 396 return(m_paircache); 441 397 } 442 398 … … 447 403 ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds; 448 404 449 450 451 m_sets[1].m_root->volume,bounds);452 else453 bounds=m_sets[0].m_root->volume;454 455 else456 bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0);457 458 405 if(!m_sets[0].empty()) 406 if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume, 407 m_sets[1].m_root->volume,bounds); 408 else 409 bounds=m_sets[0].m_root->volume; 410 else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume; 411 else 412 bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0); 413 aabbMin=bounds.Mins(); 414 aabbMax=bounds.Maxs(); 459 415 } 460 416 … … 467 423 468 424 struct btBroadphaseBenchmark 469 {425 { 470 426 struct Experiment 471 {427 { 472 428 const char* name; 473 429 int object_count; … … 477 433 btScalar speed; 478 434 btScalar amplitude; 479 };435 }; 480 436 struct Object 481 {437 { 482 438 btVector3 center; 483 439 btVector3 extents; … … 485 441 btScalar time; 486 442 void update(btScalar speed,btScalar amplitude,btBroadphaseInterface* pbi) 487 {443 { 488 444 time += speed; 489 445 center[0] = btCos(time*(btScalar)2.17)*amplitude+ 490 btSin(time)*amplitude/2;446 btSin(time)*amplitude/2; 491 447 center[1] = btCos(time*(btScalar)1.38)*amplitude+ 492 btSin(time)*amplitude;448 btSin(time)*amplitude; 493 449 center[2] = btSin(time*(btScalar)0.777)*amplitude; 494 450 pbi->setAabb(proxy,center-extents,center+extents,0); 495 }496 };451 } 452 }; 497 453 static int UnsignedRand(int range=RAND_MAX-1) { return(rand()%(range+1)); } 498 454 static btScalar UnitRand() { return(UnsignedRand(16384)/(btScalar)16384); } 499 455 static void OutputTime(const char* name,btClock& c,unsigned count=0) 500 {456 { 501 457 const unsigned long us=c.getTimeMicroseconds(); 502 458 const unsigned long ms=(us+500)/1000; … … 504 460 if(count>0) 505 461 printf("%s : %u us (%u ms), %.2f/s\r\n",name,us,ms,count/sec); 506 else462 else 507 463 printf("%s : %u us (%u ms)\r\n",name,us,ms); 508 }509 };464 } 465 }; 510 466 511 467 void btDbvtBroadphase::benchmark(btBroadphaseInterface* pbi) 512 468 { 513 514 { 515 516 517 469 static const btBroadphaseBenchmark::Experiment experiments[]= 470 { 471 {"1024o.10%",1024,10,0,8192,(btScalar)0.005,(btScalar)100}, 472 /*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100}, 473 {"8192o.10%",8192,10,0,8192,(btScalar)0.005,(btScalar)100},*/ 518 474 }; 519 520 521 522 523 524 { 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 { 543 544 545 546 547 548 549 550 551 552 553 } 554 555 556 557 558 { 559 560 } 561 562 563 564 565 { 566 475 static const int nexperiments=sizeof(experiments)/sizeof(experiments[0]); 476 btAlignedObjectArray<btBroadphaseBenchmark::Object*> objects; 477 btClock wallclock; 478 /* Begin */ 479 for(int iexp=0;iexp<nexperiments;++iexp) 480 { 481 const btBroadphaseBenchmark::Experiment& experiment=experiments[iexp]; 482 const int object_count=experiment.object_count; 483 const int update_count=(object_count*experiment.update_count)/100; 484 const int spawn_count=(object_count*experiment.spawn_count)/100; 485 const btScalar speed=experiment.speed; 486 const btScalar amplitude=experiment.amplitude; 487 printf("Experiment #%u '%s':\r\n",iexp,experiment.name); 488 printf("\tObjects: %u\r\n",object_count); 489 printf("\tUpdate: %u\r\n",update_count); 490 printf("\tSpawn: %u\r\n",spawn_count); 491 printf("\tSpeed: %f\r\n",speed); 492 printf("\tAmplitude: %f\r\n",amplitude); 493 srand(180673); 494 /* Create objects */ 495 wallclock.reset(); 496 objects.reserve(object_count); 497 for(int i=0;i<object_count;++i) 498 { 499 btBroadphaseBenchmark::Object* po=new btBroadphaseBenchmark::Object(); 500 po->center[0]=btBroadphaseBenchmark::UnitRand()*50; 501 po->center[1]=btBroadphaseBenchmark::UnitRand()*50; 502 po->center[2]=btBroadphaseBenchmark::UnitRand()*50; 503 po->extents[0]=btBroadphaseBenchmark::UnitRand()*2+2; 504 po->extents[1]=btBroadphaseBenchmark::UnitRand()*2+2; 505 po->extents[2]=btBroadphaseBenchmark::UnitRand()*2+2; 506 po->time=btBroadphaseBenchmark::UnitRand()*2000; 507 po->proxy=pbi->createProxy(po->center-po->extents,po->center+po->extents,0,po,1,1,0,0); 508 objects.push_back(po); 509 } 510 btBroadphaseBenchmark::OutputTime("\tInitialization",wallclock); 511 /* First update */ 512 wallclock.reset(); 513 for(int i=0;i<objects.size();++i) 514 { 515 objects[i]->update(speed,amplitude,pbi); 516 } 517 btBroadphaseBenchmark::OutputTime("\tFirst update",wallclock); 518 /* Updates */ 519 wallclock.reset(); 520 for(int i=0;i<experiment.iterations;++i) 521 { 522 for(int j=0;j<update_count;++j) 567 523 { 568 524 objects[j]->update(speed,amplitude,pbi); 569 525 } 570 571 } 572 573 574 575 576 { 577 578 579 } 580 581 526 pbi->calculateOverlappingPairs(0); 527 } 528 btBroadphaseBenchmark::OutputTime("\tUpdate",wallclock,experiment.iterations); 529 /* Clean up */ 530 wallclock.reset(); 531 for(int i=0;i<objects.size();++i) 532 { 533 pbi->destroyProxy(objects[i]->proxy,0); 534 delete objects[i]; 535 } 536 objects.resize(0); 537 btBroadphaseBenchmark::OutputTime("\tRelease",wallclock); 582 538 } 583 539 -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h
r1963 r1972 32 32 33 33 #if DBVT_BP_PROFILE 34 #define DBVT_BP_PROFILING_RATE 25635 #include "LinearMath/btQuickprof.h"34 #define DBVT_BP_PROFILING_RATE 256 35 #include "LinearMath/btQuickprof.h" 36 36 #endif 37 37 … … 41 41 struct btDbvtProxy : btBroadphaseProxy 42 42 { 43 44 //btDbvtAabbMm aabb;45 46 47 48 49 btDbvtProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) :50 btBroadphaseProxy( aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask)43 /* Fields */ 44 btDbvtAabbMm aabb; 45 btDbvtNode* leaf; 46 btDbvtProxy* links[2]; 47 int stage; 48 /* ctor */ 49 btDbvtProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) : 50 btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask) 51 51 { 52 52 links[0]=links[1]=0; 53 53 } 54 54 }; … … 61 61 struct btDbvtBroadphase : btBroadphaseInterface 62 62 { 63 64 63 /* Config */ 64 enum { 65 65 DYNAMIC_SET = 0, /* Dynamic set index */ 66 66 FIXED_SET = 1, /* Fixed set index */ 67 67 STAGECOUNT = 2 /* Number of stages */ 68 };69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 68 }; 69 /* Fields */ 70 btDbvt m_sets[2]; // Dbvt sets 71 btDbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list 72 btOverlappingPairCache* m_paircache; // Pair cache 73 btScalar m_prediction; // Velocity prediction 74 int m_stageCurrent; // Current stage 75 int m_fupdates; // % of fixed updates per frame 76 int m_dupdates; // % of dynamic updates per frame 77 int m_cupdates; // % of cleanup updates per frame 78 int m_newpairs; // Number of pairs created 79 int m_fixedleft; // Fixed optimization left 80 unsigned m_updates_call; // Number of updates call 81 unsigned m_updates_done; // Number of updates done 82 btScalar m_updates_ratio; // m_updates_done/m_updates_call 83 int m_pid; // Parse id 84 int m_cid; // Cleanup index 85 int m_gid; // Gen id 86 bool m_releasepaircache; // Release pair cache on delete 87 bool m_deferedcollide; // Defere dynamic/static collision to collide call 88 bool m_needcleanup; // Need to run cleanup? 89 89 #if DBVT_BP_PROFILE 90 91 90 btClock m_clock; 91 struct { 92 92 unsigned long m_total; 93 93 unsigned long m_ddcollide; … … 95 95 unsigned long m_cleanup; 96 96 unsigned long m_jobcount; 97 } m_profiling;97 } m_profiling; 98 98 #endif 99 /* Methods */ 100 btDbvtBroadphase(btOverlappingPairCache* paircache=0); 101 ~btDbvtBroadphase(); 102 void collide(btDispatcher* dispatcher); 103 void optimize(); 104 /* btBroadphaseInterface Implementation */ 105 btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy); 106 void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); 107 void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); 108 virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback); 109 110 virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; 111 void calculateOverlappingPairs(btDispatcher* dispatcher); 112 btOverlappingPairCache* getOverlappingPairCache(); 113 const btOverlappingPairCache* getOverlappingPairCache() const; 114 void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const; 115 void printStats(); 116 static void benchmark(btBroadphaseInterface*); 99 /* Methods */ 100 btDbvtBroadphase(btOverlappingPairCache* paircache=0); 101 ~btDbvtBroadphase(); 102 void collide(btDispatcher* dispatcher); 103 void optimize(); 104 /* btBroadphaseInterface Implementation */ 105 btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy); 106 void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); 107 void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); 108 void calculateOverlappingPairs(btDispatcher* dispatcher); 109 btOverlappingPairCache* getOverlappingPairCache(); 110 const btOverlappingPairCache* getOverlappingPairCache() const; 111 void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const; 112 void printStats(); 113 static void benchmark(btBroadphaseInterface*); 117 114 }; 118 115 -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp
r1963 r1972 150 150 151 151 152 void btMultiSapBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const153 {154 btMultiSapProxy* multiProxy = static_cast<btMultiSapProxy*>(proxy);155 aabbMin = multiProxy->m_aabbMin;156 aabbMax = multiProxy->m_aabbMax;157 }158 159 void btMultiSapBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback)160 {161 for (int i=0;i<m_multiSapProxies.size();i++)162 {163 rayCallback.process(m_multiSapProxies[i]);164 }165 }166 167 168 152 //#include <stdio.h> 169 153 -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h
r1963 r1972 73 73 */ 74 74 btMultiSapProxy(const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask) 75 :btBroadphaseProxy( aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask),75 :btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask), 76 76 m_aabbMin(aabbMin), 77 77 m_aabbMax(aabbMax), … … 109 109 virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); 110 110 virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher); 111 virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;112 113 virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback);114 111 115 112 void addToChildBroadphase(btMultiSapProxy* parentMultiSapProxy, btBroadphaseProxy* childProxy, btBroadphaseInterface* childBroadphase); -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
r1963 r1972 19 19 #include "LinearMath/btIDebugDraw.h" 20 20 21 #define RAYAABB222 21 23 22 btQuantizedBvh::btQuantizedBvh() : m_useQuantization(false), … … 26 25 //m_traversalMode(TRAVERSAL_RECURSIVE) 27 26 ,m_subtreeHeaderCount(0) //PCK: add this line 28 { 29 m_bvhAabbMin.setValue(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY); 30 m_bvhAabbMax.setValue(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY); 27 { 28 31 29 } 32 30 … … 122 120 int curIndex = m_curNodeIndex; 123 121 124 btAssert(numIndices>0);122 assert(numIndices>0); 125 123 126 124 if (numIndices==1) … … 143 141 int internalNodeIndex = m_curNodeIndex; 144 142 145 //set the min aabb to 'inf' or a max value, and set the max aabb to a -inf/minimum value. 146 //the aabb will be expanded during buildTree/mergeInternalNodeAabb with actual node values 147 setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);//can't use btVector3(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY)) because of quantization 148 setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);//can't use btVector3(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY)) because of quantization 149 143 setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin); 144 setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax); 150 145 151 146 for (i=startIndex;i<endIndex;i++) … … 183 178 updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex); 184 179 } 185 } else186 {187 188 180 } 189 181 … … 347 339 int maxIterations = 0; 348 340 349 350 341 void btQuantizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const 351 342 { … … 362 353 { 363 354 //catch bugs in tree data 364 btAssert (walkIterations < m_curNodeIndex);355 assert (walkIterations < m_curNodeIndex); 365 356 366 357 walkIterations++; … … 444 435 445 436 446 void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const447 {448 btAssert(!m_useQuantization);449 450 const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];451 int escapeIndex, curIndex = 0;452 int walkIterations = 0;453 bool isLeafNode;454 //PCK: unsigned instead of bool455 unsigned aabbOverlap=0;456 unsigned rayBoxOverlap=0;457 btScalar lambda_max = 1.0;458 459 /* Quick pruning by quantized box */460 btVector3 rayAabbMin = raySource;461 btVector3 rayAabbMax = raySource;462 rayAabbMin.setMin(rayTarget);463 rayAabbMax.setMax(rayTarget);464 465 /* Add box cast extents to bounding box */466 rayAabbMin += aabbMin;467 rayAabbMax += aabbMax;468 469 #ifdef RAYAABB2470 btVector3 rayFrom = raySource;471 btVector3 rayDir = (rayTarget-raySource);472 rayDir.normalize ();473 lambda_max = rayDir.dot(rayTarget-raySource);474 ///what about division by zero? --> just set rayDirection[i] to 1.0475 btVector3 rayDirectionInverse;476 rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];477 rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];478 rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];479 unsigned int sign[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};480 #endif481 482 btVector3 bounds[2];483 484 while (curIndex < m_curNodeIndex)485 {486 btScalar param = 1.0;487 //catch bugs in tree data488 btAssert (walkIterations < m_curNodeIndex);489 490 walkIterations++;491 492 bounds[0] = rootNode->m_aabbMinOrg;493 bounds[1] = rootNode->m_aabbMaxOrg;494 /* Add box cast extents */495 bounds[0] += aabbMin;496 bounds[1] += aabbMax;497 498 aabbOverlap = TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);499 //perhaps profile if it is worth doing the aabbOverlap test first500 501 #ifdef RAYAABB2502 ///careful with this check: need to check division by zero (above) and fix the unQuantize method503 ///thanks Joerg/hiker for the reproduction case!504 ///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858505 rayBoxOverlap = aabbOverlap ? btRayAabb2 (raySource, rayDirectionInverse, sign, bounds, param, 0.0f, lambda_max) : false;506 507 #else508 btVector3 normal;509 rayBoxOverlap = btRayAabb(raySource, rayTarget,bounds[0],bounds[1],param, normal);510 #endif511 512 isLeafNode = rootNode->m_escapeIndex == -1;513 514 //PCK: unsigned instead of bool515 if (isLeafNode && (rayBoxOverlap != 0))516 {517 nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);518 }519 520 //PCK: unsigned instead of bool521 if ((rayBoxOverlap != 0) || isLeafNode)522 {523 rootNode++;524 curIndex++;525 } else526 {527 escapeIndex = rootNode->m_escapeIndex;528 rootNode += escapeIndex;529 curIndex += escapeIndex;530 }531 }532 if (maxIterations < walkIterations)533 maxIterations = walkIterations;534 535 }536 537 437 538 438 … … 555 455 556 456 btScalar lambda_max = 1.0; 557 457 #define RAYAABB2 558 458 #ifdef RAYAABB2 559 459 btVector3 rayFrom = raySource; … … 603 503 604 504 //catch bugs in tree data 605 btAssert (walkIterations < subTreeSize);505 assert (walkIterations < subTreeSize); 606 506 607 507 walkIterations++; … … 634 534 ///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858 635 535 636 //BT_PROFILE("btRayAabb2");637 536 rayBoxOverlap = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0f, lambda_max); 638 639 537 #else 640 538 rayBoxOverlap = true;//btRayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal); … … 700 598 701 599 //catch bugs in tree data 702 btAssert (walkIterations < subTreeSize);600 assert (walkIterations < subTreeSize); 703 601 704 602 walkIterations++; … … 755 653 void btQuantizedBvh::reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const 756 654 { 757 reportBoxCastOverlappingNodex(nodeCallback,raySource,rayTarget,btVector3(0,0,0),btVector3(0,0,0)); 655 bool fast_path = m_useQuantization && m_traversalMode == TRAVERSAL_STACKLESS; 656 if (fast_path) 657 { 658 walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, btVector3(0, 0, 0), btVector3(0, 0, 0), 0, m_curNodeIndex); 659 } else { 660 /* Otherwise fallback to AABB overlap test */ 661 btVector3 aabbMin = raySource; 662 btVector3 aabbMax = raySource; 663 aabbMin.setMin(rayTarget); 664 aabbMax.setMax(rayTarget); 665 reportAabbOverlappingNodex(nodeCallback,aabbMin,aabbMax); 666 } 758 667 } 759 668 … … 761 670 void btQuantizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const 762 671 { 763 //always use stackless 764 765 if (m_useQuantization) 672 bool fast_path = m_useQuantization && m_traversalMode == TRAVERSAL_STACKLESS; 673 if (fast_path) 766 674 { 767 675 walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex); 768 } 769 else 770 { 771 walkStacklessTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex); 772 } 773 /* 774 { 775 //recursive traversal 676 } else { 677 /* Slow path: 678 Construct the bounding box for the entire box cast and send that down the tree */ 776 679 btVector3 qaabbMin = raySource; 777 680 btVector3 qaabbMax = raySource; … … 782 685 reportAabbOverlappingNodex(nodeCallback,qaabbMin,qaabbMax); 783 686 } 784 */785 786 687 } 787 688 … … 843 744 bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian) 844 745 { 845 btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size());746 assert(m_subtreeHeaderCount == m_SubtreeHeaders.size()); 846 747 m_subtreeHeaderCount = m_SubtreeHeaders.size(); 847 748 -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.h
r1963 r1972 297 297 void walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const; 298 298 void walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const; 299 void walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const;300 299 301 300 ///tree traversal designed for small-memory processors like PS3 SPU -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
r1963 r1972 89 89 return 0; //should never happen, but don't let the game crash ;-) 90 90 } 91 btAssert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]);91 assert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]); 92 92 93 93 int newHandleIndex = allocHandle(); … … 138 138 } 139 139 140 void btSimpleBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const141 {142 const btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);143 aabbMin = sbp->m_aabbMin;144 aabbMax = sbp->m_aabbMax;145 }146 147 140 void btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* /*dispatcher*/) 148 141 { 149 142 btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy); 150 sbp->m_aabbMin = aabbMin; 151 sbp->m_aabbMax = aabbMax; 152 } 153 154 void btSimpleBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback) 155 { 156 for (int i=0;i<m_numHandles;i++) 157 { 158 btSimpleBroadphaseProxy* proxy = &m_pHandles[i]; 159 rayCallback.process(proxy); 160 } 161 } 143 sbp->m_min = aabbMin; 144 sbp->m_max = aabbMax; 145 } 146 147 162 148 163 149 … … 169 155 bool btSimpleBroadphase::aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1) 170 156 { 171 return proxy0->m_ aabbMin[0] <= proxy1->m_aabbMax[0] && proxy1->m_aabbMin[0] <= proxy0->m_aabbMax[0] &&172 proxy0->m_ aabbMin[1] <= proxy1->m_aabbMax[1] && proxy1->m_aabbMin[1] <= proxy0->m_aabbMax[1] &&173 proxy0->m_ aabbMin[2] <= proxy1->m_aabbMax[2] && proxy1->m_aabbMin[2] <= proxy0->m_aabbMax[2];157 return proxy0->m_min[0] <= proxy1->m_max[0] && proxy1->m_min[0] <= proxy0->m_max[0] && 158 proxy0->m_min[1] <= proxy1->m_max[1] && proxy1->m_min[1] <= proxy0->m_max[1] && 159 proxy0->m_min[2] <= proxy1->m_max[2] && proxy1->m_min[2] <= proxy0->m_max[2]; 174 160 175 161 } -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
r1963 r1972 23 23 struct btSimpleBroadphaseProxy : public btBroadphaseProxy 24 24 { 25 btVector3 m_min; 26 btVector3 m_max; 25 27 int m_nextFree; 26 28 … … 31 33 32 34 btSimpleBroadphaseProxy(const btPoint3& minpt,const btPoint3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,void* multiSapProxy) 33 :btBroadphaseProxy(minpt,maxpt,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy) 35 :btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy), 36 m_min(minpt),m_max(maxpt) 34 37 { 35 38 (void)shapeType; … … 93 96 } 94 97 95 inline const btSimpleBroadphaseProxy* getSimpleProxyFromProxy(btBroadphaseProxy* proxy) const96 {97 const btSimpleBroadphaseProxy* proxy0 = static_cast<const btSimpleBroadphaseProxy*>(proxy);98 return proxy0;99 }100 101 98 102 99 void validate(); … … 121 118 virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); 122 119 virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher); 123 virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;124 125 virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback);126 120 127 121 btOverlappingPairCache* getOverlappingPairCache()
Note: See TracChangeset
for help on using the changeset viewer.