Changeset 1972
- Timestamp:
- Oct 20, 2008, 5:40:38 PM (16 years ago)
- Location:
- code/branches/physics/src/bullet
- Files:
-
- 1 deleted
- 47 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() -
code/branches/physics/src/bullet/BulletCollision/CMakeLists.txt
r1963 r1972 124 124 CollisionShapes/btUniformScalingShape.cpp 125 125 CollisionShapes/btUniformScalingShape.h 126 Gimpact/btContactProcessing.cpp127 Gimpact/btGImpactShape.cpp128 Gimpact/gim_contact.cpp129 Gimpact/btGImpactBvh.cpp130 Gimpact/btGenericPoolAllocator.cpp131 Gimpact/gim_memory.cpp132 Gimpact/btGImpactCollisionAlgorithm.cpp133 Gimpact/btTriangleShapeEx.cpp134 Gimpact/gim_tri_collision.cpp135 Gimpact/btGImpactQuantizedBvh.cpp136 Gimpact/gim_box_set.cpp137 126 NarrowPhaseCollision/btContinuousConvexCollision.cpp 138 127 NarrowPhaseCollision/btContinuousConvexCollision.h -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h
r1963 r1972 238 238 239 239 240 SIMD_FORCE_INLINEbtBroadphaseProxy* getBroadphaseHandle()240 btBroadphaseProxy* getBroadphaseHandle() 241 241 { 242 242 return m_broadphaseHandle; 243 243 } 244 244 245 SIMD_FORCE_INLINEconst btBroadphaseProxy* getBroadphaseHandle() const245 const btBroadphaseProxy* getBroadphaseHandle() const 246 246 { 247 247 return m_broadphaseHandle; -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
r1963 r1972 33 33 #include "LinearMath/btStackAlloc.h" 34 34 35 //#define USE_BRUTEFORCE_RAYBROADPHASE 136 //RECALCULATE_AABB is slower, but benefit is that you don't need to call 'stepSimulation' or 'updateAabbs' before using a rayTest37 //#define RECALCULATE_AABB_RAYCAST 138 35 39 36 //When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor) … … 230 227 if (collisionShape->isConvex()) 231 228 { 232 BT_PROFILE("rayTestConvex");233 229 btConvexCast::CastResult castResult; 234 230 castResult.m_fraction = resultCallback.m_closestHitFraction; … … 274 270 if (collisionShape->isConcave()) 275 271 { 276 BT_PROFILE("rayTestConcave");277 272 if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE) 278 273 { … … 380 375 } 381 376 } else { 382 BT_PROFILE("rayTestCompound");383 377 //todo: use AABB tree or other BVH acceleration structure! 384 378 if (collisionShape->isCompound()) … … 603 597 } 604 598 605 606 struct btSingleRayCallback : public btBroadphaseRayCallback 607 { 608 609 btVector3 m_rayFromWorld; 610 btVector3 m_rayToWorld; 611 const btCollisionWorld* m_world; 612 btCollisionWorld::RayResultCallback& m_resultCallback; 613 614 btSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btCollisionWorld* world,btCollisionWorld::RayResultCallback& resultCallback) 615 :m_rayFromWorld(rayFromWorld), 616 m_rayToWorld(rayToWorld), 617 m_world(world), 618 m_resultCallback(resultCallback) 619 { 620 621 } 622 623 virtual bool process(const btBroadphaseProxy* proxy) 599 void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const 600 { 601 602 603 btTransform rayFromTrans,rayToTrans; 604 rayFromTrans.setIdentity(); 605 rayFromTrans.setOrigin(rayFromWorld); 606 rayToTrans.setIdentity(); 607 608 rayToTrans.setOrigin(rayToWorld); 609 610 /// go over all objects, and if the ray intersects their aabb, do a ray-shape query using convexCaster (CCD) 611 612 int i; 613 for (i=0;i<m_collisionObjects.size();i++) 624 614 { 625 615 ///terminate further ray tests, once the closestHitFraction reached zero 626 if (m_resultCallback.m_closestHitFraction == btScalar(0.f)) 627 return false; 628 629 btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; 630 616 if (resultCallback.m_closestHitFraction == btScalar(0.f)) 617 break; 618 619 btCollisionObject* collisionObject= m_collisionObjects[i]; 631 620 //only perform raycast if filterMask matches 632 if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) 633 { 621 if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) { 634 622 //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); 635 //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;636 637 #ifdef RECALCULATE_AABB638 623 btVector3 collisionObjectAabbMin,collisionObjectAabbMax; 639 624 collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax); 640 #else 641 //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax); 642 btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin; 643 btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax; 644 #endif 645 btScalar hitLambda = m_resultCallback.m_closestHitFraction; 625 626 btScalar hitLambda = resultCallback.m_closestHitFraction; 646 627 btVector3 hitNormal; 647 if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal)) 648 { 649 btTransform rayFromTrans,rayToTrans; 650 rayFromTrans.setIdentity(); 651 rayFromTrans.setOrigin(m_rayFromWorld); 652 rayToTrans.setIdentity(); 653 rayToTrans.setOrigin(m_rayToWorld); 654 655 m_world->rayTestSingle(rayFromTrans,rayToTrans, 628 if (btRayAabb(rayFromWorld,rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal)) 629 { 630 rayTestSingle(rayFromTrans,rayToTrans, 656 631 collisionObject, 657 632 collisionObject->getCollisionShape(), 658 633 collisionObject->getWorldTransform(), 659 m_resultCallback); 660 } 661 } 662 return true; 663 } 664 }; 665 666 void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const 667 { 668 BT_PROFILE("rayTest"); 669 /// go over all objects, and if the ray intersects their aabb, do a ray-shape query using convexCaster (CCD) 670 btSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback); 671 672 #ifndef USE_BRUTEFORCE_RAYBROADPHASE 673 m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB); 674 #else 675 for (int i=0;i<this->getNumCollisionObjects();i++) 676 { 677 rayCB.process(m_collisionObjects[i]->getBroadphaseHandle()); 678 } 679 #endif //USE_BRUTEFORCE_RAYBROADPHASE 634 resultCallback); 635 } 636 } 637 638 } 680 639 681 640 } -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h
r1963 r1972 108 108 } 109 109 110 const btBroadphaseInterface* getBroadphase() const111 {112 return m_broadphasePairCache;113 }114 115 110 btBroadphaseInterface* getBroadphase() 116 111 { -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
r1963 r1972 18 18 #include "LinearMath/btQuaternion.h" 19 19 20 btConvexPointCloudShape::btConvexPointCloudShape (btVector3* points,int numPoints) : btPolyhedralConvexShape () 21 { 22 m_shapeType = CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE; 23 m_points = points; 24 m_numPoints = numPoints; 25 26 recalcLocalAabb(); 27 } 28 29 void btConvexPointCloudShape::setPoints (btVector3* points, int numPoints) 30 { 31 m_points = points; 32 m_numPoints = numPoints; 33 34 recalcLocalAabb(); 35 } 36 37 20 38 void btConvexPointCloudShape::setLocalScaling(const btVector3& scaling) 21 39 { … … 24 42 } 25 43 26 #ifndef __SPU__27 44 btVector3 btConvexPointCloudShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const 28 45 { … … 108 125 109 126 110 #endif 127 111 128 112 129 -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.h
r1963 r1972 29 29 BT_DECLARE_ALIGNED_ALLOCATOR(); 30 30 31 btConvexPointCloudShape(btVector3* points,int numPoints, bool computeAabb = true) 32 { 33 m_shapeType = CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE; 34 m_points = points; 35 m_numPoints = numPoints; 31 btConvexPointCloudShape(btVector3* points,int numPoints); 36 32 37 if (computeAabb) 38 recalcLocalAabb(); 39 } 40 41 void setPoints (btVector3* points, int numPoints, bool computeAabb = true) 42 { 43 m_points = points; 44 m_numPoints = numPoints; 45 46 if (computeAabb) 47 recalcLocalAabb(); 48 } 33 void setPoints (btVector3* points, int numPoints); 49 34 50 35 btPoint3* getPoints() … … 63 48 } 64 49 65 #ifndef __SPU__66 50 virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; 67 51 virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; 68 52 virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; 69 #endif70 53 71 54 -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
r1963 r1972 16 16 #include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h" 17 17 18 btPolyhedralConvexShape::btPolyhedralConvexShape() :btConvexInternalShape(), 18 btPolyhedralConvexShape::btPolyhedralConvexShape() 19 :btConvexInternalShape(), 19 20 m_localAabbMin(1,1,1), 20 21 m_localAabbMax(-1,-1,-1), … … 24 25 25 26 } 27 26 28 27 29 -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
r1963 r1972 32 32 bool m_isLocalAabbValid; 33 33 34 btPolyhedralConvexShape(); 34 35 public: 35 36 36 btPolyhedralConvexShape();37 37 38 38 39 //brute force implementations 39 40 40 virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; 41 41 virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; 42 43 42 44 43 virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; 45 44 46 47 void setCachedLocalAabb (const btVector3& aabbMin, const btVector3& aabbMax)48 {49 m_isLocalAabbValid = true;50 m_localAabbMin = aabbMin;51 m_localAabbMax = aabbMax;52 }53 54 inline void getCachedLocalAabb (btVector3& aabbMin, btVector3& aabbMax) const55 {56 btAssert(m_isLocalAabbValid);57 aabbMin = m_localAabbMin;58 aabbMax = m_localAabbMax;59 }60 45 61 46 inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btSphereShape.cpp
r1963 r1972 18 18 19 19 #include "LinearMath/btQuaternion.h" 20 21 22 btSphereShape ::btSphereShape (btScalar radius) : btConvexInternalShape () 23 { 24 m_shapeType = SPHERE_SHAPE_PROXYTYPE; 25 m_implicitShapeDimensions.setX(radius); 26 m_collisionMargin = radius; 27 } 20 28 21 29 btVector3 btSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btSphereShape.h
r1963 r1972 28 28 BT_DECLARE_ALIGNED_ALLOCATOR(); 29 29 30 btSphereShape (btScalar radius) : btConvexInternalShape () 31 { 32 m_shapeType = SPHERE_SHAPE_PROXYTYPE; 33 m_implicitShapeDimensions.setX(radius); 34 m_collisionMargin = radius; 35 } 30 btSphereShape (btScalar radius); 31 36 32 37 33 virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp
r1963 r1972 886 886 const btVector3 delta= results.witnesses[1]- 887 887 results.witnesses[0]; 888 const btScalar margin= shape0->getMargin NonVirtual()+889 shape1.getMargin NonVirtual();888 const btScalar margin= shape0->getMargin()+ 889 shape1.getMargin(); 890 890 const btScalar length= delta.length(); 891 891 results.normal = delta/length; -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
r1963 r1972 22 22 23 23 #if defined(DEBUG) || defined (_DEBUG) 24 //#define TEST_NON_VIRTUAL 124 #define TEST_NON_VIRTUAL 1 25 25 #include <stdio.h> //for debug printf 26 26 #ifdef __SPU__ -
code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
r1963 r1972 45 45 46 46 int m_solverMode; 47 int m_restingContactRestitutionThreshold;48 47 49 48 … … 71 70 m_warmstartingFactor=btScalar(0.85); 72 71 m_solverMode = SOLVER_RANDMIZE_ORDER | SOLVER_CACHE_FRIENDLY | SOLVER_USE_WARMSTARTING; 73 m_restingContactRestitutionThreshold = 2;//resting contact lifetime threshold to disable restitution74 72 } 75 73 }; -
code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
r1963 r1972 719 719 720 720 solverConstraint.m_friction = cp.m_combinedFriction; 721 722 723 if (cp.m_lifeTime>infoGlobal.m_restingContactRestitutionThreshold) 721 solverConstraint.m_restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution); 722 if (solverConstraint.m_restitution <= btScalar(0.)) 724 723 { 725 724 solverConstraint.m_restitution = 0.f; 726 } else 727 { 728 solverConstraint.m_restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution); 729 if (solverConstraint.m_restitution <= btScalar(0.)) 730 { 731 solverConstraint.m_restitution = 0.f; 732 }; 733 } 725 }; 734 726 735 727 … … 994 986 pt->m_appliedImpulse = solveManifold.m_appliedImpulse; 995 987 pt->m_appliedImpulseLateral1 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse; 996 pt->m_appliedImpulseLateral 2= m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse;988 pt->m_appliedImpulseLateral1 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse; 997 989 998 990 //do a callback here? … … 1229 1221 cpd->m_penetration = cp.getDistance();///btScalar(info.m_numIterations); 1230 1222 cpd->m_friction = cp.m_combinedFriction; 1231 if (cp.m_lifeTime>info.m_restingContactRestitutionThreshold) 1232 { 1233 cpd->m_restitution = 0.f; 1234 } else 1235 { 1236 cpd->m_restitution = restitutionCurve(rel_vel, combinedRestitution); 1237 if (cpd->m_restitution <= btScalar(0.)) 1238 { 1239 cpd->m_restitution = btScalar(0.0); 1240 }; 1241 } 1223 cpd->m_restitution = restitutionCurve(rel_vel, combinedRestitution); 1224 if (cpd->m_restitution <= btScalar(0.)) 1225 { 1226 cpd->m_restitution = btScalar(0.0); 1227 1228 }; 1242 1229 1243 1230 //restitution and penetration work in same direction so -
code/branches/physics/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
r1963 r1972 126 126 void btDiscreteDynamicsWorld::debugDrawWorld() 127 127 { 128 BT_PROFILE("debugDrawWorld");129 128 130 129 if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints) … … 255 254 void btDiscreteDynamicsWorld::synchronizeMotionStates() 256 255 { 257 BT_PROFILE("synchronizeMotionStates");258 256 { 259 257 //todo: iterate over awake simulation islands! -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBody.cpp
r1963 r1972 151 151 btSoftBody::Material* btSoftBody::appendMaterial() 152 152 { 153 154 155 153 Material* pm=new(btAlignedAlloc(sizeof(Material),16)) Material(); 154 if(m_materials.size()>0) 155 *pm=*m_materials[0]; 156 156 else 157 158 159 157 ZeroInitialize(*pm); 158 m_materials.push_back(pm); 159 return(pm); 160 160 } 161 161 162 162 // 163 163 void btSoftBody::appendNote( const char* text, 164 165 166 167 168 169 170 { 171 172 173 174 175 176 177 178 179 180 181 182 183 184 164 const btVector3& o, 165 const btVector4& c, 166 Node* n0, 167 Node* n1, 168 Node* n2, 169 Node* n3) 170 { 171 Note n; 172 ZeroInitialize(n); 173 n.m_rank = 0; 174 n.m_text = text; 175 n.m_offset = o; 176 n.m_coords[0] = c.x(); 177 n.m_coords[1] = c.y(); 178 n.m_coords[2] = c.z(); 179 n.m_coords[3] = c.w(); 180 n.m_nodes[0] = n0;n.m_rank+=n0?1:0; 181 n.m_nodes[1] = n1;n.m_rank+=n1?1:0; 182 n.m_nodes[2] = n2;n.m_rank+=n2?1:0; 183 n.m_nodes[3] = n3;n.m_rank+=n3?1:0; 184 m_notes.push_back(n); 185 185 } 186 186 187 187 // 188 188 void btSoftBody::appendNote( const char* text, 189 190 191 { 192 189 const btVector3& o, 190 Node* feature) 191 { 192 appendNote(text,o,btVector4(1,0,0,0),feature); 193 193 } 194 194 195 195 // 196 196 void btSoftBody::appendNote( const char* text, 197 198 199 { 200 201 202 feature->m_n[1]);203 } 204 197 const btVector3& o, 198 Link* feature) 199 { 200 static const btScalar w=1/(btScalar)2; 201 appendNote(text,o,btVector4(w,w,0,0), feature->m_n[0], 202 feature->m_n[1]); 203 } 204 205 205 // 206 206 void btSoftBody::appendNote( const char* text, 207 208 209 { 210 211 212 feature->m_n[1],213 feature->m_n[2]);207 const btVector3& o, 208 Face* feature) 209 { 210 static const btScalar w=1/(btScalar)3; 211 appendNote(text,o,btVector4(w,w,w,0), feature->m_n[0], 212 feature->m_n[1], 213 feature->m_n[2]); 214 214 } 215 215 … … 217 217 void btSoftBody::appendNode( const btVector3& x,btScalar m) 218 218 { 219 220 { 221 222 223 224 } 225 226 227 228 229 230 231 232 233 219 if(m_nodes.capacity()==m_nodes.size()) 220 { 221 pointersToIndices(); 222 m_nodes.reserve(m_nodes.size()*2+1); 223 indicesToPointers(); 224 } 225 const btScalar margin=getCollisionShape()->getMargin(); 226 m_nodes.push_back(Node()); 227 Node& n=m_nodes[m_nodes.size()-1]; 228 ZeroInitialize(n); 229 n.m_x = x; 230 n.m_q = n.m_x; 231 n.m_im = m>0?1/m:0; 232 n.m_material = m_materials[0]; 233 n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x,margin),&n); 234 234 } 235 235 … … 237 237 void btSoftBody::appendLink(int model,Material* mat) 238 238 { 239 240 241 239 Link l; 240 if(model>=0) 241 l=m_links[model]; 242 242 else 243 243 { ZeroInitialize(l);l.m_material=mat?mat:m_materials[0]; } 244 244 m_links.push_back(l); 245 245 } 246 246 … … 274 274 void btSoftBody::appendFace(int model,Material* mat) 275 275 { 276 277 276 Face f; 277 if(model>=0) 278 278 { f=m_faces[model]; } 279 279 else 280 280 { ZeroInitialize(f);f.m_material=mat?mat:m_materials[0]; } 281 281 m_faces.push_back(f); 282 282 } 283 283 … … 320 320 void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1) 321 321 { 322 323 324 325 326 327 328 329 330 322 LJoint* pj = new(btAlignedAlloc(sizeof(LJoint),16)) LJoint(); 323 pj->m_bodies[0] = body0; 324 pj->m_bodies[1] = body1; 325 pj->m_refs[0] = pj->m_bodies[0].xform().inverse()*specs.position; 326 pj->m_refs[1] = pj->m_bodies[1].xform().inverse()*specs.position; 327 pj->m_cfm = specs.cfm; 328 pj->m_erp = specs.erp; 329 pj->m_split = specs.split; 330 m_joints.push_back(pj); 331 331 } 332 332 … … 334 334 void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,Body body) 335 335 { 336 336 appendLinearJoint(specs,m_clusters[0],body); 337 337 } 338 338 … … 340 340 void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,btSoftBody* body) 341 341 { 342 342 appendLinearJoint(specs,m_clusters[0],body->m_clusters[0]); 343 343 } 344 344 … … 346 346 void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,Cluster* body0,Body body1) 347 347 { 348 349 350 351 352 353 354 355 356 357 348 AJoint* pj = new(btAlignedAlloc(sizeof(AJoint),16)) AJoint(); 349 pj->m_bodies[0] = body0; 350 pj->m_bodies[1] = body1; 351 pj->m_refs[0] = pj->m_bodies[0].xform().inverse().getBasis()*specs.axis; 352 pj->m_refs[1] = pj->m_bodies[1].xform().inverse().getBasis()*specs.axis; 353 pj->m_cfm = specs.cfm; 354 pj->m_erp = specs.erp; 355 pj->m_split = specs.split; 356 pj->m_icontrol = specs.icontrol; 357 m_joints.push_back(pj); 358 358 } 359 359 … … 361 361 void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,Body body) 362 362 { 363 363 appendAngularJoint(specs,m_clusters[0],body); 364 364 } 365 365 … … 367 367 void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,btSoftBody* body) 368 368 { 369 369 appendAngularJoint(specs,m_clusters[0],body->m_clusters[0]); 370 370 } 371 371 … … 456 456 const Face& f=m_faces[i]; 457 457 const btScalar twicearea=AreaOf( f.m_n[0]->m_x, 458 f.m_n[1]->m_x,459 f.m_n[2]->m_x);458 f.m_n[1]->m_x, 459 f.m_n[2]->m_x); 460 460 for(int j=0;j<3;++j) 461 461 { … … 503 503 void btSoftBody::translate(const btVector3& trs) 504 504 { 505 506 507 508 505 btTransform t; 506 t.setIdentity(); 507 t.setOrigin(trs); 508 transform(t); 509 509 } 510 510 … … 512 512 void btSoftBody::rotate( const btQuaternion& rot) 513 513 { 514 515 516 517 514 btTransform t; 515 t.setIdentity(); 516 t.setRotation(rot); 517 transform(t); 518 518 } 519 519 … … 554 554 Node& n=m_nodes[i]; 555 555 m_pose.m_wgh[i]= n.m_im>0 ? 556 1/(m_nodes[i].m_im*tmass) :557 kmass/tmass;556 1/(m_nodes[i].m_im*tmass) : 557 kmass/tmass; 558 558 } 559 559 /* Pos */ … … 570 570 /* Aqq */ 571 571 m_pose.m_aqq[0] = 572 573 572 m_pose.m_aqq[1] = 573 m_pose.m_aqq[2] = btVector3(0,0,0); 574 574 for( i=0,ni=m_nodes.size();i<ni;++i) 575 {575 { 576 576 const btVector3& q=m_pose.m_pos[i]; 577 577 const btVector3 mq=m_pose.m_wgh[i]*q; … … 579 579 m_pose.m_aqq[1]+=mq.y()*q; 580 580 m_pose.m_aqq[2]+=mq.z()*q; 581 }581 } 582 582 m_pose.m_aqq=m_pose.m_aqq.inverse(); 583 583 updateConstants(); … … 606 606 int btSoftBody::clusterCount() const 607 607 { 608 608 return(m_clusters.size()); 609 609 } 610 610 … … 612 612 btVector3 btSoftBody::clusterCom(const Cluster* cluster) 613 613 { 614 615 616 { 617 618 } 619 614 btVector3 com(0,0,0); 615 for(int i=0,ni=cluster->m_nodes.size();i<ni;++i) 616 { 617 com+=cluster->m_nodes[i]->m_x*cluster->m_masses[i]; 618 } 619 return(com*cluster->m_imass); 620 620 } 621 621 … … 623 623 btVector3 btSoftBody::clusterCom(int cluster) const 624 624 { 625 625 return(clusterCom(m_clusters[cluster])); 626 626 } 627 627 … … 629 629 btVector3 btSoftBody::clusterVelocity(const Cluster* cluster,const btVector3& rpos) 630 630 { 631 631 return(cluster->m_lv+cross(cluster->m_av,rpos)); 632 632 } 633 633 … … 635 635 void btSoftBody::clusterVImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse) 636 636 { 637 638 639 640 641 637 const btVector3 li=cluster->m_imass*impulse; 638 const btVector3 ai=cluster->m_invwi*cross(rpos,impulse); 639 cluster->m_vimpulses[0]+=li;cluster->m_lv+=li; 640 cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai; 641 cluster->m_nvimpulses++; 642 642 } 643 643 … … 645 645 void btSoftBody::clusterDImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse) 646 646 { 647 648 649 650 651 647 const btVector3 li=cluster->m_imass*impulse; 648 const btVector3 ai=cluster->m_invwi*cross(rpos,impulse); 649 cluster->m_dimpulses[0]+=li; 650 cluster->m_dimpulses[1]+=ai; 651 cluster->m_ndimpulses++; 652 652 } 653 653 … … 655 655 void btSoftBody::clusterImpulse(Cluster* cluster,const btVector3& rpos,const Impulse& impulse) 656 656 { 657 658 657 if(impulse.m_asVelocity) clusterVImpulse(cluster,rpos,impulse.m_velocity); 658 if(impulse.m_asDrift) clusterDImpulse(cluster,rpos,impulse.m_drift); 659 659 } 660 660 … … 662 662 void btSoftBody::clusterVAImpulse(Cluster* cluster,const btVector3& impulse) 663 663 { 664 665 666 664 const btVector3 ai=cluster->m_invwi*impulse; 665 cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai; 666 cluster->m_nvimpulses++; 667 667 } 668 668 … … 670 670 void btSoftBody::clusterDAImpulse(Cluster* cluster,const btVector3& impulse) 671 671 { 672 673 674 672 const btVector3 ai=cluster->m_invwi*impulse; 673 cluster->m_dimpulses[1]+=ai; 674 cluster->m_ndimpulses++; 675 675 } 676 676 … … 678 678 void btSoftBody::clusterAImpulse(Cluster* cluster,const Impulse& impulse) 679 679 { 680 681 680 if(impulse.m_asVelocity) clusterVAImpulse(cluster,impulse.m_velocity); 681 if(impulse.m_asDrift) clusterDAImpulse(cluster,impulse.m_drift); 682 682 } 683 683 … … 685 685 void btSoftBody::clusterDCImpulse(Cluster* cluster,const btVector3& impulse) 686 686 { 687 688 687 cluster->m_dimpulses[0]+=impulse*cluster->m_imass; 688 cluster->m_ndimpulses++; 689 689 } 690 690 … … 754 754 void btSoftBody::randomizeConstraints() 755 755 { 756 756 unsigned long seed=243703; 757 757 #define NEXTRAND (seed=(1664525L*seed+1013904223L)&0xffffffff) 758 758 int i,ni; 759 759 760 760 for(i=0,ni=m_links.size();i<ni;++i) … … 772 772 void btSoftBody::releaseCluster(int index) 773 773 { 774 775 776 777 778 774 Cluster* c=m_clusters[index]; 775 if(c->m_leaf) m_cdbvt.remove(c->m_leaf); 776 c->~Cluster(); 777 btAlignedFree(c); 778 m_clusters.remove(c); 779 779 } 780 780 … … 782 782 void btSoftBody::releaseClusters() 783 783 { 784 784 while(m_clusters.size()>0) releaseCluster(0); 785 785 } 786 786 … … 788 788 int btSoftBody::generateClusters(int k,int maxiterations) 789 789 { 790 int i; 791 releaseClusters(); 792 m_clusters.resize(btMin(k,m_nodes.size())); 793 for(i=0;i<m_clusters.size();++i) 794 { 795 m_clusters[i] = new(btAlignedAlloc(sizeof(Cluster),16)) Cluster(); 796 m_clusters[i]->m_collide= true; 797 } 798 k=m_clusters.size(); 799 if(k>0) 800 { 801 /* Initialize */ 802 btAlignedObjectArray<btVector3> centers; 803 btVector3 cog(0,0,0); 804 int i; 790 int i; 791 releaseClusters(); 792 m_clusters.resize(btMin(k,m_nodes.size())); 793 for(i=0;i<m_clusters.size();++i) 794 { 795 m_clusters[i] = new(btAlignedAlloc(sizeof(Cluster),16)) Cluster(); 796 m_clusters[i]->m_collide= true; 797 } 798 k=m_clusters.size(); 799 if(k>0) 800 { 801 /* Initialize */ 802 btAlignedObjectArray<btVector3> centers; 803 btVector3 cog(0,0,0); 804 int i; 805 for(i=0;i<m_nodes.size();++i) 806 { 807 cog+=m_nodes[i].m_x; 808 m_clusters[(i*29873)%m_clusters.size()]->m_nodes.push_back(&m_nodes[i]); 809 } 810 cog/=(btScalar)m_nodes.size(); 811 centers.resize(k,cog); 812 /* Iterate */ 813 const btScalar slope=16; 814 bool changed; 815 int iterations=0; 816 do { 817 const btScalar w=2-btMin<btScalar>(1,iterations/slope); 818 changed=false; 819 iterations++; 820 int i; 821 822 for(i=0;i<k;++i) 823 { 824 btVector3 c(0,0,0); 825 for(int j=0;j<m_clusters[i]->m_nodes.size();++j) 826 { 827 c+=m_clusters[i]->m_nodes[j]->m_x; 828 } 829 if(m_clusters[i]->m_nodes.size()) 830 { 831 c /= (btScalar)m_clusters[i]->m_nodes.size(); 832 c = centers[i]+(c-centers[i])*w; 833 changed |= ((c-centers[i]).length2()>SIMD_EPSILON); 834 centers[i] = c; 835 m_clusters[i]->m_nodes.resize(0); 836 } 837 } 805 838 for(i=0;i<m_nodes.size();++i) 806 { 807 cog+=m_nodes[i].m_x; 808 m_clusters[(i*29873)%m_clusters.size()]->m_nodes.push_back(&m_nodes[i]); 809 } 810 cog/=(btScalar)m_nodes.size(); 811 centers.resize(k,cog); 812 /* Iterate */ 813 const btScalar slope=16; 814 bool changed; 815 int iterations=0; 816 do { 817 const btScalar w=2-btMin<btScalar>(1,iterations/slope); 818 changed=false; 819 iterations++; 820 int i; 821 822 for(i=0;i<k;++i) 823 { 824 btVector3 c(0,0,0); 825 for(int j=0;j<m_clusters[i]->m_nodes.size();++j) 839 { 840 const btVector3 nx=m_nodes[i].m_x; 841 int kbest=0; 842 btScalar kdist=ClusterMetric(centers[0],nx); 843 for(int j=1;j<k;++j) 826 844 { 827 c+=m_clusters[i]->m_nodes[j]->m_x; 828 } 829 if(m_clusters[i]->m_nodes.size()) 830 { 831 c /= (btScalar)m_clusters[i]->m_nodes.size(); 832 c = centers[i]+(c-centers[i])*w; 833 changed |= ((c-centers[i]).length2()>SIMD_EPSILON); 834 centers[i] = c; 835 m_clusters[i]->m_nodes.resize(0); 836 } 837 } 838 for(i=0;i<m_nodes.size();++i) 839 { 840 const btVector3 nx=m_nodes[i].m_x; 841 int kbest=0; 842 btScalar kdist=ClusterMetric(centers[0],nx); 843 for(int j=1;j<k;++j) 844 { 845 const btScalar d=ClusterMetric(centers[j],nx); 846 if(d<kdist) 845 const btScalar d=ClusterMetric(centers[j],nx); 846 if(d<kdist) 847 847 { 848 849 848 kbest=j; 849 kdist=d; 850 850 } 851 851 } 852 852 m_clusters[kbest]->m_nodes.push_back(&m_nodes[i]); 853 853 } 854 854 } while(changed&&(iterations<maxiterations)); 855 856 857 858 859 { 860 861 { 862 863 } 864 } 865 866 { 867 868 int(m_faces[i].m_n[1]-&m_nodes[0]),869 int(m_faces[i].m_n[2]-&m_nodes[0])};870 871 { 872 873 855 /* Merge */ 856 btAlignedObjectArray<int> cids; 857 cids.resize(m_nodes.size(),-1); 858 for(i=0;i<m_clusters.size();++i) 859 { 860 for(int j=0;j<m_clusters[i]->m_nodes.size();++j) 861 { 862 cids[int(m_clusters[i]->m_nodes[j]-&m_nodes[0])]=i; 863 } 864 } 865 for(i=0;i<m_faces.size();++i) 866 { 867 const int idx[]={ int(m_faces[i].m_n[0]-&m_nodes[0]), 868 int(m_faces[i].m_n[1]-&m_nodes[0]), 869 int(m_faces[i].m_n[2]-&m_nodes[0])}; 870 for(int j=0;j<3;++j) 871 { 872 const int cid=cids[idx[j]]; 873 for(int q=1;q<3;++q) 874 874 { 875 876 875 const int kid=idx[(j+q)%3]; 876 if(cids[kid]!=cid) 877 877 { 878 878 if(m_clusters[cid]->m_nodes.findLinearSearch(&m_nodes[kid])==m_clusters[cid]->m_nodes.size()) 879 879 { 880 880 m_clusters[cid]->m_nodes.push_back(&m_nodes[kid]); 881 881 } 882 882 } … … 884 884 } 885 885 } 886 887 888 { 889 890 891 892 893 894 895 } 896 897 898 { 899 900 { 901 902 } 903 } 904 905 906 907 908 } 909 886 /* Master */ 887 if(m_clusters.size()>1) 888 { 889 Cluster* pmaster=new(btAlignedAlloc(sizeof(Cluster),16)) Cluster(); 890 pmaster->m_collide = false; 891 pmaster->m_nodes.reserve(m_nodes.size()); 892 for(int i=0;i<m_nodes.size();++i) pmaster->m_nodes.push_back(&m_nodes[i]); 893 m_clusters.push_back(pmaster); 894 btSwap(m_clusters[0],m_clusters[m_clusters.size()-1]); 895 } 896 /* Terminate */ 897 for(i=0;i<m_clusters.size();++i) 898 { 899 if(m_clusters[i]->m_nodes.size()==0) 900 { 901 releaseCluster(i--); 902 } 903 } 904 905 initializeClusters(); 906 updateClusters(); 907 return(m_clusters.size()); 908 } 909 return(0); 910 910 } 911 911 … … 913 913 void btSoftBody::refine(ImplicitFn* ifn,btScalar accurary,bool cut) 914 914 { 915 916 917 918 919 920 921 922 923 { 924 925 926 { 927 928 { 929 930 915 const Node* nbase = &m_nodes[0]; 916 int ncount = m_nodes.size(); 917 btSymMatrix<int> edges(ncount,-2); 918 int newnodes=0; 919 int i,j,k,ni; 920 921 /* Filter out */ 922 for(i=0;i<m_links.size();++i) 923 { 924 Link& l=m_links[i]; 925 if(l.m_bbending) 926 { 927 if(!SameSign(ifn->Eval(l.m_n[0]->m_x),ifn->Eval(l.m_n[1]->m_x))) 928 { 929 btSwap(m_links[i],m_links[m_links.size()-1]); 930 m_links.pop_back();--i; 931 931 } 932 932 } 933 933 } 934 935 936 { 937 938 939 } 940 934 /* Fill edges */ 935 for(i=0;i<m_links.size();++i) 936 { 937 Link& l=m_links[i]; 938 edges(int(l.m_n[0]-nbase),int(l.m_n[1]-nbase))=-1; 939 } 940 for(i=0;i<m_faces.size();++i) 941 941 { 942 943 944 945 946 } 947 948 949 { 950 951 { 952 953 { 954 955 956 957 942 Face& f=m_faces[i]; 943 edges(int(f.m_n[0]-nbase),int(f.m_n[1]-nbase))=-1; 944 edges(int(f.m_n[1]-nbase),int(f.m_n[2]-nbase))=-1; 945 edges(int(f.m_n[2]-nbase),int(f.m_n[0]-nbase))=-1; 946 } 947 /* Intersect */ 948 for(i=0;i<ncount;++i) 949 { 950 for(j=i+1;j<ncount;++j) 951 { 952 if(edges(i,j)==-1) 953 { 954 Node& a=m_nodes[i]; 955 Node& b=m_nodes[j]; 956 const btScalar t=ImplicitSolve(ifn,a.m_x,b.m_x,accurary); 957 if(t>0) 958 958 { 959 960 961 962 959 const btVector3 x=Lerp(a.m_x,b.m_x,t); 960 const btVector3 v=Lerp(a.m_v,b.m_v,t); 961 btScalar m=0; 962 if(a.m_im>0) 963 963 { 964 964 if(b.m_im>0) 965 965 { 966 967 968 969 970 971 972 966 const btScalar ma=1/a.m_im; 967 const btScalar mb=1/b.m_im; 968 const btScalar mc=Lerp(ma,mb,t); 969 const btScalar f=(ma+mb)/(ma+mb+mc); 970 a.m_im=1/(ma*f); 971 b.m_im=1/(mb*f); 972 m=mc*f; 973 973 } 974 974 else … … 977 977 else 978 978 { 979 979 if(b.m_im>0) 980 980 { b.m_im/=0.5;m=1/b.m_im; } 981 981 else 982 982 m=0; 983 983 } 984 985 986 987 984 appendNode(x,m); 985 edges(i,j)=m_nodes.size()-1; 986 m_nodes[edges(i,j)].m_v=v; 987 ++newnodes; 988 988 } 989 989 } 990 990 } 991 991 } 992 nbase=&m_nodes[0]; 993 /* Refine links */ 994 for(i=0,ni=m_links.size();i<ni;++i) 995 { 996 Link& feat=m_links[i]; 997 const int idx[]={ int(feat.m_n[0]-nbase), 998 int(feat.m_n[1]-nbase)}; 999 if((idx[0]<ncount)&&(idx[1]<ncount)) 1000 { 1001 const int ni=edges(idx[0],idx[1]); 1002 if(ni>0) 1003 { 1004 appendLink(i); 1005 Link* pft[]={ &m_links[i], 1006 &m_links[m_links.size()-1]}; 1007 pft[0]->m_n[0]=&m_nodes[idx[0]]; 1008 pft[0]->m_n[1]=&m_nodes[ni]; 1009 pft[1]->m_n[0]=&m_nodes[ni]; 1010 pft[1]->m_n[1]=&m_nodes[idx[1]]; 1011 } 1012 } 1013 } 1014 /* Refine faces */ 1015 for(i=0;i<m_faces.size();++i) 1016 { 1017 const Face& feat=m_faces[i]; 1018 const int idx[]={ int(feat.m_n[0]-nbase), 1019 int(feat.m_n[1]-nbase), 1020 int(feat.m_n[2]-nbase)}; 1021 for(j=2,k=0;k<3;j=k++) 1022 { 1023 if((idx[j]<ncount)&&(idx[k]<ncount)) 1024 { 1025 const int ni=edges(idx[j],idx[k]); 1026 if(ni>0) 1027 { 1028 appendFace(i); 1029 const int l=(k+1)%3; 1030 Face* pft[]={ &m_faces[i], 1031 &m_faces[m_faces.size()-1]}; 1032 pft[0]->m_n[0]=&m_nodes[idx[l]]; 1033 pft[0]->m_n[1]=&m_nodes[idx[j]]; 1034 pft[0]->m_n[2]=&m_nodes[ni]; 1035 pft[1]->m_n[0]=&m_nodes[ni]; 1036 pft[1]->m_n[1]=&m_nodes[idx[k]]; 1037 pft[1]->m_n[2]=&m_nodes[idx[l]]; 1038 appendLink(ni,idx[l],pft[0]->m_material); 1039 --i;break; 1040 } 1041 } 1042 } 1043 } 1044 /* Cut */ 1045 if(cut) 1046 { 1047 btAlignedObjectArray<int> cnodes; 1048 const int pcount=ncount; 1049 int i; 1050 ncount=m_nodes.size(); 1051 cnodes.resize(ncount,0); 1052 /* Nodes */ 1053 for(i=0;i<ncount;++i) 1054 { 1055 const btVector3 x=m_nodes[i].m_x; 1056 if((i>=pcount)||(btFabs(ifn->Eval(x))<accurary)) 1057 { 1058 const btVector3 v=m_nodes[i].m_v; 1059 btScalar m=getMass(i); 1060 if(m>0) { m*=0.5;m_nodes[i].m_im/=0.5; } 1061 appendNode(x,m); 1062 cnodes[i]=m_nodes.size()-1; 1063 m_nodes[cnodes[i]].m_v=v; 1064 } 1065 } 992 1066 nbase=&m_nodes[0]; 993 /* Refine links */1067 /* Links */ 994 1068 for(i=0,ni=m_links.size();i<ni;++i) 995 { 996 Link& feat=m_links[i]; 997 const int idx[]={ int(feat.m_n[0]-nbase), 998 int(feat.m_n[1]-nbase)}; 999 if((idx[0]<ncount)&&(idx[1]<ncount)) 1000 { 1001 const int ni=edges(idx[0],idx[1]); 1002 if(ni>0) 1003 { 1004 appendLink(i); 1005 Link* pft[]={ &m_links[i], 1006 &m_links[m_links.size()-1]}; 1007 pft[0]->m_n[0]=&m_nodes[idx[0]]; 1008 pft[0]->m_n[1]=&m_nodes[ni]; 1009 pft[1]->m_n[0]=&m_nodes[ni]; 1010 pft[1]->m_n[1]=&m_nodes[idx[1]]; 1011 } 1012 } 1013 } 1014 /* Refine faces */ 1015 for(i=0;i<m_faces.size();++i) 1016 { 1017 const Face& feat=m_faces[i]; 1018 const int idx[]={ int(feat.m_n[0]-nbase), 1019 int(feat.m_n[1]-nbase), 1020 int(feat.m_n[2]-nbase)}; 1021 for(j=2,k=0;k<3;j=k++) 1022 { 1023 if((idx[j]<ncount)&&(idx[k]<ncount)) 1024 { 1025 const int ni=edges(idx[j],idx[k]); 1026 if(ni>0) 1069 { 1070 const int id[]={ int(m_links[i].m_n[0]-nbase), 1071 int(m_links[i].m_n[1]-nbase)}; 1072 int todetach=0; 1073 if(cnodes[id[0]]&&cnodes[id[1]]) 1074 { 1075 appendLink(i); 1076 todetach=m_links.size()-1; 1077 } 1078 else 1079 { 1080 if(( (ifn->Eval(m_nodes[id[0]].m_x)<accurary)&& 1081 (ifn->Eval(m_nodes[id[1]].m_x)<accurary))) 1082 todetach=i; 1083 } 1084 if(todetach) 1085 { 1086 Link& l=m_links[todetach]; 1087 for(int j=0;j<2;++j) 1027 1088 { 1028 appendFace(i); 1029 const int l=(k+1)%3; 1030 Face* pft[]={ &m_faces[i], 1031 &m_faces[m_faces.size()-1]}; 1032 pft[0]->m_n[0]=&m_nodes[idx[l]]; 1033 pft[0]->m_n[1]=&m_nodes[idx[j]]; 1034 pft[0]->m_n[2]=&m_nodes[ni]; 1035 pft[1]->m_n[0]=&m_nodes[ni]; 1036 pft[1]->m_n[1]=&m_nodes[idx[k]]; 1037 pft[1]->m_n[2]=&m_nodes[idx[l]]; 1038 appendLink(ni,idx[l],pft[0]->m_material); 1039 --i;break; 1089 int cn=cnodes[int(l.m_n[j]-nbase)]; 1090 if(cn) l.m_n[j]=&m_nodes[cn]; 1091 } 1092 } 1093 } 1094 /* Faces */ 1095 for(i=0,ni=m_faces.size();i<ni;++i) 1096 { 1097 Node** n= m_faces[i].m_n; 1098 if( (ifn->Eval(n[0]->m_x)<accurary)&& 1099 (ifn->Eval(n[1]->m_x)<accurary)&& 1100 (ifn->Eval(n[2]->m_x)<accurary)) 1101 { 1102 for(int j=0;j<3;++j) 1103 { 1104 int cn=cnodes[int(n[j]-nbase)]; 1105 if(cn) n[j]=&m_nodes[cn]; 1040 1106 } 1041 1107 } 1042 1108 } 1043 } 1044 /* Cut */ 1045 if(cut) 1046 { 1047 btAlignedObjectArray<int> cnodes; 1048 const int pcount=ncount; 1049 int i; 1050 ncount=m_nodes.size(); 1051 cnodes.resize(ncount,0); 1052 /* Nodes */ 1053 for(i=0;i<ncount;++i) 1054 { 1055 const btVector3 x=m_nodes[i].m_x; 1056 if((i>=pcount)||(btFabs(ifn->Eval(x))<accurary)) 1057 { 1058 const btVector3 v=m_nodes[i].m_v; 1059 btScalar m=getMass(i); 1060 if(m>0) { m*=0.5;m_nodes[i].m_im/=0.5; } 1061 appendNode(x,m); 1062 cnodes[i]=m_nodes.size()-1; 1063 m_nodes[cnodes[i]].m_v=v; 1064 } 1065 } 1066 nbase=&m_nodes[0]; 1067 /* Links */ 1068 for(i=0,ni=m_links.size();i<ni;++i) 1069 { 1070 const int id[]={ int(m_links[i].m_n[0]-nbase), 1071 int(m_links[i].m_n[1]-nbase)}; 1072 int todetach=0; 1073 if(cnodes[id[0]]&&cnodes[id[1]]) 1074 { 1075 appendLink(i); 1076 todetach=m_links.size()-1; 1077 } 1078 else 1079 { 1080 if(( (ifn->Eval(m_nodes[id[0]].m_x)<accurary)&& 1081 (ifn->Eval(m_nodes[id[1]].m_x)<accurary))) 1082 todetach=i; 1083 } 1084 if(todetach) 1085 { 1086 Link& l=m_links[todetach]; 1087 for(int j=0;j<2;++j) 1088 { 1089 int cn=cnodes[int(l.m_n[j]-nbase)]; 1090 if(cn) l.m_n[j]=&m_nodes[cn]; 1091 } 1092 } 1093 } 1094 /* Faces */ 1095 for(i=0,ni=m_faces.size();i<ni;++i) 1096 { 1097 Node** n= m_faces[i].m_n; 1098 if( (ifn->Eval(n[0]->m_x)<accurary)&& 1099 (ifn->Eval(n[1]->m_x)<accurary)&& 1100 (ifn->Eval(n[2]->m_x)<accurary)) 1101 { 1102 for(int j=0;j<3;++j) 1103 { 1104 int cn=cnodes[int(n[j]-nbase)]; 1105 if(cn) n[j]=&m_nodes[cn]; 1106 } 1107 } 1108 } 1109 /* Clean orphans */ 1110 int nnodes=m_nodes.size(); 1111 btAlignedObjectArray<int> ranks; 1112 btAlignedObjectArray<int> todelete; 1113 ranks.resize(nnodes,0); 1114 for(i=0,ni=m_links.size();i<ni;++i) 1115 { 1116 for(int j=0;j<2;++j) ranks[int(m_links[i].m_n[j]-nbase)]++; 1117 } 1118 for(i=0,ni=m_faces.size();i<ni;++i) 1119 { 1120 for(int j=0;j<3;++j) ranks[int(m_faces[i].m_n[j]-nbase)]++; 1121 } 1122 for(i=0;i<m_links.size();++i) 1123 { 1124 const int id[]={ int(m_links[i].m_n[0]-nbase), 1125 int(m_links[i].m_n[1]-nbase)}; 1126 const bool sg[]={ ranks[id[0]]==1, 1127 ranks[id[1]]==1}; 1128 if(sg[0]||sg[1]) 1129 { 1130 --ranks[id[0]]; 1131 --ranks[id[1]]; 1132 btSwap(m_links[i],m_links[m_links.size()-1]); 1133 m_links.pop_back();--i; 1134 } 1135 } 1136 #if 0 1137 for(i=nnodes-1;i>=0;--i) 1138 { 1139 if(!ranks[i]) todelete.push_back(i); 1109 /* Clean orphans */ 1110 int nnodes=m_nodes.size(); 1111 btAlignedObjectArray<int> ranks; 1112 btAlignedObjectArray<int> todelete; 1113 ranks.resize(nnodes,0); 1114 for(i=0,ni=m_links.size();i<ni;++i) 1115 { 1116 for(int j=0;j<2;++j) ranks[int(m_links[i].m_n[j]-nbase)]++; 1117 } 1118 for(i=0,ni=m_faces.size();i<ni;++i) 1119 { 1120 for(int j=0;j<3;++j) ranks[int(m_faces[i].m_n[j]-nbase)]++; 1121 } 1122 for(i=0;i<m_links.size();++i) 1123 { 1124 const int id[]={ int(m_links[i].m_n[0]-nbase), 1125 int(m_links[i].m_n[1]-nbase)}; 1126 const bool sg[]={ ranks[id[0]]==1, 1127 ranks[id[1]]==1}; 1128 if(sg[0]||sg[1]) 1129 { 1130 --ranks[id[0]]; 1131 --ranks[id[1]]; 1132 btSwap(m_links[i],m_links[m_links.size()-1]); 1133 m_links.pop_back();--i; 1134 } 1135 } 1136 #if 0 1137 for(i=nnodes-1;i>=0;--i) 1138 { 1139 if(!ranks[i]) todelete.push_back(i); 1140 1140 } 1141 1141 if(todelete.size()) 1142 1142 { 1143 1144 1145 1146 1147 { 1148 1149 1150 1151 1152 1153 1154 } 1155 1156 1157 } 1158 #endif1159 } 1160 1143 btAlignedObjectArray<int>& map=ranks; 1144 for(int i=0;i<nnodes;++i) map[i]=i; 1145 PointersToIndices(this); 1146 for(int i=0,ni=todelete.size();i<ni;++i) 1147 { 1148 int j=todelete[i]; 1149 int& a=map[j]; 1150 int& b=map[--nnodes]; 1151 m_ndbvt.remove(m_nodes[a].m_leaf);m_nodes[a].m_leaf=0; 1152 btSwap(m_nodes[a],m_nodes[b]); 1153 j=a;a=b;b=j; 1154 } 1155 IndicesToPointers(this,&map[0]); 1156 m_nodes.resize(nnodes); 1157 } 1158 #endif 1159 } 1160 m_bUpdateRtCst=true; 1161 1161 } 1162 1162 … … 1164 1164 bool btSoftBody::cutLink(const Node* node0,const Node* node1,btScalar position) 1165 1165 { 1166 1166 return(cutLink(int(node0-&m_nodes[0]),int(node1-&m_nodes[0]),position)); 1167 1167 } 1168 1168 … … 1170 1170 bool btSoftBody::cutLink(int node0,int node1,btScalar position) 1171 1171 { 1172 bool done=false; 1173 int i,ni; 1174 const btVector3 d=m_nodes[node0].m_x-m_nodes[node1].m_x; 1175 const btVector3 x=Lerp(m_nodes[node0].m_x,m_nodes[node1].m_x,position); 1176 const btVector3 v=Lerp(m_nodes[node0].m_v,m_nodes[node1].m_v,position); 1177 const btScalar m=1; 1178 appendNode(x,m); 1179 appendNode(x,m); 1180 Node* pa=&m_nodes[node0]; 1181 Node* pb=&m_nodes[node1]; 1182 Node* pn[2]={ &m_nodes[m_nodes.size()-2], 1183 &m_nodes[m_nodes.size()-1]}; 1184 pn[0]->m_v=v; 1185 pn[1]->m_v=v; 1186 for(i=0,ni=m_links.size();i<ni;++i) 1187 { 1188 const int mtch=MatchEdge(m_links[i].m_n[0],m_links[i].m_n[1],pa,pb); 1172 bool done=false; 1173 int i,ni; 1174 const btVector3 d=m_nodes[node0].m_x-m_nodes[node1].m_x; 1175 const btVector3 x=Lerp(m_nodes[node0].m_x,m_nodes[node1].m_x,position); 1176 const btVector3 v=Lerp(m_nodes[node0].m_v,m_nodes[node1].m_v,position); 1177 const btScalar m=1; 1178 appendNode(x,m); 1179 appendNode(x,m); 1180 Node* pa=&m_nodes[node0]; 1181 Node* pb=&m_nodes[node1]; 1182 Node* pn[2]={ &m_nodes[m_nodes.size()-2], 1183 &m_nodes[m_nodes.size()-1]}; 1184 pn[0]->m_v=v; 1185 pn[1]->m_v=v; 1186 for(i=0,ni=m_links.size();i<ni;++i) 1187 { 1188 const int mtch=MatchEdge(m_links[i].m_n[0],m_links[i].m_n[1],pa,pb); 1189 if(mtch!=-1) 1190 { 1191 appendLink(i); 1192 Link* pft[]={&m_links[i],&m_links[m_links.size()-1]}; 1193 pft[0]->m_n[1]=pn[mtch]; 1194 pft[1]->m_n[0]=pn[1-mtch]; 1195 done=true; 1196 } 1197 } 1198 for(i=0,ni=m_faces.size();i<ni;++i) 1199 { 1200 for(int k=2,l=0;l<3;k=l++) 1201 { 1202 const int mtch=MatchEdge(m_faces[i].m_n[k],m_faces[i].m_n[l],pa,pb); 1189 1203 if(mtch!=-1) 1190 { 1191 appendLink(i); 1192 Link* pft[]={&m_links[i],&m_links[m_links.size()-1]}; 1193 pft[0]->m_n[1]=pn[mtch]; 1194 pft[1]->m_n[0]=pn[1-mtch]; 1195 done=true; 1196 } 1197 } 1198 for(i=0,ni=m_faces.size();i<ni;++i) 1199 { 1200 for(int k=2,l=0;l<3;k=l++) 1201 { 1202 const int mtch=MatchEdge(m_faces[i].m_n[k],m_faces[i].m_n[l],pa,pb); 1203 if(mtch!=-1) 1204 { 1205 appendFace(i); 1206 Face* pft[]={&m_faces[i],&m_faces[m_faces.size()-1]}; 1207 pft[0]->m_n[l]=pn[mtch]; 1208 pft[1]->m_n[k]=pn[1-mtch]; 1209 appendLink(pn[0],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true); 1210 appendLink(pn[1],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true); 1211 } 1212 } 1213 } 1214 if(!done) 1215 { 1216 m_ndbvt.remove(pn[0]->m_leaf); 1217 m_ndbvt.remove(pn[1]->m_leaf); 1218 m_nodes.pop_back(); 1219 m_nodes.pop_back(); 1220 } 1221 return(done); 1222 } 1223 1224 // 1225 bool btSoftBody::rayTest(const btVector3& rayFrom, 1226 const btVector3& rayTo, 1227 sRayCast& results) 1228 { 1229 if(m_faces.size()&&m_fdbvt.empty()) 1230 initializeFaceTree(); 1231 1232 results.body = this; 1233 results.fraction = 1.f; 1234 results.feature = eFeature::None; 1235 results.index = -1; 1236 1237 return(rayTest(rayFrom,rayTo,results.fraction,results.feature,results.index,false)!=0); 1204 { 1205 appendFace(i); 1206 Face* pft[]={&m_faces[i],&m_faces[m_faces.size()-1]}; 1207 pft[0]->m_n[l]=pn[mtch]; 1208 pft[1]->m_n[k]=pn[1-mtch]; 1209 appendLink(pn[0],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true); 1210 appendLink(pn[1],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true); 1211 } 1212 } 1213 } 1214 if(!done) 1215 { 1216 m_ndbvt.remove(pn[0]->m_leaf); 1217 m_ndbvt.remove(pn[1]->m_leaf); 1218 m_nodes.pop_back(); 1219 m_nodes.pop_back(); 1220 } 1221 return(done); 1222 } 1223 1224 // 1225 bool btSoftBody::rayCast(const btVector3& org, 1226 const btVector3& dir, 1227 sRayCast& results, 1228 btScalar maxtime) 1229 { 1230 if(m_faces.size()&&m_fdbvt.empty()) initializeFaceTree(); 1231 results.body = this; 1232 results.time = maxtime; 1233 results.feature = eFeature::None; 1234 results.index = -1; 1235 return(rayCast(org,dir,results.time,results.feature,results.index,false)!=0); 1238 1236 } 1239 1237 … … 1241 1239 void btSoftBody::setSolver(eSolverPresets::_ preset) 1242 1240 { 1243 1244 1245 1246 1241 m_cfg.m_vsequence.clear(); 1242 m_cfg.m_psequence.clear(); 1243 m_cfg.m_dsequence.clear(); 1244 switch(preset) 1247 1245 { 1248 1246 case eSolverPresets::Positions: 1249 1250 1251 1252 1253 1247 m_cfg.m_psequence.push_back(ePSolver::Anchors); 1248 m_cfg.m_psequence.push_back(ePSolver::RContacts); 1249 m_cfg.m_psequence.push_back(ePSolver::SContacts); 1250 m_cfg.m_psequence.push_back(ePSolver::Linear); 1251 break; 1254 1252 case eSolverPresets::Velocities: 1255 1256 1257 1258 1259 1260 1261 1262 1253 m_cfg.m_vsequence.push_back(eVSolver::Linear); 1254 1255 m_cfg.m_psequence.push_back(ePSolver::Anchors); 1256 m_cfg.m_psequence.push_back(ePSolver::RContacts); 1257 m_cfg.m_psequence.push_back(ePSolver::SContacts); 1258 1259 m_cfg.m_dsequence.push_back(ePSolver::Linear); 1260 break; 1263 1261 } 1264 1262 } … … 1276 1274 m_fdbvt.clear(); 1277 1275 if(m_cfg.collisions&fCollision::VF_SS) 1278 {1276 { 1279 1277 initializeFaceTree(); 1280 }1281 } 1282 1278 } 1279 } 1280 1283 1281 /* Prepare */ 1284 1282 m_sst.sdt = dt*m_cfg.timescale; … … 1308 1306 Node& n=m_nodes[i]; 1309 1307 m_ndbvt.update( n.m_leaf, 1310 btDbvtVolume::FromCR(n.m_x,m_sst.radmrg),1311 n.m_v*m_sst.velmrg,1312 m_sst.updmrg);1308 btDbvtVolume::FromCR(n.m_x,m_sst.radmrg), 1309 n.m_v*m_sst.velmrg, 1310 m_sst.updmrg); 1313 1311 } 1314 1312 /* Faces */ 1315 1313 if(!m_fdbvt.empty()) 1316 {1314 { 1317 1315 for(int i=0;i<m_faces.size();++i) 1318 {1316 { 1319 1317 Face& f=m_faces[i]; 1320 1318 const btVector3 v=( f.m_n[0]->m_v+ 1321 f.m_n[1]->m_v+1322 f.m_n[2]->m_v)/3;1319 f.m_n[1]->m_v+ 1320 f.m_n[2]->m_v)/3; 1323 1321 m_fdbvt.update( f.m_leaf, 1324 VolumeOf(f,m_sst.radmrg),1325 v*m_sst.velmrg,1326 m_sst.updmrg);1327 }1328 }1322 VolumeOf(f,m_sst.radmrg), 1323 v*m_sst.velmrg, 1324 m_sst.updmrg); 1325 } 1326 } 1329 1327 /* Pose */ 1330 1328 updatePose(); 1331 1329 /* Match */ 1332 1330 if(m_pose.m_bframe&&(m_cfg.kMT>0)) 1333 {1331 { 1334 1332 const btMatrix3x3 posetrs=m_pose.m_rot; 1335 1333 for(int i=0,ni=m_nodes.size();i<ni;++i) 1336 {1334 { 1337 1335 Node& n=m_nodes[i]; 1338 1336 if(n.m_im>0) 1339 {1337 { 1340 1338 const btVector3 x=posetrs*m_pose.m_pos[i]+m_pose.m_com; 1341 1339 n.m_x=Lerp(n.m_x,x,m_cfg.kMT); 1342 }1343 }1344 }1340 } 1341 } 1342 } 1345 1343 /* Clear contacts */ 1346 1344 m_rcontacts.resize(0); … … 1355 1353 void btSoftBody::solveConstraints() 1356 1354 { 1357 1358 1359 1360 1361 1362 1363 1364 { 1365 1366 1367 1368 } 1369 1370 1371 { 1372 1373 1374 1375 a.m_node->m_im,1376 a.m_body->getInvMass(),1377 a.m_body->getInvInertiaTensorWorld(),1378 ra);1379 1380 1381 1382 } 1383 1384 1385 { 1386 1387 1388 { 1389 1390 { 1391 1392 } 1393 } 1394 1395 1396 { 1397 1398 1399 } 1400 } 1401 1402 1403 { 1404 1405 { 1406 1407 1408 { 1409 1410 } 1411 } 1412 1413 1414 { 1415 1416 1417 1418 } 1419 } 1420 1421 1422 { 1423 1424 1425 { 1426 1427 1428 } 1429 1430 { 1431 1432 { 1433 1434 } 1435 } 1436 1437 { 1438 1439 1440 } 1441 } 1442 1443 1444 1355 /* Apply clusters */ 1356 applyClusters(false); 1357 /* Prepare links */ 1358 1359 int i,ni; 1360 1361 for(i=0,ni=m_links.size();i<ni;++i) 1362 { 1363 Link& l=m_links[i]; 1364 l.m_c3 = l.m_n[1]->m_q-l.m_n[0]->m_q; 1365 l.m_c2 = 1/(l.m_c3.length2()*l.m_c0); 1366 } 1367 /* Prepare anchors */ 1368 for(i=0,ni=m_anchors.size();i<ni;++i) 1369 { 1370 Anchor& a=m_anchors[i]; 1371 const btVector3 ra=a.m_body->getWorldTransform().getBasis()*a.m_local; 1372 a.m_c0 = ImpulseMatrix( m_sst.sdt, 1373 a.m_node->m_im, 1374 a.m_body->getInvMass(), 1375 a.m_body->getInvInertiaTensorWorld(), 1376 ra); 1377 a.m_c1 = ra; 1378 a.m_c2 = m_sst.sdt*a.m_node->m_im; 1379 a.m_body->activate(); 1380 } 1381 /* Solve velocities */ 1382 if(m_cfg.viterations>0) 1383 { 1384 /* Solve */ 1385 for(int isolve=0;isolve<m_cfg.viterations;++isolve) 1386 { 1387 for(int iseq=0;iseq<m_cfg.m_vsequence.size();++iseq) 1388 { 1389 getSolver(m_cfg.m_vsequence[iseq])(this,1); 1390 } 1391 } 1392 /* Update */ 1393 for(i=0,ni=m_nodes.size();i<ni;++i) 1394 { 1395 Node& n=m_nodes[i]; 1396 n.m_x = n.m_q+n.m_v*m_sst.sdt; 1397 } 1398 } 1399 /* Solve positions */ 1400 if(m_cfg.piterations>0) 1401 { 1402 for(int isolve=0;isolve<m_cfg.piterations;++isolve) 1403 { 1404 const btScalar ti=isolve/(btScalar)m_cfg.piterations; 1405 for(int iseq=0;iseq<m_cfg.m_psequence.size();++iseq) 1406 { 1407 getSolver(m_cfg.m_psequence[iseq])(this,1,ti); 1408 } 1409 } 1410 const btScalar vc=m_sst.isdt*(1-m_cfg.kDP); 1411 for(i=0,ni=m_nodes.size();i<ni;++i) 1412 { 1413 Node& n=m_nodes[i]; 1414 n.m_v = (n.m_x-n.m_q)*vc; 1415 n.m_f = btVector3(0,0,0); 1416 } 1417 } 1418 /* Solve drift */ 1419 if(m_cfg.diterations>0) 1420 { 1421 const btScalar vcf=m_cfg.kVCF*m_sst.isdt; 1422 for(i=0,ni=m_nodes.size();i<ni;++i) 1423 { 1424 Node& n=m_nodes[i]; 1425 n.m_q = n.m_x; 1426 } 1427 for(int idrift=0;idrift<m_cfg.diterations;++idrift) 1428 { 1429 for(int iseq=0;iseq<m_cfg.m_dsequence.size();++iseq) 1430 { 1431 getSolver(m_cfg.m_dsequence[iseq])(this,1,0); 1432 } 1433 } 1434 for(int i=0,ni=m_nodes.size();i<ni;++i) 1435 { 1436 Node& n=m_nodes[i]; 1437 n.m_v += (n.m_x-n.m_q)*vcf; 1438 } 1439 } 1440 /* Apply clusters */ 1441 dampClusters(); 1442 applyClusters(true); 1445 1443 } 1446 1444 … … 1448 1446 void btSoftBody::staticSolve(int iterations) 1449 1447 { 1450 1451 { 1452 1453 { 1454 1448 for(int isolve=0;isolve<iterations;++isolve) 1449 { 1450 for(int iseq=0;iseq<m_cfg.m_psequence.size();++iseq) 1451 { 1452 getSolver(m_cfg.m_psequence[iseq])(this,1,0); 1455 1453 } 1456 1454 } … … 1460 1458 void btSoftBody::solveCommonConstraints(btSoftBody** /*bodies*/,int /*count*/,int /*iterations*/) 1461 1459 { 1462 1460 /// placeholder 1463 1461 } 1464 1462 … … 1466 1464 void btSoftBody::solveClusters(const btAlignedObjectArray<btSoftBody*>& bodies) 1467 1465 { 1468 1469 1470 1471 1472 1473 { 1474 1475 } 1476 1477 { 1478 1479 } 1480 1481 { 1482 1483 1484 { 1485 1486 } 1487 } 1488 1489 { 1490 1466 const int nb=bodies.size(); 1467 int iterations=0; 1468 int i; 1469 1470 for(i=0;i<nb;++i) 1471 { 1472 iterations=btMax(iterations,bodies[i]->m_cfg.citerations); 1473 } 1474 for(i=0;i<nb;++i) 1475 { 1476 bodies[i]->prepareClusters(iterations); 1477 } 1478 for(i=0;i<iterations;++i) 1479 { 1480 const btScalar sor=1; 1481 for(int j=0;j<nb;++j) 1482 { 1483 bodies[j]->solveClusters(sor); 1484 } 1485 } 1486 for(i=0;i<nb;++i) 1487 { 1488 bodies[i]->cleanupClusters(); 1491 1489 } 1492 1490 } … … 1500 1498 1501 1499 // 1502 btSoftBody::RayFromToCaster::RayFromToCaster(const btVector3& rayFrom,const btVector3& rayTo,btScalar mxt) 1503 { 1504 m_rayFrom = rayFrom; 1505 m_rayNormalizedDirection = (rayTo-rayFrom); 1506 m_rayTo = rayTo; 1507 m_mint = mxt; 1508 m_face = 0; 1509 m_tests = 0; 1510 } 1511 1512 // 1513 void btSoftBody::RayFromToCaster::Process(const btDbvtNode* leaf) 1514 { 1515 btSoftBody::Face& f=*(btSoftBody::Face*)leaf->data; 1516 const btScalar t=rayFromToTriangle( m_rayFrom,m_rayTo,m_rayNormalizedDirection, 1517 f.m_n[0]->m_x, 1518 f.m_n[1]->m_x, 1519 f.m_n[2]->m_x, 1520 m_mint); 1521 if((t>0)&&(t<m_mint)) 1522 { 1523 m_mint=t;m_face=&f; 1524 } 1525 ++m_tests; 1526 } 1527 1528 // 1529 btScalar btSoftBody::RayFromToCaster::rayFromToTriangle( const btVector3& rayFrom, 1530 const btVector3& rayTo, 1531 const btVector3& rayNormalizedDirection, 1532 const btVector3& a, 1533 const btVector3& b, 1534 const btVector3& c, 1535 btScalar maxt) 1500 btSoftBody::RayCaster::RayCaster(const btVector3& org,const btVector3& dir,btScalar mxt) 1501 { 1502 o = org; 1503 d = dir; 1504 mint = mxt; 1505 face = 0; 1506 tests = 0; 1507 } 1508 1509 // 1510 void btSoftBody::RayCaster::Process(const btDbvtNode* leaf) 1511 { 1512 btSoftBody::Face& f=*(btSoftBody::Face*)leaf->data; 1513 const btScalar t=rayTriangle( o,d, 1514 f.m_n[0]->m_x, 1515 f.m_n[1]->m_x, 1516 f.m_n[2]->m_x, 1517 mint); 1518 if((t>0)&&(t<mint)) { mint=t;face=&f; } 1519 ++tests; 1520 } 1521 1522 // 1523 btScalar btSoftBody::RayCaster::rayTriangle( const btVector3& org, 1524 const btVector3& dir, 1525 const btVector3& a, 1526 const btVector3& b, 1527 const btVector3& c, 1528 btScalar maxt) 1536 1529 { 1537 1530 static const btScalar ceps=-SIMD_EPSILON*10; 1538 1531 static const btScalar teps=SIMD_EPSILON*10; 1539 1540 1532 const btVector3 n=cross(b-a,c-a); 1541 1533 const btScalar d=dot(a,n); 1542 const btScalar den=dot( rayNormalizedDirection,n);1534 const btScalar den=dot(dir,n); 1543 1535 if(!btFuzzyZero(den)) 1544 1536 { 1545 const btScalar num=dot( rayFrom,n)-d;1537 const btScalar num=dot(org,n)-d; 1546 1538 const btScalar t=-num/den; 1547 1539 if((t>teps)&&(t<maxt)) 1548 1540 { 1549 const btVector3 hit= rayFrom+rayNormalizedDirection*t;1541 const btVector3 hit=org+dir*t; 1550 1542 if( (dot(n,cross(a-hit,b-hit))>ceps) && 1551 1543 (dot(n,cross(b-hit,c-hit))>ceps) && … … 1569 1561 { 1570 1562 if(m_nodes[i].m_leaf) 1571 {1563 { 1572 1564 m_nodes[i].m_leaf->data=*(void**)&i; 1573 }1565 } 1574 1566 } 1575 1567 for(i=0,ni=m_links.size();i<ni;++i) … … 1584 1576 m_faces[i].m_n[2]=PTR2IDX(m_faces[i].m_n[2],base); 1585 1577 if(m_faces[i].m_leaf) 1586 {1578 { 1587 1579 m_faces[i].m_leaf->data=*(void**)&i; 1588 }1580 } 1589 1581 } 1590 1582 for(i=0,ni=m_anchors.size();i<ni;++i) 1591 {1583 { 1592 1584 m_anchors[i].m_node=PTR2IDX(m_anchors[i].m_node,base); 1593 }1585 } 1594 1586 for(i=0,ni=m_notes.size();i<ni;++i) 1595 {1587 { 1596 1588 for(int j=0;j<m_notes[i].m_rank;++j) 1597 {1589 { 1598 1590 m_notes[i].m_nodes[j]=PTR2IDX(m_notes[i].m_nodes[j],base); 1599 }1600 }1591 } 1592 } 1601 1593 #undef PTR2IDX 1602 1594 } … … 1606 1598 { 1607 1599 #define IDX2PTR(_p_,_b_) map?(&(_b_)[map[(((char*)_p_)-(char*)0)]]): \ 1608 (&(_b_)[(((char*)_p_)-(char*)0)])1600 (&(_b_)[(((char*)_p_)-(char*)0)]) 1609 1601 btSoftBody::Node* base=&m_nodes[0]; 1610 1602 int i,ni; … … 1613 1605 { 1614 1606 if(m_nodes[i].m_leaf) 1615 {1607 { 1616 1608 m_nodes[i].m_leaf->data=&m_nodes[i]; 1617 }1609 } 1618 1610 } 1619 1611 for(i=0,ni=m_links.size();i<ni;++i) … … 1628 1620 m_faces[i].m_n[2]=IDX2PTR(m_faces[i].m_n[2],base); 1629 1621 if(m_faces[i].m_leaf) 1630 {1622 { 1631 1623 m_faces[i].m_leaf->data=&m_faces[i]; 1632 }1624 } 1633 1625 } 1634 1626 for(i=0,ni=m_anchors.size();i<ni;++i) 1635 {1627 { 1636 1628 m_anchors[i].m_node=IDX2PTR(m_anchors[i].m_node,base); 1637 }1629 } 1638 1630 for(i=0,ni=m_notes.size();i<ni;++i) 1639 {1631 { 1640 1632 for(int j=0;j<m_notes[i].m_rank;++j) 1641 {1633 { 1642 1634 m_notes[i].m_nodes[j]=IDX2PTR(m_notes[i].m_nodes[j],base); 1643 }1644 }1635 } 1636 } 1645 1637 #undef IDX2PTR 1646 1638 } 1647 1639 1648 1640 // 1649 int btSoftBody::ray Test(const btVector3& rayFrom,const btVector3& rayTo,1641 int btSoftBody::rayCast(const btVector3& org,const btVector3& dir, 1650 1642 btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const 1651 1643 { 1652 1644 int cnt=0; 1653 1645 if(bcountonly||m_fdbvt.empty()) 1654 {/* Full search */ 1655 btVector3 dir = rayTo-rayFrom; 1656 dir.normalize(); 1657 1646 {/* Full search */ 1658 1647 for(int i=0,ni=m_faces.size();i<ni;++i) 1659 {1648 { 1660 1649 const btSoftBody::Face& f=m_faces[i]; 1661 1662 const btScalar t=RayFromToCaster::rayFromToTriangle( rayFrom,rayTo,dir, 1663 f.m_n[0]->m_x, 1664 f.m_n[1]->m_x, 1665 f.m_n[2]->m_x, 1666 mint); 1650 const btScalar t=RayCaster::rayTriangle( org,dir, 1651 f.m_n[0]->m_x, 1652 f.m_n[1]->m_x, 1653 f.m_n[2]->m_x, 1654 mint); 1667 1655 if(t>0) 1668 {1656 { 1669 1657 ++cnt; 1670 1658 if(!bcountonly) 1671 {1659 { 1672 1660 feature=btSoftBody::eFeature::Face; 1673 1661 index=i; 1674 1662 mint=t; 1663 } 1675 1664 } 1676 1665 } 1677 1666 } 1678 } 1679 else 1680 {/* Use dbvt */ 1681 RayFromToCaster collider(rayFrom,rayTo,mint); 1682 1683 btDbvt::rayTest(m_fdbvt.m_root,rayFrom,rayTo,collider); 1684 if(collider.m_face) 1685 { 1686 mint=collider.m_mint; 1667 else 1668 {/* Use dbvt */ 1669 RayCaster collider(org,dir,mint); 1670 btDbvt::collideRAY(m_fdbvt.m_root,org,dir,collider); 1671 if(collider.face) 1672 { 1673 mint=collider.mint; 1687 1674 feature=btSoftBody::eFeature::Face; 1688 index=(int)(collider. m_face-&m_faces[0]);1675 index=(int)(collider.face-&m_faces[0]); 1689 1676 cnt=1; 1690 }1691 }1677 } 1678 } 1692 1679 return(cnt); 1693 1680 } … … 1696 1683 void btSoftBody::initializeFaceTree() 1697 1684 { 1698 1699 1700 { 1701 1702 1685 m_fdbvt.clear(); 1686 for(int i=0;i<m_faces.size();++i) 1687 { 1688 Face& f=m_faces[i]; 1689 f.m_leaf=m_fdbvt.insert(VolumeOf(f,0),&f); 1703 1690 } 1704 1691 } … … 1707 1694 btVector3 btSoftBody::evaluateCom() const 1708 1695 { 1709 1710 1711 { 1712 1713 { 1714 1696 btVector3 com(0,0,0); 1697 if(m_pose.m_bframe) 1698 { 1699 for(int i=0,ni=m_nodes.size();i<ni;++i) 1700 { 1701 com+=m_nodes[i].m_x*m_pose.m_wgh[i]; 1715 1702 } 1716 1703 } 1717 1704 return(com); 1718 1705 } 1719 1706 1720 1707 // 1721 1708 bool btSoftBody::checkContact( btRigidBody* prb, 1722 1723 1724 1709 const btVector3& x, 1710 btScalar margin, 1711 btSoftBody::sCti& cti) const 1725 1712 { 1726 1713 btVector3 nrm; … … 1728 1715 const btTransform& wtr=prb->getInterpolationWorldTransform(); 1729 1716 btScalar dst=m_worldInfo->m_sparsesdf.Evaluate( wtr.invXform(x), 1730 shp,1731 nrm,1732 margin);1717 shp, 1718 nrm, 1719 margin); 1733 1720 if(dst<0) 1734 1721 { … … 1736 1723 cti.m_normal = wtr.getBasis()*nrm; 1737 1724 cti.m_offset = -dot( cti.m_normal, 1738 x-cti.m_normal*dst);1725 x-cti.m_normal*dst); 1739 1726 return(true); 1740 1727 } … … 1756 1743 btSoftBody::Face& f=m_faces[i]; 1757 1744 const btVector3 n=cross(f.m_n[1]->m_x-f.m_n[0]->m_x, 1758 f.m_n[2]->m_x-f.m_n[0]->m_x);1745 f.m_n[2]->m_x-f.m_n[0]->m_x); 1759 1746 f.m_normal=n.normalized(); 1760 1747 f.m_n[0]->m_n+=n; … … 1774 1761 { 1775 1762 if(m_ndbvt.m_root) 1776 {1763 { 1777 1764 const btVector3& mins=m_ndbvt.m_root->volume.Mins(); 1778 1765 const btVector3& maxs=m_ndbvt.m_root->volume.Maxs(); 1779 1766 const btScalar csm=getCollisionShape()->getMargin(); 1780 1767 const btVector3 mrg=btVector3( csm, 1781 csm,1782 csm)*1; // ??? to investigate...1768 csm, 1769 csm)*1; // ??? to investigate... 1783 1770 m_bounds[0]=mins-mrg; 1784 1771 m_bounds[1]=maxs+mrg; 1785 if(0!=getBroadphaseHandle())1786 {1787 m_worldInfo->m_broadphase->setAabb( getBroadphaseHandle(),1788 m_bounds[0],1789 m_bounds[1],1790 m_worldInfo->m_dispatcher);1791 }1792 }1793 else1794 {1772 if(0!=getBroadphaseHandle()) 1773 { 1774 m_worldInfo->m_broadphase->setAabb( getBroadphaseHandle(), 1775 m_bounds[0], 1776 m_bounds[1], 1777 m_worldInfo->m_dispatcher); 1778 } 1779 } 1780 else 1781 { 1795 1782 m_bounds[0]= 1796 1797 }1783 m_bounds[1]=btVector3(0,0,0); 1784 } 1798 1785 } 1799 1786 … … 1826 1813 pose.m_scl=pose.m_aqq*r.transpose()*Apq; 1827 1814 if(m_cfg.maxvolume>1) 1828 {1815 { 1829 1816 const btScalar idet=Clamp<btScalar>( 1/pose.m_scl.determinant(), 1830 1,m_cfg.maxvolume);1817 1,m_cfg.maxvolume); 1831 1818 pose.m_scl=Mul(pose.m_scl,idet); 1832 }1833 1819 } 1820 1834 1821 } 1835 1822 } … … 1886 1873 int i; 1887 1874 1888 for( i=0;i<m_clusters.size();++i) 1889 { 1890 Cluster& c=*m_clusters[i]; 1891 c.m_imass=0; 1892 c.m_masses.resize(c.m_nodes.size()); 1893 for(int j=0;j<c.m_nodes.size();++j) 1894 { 1895 c.m_masses[j] = c.m_nodes[j]->m_im>0?1/c.m_nodes[j]->m_im:0; 1896 c.m_imass += c.m_masses[j]; 1897 } 1898 c.m_imass = 1/c.m_imass; 1899 c.m_com = btSoftBody::clusterCom(&c); 1900 c.m_lv = btVector3(0,0,0); 1901 c.m_av = btVector3(0,0,0); 1902 c.m_leaf = 0; 1903 /* Inertia */ 1904 btMatrix3x3& ii=c.m_locii; 1905 ii[0]=ii[1]=ii[2]=btVector3(0,0,0); 1906 { 1907 int i,ni; 1908 1909 for(i=0,ni=c.m_nodes.size();i<ni;++i) 1910 { 1911 const btVector3 k=c.m_nodes[i]->m_x-c.m_com; 1912 const btVector3 q=k*k; 1913 const btScalar m=c.m_masses[i]; 1914 ii[0][0] += m*(q[1]+q[2]); 1915 ii[1][1] += m*(q[0]+q[2]); 1916 ii[2][2] += m*(q[0]+q[1]); 1917 ii[0][1] -= m*k[0]*k[1]; 1918 ii[0][2] -= m*k[0]*k[2]; 1919 ii[1][2] -= m*k[1]*k[2]; 1920 } 1921 } 1922 ii[1][0]=ii[0][1]; 1923 ii[2][0]=ii[0][2]; 1924 ii[2][1]=ii[1][2]; 1925 ii=ii.inverse(); 1926 /* Frame */ 1927 c.m_framexform.setIdentity(); 1875 for( i=0;i<m_clusters.size();++i) 1876 { 1877 Cluster& c=*m_clusters[i]; 1878 c.m_imass=0; 1879 c.m_masses.resize(c.m_nodes.size()); 1880 for(int j=0;j<c.m_nodes.size();++j) 1881 { 1882 c.m_masses[j] = c.m_nodes[j]->m_im>0?1/c.m_nodes[j]->m_im:0; 1883 c.m_imass += c.m_masses[j]; 1884 } 1885 c.m_imass = 1/c.m_imass; 1886 c.m_com = btSoftBody::clusterCom(&c); 1887 c.m_lv = btVector3(0,0,0); 1888 c.m_av = btVector3(0,0,0); 1889 c.m_leaf = 0; 1890 /* Inertia */ 1891 btMatrix3x3& ii=c.m_locii; 1892 ii[0]=ii[1]=ii[2]=btVector3(0,0,0); 1893 { 1894 int i,ni; 1895 1896 for(i=0,ni=c.m_nodes.size();i<ni;++i) 1897 { 1898 const btVector3 k=c.m_nodes[i]->m_x-c.m_com; 1899 const btVector3 q=k*k; 1900 const btScalar m=c.m_masses[i]; 1901 ii[0][0] += m*(q[1]+q[2]); 1902 ii[1][1] += m*(q[0]+q[2]); 1903 ii[2][2] += m*(q[0]+q[1]); 1904 ii[0][1] -= m*k[0]*k[1]; 1905 ii[0][2] -= m*k[0]*k[2]; 1906 ii[1][2] -= m*k[1]*k[2]; 1907 } 1908 } 1909 ii[1][0]=ii[0][1]; 1910 ii[2][0]=ii[0][2]; 1911 ii[2][1]=ii[1][2]; 1912 ii=ii.inverse(); 1913 /* Frame */ 1914 c.m_framexform.setIdentity(); 1915 c.m_framexform.setOrigin(c.m_com); 1916 c.m_framerefs.resize(c.m_nodes.size()); 1917 { 1918 int i; 1919 for(i=0;i<c.m_framerefs.size();++i) 1920 { 1921 c.m_framerefs[i]=c.m_nodes[i]->m_x-c.m_com; 1922 } 1923 } 1924 } 1925 } 1926 1927 // 1928 void btSoftBody::updateClusters() 1929 { 1930 BT_PROFILE("UpdateClusters"); 1931 int i; 1932 1933 for(i=0;i<m_clusters.size();++i) 1934 { 1935 btSoftBody::Cluster& c=*m_clusters[i]; 1936 const int n=c.m_nodes.size(); 1937 const btScalar invn=1/(btScalar)n; 1938 if(n) 1939 { 1940 /* Frame */ 1941 const btScalar eps=btScalar(0.0001); 1942 btMatrix3x3 m,r,s; 1943 m[0]=m[1]=m[2]=btVector3(0,0,0); 1944 m[0][0]=eps*1; 1945 m[1][1]=eps*2; 1946 m[2][2]=eps*3; 1947 c.m_com=clusterCom(&c); 1948 for(int i=0;i<c.m_nodes.size();++i) 1949 { 1950 const btVector3 a=c.m_nodes[i]->m_x-c.m_com; 1951 const btVector3& b=c.m_framerefs[i]; 1952 m[0]+=a[0]*b;m[1]+=a[1]*b;m[2]+=a[2]*b; 1953 } 1954 PolarDecompose(m,r,s); 1928 1955 c.m_framexform.setOrigin(c.m_com); 1929 c.m_framerefs.resize(c.m_nodes.size()); 1930 { 1931 int i; 1932 for(i=0;i<c.m_framerefs.size();++i) 1933 { 1934 c.m_framerefs[i]=c.m_nodes[i]->m_x-c.m_com; 1935 } 1936 } 1937 } 1938 } 1939 1940 // 1941 void btSoftBody::updateClusters() 1942 { 1943 BT_PROFILE("UpdateClusters"); 1944 int i; 1945 1946 for(i=0;i<m_clusters.size();++i) 1947 { 1948 btSoftBody::Cluster& c=*m_clusters[i]; 1949 const int n=c.m_nodes.size(); 1950 const btScalar invn=1/(btScalar)n; 1951 if(n) 1952 { 1953 /* Frame */ 1954 const btScalar eps=btScalar(0.0001); 1955 btMatrix3x3 m,r,s; 1956 m[0]=m[1]=m[2]=btVector3(0,0,0); 1957 m[0][0]=eps*1; 1958 m[1][1]=eps*2; 1959 m[2][2]=eps*3; 1960 c.m_com=clusterCom(&c); 1961 for(int i=0;i<c.m_nodes.size();++i) 1962 { 1963 const btVector3 a=c.m_nodes[i]->m_x-c.m_com; 1964 const btVector3& b=c.m_framerefs[i]; 1965 m[0]+=a[0]*b;m[1]+=a[1]*b;m[2]+=a[2]*b; 1966 } 1967 PolarDecompose(m,r,s); 1968 c.m_framexform.setOrigin(c.m_com); 1969 c.m_framexform.setBasis(r); 1970 /* Inertia */ 1971 #if 1/* Constant */ 1972 c.m_invwi=c.m_framexform.getBasis()*c.m_locii*c.m_framexform.getBasis().transpose(); 1973 #else 1974 #if 0/* Sphere */ 1956 c.m_framexform.setBasis(r); 1957 /* Inertia */ 1958 #if 1/* Constant */ 1959 c.m_invwi=c.m_framexform.getBasis()*c.m_locii*c.m_framexform.getBasis().transpose(); 1960 #else 1961 #if 0/* Sphere */ 1975 1962 const btScalar rk=(2*c.m_extents.length2())/(5*c.m_imass); 1976 1963 const btVector3 inertia(rk,rk,rk); 1977 1964 const btVector3 iin(btFabs(inertia[0])>SIMD_EPSILON?1/inertia[0]:0, 1978 btFabs(inertia[1])>SIMD_EPSILON?1/inertia[1]:0,1979 btFabs(inertia[2])>SIMD_EPSILON?1/inertia[2]:0);1980 1965 btFabs(inertia[1])>SIMD_EPSILON?1/inertia[1]:0, 1966 btFabs(inertia[2])>SIMD_EPSILON?1/inertia[2]:0); 1967 1981 1968 c.m_invwi=c.m_xform.getBasis().scaled(iin)*c.m_xform.getBasis().transpose(); 1982 #else/* Actual */1969 #else/* Actual */ 1983 1970 c.m_invwi[0]=c.m_invwi[1]=c.m_invwi[2]=btVector3(0,0,0); 1984 1971 for(int i=0;i<n;++i) 1985 {1972 { 1986 1973 const btVector3 k=c.m_nodes[i]->m_x-c.m_com; 1987 1974 const btVector3 q=k*k; … … 1993 1980 c.m_invwi[0][2] -= m*k[0]*k[2]; 1994 1981 c.m_invwi[1][2] -= m*k[1]*k[2]; 1995 }1982 } 1996 1983 c.m_invwi[1][0]=c.m_invwi[0][1]; 1997 1984 c.m_invwi[2][0]=c.m_invwi[0][2]; 1998 1985 c.m_invwi[2][1]=c.m_invwi[1][2]; 1999 1986 c.m_invwi=c.m_invwi.inverse(); 2000 #endif 2001 #endif 2002 /* Velocities */ 2003 c.m_lv=btVector3(0,0,0); 2004 c.m_av=btVector3(0,0,0); 2005 { 2006 int i; 2007 2008 for(i=0;i<n;++i) 1987 #endif 1988 #endif 1989 /* Velocities */ 1990 c.m_lv=btVector3(0,0,0); 1991 c.m_av=btVector3(0,0,0); 1992 { 1993 int i; 1994 1995 for(i=0;i<n;++i) 1996 { 1997 const btVector3 v=c.m_nodes[i]->m_v*c.m_masses[i]; 1998 c.m_lv += v; 1999 c.m_av += cross(c.m_nodes[i]->m_x-c.m_com,v); 2000 } 2001 } 2002 c.m_lv=c.m_imass*c.m_lv*(1-c.m_ldamping); 2003 c.m_av=c.m_invwi*c.m_av*(1-c.m_adamping); 2004 c.m_vimpulses[0] = 2005 c.m_vimpulses[1] = btVector3(0,0,0); 2006 c.m_dimpulses[0] = 2007 c.m_dimpulses[1] = btVector3(0,0,0); 2008 c.m_nvimpulses = 0; 2009 c.m_ndimpulses = 0; 2010 /* Matching */ 2011 if(c.m_matching>0) 2012 { 2013 for(int j=0;j<c.m_nodes.size();++j) 2009 2014 { 2010 const btVector3 v=c.m_nodes[i]->m_v*c.m_masses[i];2011 c.m_lv += v;2012 c.m_av += cross(c.m_nodes[i]->m_x-c.m_com,v);2015 Node& n=*c.m_nodes[j]; 2016 const btVector3 x=c.m_framexform*c.m_framerefs[j]; 2017 n.m_x=Lerp(n.m_x,x,c.m_matching); 2013 2018 } 2014 2019 } 2015 c.m_lv=c.m_imass*c.m_lv*(1-c.m_ldamping); 2016 c.m_av=c.m_invwi*c.m_av*(1-c.m_adamping); 2017 c.m_vimpulses[0] = 2018 c.m_vimpulses[1] = btVector3(0,0,0); 2019 c.m_dimpulses[0] = 2020 c.m_dimpulses[1] = btVector3(0,0,0); 2021 c.m_nvimpulses = 0; 2022 c.m_ndimpulses = 0; 2023 /* Matching */ 2024 if(c.m_matching>0) 2025 { 2026 for(int j=0;j<c.m_nodes.size();++j) 2020 /* Dbvt */ 2021 if(c.m_collide) 2022 { 2023 btVector3 mi=c.m_nodes[0]->m_x; 2024 btVector3 mx=mi; 2025 for(int j=1;j<n;++j) 2027 2026 { 2028 Node& n=*c.m_nodes[j]; 2029 const btVector3 x=c.m_framexform*c.m_framerefs[j]; 2030 n.m_x=Lerp(n.m_x,x,c.m_matching); 2027 mi.setMin(c.m_nodes[j]->m_x); 2028 mx.setMax(c.m_nodes[j]->m_x); 2029 } 2030 const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(mi,mx); 2031 if(c.m_leaf) 2032 m_cdbvt.update(c.m_leaf,bounds,c.m_lv*m_sst.sdt*3,m_sst.radmrg); 2033 else 2034 c.m_leaf=m_cdbvt.insert(bounds,&c); 2035 } 2036 } 2037 } 2038 } 2039 2040 // 2041 void btSoftBody::cleanupClusters() 2042 { 2043 for(int i=0;i<m_joints.size();++i) 2044 { 2045 m_joints[i]->Terminate(m_sst.sdt); 2046 if(m_joints[i]->m_delete) 2047 { 2048 btAlignedFree(m_joints[i]); 2049 m_joints.remove(m_joints[i--]); 2050 } 2051 } 2052 } 2053 2054 // 2055 void btSoftBody::prepareClusters(int iterations) 2056 { 2057 for(int i=0;i<m_joints.size();++i) 2058 { 2059 m_joints[i]->Prepare(m_sst.sdt,iterations); 2060 } 2061 } 2062 2063 2064 // 2065 void btSoftBody::solveClusters(btScalar sor) 2066 { 2067 for(int i=0,ni=m_joints.size();i<ni;++i) 2068 { 2069 m_joints[i]->Solve(m_sst.sdt,sor); 2070 } 2071 } 2072 2073 // 2074 void btSoftBody::applyClusters(bool drift) 2075 { 2076 BT_PROFILE("ApplyClusters"); 2077 const btScalar f0=m_sst.sdt; 2078 const btScalar f1=f0/2; 2079 btAlignedObjectArray<btVector3> deltas; 2080 btAlignedObjectArray<btScalar> weights; 2081 deltas.resize(m_nodes.size(),btVector3(0,0,0)); 2082 weights.resize(m_nodes.size(),0); 2083 int i; 2084 2085 if(drift) 2086 { 2087 for(i=0;i<m_clusters.size();++i) 2088 { 2089 Cluster& c=*m_clusters[i]; 2090 if(c.m_ndimpulses) 2091 { 2092 c.m_dimpulses[0]/=(btScalar)c.m_ndimpulses; 2093 c.m_dimpulses[1]/=(btScalar)c.m_ndimpulses; 2094 } 2095 } 2096 } 2097 for(i=0;i<m_clusters.size();++i) 2098 { 2099 Cluster& c=*m_clusters[i]; 2100 if(0<(drift?c.m_ndimpulses:c.m_nvimpulses)) 2101 { 2102 const btVector3 v=(drift?c.m_dimpulses[0]:c.m_vimpulses[0])*m_sst.sdt; 2103 const btVector3 w=(drift?c.m_dimpulses[1]:c.m_vimpulses[1])*m_sst.sdt; 2104 for(int j=0;j<c.m_nodes.size();++j) 2105 { 2106 const int idx=int(c.m_nodes[j]-&m_nodes[0]); 2107 const btVector3& x=c.m_nodes[j]->m_x; 2108 const btScalar q=c.m_masses[j]; 2109 deltas[idx] += (v+cross(w,x-c.m_com))*q; 2110 weights[idx] += q; 2111 } 2112 } 2113 } 2114 for(i=0;i<deltas.size();++i) 2115 { 2116 if(weights[i]>0) m_nodes[i].m_x+=deltas[i]/weights[i]; 2117 } 2118 } 2119 2120 // 2121 void btSoftBody::dampClusters() 2122 { 2123 int i; 2124 2125 for(i=0;i<m_clusters.size();++i) 2126 { 2127 Cluster& c=*m_clusters[i]; 2128 if(c.m_ndamping>0) 2129 { 2130 for(int j=0;j<c.m_nodes.size();++j) 2131 { 2132 Node& n=*c.m_nodes[j]; 2133 if(n.m_im>0) 2134 { 2135 const btVector3 vx=c.m_lv+cross(c.m_av,c.m_nodes[j]->m_q-c.m_com); 2136 n.m_v += c.m_ndamping*(vx-n.m_v); 2031 2137 } 2032 2138 } 2033 /* Dbvt */2034 if(c.m_collide)2035 {2036 btVector3 mi=c.m_nodes[0]->m_x;2037 btVector3 mx=mi;2038 for(int j=1;j<n;++j)2039 {2040 mi.setMin(c.m_nodes[j]->m_x);2041 mx.setMax(c.m_nodes[j]->m_x);2042 }2043 const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(mi,mx);2044 if(c.m_leaf)2045 m_cdbvt.update(c.m_leaf,bounds,c.m_lv*m_sst.sdt*3,m_sst.radmrg);2046 else2047 c.m_leaf=m_cdbvt.insert(bounds,&c);2048 }2049 }2050 }2051 }2052 2053 //2054 void btSoftBody::cleanupClusters()2055 {2056 for(int i=0;i<m_joints.size();++i)2057 {2058 m_joints[i]->Terminate(m_sst.sdt);2059 if(m_joints[i]->m_delete)2060 {2061 btAlignedFree(m_joints[i]);2062 m_joints.remove(m_joints[i--]);2063 }2064 }2065 }2066 2067 //2068 void btSoftBody::prepareClusters(int iterations)2069 {2070 for(int i=0;i<m_joints.size();++i)2071 {2072 m_joints[i]->Prepare(m_sst.sdt,iterations);2073 }2074 }2075 2076 2077 //2078 void btSoftBody::solveClusters(btScalar sor)2079 {2080 for(int i=0,ni=m_joints.size();i<ni;++i)2081 {2082 m_joints[i]->Solve(m_sst.sdt,sor);2083 }2084 }2085 2086 //2087 void btSoftBody::applyClusters(bool drift)2088 {2089 BT_PROFILE("ApplyClusters");2090 const btScalar f0=m_sst.sdt;2091 const btScalar f1=f0/2;2092 btAlignedObjectArray<btVector3> deltas;2093 btAlignedObjectArray<btScalar> weights;2094 deltas.resize(m_nodes.size(),btVector3(0,0,0));2095 weights.resize(m_nodes.size(),0);2096 int i;2097 2098 if(drift)2099 {2100 for(i=0;i<m_clusters.size();++i)2101 {2102 Cluster& c=*m_clusters[i];2103 if(c.m_ndimpulses)2104 {2105 c.m_dimpulses[0]/=(btScalar)c.m_ndimpulses;2106 c.m_dimpulses[1]/=(btScalar)c.m_ndimpulses;2107 }2108 }2109 }2110 for(i=0;i<m_clusters.size();++i)2111 {2112 Cluster& c=*m_clusters[i];2113 if(0<(drift?c.m_ndimpulses:c.m_nvimpulses))2114 {2115 const btVector3 v=(drift?c.m_dimpulses[0]:c.m_vimpulses[0])*m_sst.sdt;2116 const btVector3 w=(drift?c.m_dimpulses[1]:c.m_vimpulses[1])*m_sst.sdt;2117 for(int j=0;j<c.m_nodes.size();++j)2118 {2119 const int idx=int(c.m_nodes[j]-&m_nodes[0]);2120 const btVector3& x=c.m_nodes[j]->m_x;2121 const btScalar q=c.m_masses[j];2122 deltas[idx] += (v+cross(w,x-c.m_com))*q;2123 weights[idx] += q;2124 }2125 }2126 }2127 for(i=0;i<deltas.size();++i)2128 {2129 if(weights[i]>0) m_nodes[i].m_x+=deltas[i]/weights[i];2130 }2131 }2132 2133 //2134 void btSoftBody::dampClusters()2135 {2136 int i;2137 2138 for(i=0;i<m_clusters.size();++i)2139 {2140 Cluster& c=*m_clusters[i];2141 if(c.m_ndamping>0)2142 {2143 for(int j=0;j<c.m_nodes.size();++j)2144 {2145 Node& n=*c.m_nodes[j];2146 if(n.m_im>0)2147 {2148 const btVector3 vx=c.m_lv+cross(c.m_av,c.m_nodes[j]->m_q-c.m_com);2149 n.m_v += c.m_ndamping*(vx-n.m_v);2150 }2151 }2152 2139 } 2153 2140 } … … 2157 2144 void btSoftBody::Joint::Prepare(btScalar dt,int) 2158 2145 { 2159 2160 2146 m_bodies[0].activate(); 2147 m_bodies[1].activate(); 2161 2148 } 2162 2149 … … 2164 2151 void btSoftBody::LJoint::Prepare(btScalar dt,int iterations) 2165 2152 { 2166 static const btScalar maxdrift=4; 2167 Joint::Prepare(dt,iterations); 2168 m_rpos[0] = m_bodies[0].xform()*m_refs[0]; 2169 m_rpos[1] = m_bodies[1].xform()*m_refs[1]; 2170 m_drift = Clamp(m_rpos[0]-m_rpos[1],maxdrift)*m_erp/dt; 2171 m_rpos[0] -= m_bodies[0].xform().getOrigin(); 2172 m_rpos[1] -= m_bodies[1].xform().getOrigin(); 2173 m_massmatrix = ImpulseMatrix( m_bodies[0].invMass(),m_bodies[0].invWorldInertia(),m_rpos[0], 2174 m_bodies[1].invMass(),m_bodies[1].invWorldInertia(),m_rpos[1]); 2153 static const btScalar maxdrift=4; 2154 Joint::Prepare(dt,iterations); 2155 m_rpos[0] = m_bodies[0].xform()*m_refs[0]; 2156 m_rpos[1] = m_bodies[1].xform()*m_refs[1]; 2157 m_drift = Clamp(m_rpos[0]-m_rpos[1],maxdrift)*m_erp/dt; 2158 m_rpos[0] -= m_bodies[0].xform().getOrigin(); 2159 m_rpos[1] -= m_bodies[1].xform().getOrigin(); 2160 m_massmatrix = ImpulseMatrix( m_bodies[0].invMass(),m_bodies[0].invWorldInertia(),m_rpos[0], 2161 m_bodies[1].invMass(),m_bodies[1].invWorldInertia(),m_rpos[1]); 2162 if(m_split>0) 2163 { 2164 m_sdrift = m_massmatrix*(m_drift*m_split); 2165 m_drift *= 1-m_split; 2166 } 2167 m_drift /=(btScalar)iterations; 2168 } 2169 2170 // 2171 void btSoftBody::LJoint::Solve(btScalar dt,btScalar sor) 2172 { 2173 const btVector3 va=m_bodies[0].velocity(m_rpos[0]); 2174 const btVector3 vb=m_bodies[1].velocity(m_rpos[1]); 2175 const btVector3 vr=va-vb; 2176 btSoftBody::Impulse impulse; 2177 impulse.m_asVelocity = 1; 2178 impulse.m_velocity = m_massmatrix*(m_drift+vr*m_cfm)*sor; 2179 m_bodies[0].applyImpulse(-impulse,m_rpos[0]); 2180 m_bodies[1].applyImpulse( impulse,m_rpos[1]); 2181 } 2182 2183 // 2184 void btSoftBody::LJoint::Terminate(btScalar dt) 2185 { 2186 if(m_split>0) 2187 { 2188 m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]); 2189 m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]); 2190 } 2191 } 2192 2193 // 2194 void btSoftBody::AJoint::Prepare(btScalar dt,int iterations) 2195 { 2196 static const btScalar maxdrift=SIMD_PI/16; 2197 m_icontrol->Prepare(this); 2198 Joint::Prepare(dt,iterations); 2199 m_axis[0] = m_bodies[0].xform().getBasis()*m_refs[0]; 2200 m_axis[1] = m_bodies[1].xform().getBasis()*m_refs[1]; 2201 m_drift = NormalizeAny(cross(m_axis[1],m_axis[0])); 2202 m_drift *= btMin(maxdrift,btAcos(Clamp<btScalar>(dot(m_axis[0],m_axis[1]),-1,+1))); 2203 m_drift *= m_erp/dt; 2204 m_massmatrix= AngularImpulseMatrix(m_bodies[0].invWorldInertia(),m_bodies[1].invWorldInertia()); 2205 if(m_split>0) 2206 { 2207 m_sdrift = m_massmatrix*(m_drift*m_split); 2208 m_drift *= 1-m_split; 2209 } 2210 m_drift /=(btScalar)iterations; 2211 } 2212 2213 // 2214 void btSoftBody::AJoint::Solve(btScalar dt,btScalar sor) 2215 { 2216 const btVector3 va=m_bodies[0].angularVelocity(); 2217 const btVector3 vb=m_bodies[1].angularVelocity(); 2218 const btVector3 vr=va-vb; 2219 const btScalar sp=dot(vr,m_axis[0]); 2220 const btVector3 vc=vr-m_axis[0]*m_icontrol->Speed(this,sp); 2221 btSoftBody::Impulse impulse; 2222 impulse.m_asVelocity = 1; 2223 impulse.m_velocity = m_massmatrix*(m_drift+vc*m_cfm)*sor; 2224 m_bodies[0].applyAImpulse(-impulse); 2225 m_bodies[1].applyAImpulse( impulse); 2226 } 2227 2228 // 2229 void btSoftBody::AJoint::Terminate(btScalar dt) 2230 { 2231 if(m_split>0) 2232 { 2233 m_bodies[0].applyDAImpulse(-m_sdrift); 2234 m_bodies[1].applyDAImpulse( m_sdrift); 2235 } 2236 } 2237 2238 // 2239 void btSoftBody::CJoint::Prepare(btScalar dt,int iterations) 2240 { 2241 Joint::Prepare(dt,iterations); 2242 const bool dodrift=(m_life==0); 2243 m_delete=(++m_life)>m_maxlife; 2244 if(dodrift) 2245 { 2246 m_drift=m_drift*m_erp/dt; 2175 2247 if(m_split>0) 2176 {2248 { 2177 2249 m_sdrift = m_massmatrix*(m_drift*m_split); 2178 2250 m_drift *= 1-m_split; 2179 } 2180 m_drift /=(btScalar)iterations; 2181 } 2182 2183 // 2184 void btSoftBody::LJoint::Solve(btScalar dt,btScalar sor) 2185 { 2186 const btVector3 va=m_bodies[0].velocity(m_rpos[0]); 2187 const btVector3 vb=m_bodies[1].velocity(m_rpos[1]); 2188 const btVector3 vr=va-vb; 2189 btSoftBody::Impulse impulse; 2190 impulse.m_asVelocity = 1; 2191 impulse.m_velocity = m_massmatrix*(m_drift+vr*m_cfm)*sor; 2192 m_bodies[0].applyImpulse(-impulse,m_rpos[0]); 2193 m_bodies[1].applyImpulse( impulse,m_rpos[1]); 2194 } 2195 2196 // 2197 void btSoftBody::LJoint::Terminate(btScalar dt) 2198 { 2199 if(m_split>0) 2200 { 2201 m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]); 2202 m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]); 2203 } 2204 } 2205 2206 // 2207 void btSoftBody::AJoint::Prepare(btScalar dt,int iterations) 2208 { 2209 static const btScalar maxdrift=SIMD_PI/16; 2210 m_icontrol->Prepare(this); 2211 Joint::Prepare(dt,iterations); 2212 m_axis[0] = m_bodies[0].xform().getBasis()*m_refs[0]; 2213 m_axis[1] = m_bodies[1].xform().getBasis()*m_refs[1]; 2214 m_drift = NormalizeAny(cross(m_axis[1],m_axis[0])); 2215 m_drift *= btMin(maxdrift,btAcos(Clamp<btScalar>(dot(m_axis[0],m_axis[1]),-1,+1))); 2216 m_drift *= m_erp/dt; 2217 m_massmatrix= AngularImpulseMatrix(m_bodies[0].invWorldInertia(),m_bodies[1].invWorldInertia()); 2218 if(m_split>0) 2219 { 2220 m_sdrift = m_massmatrix*(m_drift*m_split); 2221 m_drift *= 1-m_split; 2222 } 2223 m_drift /=(btScalar)iterations; 2224 } 2225 2226 // 2227 void btSoftBody::AJoint::Solve(btScalar dt,btScalar sor) 2228 { 2229 const btVector3 va=m_bodies[0].angularVelocity(); 2230 const btVector3 vb=m_bodies[1].angularVelocity(); 2231 const btVector3 vr=va-vb; 2232 const btScalar sp=dot(vr,m_axis[0]); 2233 const btVector3 vc=vr-m_axis[0]*m_icontrol->Speed(this,sp); 2234 btSoftBody::Impulse impulse; 2235 impulse.m_asVelocity = 1; 2236 impulse.m_velocity = m_massmatrix*(m_drift+vc*m_cfm)*sor; 2237 m_bodies[0].applyAImpulse(-impulse); 2238 m_bodies[1].applyAImpulse( impulse); 2239 } 2240 2241 // 2242 void btSoftBody::AJoint::Terminate(btScalar dt) 2243 { 2244 if(m_split>0) 2245 { 2246 m_bodies[0].applyDAImpulse(-m_sdrift); 2247 m_bodies[1].applyDAImpulse( m_sdrift); 2248 } 2249 } 2250 2251 // 2252 void btSoftBody::CJoint::Prepare(btScalar dt,int iterations) 2253 { 2254 Joint::Prepare(dt,iterations); 2255 const bool dodrift=(m_life==0); 2256 m_delete=(++m_life)>m_maxlife; 2257 if(dodrift) 2258 { 2259 m_drift=m_drift*m_erp/dt; 2260 if(m_split>0) 2261 { 2262 m_sdrift = m_massmatrix*(m_drift*m_split); 2263 m_drift *= 1-m_split; 2264 } 2265 m_drift/=(btScalar)iterations; 2251 } 2252 m_drift/=(btScalar)iterations; 2266 2253 } 2267 2254 else 2268 2255 { 2269 2256 m_drift=m_sdrift=btVector3(0,0,0); 2270 2257 } 2271 2258 } … … 2274 2261 void btSoftBody::CJoint::Solve(btScalar dt,btScalar sor) 2275 2262 { 2276 2277 2278 2279 2280 2281 2282 2283 2284 { 2285 2286 2287 2288 } 2289 2290 2291 2263 const btVector3 va=m_bodies[0].velocity(m_rpos[0]); 2264 const btVector3 vb=m_bodies[1].velocity(m_rpos[1]); 2265 const btVector3 vrel=va-vb; 2266 const btScalar rvac=dot(vrel,m_normal); 2267 btSoftBody::Impulse impulse; 2268 impulse.m_asVelocity = 1; 2269 impulse.m_velocity = m_drift; 2270 if(rvac<0) 2271 { 2272 const btVector3 iv=m_normal*rvac; 2273 const btVector3 fv=vrel-iv; 2274 impulse.m_velocity += iv+fv*m_friction; 2275 } 2276 impulse.m_velocity=m_massmatrix*impulse.m_velocity*sor; 2277 m_bodies[0].applyImpulse(-impulse,m_rpos[0]); 2278 m_bodies[1].applyImpulse( impulse,m_rpos[1]); 2292 2279 } 2293 2280 … … 2295 2282 void btSoftBody::CJoint::Terminate(btScalar dt) 2296 2283 { 2297 2298 { 2299 2300 2284 if(m_split>0) 2285 { 2286 m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]); 2287 m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]); 2301 2288 } 2302 2289 } … … 2316 2303 const bool as_volume=kVC>0; 2317 2304 const bool as_aero= as_lift || 2318 as_drag ;2305 as_drag ; 2319 2306 const bool as_vaero= as_aero && 2320 (m_cfg.aeromodel<btSoftBody::eAeroModel::F_TwoSided);2307 (m_cfg.aeromodel<btSoftBody::eAeroModel::F_TwoSided); 2321 2308 const bool as_faero= as_aero && 2322 (m_cfg.aeromodel>=btSoftBody::eAeroModel::F_TwoSided);2309 (m_cfg.aeromodel>=btSoftBody::eAeroModel::F_TwoSided); 2323 2310 const bool use_medium= as_aero; 2324 2311 const bool use_volume= as_pressure || 2325 as_volume ;2312 as_volume ; 2326 2313 btScalar volume=0; 2327 2314 btScalar ivolumetp=0; … … 2471 2458 void btSoftBody::PSolve_SContacts(btSoftBody* psb,btScalar,btScalar ti) 2472 2459 { 2473 2474 { 2475 2476 2477 2478 2479 2480 f.m_n[1]->m_x,2481 f.m_n[2]->m_x,2482 c.m_weights);2483 2484 f.m_n[1]->m_q,2485 f.m_n[2]->m_q,2486 c.m_weights);2487 2488 2489 2490 { 2491 2492 2493 } 2494 2495 2496 2497 2498 2460 for(int i=0,ni=psb->m_scontacts.size();i<ni;++i) 2461 { 2462 const SContact& c=psb->m_scontacts[i]; 2463 const btVector3& nr=c.m_normal; 2464 Node& n=*c.m_node; 2465 Face& f=*c.m_face; 2466 const btVector3 p=BaryEval( f.m_n[0]->m_x, 2467 f.m_n[1]->m_x, 2468 f.m_n[2]->m_x, 2469 c.m_weights); 2470 const btVector3 q=BaryEval( f.m_n[0]->m_q, 2471 f.m_n[1]->m_q, 2472 f.m_n[2]->m_q, 2473 c.m_weights); 2474 const btVector3 vr=(n.m_x-n.m_q)-(p-q); 2475 btVector3 corr(0,0,0); 2476 if(dot(vr,nr)<0) 2477 { 2478 const btScalar j=c.m_margin-(dot(nr,n.m_x)-dot(nr,p)); 2479 corr+=c.m_normal*j; 2480 } 2481 corr -= ProjectOnPlane(vr,nr)*c.m_friction; 2482 n.m_x += corr*c.m_cfm[0]; 2483 f.m_n[0]->m_x -= corr*(c.m_cfm[1]*c.m_weights.x()); 2484 f.m_n[1]->m_x -= corr*(c.m_cfm[1]*c.m_weights.y()); 2485 f.m_n[2]->m_x -= corr*(c.m_cfm[1]*c.m_weights.z()); 2499 2486 } 2500 2487 } … … 2523 2510 void btSoftBody::VSolve_Links(btSoftBody* psb,btScalar kst) 2524 2511 { 2525 2512 for(int i=0,ni=psb->m_links.size();i<ni;++i) 2526 2513 { 2527 2528 2529 2530 2531 2514 Link& l=psb->m_links[i]; 2515 Node** n=l.m_n; 2516 const btScalar j=-dot(l.m_c3,n[0]->m_v-n[1]->m_v)*l.m_c2*kst; 2517 n[0]->m_v+= l.m_c3*(j*n[0]->m_im); 2518 n[1]->m_v-= l.m_c3*(j*n[1]->m_im); 2532 2519 } 2533 2520 } … … 2536 2523 btSoftBody::psolver_t btSoftBody::getSolver(ePSolver::_ solver) 2537 2524 { 2538 2525 switch(solver) 2539 2526 { 2540 2527 case ePSolver::Anchors: return(&btSoftBody::PSolve_Anchors); … … 2543 2530 case ePSolver::SContacts: return(&btSoftBody::PSolve_SContacts); 2544 2531 } 2545 2532 return(0); 2546 2533 } 2547 2534 … … 2549 2536 btSoftBody::vsolver_t btSoftBody::getSolver(eVSolver::_ solver) 2550 2537 { 2551 2538 switch(solver) 2552 2539 { 2553 2540 case eVSolver::Linear: return(&btSoftBody::VSolve_Links); 2554 2541 } 2555 2542 return(0); 2556 2543 } 2557 2544 … … 2559 2546 void btSoftBody::defaultCollisionHandler(btCollisionObject* pco) 2560 2547 { 2561 2548 switch(m_cfg.collisions&fCollision::RVSmask) 2562 2549 { 2563 2550 case fCollision::SDF_RS: 2564 2551 { 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 mins,2576 maxs);2577 2578 2579 2580 2581 2582 2583 2584 } 2585 2552 btSoftColliders::CollideSDF_RS docollide; 2553 btRigidBody* prb=btRigidBody::upcast(pco); 2554 const btTransform wtr=prb->getInterpolationWorldTransform(); 2555 const btTransform ctr=prb->getWorldTransform(); 2556 const btScalar timemargin=(wtr.getOrigin()-ctr.getOrigin()).length(); 2557 const btScalar basemargin=getCollisionShape()->getMargin(); 2558 btVector3 mins; 2559 btVector3 maxs; 2560 ATTRIBUTE_ALIGNED16(btDbvtVolume) volume; 2561 pco->getCollisionShape()->getAabb( pco->getInterpolationWorldTransform(), 2562 mins, 2563 maxs); 2564 volume=btDbvtVolume::FromMM(mins,maxs); 2565 volume.Expand(btVector3(basemargin,basemargin,basemargin)); 2566 docollide.psb = this; 2567 docollide.prb = prb; 2568 docollide.dynmargin = basemargin+timemargin; 2569 docollide.stamargin = basemargin; 2570 btDbvt::collideTV(m_ndbvt.m_root,volume,docollide); 2571 } 2572 break; 2586 2573 case fCollision::CL_RS: 2587 2574 { 2588 2589 2590 } 2591 2575 btSoftColliders::CollideCL_RS collider; 2576 collider.Process(this,btRigidBody::upcast(pco)); 2577 } 2578 break; 2592 2579 } 2593 2580 } … … 2596 2583 void btSoftBody::defaultCollisionHandler(btSoftBody* psb) 2597 2584 { 2598 2599 2585 const int cf=m_cfg.collisions&psb->m_cfg.collisions; 2586 switch(cf&fCollision::SVSmask) 2600 2587 { 2601 2588 case fCollision::CL_SS: 2602 2589 { 2603 2604 2605 } 2606 2590 btSoftColliders::CollideCL_SS docollide; 2591 docollide.Process(this,psb); 2592 } 2593 break; 2607 2594 case fCollision::VF_SS: 2608 2595 { 2609 2610 2611 2612 psb->getCollisionShape()->getMargin();2613 2614 2615 2616 2617 docollide.psb[1]->m_fdbvt.m_root,2618 docollide);2619 2620 2621 2622 2623 docollide.psb[1]->m_fdbvt.m_root,2624 docollide);2625 } 2626 2627 } 2628 } 2596 btSoftColliders::CollideVF_SS docollide; 2597 /* common */ 2598 docollide.mrg= getCollisionShape()->getMargin()+ 2599 psb->getCollisionShape()->getMargin(); 2600 /* psb0 nodes vs psb1 faces */ 2601 docollide.psb[0]=this; 2602 docollide.psb[1]=psb; 2603 btDbvt::collideTT( docollide.psb[0]->m_ndbvt.m_root, 2604 docollide.psb[1]->m_fdbvt.m_root, 2605 docollide); 2606 /* psb1 nodes vs psb0 faces */ 2607 docollide.psb[0]=psb; 2608 docollide.psb[1]=this; 2609 btDbvt::collideTT( docollide.psb[0]->m_ndbvt.m_root, 2610 docollide.psb[1]->m_fdbvt.m_root, 2611 docollide); 2612 } 2613 break; 2614 } 2615 } -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBody.h
r1963 r1972 63 63 END 64 64 };}; 65 65 66 66 ///eVSolver : velocities solvers 67 67 struct eVSolver { enum _ { … … 69 69 END 70 70 };}; 71 71 72 72 ///ePSolver : positions solvers 73 73 struct ePSolver { enum _ { … … 78 78 END 79 79 };}; 80 80 81 81 ///eSolverPresets 82 82 struct eSolverPresets { enum _ { … … 86 86 END 87 87 };}; 88 88 89 89 ///eFeature 90 90 struct eFeature { enum _ { … … 95 95 END 96 96 };}; 97 97 98 98 typedef btAlignedObjectArray<eVSolver::_> tVSolverArray; 99 99 typedef btAlignedObjectArray<ePSolver::_> tPSolverArray; 100 100 101 101 // 102 102 // Flags 103 103 // 104 104 105 105 ///fCollision 106 106 struct fCollision { enum _ { … … 108 108 SDF_RS = 0x0001, ///SDF based rigid vs soft 109 109 CL_RS = 0x0002, ///Cluster vs convex rigid vs soft 110 110 111 111 SVSmask = 0x00f0, ///Rigid versus soft mask 112 112 VF_SS = 0x0010, ///Vertex vs face soft vs soft handling … … 116 116 END 117 117 };}; 118 118 119 119 ///fMaterial 120 120 struct fMaterial { enum _ { … … 124 124 END 125 125 };}; 126 126 127 127 // 128 128 // API Types 129 129 // 130 130 131 131 /* sRayCast */ 132 132 struct sRayCast … … 135 135 eFeature::_ feature; /// feature type 136 136 int index; /// feature index 137 btScalar fraction; /// time of impact fraction (rayorg+(rayto-rayfrom)*fraction)138 }; 139 137 btScalar time; /// time of impact (rayorg+raydir*time) 138 }; 139 140 140 /* ImplicitFn */ 141 141 struct ImplicitFn … … 143 143 virtual btScalar Eval(const btVector3& x)=0; 144 144 }; 145 145 146 146 // 147 147 // Internal types … … 181 181 int m_flags; // Flags 182 182 }; 183 183 184 184 /* Feature */ 185 185 struct Feature : Element … … 297 297 btScalar m_matching; 298 298 bool m_collide; 299 Cluster() : m_leaf(0),m_ndamping(0),m_ldamping(0),m_adamping(0),m_matching(0) {}299 Cluster() : m_leaf(0),m_ndamping(0),m_ldamping(0),m_adamping(0),m_matching(0) {} 300 300 }; 301 301 /* Impulse */ … … 308 308 Impulse() : m_velocity(0,0,0),m_drift(0,0,0),m_asVelocity(0),m_asDrift(0) {} 309 309 Impulse operator -() const 310 {310 { 311 311 Impulse i=*this; 312 312 i.m_velocity=-i.m_velocity; 313 313 i.m_drift=-i.m_drift; 314 314 return(i); 315 }315 } 316 316 Impulse operator*(btScalar x) const 317 {317 { 318 318 Impulse i=*this; 319 319 i.m_velocity*=x; 320 320 i.m_drift*=x; 321 321 return(i); 322 }322 } 323 323 }; 324 324 /* Body */ … … 327 327 Cluster* m_soft; 328 328 btRigidBody* m_rigid; 329 Body() : m_soft(0),m_rigid(0) {}330 Body(Cluster* p) : m_soft(p),m_rigid(0) {}331 Body(btRigidBody* p) : m_soft(0),m_rigid(p) {}329 Body() : m_soft(0),m_rigid(0) {} 330 Body(Cluster* p) : m_soft(p),m_rigid(0) {} 331 Body(btRigidBody* p) : m_soft(0),m_rigid(p) {} 332 332 void activate() const 333 {333 { 334 334 if(m_rigid) m_rigid->activate(); 335 }335 } 336 336 const btMatrix3x3& invWorldInertia() const 337 {337 { 338 338 static const btMatrix3x3 iwi(0,0,0,0,0,0,0,0,0); 339 339 if(m_rigid) return(m_rigid->getInvInertiaTensorWorld()); 340 340 if(m_soft) return(m_soft->m_invwi); 341 341 return(iwi); 342 }342 } 343 343 btScalar invMass() const 344 {344 { 345 345 if(m_rigid) return(m_rigid->getInvMass()); 346 346 if(m_soft) return(m_soft->m_imass); 347 347 return(0); 348 }348 } 349 349 const btTransform& xform() const 350 {350 { 351 351 static const btTransform identity=btTransform::getIdentity(); 352 352 if(m_rigid) return(m_rigid->getInterpolationWorldTransform()); 353 353 if(m_soft) return(m_soft->m_framexform); 354 354 return(identity); 355 }355 } 356 356 btVector3 linearVelocity() const 357 {357 { 358 358 if(m_rigid) return(m_rigid->getLinearVelocity()); 359 359 if(m_soft) return(m_soft->m_lv); 360 360 return(btVector3(0,0,0)); 361 }361 } 362 362 btVector3 angularVelocity(const btVector3& rpos) const 363 {363 { 364 364 if(m_rigid) return(cross(m_rigid->getAngularVelocity(),rpos)); 365 365 if(m_soft) return(cross(m_soft->m_av,rpos)); 366 366 return(btVector3(0,0,0)); 367 }367 } 368 368 btVector3 angularVelocity() const 369 {369 { 370 370 if(m_rigid) return(m_rigid->getAngularVelocity()); 371 371 if(m_soft) return(m_soft->m_av); 372 372 return(btVector3(0,0,0)); 373 }373 } 374 374 btVector3 velocity(const btVector3& rpos) const 375 {375 { 376 376 return(linearVelocity()+angularVelocity(rpos)); 377 }377 } 378 378 void applyVImpulse(const btVector3& impulse,const btVector3& rpos) const 379 {379 { 380 380 if(m_rigid) m_rigid->applyImpulse(impulse,rpos); 381 381 if(m_soft) btSoftBody::clusterVImpulse(m_soft,rpos,impulse); 382 }382 } 383 383 void applyDImpulse(const btVector3& impulse,const btVector3& rpos) const 384 {384 { 385 385 if(m_rigid) m_rigid->applyImpulse(impulse,rpos); 386 386 if(m_soft) btSoftBody::clusterDImpulse(m_soft,rpos,impulse); 387 }387 } 388 388 void applyImpulse(const Impulse& impulse,const btVector3& rpos) const 389 {389 { 390 390 if(impulse.m_asVelocity) applyVImpulse(impulse.m_velocity,rpos); 391 391 if(impulse.m_asDrift) applyDImpulse(impulse.m_drift,rpos); 392 }392 } 393 393 void applyVAImpulse(const btVector3& impulse) const 394 {394 { 395 395 if(m_rigid) m_rigid->applyTorqueImpulse(impulse); 396 396 if(m_soft) btSoftBody::clusterVAImpulse(m_soft,impulse); 397 }397 } 398 398 void applyDAImpulse(const btVector3& impulse) const 399 {399 { 400 400 if(m_rigid) m_rigid->applyTorqueImpulse(impulse); 401 401 if(m_soft) btSoftBody::clusterDAImpulse(m_soft,impulse); 402 }402 } 403 403 void applyAImpulse(const Impulse& impulse) const 404 {404 { 405 405 if(impulse.m_asVelocity) applyVAImpulse(impulse.m_velocity); 406 406 if(impulse.m_asDrift) applyDAImpulse(impulse.m_drift); 407 }407 } 408 408 void applyDCImpulse(const btVector3& impulse) const 409 {409 { 410 410 if(m_rigid) m_rigid->applyCentralImpulse(impulse); 411 411 if(m_soft) btSoftBody::clusterDCImpulse(m_soft,impulse); 412 }412 } 413 413 }; 414 414 /* Joint */ … … 421 421 };}; 422 422 struct Specs 423 {424 Specs() : erp(1),cfm(1),split(1) {}423 { 424 Specs() : erp(1),cfm(1),split(1) {} 425 425 btScalar erp; 426 426 btScalar cfm; 427 427 btScalar split; 428 };428 }; 429 429 Body m_bodies[2]; 430 430 btVector3 m_refs[2]; … … 437 437 bool m_delete; 438 438 virtual ~Joint() {} 439 Joint() : m_delete(false) {}439 Joint() : m_delete(false) {} 440 440 virtual void Prepare(btScalar dt,int iterations); 441 441 virtual void Solve(btScalar dt,btScalar sor)=0; … … 447 447 { 448 448 struct Specs : Joint::Specs 449 {449 { 450 450 btVector3 position; 451 };451 }; 452 452 btVector3 m_rpos[2]; 453 453 void Prepare(btScalar dt,int iterations); … … 460 460 { 461 461 struct IControl 462 {462 { 463 463 virtual void Prepare(AJoint*) {} 464 464 virtual btScalar Speed(AJoint*,btScalar current) { return(current); } 465 465 static IControl* Default() { static IControl def;return(&def); } 466 };466 }; 467 467 struct Specs : Joint::Specs 468 {469 Specs() : icontrol(IControl::Default()) {}468 { 469 Specs() : icontrol(IControl::Default()) {} 470 470 btVector3 axis; 471 471 IControl* icontrol; 472 };472 }; 473 473 btVector3 m_axis[2]; 474 474 IControl* m_icontrol; … … 533 533 btScalar updmrg; // Update margin 534 534 }; 535 /// RayFromToCaster takes a ray from, ray to (instead of direction!) 536 struct RayFromToCaster : btDbvt::ICollide 537 { 538 btVector3 m_rayFrom; 539 btVector3 m_rayTo; 540 btVector3 m_rayNormalizedDirection; 541 btScalar m_mint; 542 Face* m_face; 543 int m_tests; 544 RayFromToCaster(const btVector3& rayFrom,const btVector3& rayTo,btScalar mxt); 535 /* RayCaster */ 536 struct RayCaster : btDbvt::ICollide 537 { 538 btVector3 o; 539 btVector3 d; 540 btScalar mint; 541 Face* face; 542 int tests; 543 RayCaster(const btVector3& org,const btVector3& dir,btScalar mxt); 545 544 void Process(const btDbvtNode* leaf); 546 547 static inline btScalar rayFromToTriangle(const btVector3& rayFrom, 548 const btVector3& rayTo, 549 const btVector3& rayNormalizedDirection, 550 const btVector3& a, 551 const btVector3& b, 552 const btVector3& c, 553 btScalar maxt=SIMD_INFINITY); 554 }; 545 static inline btScalar rayTriangle(const btVector3& org, 546 const btVector3& dir, 547 const btVector3& a, 548 const btVector3& b, 549 const btVector3& c, 550 btScalar maxt=SIMD_INFINITY); 551 }; 555 552 556 553 // … … 598 595 btDbvt m_cdbvt; // Clusters tree 599 596 tClusterArray m_clusters; // Clusters 600 597 601 598 // 602 599 // Api 603 600 // 604 601 605 602 /* ctor */ 606 603 btSoftBody( btSoftBodyWorldInfo* worldInfo,int node_count, 607 const btVector3* x,608 const btScalar* m);604 const btVector3* x, 605 const btScalar* m); 609 606 /* dtor */ 610 607 virtual ~btSoftBody(); … … 626 623 int node1) const; 627 624 bool checkLink( const Node* node0, 628 const Node* node1) const;625 const Node* node1) const; 629 626 /* Check for existring face */ 630 627 bool checkFace( int node0, 631 int node1,632 int node2) const;628 int node1, 629 int node2) const; 633 630 /* Append material */ 634 631 Material* appendMaterial(); 635 632 /* Append note */ 636 633 void appendNote( const char* text, 637 const btVector3& o,638 const btVector4& c=btVector4(1,0,0,0),639 Node* n0=0,640 Node* n1=0,641 Node* n2=0,642 Node* n3=0);634 const btVector3& o, 635 const btVector4& c=btVector4(1,0,0,0), 636 Node* n0=0, 637 Node* n1=0, 638 Node* n2=0, 639 Node* n3=0); 643 640 void appendNote( const char* text, 644 const btVector3& o,645 Node* feature);641 const btVector3& o, 642 Node* feature); 646 643 void appendNote( const char* text, 647 const btVector3& o,648 Link* feature);644 const btVector3& o, 645 Link* feature); 649 646 void appendNote( const char* text, 650 const btVector3& o,651 Face* feature);647 const btVector3& o, 648 Face* feature); 652 649 /* Append node */ 653 650 void appendNode( const btVector3& x,btScalar m); … … 655 652 void appendLink(int model=-1,Material* mat=0); 656 653 void appendLink( int node0, 657 int node1,658 Material* mat=0,659 bool bcheckexist=false);654 int node1, 655 Material* mat=0, 656 bool bcheckexist=false); 660 657 void appendLink( Node* node0, 661 Node* node1,662 Material* mat=0,663 bool bcheckexist=false);658 Node* node1, 659 Material* mat=0, 660 bool bcheckexist=false); 664 661 /* Append face */ 665 662 void appendFace(int model=-1,Material* mat=0); 666 663 void appendFace( int node0, 667 int node1,668 int node2,669 Material* mat=0);664 int node1, 665 int node2, 666 Material* mat=0); 670 667 /* Append anchor */ 671 668 void appendAnchor( int node, 672 btRigidBody* body);669 btRigidBody* body); 673 670 /* Append linear joint */ 674 671 void appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1); … … 683 680 /* Add force (or gravity) to a node of the body */ 684 681 void addForce( const btVector3& force, 685 int node);682 int node); 686 683 /* Add velocity to the entire body */ 687 684 void addVelocity( const btVector3& velocity); … … 692 689 /* Add velocity to a node of the body */ 693 690 void addVelocity( const btVector3& velocity, 694 int node);691 int node); 695 692 /* Set mass */ 696 693 void setMass( int node, 697 btScalar mass);694 btScalar mass); 698 695 /* Get mass */ 699 696 btScalar getMass( int node) const; … … 702 699 /* Set total mass (weighted by previous masses) */ 703 700 void setTotalMass( btScalar mass, 704 bool fromfaces=false);701 bool fromfaces=false); 705 702 /* Set total density */ 706 703 void setTotalDensity(btScalar density); … … 715 712 /* Set current state as pose */ 716 713 void setPose( bool bvolume, 717 bool bframe);714 bool bframe); 718 715 /* Return the volume */ 719 716 btScalar getVolume() const; … … 735 732 /* Generate bending constraints based on distance in the adjency graph */ 736 733 int generateBendingConstraints( int distance, 737 Material* mat=0);734 Material* mat=0); 738 735 /* Randomize constraints to reduce solver bias */ 739 736 void randomizeConstraints(); … … 748 745 bool cutLink(int node0,int node1,btScalar position); 749 746 bool cutLink(const Node* node0,const Node* node1,btScalar position); 750 751 ///Ray casting using rayFrom and rayTo in worldspace, (not direction!)752 bool rayTest(const btVector3& rayFrom,753 const btVector3& rayTo,754 sRayCast& results);747 /* Ray casting */ 748 bool rayCast(const btVector3& org, 749 const btVector3& dir, 750 sRayCast& results, 751 btScalar maxtime=SIMD_INFINITY); 755 752 /* Solver presets */ 756 753 void setSolver(eSolverPresets::_ preset); … … 770 767 void defaultCollisionHandler(btCollisionObject* pco); 771 768 void defaultCollisionHandler(btSoftBody* psb); 772 769 773 770 // 774 771 // Cast 775 772 // 776 773 777 774 static const btSoftBody* upcast(const btCollisionObject* colObj) 778 775 { … … 802 799 void pointersToIndices(); 803 800 void indicesToPointers(const int* map=0); 804 805 int rayTest(const btVector3& rayFrom,const btVector3& rayTo, 806 btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const; 801 int rayCast(const btVector3& org,const btVector3& dir, 802 btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const; 807 803 void initializeFaceTree(); 808 804 btVector3 evaluateCom() const; … … 827 823 static psolver_t getSolver(ePSolver::_ solver); 828 824 static vsolver_t getSolver(eVSolver::_ solver); 829 825 830 826 }; 831 827 -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp
r1963 r1972 51 51 52 52 btSoftBodyTriangleCallback::btSoftBodyTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped): 53 m_dispatcher(dispatcher),54 m_dispatchInfoPtr(0)53 m_dispatcher(dispatcher), 54 m_dispatchInfoPtr(0) 55 55 { 56 56 m_softBody = (btSoftBody*) (isSwapped? body1:body0); 57 57 m_triBody = isSwapped? body0:body1; 58 59 // 60 // create the manifold from the dispatcher 'manifold pool' 61 // 62 // m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBody,m_triBody); 63 58 59 // 60 // create the manifold from the dispatcher 'manifold pool' 61 // 62 // m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBody,m_triBody); 63 64 clearCache(); 65 } 66 67 btSoftBodyTriangleCallback::~btSoftBodyTriangleCallback() 68 { 64 69 clearCache(); 65 } 66 67 btSoftBodyTriangleCallback::~btSoftBodyTriangleCallback() 68 { 69 clearCache(); 70 // m_dispatcher->releaseManifold( m_manifoldPtr ); 71 72 } 73 70 // m_dispatcher->releaseManifold( m_manifoldPtr ); 71 72 } 73 74 74 75 75 void btSoftBodyTriangleCallback::clearCache() … … 89 89 void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex) 90 90 { 91 //just for debugging purposes91 //just for debugging purposes 92 92 //printf("triangle %d",m_triangleCount++); 93 93 btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody); … … 95 95 ci.m_dispatcher1 = m_dispatcher; 96 96 97 ///debug drawing of the overlapping triangles97 ///debug drawing of the overlapping triangles 98 98 if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && m_dispatchInfoPtr->m_debugDraw->getDebugMode() > 0) 99 99 { … … 108 108 btHashKey<btTriIndex> triKey(triIndex.getUid()); 109 109 110 110 111 111 btTriIndex* shapeIndex = m_shapeCache[triKey]; 112 112 if (shapeIndex) … … 117 117 //copy over user pointers to temporary shape 118 118 tm->setUserPointer(ob->getRootCollisionShape()->getUserPointer()); 119 119 120 120 btCollisionShape* tmpShape = ob->getCollisionShape(); 121 121 ob->internalSetTemporaryCollisionShape( tm ); 122 122 123 123 124 124 btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_softBody,m_triBody,0);//m_manifoldPtr); 125 125 126 126 colAlgo->processCollision(m_softBody,m_triBody,*m_dispatchInfoPtr,m_resultOut); 127 127 colAlgo->~btCollisionAlgorithm(); … … 134 134 135 135 //btCollisionObject* colObj = static_cast<btCollisionObject*>(m_convexProxy->m_clientObject); 136 137 138 { 139 136 137 // if (m_softBody->getCollisionShape()->getShapeType()== 138 { 139 // btVector3 other; 140 140 btVector3 normal = (triangle[1]-triangle[0]).cross(triangle[2]-triangle[0]); 141 141 normal.normalize(); 142 142 normal*= BT_SOFTBODY_TRIANGLE_EXTRUSION; 143 144 143 // other=(triangle[0]+triangle[1]+triangle[2])*0.333333f; 144 // other+=normal*22.f; 145 145 btVector3 pts[6] = {triangle[0]+normal, 146 146 triangle[1]+normal, 147 148 149 150 147 triangle[2]+normal, 148 triangle[0]-normal, 149 triangle[1]-normal, 150 triangle[2]-normal}; 151 151 152 152 btConvexHullShape* tm = new btConvexHullShape(&pts[0].getX(),6); 153 153 154 154 155 156 155 // btBU_Simplex1to4 tm(triangle[0],triangle[1],triangle[2],other); 156 157 157 //btTriangleShape tm(triangle[0],triangle[1],triangle[2]); 158 159 158 // tm.setMargin(m_collisionMarginTriangle); 159 160 160 //copy over user pointers to temporary shape 161 161 tm->setUserPointer(ob->getRootCollisionShape()->getUserPointer()); 162 162 163 163 btCollisionShape* tmpShape = ob->getCollisionShape(); 164 164 ob->internalSetTemporaryCollisionShape( tm ); 165 165 166 166 167 167 btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_softBody,m_triBody,0);//m_manifoldPtr); … … 170 170 171 171 //m_resultOut->setShapeIdentifiers(-1,-1,partId,triangleIndex); 172 173 172 // cvxcvxalgo.setShapeIdentifiers(-1,-1,partId,triangleIndex); 173 // cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut); 174 174 colAlgo->processCollision(m_softBody,m_triBody,*m_dispatchInfoPtr,m_resultOut); 175 175 colAlgo->~btCollisionAlgorithm(); 176 176 ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo); 177 178 177 178 179 179 ob->internalSetTemporaryCollisionShape( tmpShape ); 180 180 triIndex.m_childShape = tm; … … 183 183 } 184 184 185 185 186 186 187 187 } … … 195 195 m_resultOut = resultOut; 196 196 197 197 198 198 btVector3 aabbWorldSpaceMin,aabbWorldSpaceMax; 199 199 m_softBody->getAabb(aabbWorldSpaceMin,aabbWorldSpaceMax); … … 218 218 void btSoftBodyConcaveCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) 219 219 { 220 221 220 221 222 222 btCollisionObject* convexBody = m_isSwapped ? body1 : body0; 223 223 btCollisionObject* triBody = m_isSwapped ? body0 : body1; … … 229 229 btCollisionObject* triOb = triBody; 230 230 btConcaveShape* concaveShape = static_cast<btConcaveShape*>( triOb->getCollisionShape()); 231 232 231 232 // if (convexBody->getCollisionShape()->isConvex()) 233 233 { 234 234 btScalar collisionMarginTriangle = concaveShape->getMargin(); 235 236 235 236 // resultOut->setPersistentManifold(m_btSoftBodyTriangleCallback.m_manifoldPtr); 237 237 m_btSoftBodyTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,resultOut); 238 238 … … 240 240 //m_dispatcher->clearManifold(m_btSoftBodyTriangleCallback.m_manifoldPtr); 241 241 242 242 // m_btSoftBodyTriangleCallback.m_manifoldPtr->setBodies(convexBody,triBody); 243 243 244 244 245 245 concaveShape->processAllTriangles( &m_btSoftBodyTriangleCallback,m_btSoftBodyTriangleCallback.getAabbMin(),m_btSoftBodyTriangleCallback.getAabbMax()); 246 247 248 249 } 250 246 247 // resultOut->refreshContactPoints(); 248 249 } 250 251 251 } 252 252 … … 288 288 btScalar m_ccdSphereRadius; 289 289 btScalar m_hitFraction; 290 290 291 291 292 292 LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,btScalar ccdSphereRadius,btScalar hitFraction) … … 297 297 { 298 298 } 299 300 299 300 301 301 virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) 302 302 { … … 328 328 329 329 330 331 332 330 331 332 333 333 if (triBody->getCollisionShape()->isConcave()) 334 334 { … … 350 350 351 351 btConcaveShape* triangleMesh = (btConcaveShape*) concavebody->getCollisionShape(); 352 352 353 353 if (triangleMesh) 354 354 { 355 355 triangleMesh->processAllTriangles(&raycastCallback,rayAabbMin,rayAabbMax); 356 356 } 357 357 358 358 359 359 -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h
r1963 r1972 36 36 int m_PartIdTriangleIndex; 37 37 class btCollisionShape* m_childShape; 38 38 39 39 btTriIndex(int partId,int triangleIndex,btCollisionShape* shape) 40 40 { … … 76 76 77 77 btHashMap<btHashKey<btTriIndex>,btTriIndex> m_shapeCache; 78 78 79 79 public: 80 81 82 80 int m_triangleCount; 81 82 // btPersistentManifold* m_manifoldPtr; 83 83 84 84 btSoftBodyTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped); … … 89 89 90 90 virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); 91 91 92 92 void clearCache(); 93 93 -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBodyHelpers.cpp
r1963 r1972 23 23 // 24 24 static void drawVertex( btIDebugDraw* idraw, 25 26 {27 idraw->drawLine(x-btVector3(s,0,0),x+btVector3(s,0,0),c);28 idraw->drawLine(x-btVector3(0,s,0),x+btVector3(0,s,0),c);29 idraw->drawLine(x-btVector3(0,0,s),x+btVector3(0,0,s),c);30 }25 const btVector3& x,btScalar s,const btVector3& c) 26 { 27 idraw->drawLine(x-btVector3(s,0,0),x+btVector3(s,0,0),c); 28 idraw->drawLine(x-btVector3(0,s,0),x+btVector3(0,s,0),c); 29 idraw->drawLine(x-btVector3(0,0,s),x+btVector3(0,0,s),c); 30 } 31 31 32 32 // 33 33 static void drawBox( btIDebugDraw* idraw, 34 const btVector3& mins,35 const btVector3& maxs,36 const btVector3& color)37 { 38 39 btVector3(maxs.x(),mins.y(),mins.z()),40 btVector3(maxs.x(),maxs.y(),mins.z()),41 btVector3(mins.x(),maxs.y(),mins.z()),42 btVector3(mins.x(),mins.y(),maxs.z()),43 btVector3(maxs.x(),mins.y(),maxs.z()),44 btVector3(maxs.x(),maxs.y(),maxs.z()),45 btVector3(mins.x(),maxs.y(),maxs.z())};46 47 48 49 50 51 34 const btVector3& mins, 35 const btVector3& maxs, 36 const btVector3& color) 37 { 38 const btVector3 c[]={ btVector3(mins.x(),mins.y(),mins.z()), 39 btVector3(maxs.x(),mins.y(),mins.z()), 40 btVector3(maxs.x(),maxs.y(),mins.z()), 41 btVector3(mins.x(),maxs.y(),mins.z()), 42 btVector3(mins.x(),mins.y(),maxs.z()), 43 btVector3(maxs.x(),mins.y(),maxs.z()), 44 btVector3(maxs.x(),maxs.y(),maxs.z()), 45 btVector3(mins.x(),maxs.y(),maxs.z())}; 46 idraw->drawLine(c[0],c[1],color);idraw->drawLine(c[1],c[2],color); 47 idraw->drawLine(c[2],c[3],color);idraw->drawLine(c[3],c[0],color); 48 idraw->drawLine(c[4],c[5],color);idraw->drawLine(c[5],c[6],color); 49 idraw->drawLine(c[6],c[7],color);idraw->drawLine(c[7],c[4],color); 50 idraw->drawLine(c[0],c[4],color);idraw->drawLine(c[1],c[5],color); 51 idraw->drawLine(c[2],c[6],color);idraw->drawLine(c[3],c[7],color); 52 52 } 53 53 54 54 // 55 55 static void drawTree( btIDebugDraw* idraw, 56 57 58 59 60 61 62 { 63 64 { 65 66 { 67 68 69 } 70 71 { 72 73 74 75 56 const btDbvtNode* node, 57 int depth, 58 const btVector3& ncolor, 59 const btVector3& lcolor, 60 int mindepth, 61 int maxdepth) 62 { 63 if(node) 64 { 65 if(node->isinternal()&&((depth<maxdepth)||(maxdepth<0))) 66 { 67 drawTree(idraw,node->childs[0],depth+1,ncolor,lcolor,mindepth,maxdepth); 68 drawTree(idraw,node->childs[1],depth+1,ncolor,lcolor,mindepth,maxdepth); 69 } 70 if(depth>=mindepth) 71 { 72 const btScalar scl=(btScalar)(node->isinternal()?1:1); 73 const btVector3 mi=node->volume.Center()-node->volume.Extents()*scl; 74 const btVector3 mx=node->volume.Center()+node->volume.Extents()*scl; 75 drawBox(idraw,mi,mx,node->isleaf()?lcolor:ncolor); 76 76 } 77 77 } … … 82 82 static inline T sum(const btAlignedObjectArray<T>& items) 83 83 { 84 85 86 { 87 88 89 { 90 91 } 92 } 93 84 T v; 85 if(items.size()) 86 { 87 v=items[0]; 88 for(int i=1,ni=items.size();i<ni;++i) 89 { 90 v+=items[i]; 91 } 92 } 93 return(v); 94 94 } 95 95 … … 98 98 static inline void add(btAlignedObjectArray<T>& items,const Q& value) 99 99 { 100 101 { 102 100 for(int i=0,ni=items.size();i<ni;++i) 101 { 102 items[i]+=value; 103 103 } 104 104 } … … 108 108 static inline void mul(btAlignedObjectArray<T>& items,const Q& value) 109 109 { 110 111 { 112 110 for(int i=0,ni=items.size();i<ni;++i) 111 { 112 items[i]*=value; 113 113 } 114 114 } … … 118 118 static inline T average(const btAlignedObjectArray<T>& items) 119 119 { 120 121 120 const btScalar n=(btScalar)(items.size()>0?items.size():1); 121 return(sum(items)/n); 122 122 } 123 123 … … 137 137 #if 0 138 138 static btVector3 stresscolor(btScalar stress) 139 {139 { 140 140 static const btVector3 spectrum[]= { btVector3(1,0,1), 141 btVector3(0,0,1),142 btVector3(0,1,1),143 btVector3(0,1,0),144 btVector3(1,1,0),145 btVector3(1,0,0),146 btVector3(1,0,0)};141 btVector3(0,0,1), 142 btVector3(0,1,1), 143 btVector3(0,1,0), 144 btVector3(1,1,0), 145 btVector3(1,0,0), 146 btVector3(1,0,0)}; 147 147 static const int ncolors=sizeof(spectrum)/sizeof(spectrum[0])-1; 148 148 static const btScalar one=1; … … 151 151 const btScalar frc=stress-sel; 152 152 return(spectrum[sel]+(spectrum[sel+1]-spectrum[sel])*frc); 153 }153 } 154 154 #endif 155 155 156 156 // 157 157 void btSoftBodyHelpers::Draw( btSoftBody* psb, 158 159 158 btIDebugDraw* idraw, 159 int drawflags) 160 160 { 161 161 const btScalar scl=(btScalar)0.1; … … 252 252 const btVector3 c=(x[0]+x[1]+x[2])/3; 253 253 idraw->drawTriangle((x[0]-c)*scl+c, 254 (x[1]-c)*scl+c,255 (x[2]-c)*scl+c,256 col,alp);254 (x[1]-c)*scl+c, 255 (x[2]-c)*scl+c, 256 col,alp); 257 257 } 258 258 } 259 259 /* Clusters */ 260 260 if(0!=(drawflags&fDrawFlags::Clusters)) 261 {261 { 262 262 srand(1806); 263 263 for(i=0;i<psb->m_clusters.size();++i) 264 {264 { 265 265 if(psb->m_clusters[i]->m_collide) 266 {266 { 267 267 btVector3 color( rand()/(btScalar)RAND_MAX, 268 rand()/(btScalar)RAND_MAX,269 rand()/(btScalar)RAND_MAX);268 rand()/(btScalar)RAND_MAX, 269 rand()/(btScalar)RAND_MAX); 270 270 color=color.normalized()*0.75; 271 271 btAlignedObjectArray<btVector3> vertices; 272 272 vertices.resize(psb->m_clusters[i]->m_nodes.size()); 273 273 for(j=0,nj=vertices.size();j<nj;++j) 274 {274 { 275 275 vertices[j]=psb->m_clusters[i]->m_nodes[j]->m_x; 276 }276 } 277 277 HullDesc hdsc(QF_TRIANGLES,vertices.size(),&vertices[0]); 278 278 HullResult hres; … … 285 285 add(hres.m_OutputVertices,center); 286 286 for(j=0;j<(int)hres.mNumFaces;++j) 287 {287 { 288 288 const int idx[]={hres.m_Indices[j*3+0],hres.m_Indices[j*3+1],hres.m_Indices[j*3+2]}; 289 289 idraw->drawTriangle(hres.m_OutputVertices[idx[0]], 290 hres.m_OutputVertices[idx[1]], 291 hres.m_OutputVertices[idx[2]], 292 color,1); 290 hres.m_OutputVertices[idx[1]], 291 hres.m_OutputVertices[idx[2]], 292 color,1); 293 } 294 hlib.ReleaseResult(hres); 293 295 } 294 hlib.ReleaseResult(hres);295 }296 296 /* Velocities */ 297 #if 0297 #if 0 298 298 for(int j=0;j<psb->m_clusters[i].m_nodes.size();++j) 299 {299 { 300 300 const btSoftBody::Cluster& c=psb->m_clusters[i]; 301 301 const btVector3 r=c.m_nodes[j]->m_x-c.m_com; 302 302 const btVector3 v=c.m_lv+cross(c.m_av,r); 303 303 idraw->drawLine(c.m_nodes[j]->m_x,c.m_nodes[j]->m_x+v,btVector3(1,0,0)); 304 }305 #endif304 } 305 #endif 306 306 /* Frame */ 307 307 btSoftBody::Cluster& c=*psb->m_clusters[i]; … … 309 309 idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,10,0),btVector3(0,1,0)); 310 310 idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,0,10),btVector3(0,0,1)); 311 }312 }311 } 312 } 313 313 /* Notes */ 314 314 if(0!=(drawflags&fDrawFlags::Notes)) … … 319 319 btVector3 p=n.m_offset; 320 320 for(int j=0;j<n.m_rank;++j) 321 {321 { 322 322 p+=n.m_nodes[j]->m_x*n.m_coords[j]; 323 }323 } 324 324 idraw->draw3dText(p,n.m_text); 325 325 } … … 334 334 if(0!=(drawflags&fDrawFlags::Joints)) 335 335 { 336 337 { 338 339 336 for(i=0;i<psb->m_joints.size();++i) 337 { 338 const btSoftBody::Joint* pj=psb->m_joints[i]; 339 switch(pj->Type()) 340 340 { 341 341 case btSoftBody::Joint::eType::Linear: 342 342 { 343 344 345 346 347 348 349 343 const btSoftBody::LJoint* pjl=(const btSoftBody::LJoint*)pj; 344 const btVector3 a0=pj->m_bodies[0].xform()*pjl->m_refs[0]; 345 const btVector3 a1=pj->m_bodies[1].xform()*pjl->m_refs[1]; 346 idraw->drawLine(pj->m_bodies[0].xform().getOrigin(),a0,btVector3(1,1,0)); 347 idraw->drawLine(pj->m_bodies[1].xform().getOrigin(),a1,btVector3(0,1,1)); 348 drawVertex(idraw,a0,0.25,btVector3(1,1,0)); 349 drawVertex(idraw,a1,0.25,btVector3(0,1,1)); 350 350 } 351 351 break; 352 352 case btSoftBody::Joint::eType::Angular: 353 353 { 354 355 356 357 358 359 360 361 362 354 const btSoftBody::AJoint* pja=(const btSoftBody::AJoint*)pj; 355 const btVector3 o0=pj->m_bodies[0].xform().getOrigin(); 356 const btVector3 o1=pj->m_bodies[1].xform().getOrigin(); 357 const btVector3 a0=pj->m_bodies[0].xform().getBasis()*pj->m_refs[0]; 358 const btVector3 a1=pj->m_bodies[1].xform().getBasis()*pj->m_refs[1]; 359 idraw->drawLine(o0,o0+a0*10,btVector3(1,1,0)); 360 idraw->drawLine(o0,o0+a1*10,btVector3(1,1,0)); 361 idraw->drawLine(o1,o1+a0*10,btVector3(0,1,1)); 362 idraw->drawLine(o1,o1+a1*10,btVector3(0,1,1)); 363 363 } 364 364 } … … 369 369 // 370 370 void btSoftBodyHelpers::DrawInfos( btSoftBody* psb, 371 372 373 374 371 btIDebugDraw* idraw, 372 bool masses, 373 bool areas, 374 bool /*stress*/) 375 375 { 376 376 for(int i=0;i<psb->m_nodes.size();++i) … … 395 395 // 396 396 void btSoftBodyHelpers::DrawNodeTree( btSoftBody* psb, 397 btIDebugDraw* idraw,398 int mindepth,399 int maxdepth)400 { 401 397 btIDebugDraw* idraw, 398 int mindepth, 399 int maxdepth) 400 { 401 drawTree(idraw,psb->m_ndbvt.m_root,0,btVector3(1,0,1),btVector3(1,1,1),mindepth,maxdepth); 402 402 } 403 403 404 404 // 405 405 void btSoftBodyHelpers::DrawFaceTree( btSoftBody* psb, 406 btIDebugDraw* idraw,407 int mindepth,408 int maxdepth)409 { 410 406 btIDebugDraw* idraw, 407 int mindepth, 408 int maxdepth) 409 { 410 drawTree(idraw,psb->m_fdbvt.m_root,0,btVector3(0,1,0),btVector3(1,0,0),mindepth,maxdepth); 411 411 } 412 412 413 413 // 414 414 void btSoftBodyHelpers::DrawClusterTree( btSoftBody* psb, 415 416 417 418 { 419 415 btIDebugDraw* idraw, 416 int mindepth, 417 int maxdepth) 418 { 419 drawTree(idraw,psb->m_cdbvt.m_root,0,btVector3(0,1,1),btVector3(1,0,0),mindepth,maxdepth); 420 420 } 421 421 422 422 // 423 423 void btSoftBodyHelpers::DrawFrame( btSoftBody* psb, 424 424 btIDebugDraw* idraw) 425 425 { 426 426 if(psb->m_pose.m_bframe) … … 446 446 // 447 447 btSoftBody* btSoftBodyHelpers::CreateRope( btSoftBodyWorldInfo& worldInfo, const btVector3& from, 448 449 450 448 const btVector3& to, 449 int res, 450 int fixeds) 451 451 { 452 452 /* Create nodes */ … … 478 478 // 479 479 btSoftBody* btSoftBodyHelpers::CreatePatch(btSoftBodyWorldInfo& worldInfo,const btVector3& corner00, 480 481 482 483 484 485 486 480 const btVector3& corner10, 481 const btVector3& corner01, 482 const btVector3& corner11, 483 int resx, 484 int resy, 485 int fixeds, 486 bool gendiags) 487 487 { 488 488 #define IDX(_x_,_y_) ((_y_)*rx+(_x_)) … … 554 554 555 555 // 556 btSoftBody* btSoftBodyHelpers::CreatePatchUV(btSoftBodyWorldInfo& worldInfo,557 const btVector3& corner00,558 const btVector3& corner10,559 const btVector3& corner01,560 const btVector3& corner11,561 int resx,562 int resy,563 int fixeds,564 bool gendiags,565 float* tex_coords)566 {567 568 /*569 *570 * corners:571 *572 * [0][0] corner00 ------- corner01 [resx][0]573 * | |574 * | |575 * [0][resy] corner10 -------- corner11 [resx][resy]576 *577 *578 *579 *580 *581 *582 * "fixedgs" map:583 *584 * corner00 --> +1585 * corner01 --> +2586 * corner10 --> +4587 * corner11 --> +8588 * upper middle --> +16589 * left middle --> +32590 * right middle --> +64591 * lower middle --> +128592 * center --> +256593 *594 *595 * tex_coords size (resx-1)*(resy-1)*12596 *597 *598 *599 * SINGLE QUAD INTERNALS600 *601 * 1) btSoftBody's nodes and links,602 * diagonal link is optional ("gendiags")603 *604 *605 * node00 ------ node01606 * | .607 * | .608 * | .609 * | .610 * | .611 * node10 node11612 *613 *614 *615 * 2) Faces:616 * two triangles,617 * UV Coordinates (hier example for single quad)618 *619 * (0,1) (0,1) (1,1)620 * 1 |\ 3 \-----| 2621 * | \ \ |622 * | \ \ |623 * | \ \ |624 * | \ \ |625 * 2 |-----\ 3 \| 1626 * (0,0) (1,0) (1,0)627 *628 *629 *630 *631 *632 *633 */634 635 #define IDX(_x_,_y_) ((_y_)*rx+(_x_))636 /* Create nodes */637 if((resx<2)||(resy<2)) return(0);638 const int rx=resx;639 const int ry=resy;640 const int tot=rx*ry;641 btVector3* x=new btVector3[tot];642 btScalar* m=new btScalar[tot];643 644 for(int iy=0;iy<ry;++iy)645 {646 const btScalar ty=iy/(btScalar)(ry-1);647 const btVector3 py0=lerp(corner00,corner01,ty);648 const btVector3 py1=lerp(corner10,corner11,ty);649 for(int ix=0;ix<rx;++ix)650 {651 const btScalar tx=ix/(btScalar)(rx-1);652 x[IDX(ix,iy)]=lerp(py0,py1,tx);653 m[IDX(ix,iy)]=1;654 }655 }656 btSoftBody* psb=new btSoftBody(&worldInfo,tot,x,m);657 if(fixeds&1) psb->setMass(IDX(0,0),0);658 if(fixeds&2) psb->setMass(IDX(rx-1,0),0);659 if(fixeds&4) psb->setMass(IDX(0,ry-1),0);660 if(fixeds&8) psb->setMass(IDX(rx-1,ry-1),0);661 if(fixeds&16) psb->setMass(IDX((rx-1)/2,0),0);662 if(fixeds&32) psb->setMass(IDX(0,(ry-1)/2),0);663 if(fixeds&64) psb->setMass(IDX(rx-1,(ry-1)/2),0);664 if(fixeds&128) psb->setMass(IDX((rx-1)/2,ry-1),0);665 if(fixeds&256) psb->setMass(IDX((rx-1)/2,(ry-1)/2),0);666 delete[] x;667 delete[] m;668 669 670 int z = 0;671 /* Create links and faces */672 for(int iy=0;iy<ry;++iy)673 {674 for(int ix=0;ix<rx;++ix)675 {676 const bool mdx=(ix+1)<rx;677 const bool mdy=(iy+1)<ry;678 679 int node00=IDX(ix,iy);680 int node01=IDX(ix+1,iy);681 int node10=IDX(ix,iy+1);682 int node11=IDX(ix+1,iy+1);683 684 if(mdx) psb->appendLink(node00,node01);685 if(mdy) psb->appendLink(node00,node10);686 if(mdx&&mdy)687 {688 psb->appendFace(node00,node10,node11);689 if (tex_coords) {690 tex_coords[z+0]=CalculateUV(resx,resy,ix,iy,0);691 tex_coords[z+1]=CalculateUV(resx,resy,ix,iy,1);692 tex_coords[z+2]=CalculateUV(resx,resy,ix,iy,0);693 tex_coords[z+3]=CalculateUV(resx,resy,ix,iy,2);694 tex_coords[z+4]=CalculateUV(resx,resy,ix,iy,3);695 tex_coords[z+5]=CalculateUV(resx,resy,ix,iy,2);696 }697 psb->appendFace(node11,node01,node00);698 if (tex_coords) {699 tex_coords[z+6 ]=CalculateUV(resx,resy,ix,iy,3);700 tex_coords[z+7 ]=CalculateUV(resx,resy,ix,iy,2);701 tex_coords[z+8 ]=CalculateUV(resx,resy,ix,iy,3);702 tex_coords[z+9 ]=CalculateUV(resx,resy,ix,iy,1);703 tex_coords[z+10]=CalculateUV(resx,resy,ix,iy,0);704 tex_coords[z+11]=CalculateUV(resx,resy,ix,iy,1);705 }706 if (gendiags) psb->appendLink(node00,node11);707 z += 12;708 }709 }710 }711 /* Finished */712 #undef IDX713 return(psb);714 }715 716 float btSoftBodyHelpers::CalculateUV(int resx,int resy,int ix,int iy,int id)717 {718 719 /*720 *721 *722 * node00 --- node01723 * | |724 * node10 --- node11725 *726 *727 * ID map:728 *729 * node00 s --> 0730 * node00 t --> 1731 *732 * node01 s --> 3733 * node01 t --> 1734 *735 * node10 s --> 0736 * node10 t --> 2737 *738 * node11 s --> 3739 * node11 t --> 2740 *741 *742 */743 744 float tc=0.0f;745 if (id == 0) {746 tc = (1.0f/((resx-1))*ix);747 }748 else if (id==1) {749 tc = (1.0f/((resy-1))*(resy-1-iy));750 }751 else if (id==2) {752 tc = (1.0f/((resy-1))*(resy-1-iy-1));753 }754 else if (id==3) {755 tc = (1.0f/((resx-1))*(ix+1));756 }757 return tc;758 }759 //760 556 btSoftBody* btSoftBodyHelpers::CreateEllipsoid(btSoftBodyWorldInfo& worldInfo,const btVector3& center, 761 762 557 const btVector3& radius, 558 int res) 763 559 { 764 560 struct Hammersley … … 791 587 // 792 588 btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBodyWorldInfo& worldInfo,const btScalar* vertices, 793 794 589 const int* triangles, 590 int ntriangles) 795 591 { 796 592 int maxidx=0; … … 833 629 // 834 630 btSoftBody* btSoftBodyHelpers::CreateFromConvexHull(btSoftBodyWorldInfo& worldInfo, const btVector3* vertices, 835 631 int nvertices) 836 632 { 837 633 HullDesc hdsc(QF_TRIANGLES,nvertices,vertices); -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBodyHelpers.h
r1963 r1972 47 47 /* Draw body */ 48 48 static void Draw( btSoftBody* psb, 49 btIDebugDraw* idraw,50 int drawflags=fDrawFlags::Std);49 btIDebugDraw* idraw, 50 int drawflags=fDrawFlags::Std); 51 51 /* Draw body infos */ 52 52 static void DrawInfos( btSoftBody* psb, 53 btIDebugDraw* idraw,54 bool masses,55 bool areas,56 bool stress);53 btIDebugDraw* idraw, 54 bool masses, 55 bool areas, 56 bool stress); 57 57 /* Draw node tree */ 58 58 static void DrawNodeTree( btSoftBody* psb, 59 btIDebugDraw* idraw,60 int mindepth=0,61 int maxdepth=-1);59 btIDebugDraw* idraw, 60 int mindepth=0, 61 int maxdepth=-1); 62 62 /* Draw face tree */ 63 63 static void DrawFaceTree( btSoftBody* psb, 64 btIDebugDraw* idraw,65 int mindepth=0,66 int maxdepth=-1);64 btIDebugDraw* idraw, 65 int mindepth=0, 66 int maxdepth=-1); 67 67 /* Draw cluster tree */ 68 68 static void DrawClusterTree(btSoftBody* psb, 69 btIDebugDraw* idraw,70 int mindepth=0,71 int maxdepth=-1);69 btIDebugDraw* idraw, 70 int mindepth=0, 71 int maxdepth=-1); 72 72 /* Draw rigid frame */ 73 73 static void DrawFrame( btSoftBody* psb, 74 btIDebugDraw* idraw);74 btIDebugDraw* idraw); 75 75 /* Create a rope */ 76 76 static btSoftBody* CreateRope( btSoftBodyWorldInfo& worldInfo, 77 const btVector3& from,78 const btVector3& to,79 int res,80 int fixeds);77 const btVector3& from, 78 const btVector3& to, 79 int res, 80 int fixeds); 81 81 /* Create a patch */ 82 82 static btSoftBody* CreatePatch(btSoftBodyWorldInfo& worldInfo, 83 const btVector3& corner00, 84 const btVector3& corner10, 85 const btVector3& corner01, 86 const btVector3& corner11, 87 int resx, 88 int resy, 89 int fixeds, 90 bool gendiags); 91 /* Create a patch with UV Texture Coordinates */ 92 static btSoftBody* CreatePatchUV(btSoftBodyWorldInfo& worldInfo, 93 const btVector3& corner00, 94 const btVector3& corner10, 95 const btVector3& corner01, 96 const btVector3& corner11, 97 int resx, 98 int resy, 99 int fixeds, 100 bool gendiags, 101 float* tex_coords=0); 102 static float CalculateUV(int resx,int resy,int ix,int iy,int id); 83 const btVector3& corner00, 84 const btVector3& corner10, 85 const btVector3& corner01, 86 const btVector3& corner11, 87 int resx, 88 int resy, 89 int fixeds, 90 bool gendiags); 103 91 /* Create an ellipsoid */ 104 92 static btSoftBody* CreateEllipsoid(btSoftBodyWorldInfo& worldInfo, 105 const btVector3& center,106 const btVector3& radius,107 int res);93 const btVector3& center, 94 const btVector3& radius, 95 int res); 108 96 /* Create from trimesh */ 109 97 static btSoftBody* CreateFromTriMesh( btSoftBodyWorldInfo& worldInfo, 110 const btScalar* vertices,111 const int* triangles,112 int ntriangles);98 const btScalar* vertices, 99 const int* triangles, 100 int ntriangles); 113 101 /* Create from convex-hull */ 114 102 static btSoftBody* CreateFromConvexHull( btSoftBodyWorldInfo& worldInfo, 115 const btVector3* vertices,116 int nvertices);103 const btVector3* vertices, 104 int nvertices); 117 105 }; 118 106 -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBodyInternals.h
r1963 r1972 32 32 struct btSymMatrix 33 33 { 34 btSymMatrix() : dim(0) {}35 btSymMatrix(int n,const T& init=T()) { resize(n,init); }36 37 38 39 40 41 34 btSymMatrix() : dim(0) {} 35 btSymMatrix(int n,const T& init=T()) { resize(n,init); } 36 void resize(int n,const T& init=T()) { dim=n;store.resize((n*(n+1))/2,init); } 37 int index(int c,int r) const { if(c>r) btSwap(c,r);btAssert(r<dim);return((r*(r+1))/2+c); } 38 T& operator()(int c,int r) { return(store[index(c,r)]); } 39 const T& operator()(int c,int r) const { return(store[index(c,r)]); } 40 btAlignedObjectArray<T> store; 41 int dim; 42 42 }; 43 43 … … 49 49 public: 50 50 btSoftBody* m_body; 51 51 52 52 btSoftBodyCollisionShape(btSoftBody* backptr) 53 53 { … … 70 70 virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const 71 71 { 72 73 74 75 76 t*btVector3(maxs.x(),mins.y(),mins.z()),77 t*btVector3(maxs.x(),maxs.y(),mins.z()),78 t*btVector3(mins.x(),maxs.y(),mins.z()),79 t*btVector3(mins.x(),mins.y(),maxs.z()),80 t*btVector3(maxs.x(),mins.y(),maxs.z()),81 t*btVector3(maxs.x(),maxs.y(),maxs.z()),82 t*btVector3(mins.x(),maxs.y(),maxs.z())};83 84 85 { 86 87 88 } 89 } 90 91 72 /* t should be identity, but better be safe than...fast? */ 73 const btVector3 mins=m_body->m_bounds[0]; 74 const btVector3 maxs=m_body->m_bounds[1]; 75 const btVector3 crns[]={t*btVector3(mins.x(),mins.y(),mins.z()), 76 t*btVector3(maxs.x(),mins.y(),mins.z()), 77 t*btVector3(maxs.x(),maxs.y(),mins.z()), 78 t*btVector3(mins.x(),maxs.y(),mins.z()), 79 t*btVector3(mins.x(),mins.y(),maxs.z()), 80 t*btVector3(maxs.x(),mins.y(),maxs.z()), 81 t*btVector3(maxs.x(),maxs.y(),maxs.z()), 82 t*btVector3(mins.x(),maxs.y(),maxs.z())}; 83 aabbMin=aabbMax=crns[0]; 84 for(int i=1;i<8;++i) 85 { 86 aabbMin.setMin(crns[i]); 87 aabbMax.setMax(crns[i]); 88 } 89 } 90 91 92 92 virtual void setLocalScaling(const btVector3& /*scaling*/) 93 93 { … … 96 96 virtual const btVector3& getLocalScaling() const 97 97 { 98 99 98 static const btVector3 dummy(1,1,1); 99 return dummy; 100 100 } 101 101 virtual void calculateLocalInertia(btScalar /*mass*/,btVector3& /*inertia*/) const … … 120 120 121 121 btSoftClusterCollisionShape (const btSoftBody::Cluster* cluster) : m_cluster(cluster) { setMargin(0); } 122 123 122 123 124 124 virtual btVector3 localGetSupportingVertex(const btVector3& vec) const 125 {125 { 126 126 btSoftBody::Node* const * n=&m_cluster->m_nodes[0]; 127 127 btScalar d=dot(vec,n[0]->m_x); 128 128 int j=0; 129 129 for(int i=1,ni=m_cluster->m_nodes.size();i<ni;++i) 130 {130 { 131 131 const btScalar k=dot(vec,n[i]->m_x); 132 132 if(k>d) { d=k;j=i; } 133 }133 } 134 134 return(n[j]->m_x); 135 }135 } 136 136 virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const 137 {137 { 138 138 return(localGetSupportingVertex(vec)); 139 }139 } 140 140 //notice that the vectors should be unit length 141 141 virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const … … 150 150 151 151 virtual int getShapeType() const { return SOFTBODY_SHAPE_PROXYTYPE; } 152 152 153 153 //debugging 154 154 virtual const char* getName()const {return "SOFTCLUSTER";} … … 172 172 static inline void ZeroInitialize(T& value) 173 173 { 174 175 174 static const T zerodummy; 175 value=zerodummy; 176 176 } 177 177 // … … 193 193 // 194 194 static inline btMatrix3x3 Lerp( const btMatrix3x3& a, 195 196 197 { 198 199 200 201 202 195 const btMatrix3x3& b, 196 btScalar t) 197 { 198 btMatrix3x3 r; 199 r[0]=Lerp(a[0],b[0],t); 200 r[1]=Lerp(a[1],b[1],t); 201 r[2]=Lerp(a[2],b[2],t); 202 return(r); 203 203 } 204 204 // 205 205 static inline btVector3 Clamp(const btVector3& v,btScalar maxlength) 206 206 { 207 208 209 207 const btScalar sql=v.length2(); 208 if(sql>(maxlength*maxlength)) 209 return((v*maxlength)/btSqrt(sql)); 210 210 else 211 211 return(v); 212 212 } 213 213 // … … 234 234 static inline btScalar ClusterMetric(const btVector3& x,const btVector3& y) 235 235 { 236 237 236 const btVector3 d=x-y; 237 return(btFabs(d[0])+btFabs(d[1])+btFabs(d[2])); 238 238 } 239 239 // … … 272 272 // 273 273 static inline btMatrix3x3 Add(const btMatrix3x3& a, 274 274 const btMatrix3x3& b) 275 275 { 276 276 btMatrix3x3 r; … … 280 280 // 281 281 static inline btMatrix3x3 Sub(const btMatrix3x3& a, 282 282 const btMatrix3x3& b) 283 283 { 284 284 btMatrix3x3 r; … … 288 288 // 289 289 static inline btMatrix3x3 Mul(const btMatrix3x3& a, 290 290 btScalar b) 291 291 { 292 292 btMatrix3x3 r; … … 297 297 static inline void Orthogonalize(btMatrix3x3& m) 298 298 { 299 300 301 299 m[2]=cross(m[0],m[1]).normalized(); 300 m[1]=cross(m[2],m[0]).normalized(); 301 m[0]=cross(m[1],m[2]).normalized(); 302 302 } 303 303 // … … 310 310 // 311 311 static inline btMatrix3x3 ImpulseMatrix( btScalar dt, 312 313 314 315 312 btScalar ima, 313 btScalar imb, 314 const btMatrix3x3& iwi, 315 const btVector3& r) 316 316 { 317 317 return(Diagonal(1/dt)*Add(Diagonal(ima),MassMatrix(imb,iwi,r)).inverse()); … … 320 320 // 321 321 static inline btMatrix3x3 ImpulseMatrix( btScalar ima,const btMatrix3x3& iia,const btVector3& ra, 322 323 { 324 322 btScalar imb,const btMatrix3x3& iib,const btVector3& rb) 323 { 324 return(Add(MassMatrix(ima,iia,ra),MassMatrix(imb,iib,rb)).inverse()); 325 325 } 326 326 327 327 // 328 328 static inline btMatrix3x3 AngularImpulseMatrix( const btMatrix3x3& iia, 329 330 { 331 329 const btMatrix3x3& iib) 330 { 331 return(Add(iia,iib).inverse()); 332 332 } 333 333 334 334 // 335 335 static inline btVector3 ProjectOnAxis( const btVector3& v, 336 336 const btVector3& a) 337 337 { 338 338 return(a*dot(v,a)); … … 340 340 // 341 341 static inline btVector3 ProjectOnPlane( const btVector3& v, 342 342 const btVector3& a) 343 343 { 344 344 return(v-ProjectOnAxis(v,a)); … … 347 347 // 348 348 static inline void ProjectOrigin( const btVector3& a, 349 350 351 352 { 353 354 355 349 const btVector3& b, 350 btVector3& prj, 351 btScalar& sqd) 352 { 353 const btVector3 d=b-a; 354 const btScalar m2=d.length2(); 355 if(m2>SIMD_EPSILON) 356 356 { 357 const btScalar t=Clamp<btScalar>(-dot(a,d)/m2,0,1); 358 const btVector3 p=a+d*t; 359 const btScalar l2=p.length2(); 360 if(l2<sqd) 361 { 357 const btScalar t=Clamp<btScalar>(-dot(a,d)/m2,0,1); 358 const btVector3 p=a+d*t; 359 const btScalar l2=p.length2(); 360 if(l2<sqd) 361 { 362 prj=p; 363 sqd=l2; 364 } 365 } 366 } 367 // 368 static inline void ProjectOrigin( const btVector3& a, 369 const btVector3& b, 370 const btVector3& c, 371 btVector3& prj, 372 btScalar& sqd) 373 { 374 const btVector3& q=cross(b-a,c-a); 375 const btScalar m2=q.length2(); 376 if(m2>SIMD_EPSILON) 377 { 378 const btVector3 n=q/btSqrt(m2); 379 const btScalar k=dot(a,n); 380 const btScalar k2=k*k; 381 if(k2<sqd) 382 { 383 const btVector3 p=n*k; 384 if( (dot(cross(a-p,b-p),q)>0)&& 385 (dot(cross(b-p,c-p),q)>0)&& 386 (dot(cross(c-p,a-p),q)>0)) 387 { 362 388 prj=p; 363 sqd=l2; 364 } 365 } 366 } 367 // 368 static inline void ProjectOrigin( const btVector3& a, 369 const btVector3& b, 370 const btVector3& c, 371 btVector3& prj, 372 btScalar& sqd) 373 { 374 const btVector3& q=cross(b-a,c-a); 375 const btScalar m2=q.length2(); 376 if(m2>SIMD_EPSILON) 377 { 378 const btVector3 n=q/btSqrt(m2); 379 const btScalar k=dot(a,n); 380 const btScalar k2=k*k; 381 if(k2<sqd) 382 { 383 const btVector3 p=n*k; 384 if( (dot(cross(a-p,b-p),q)>0)&& 385 (dot(cross(b-p,c-p),q)>0)&& 386 (dot(cross(c-p,a-p),q)>0)) 387 { 388 prj=p; 389 sqd=k2; 389 sqd=k2; 390 390 } 391 391 else 392 392 { 393 394 395 393 ProjectOrigin(a,b,prj,sqd); 394 ProjectOrigin(b,c,prj,sqd); 395 ProjectOrigin(c,a,prj,sqd); 396 396 } 397 397 } … … 402 402 template <typename T> 403 403 static inline T BaryEval( const T& a, 404 405 406 404 const T& b, 405 const T& c, 406 const btVector3& coord) 407 407 { 408 408 return(a*coord.x()+b*coord.y()+c*coord.z()); … … 410 410 // 411 411 static inline btVector3 BaryCoord( const btVector3& a, 412 413 414 415 { 416 417 cross(b-p,c-p).length(),418 cross(c-p,a-p).length()};419 420 412 const btVector3& b, 413 const btVector3& c, 414 const btVector3& p) 415 { 416 const btScalar w[]={ cross(a-p,b-p).length(), 417 cross(b-p,c-p).length(), 418 cross(c-p,a-p).length()}; 419 const btScalar isum=1/(w[0]+w[1]+w[2]); 420 return(btVector3(w[1]*isum,w[2]*isum,w[0]*isum)); 421 421 } 422 422 423 423 // 424 424 static btScalar ImplicitSolve( btSoftBody::ImplicitFn* fn, 425 426 427 428 429 { 430 431 432 433 { 434 435 436 } 437 438 439 440 { 441 442 443 444 445 425 const btVector3& a, 426 const btVector3& b, 427 const btScalar accuracy, 428 const int maxiterations=256) 429 { 430 btScalar span[2]={0,1}; 431 btScalar values[2]={fn->Eval(a),fn->Eval(b)}; 432 if(values[0]>values[1]) 433 { 434 btSwap(span[0],span[1]); 435 btSwap(values[0],values[1]); 436 } 437 if(values[0]>-accuracy) return(-1); 438 if(values[1]<+accuracy) return(-1); 439 for(int i=0;i<maxiterations;++i) 440 { 441 const btScalar t=Lerp(span[0],span[1],values[0]/(values[0]-values[1])); 442 const btScalar v=fn->Eval(Lerp(a,b,t)); 443 if((t<=0)||(t>=1)) break; 444 if(btFabs(v)<accuracy) return(t); 445 if(v<0) 446 446 { span[0]=t;values[0]=v; } 447 447 else 448 448 { span[1]=t;values[1]=v; } 449 449 } 450 450 return(-1); 451 451 } 452 452 … … 463 463 // 464 464 static inline btDbvtVolume VolumeOf( const btSoftBody::Face& f, 465 466 { 467 468 &f.m_n[1]->m_x,469 &f.m_n[2]->m_x};470 471 472 465 btScalar margin) 466 { 467 const btVector3* pts[]={ &f.m_n[0]->m_x, 468 &f.m_n[1]->m_x, 469 &f.m_n[2]->m_x}; 470 btDbvtVolume vol=btDbvtVolume::FromPoints(pts,3); 471 vol.Expand(btVector3(margin,margin,margin)); 472 return(vol); 473 473 } 474 474 … … 476 476 static inline btVector3 CenterOf( const btSoftBody::Face& f) 477 477 { 478 478 return((f.m_n[0]->m_x+f.m_n[1]->m_x+f.m_n[2]->m_x)/3); 479 479 } 480 480 481 481 // 482 482 static inline btScalar AreaOf( const btVector3& x0, 483 484 483 const btVector3& x1, 484 const btVector3& x2) 485 485 { 486 486 const btVector3 a=x1-x0; … … 493 493 // 494 494 static inline btScalar VolumeOf( const btVector3& x0, 495 496 497 495 const btVector3& x1, 496 const btVector3& x2, 497 const btVector3& x3) 498 498 { 499 499 const btVector3 a=x1-x0; … … 505 505 // 506 506 static void EvaluateMedium( const btSoftBodyWorldInfo* wfi, 507 508 507 const btVector3& x, 508 btSoftBody::sMedium& medium) 509 509 { 510 510 medium.m_velocity = btVector3(0,0,0); … … 524 524 // 525 525 static inline void ApplyClampedForce( btSoftBody::Node& n, 526 527 526 const btVector3& f, 527 btScalar dt) 528 528 { 529 529 const btScalar dtim=dt*n.m_im; … … 540 540 // 541 541 static inline int MatchEdge( const btSoftBody::Node* a, 542 543 544 545 { 546 547 548 542 const btSoftBody::Node* b, 543 const btSoftBody::Node* ma, 544 const btSoftBody::Node* mb) 545 { 546 if((a==ma)&&(b==mb)) return(0); 547 if((a==mb)&&(b==ma)) return(1); 548 return(-1); 549 549 } 550 550 … … 556 556 struct btEigen 557 557 { 558 559 { 560 561 562 563 564 565 566 567 568 569 558 static int system(btMatrix3x3& a,btMatrix3x3* vectors,btVector3* values=0) 559 { 560 static const int maxiterations=16; 561 static const btScalar accuracy=(btScalar)0.0001; 562 btMatrix3x3& v=*vectors; 563 int iterations=0; 564 vectors->setIdentity(); 565 do { 566 int p=0,q=1; 567 if(btFabs(a[p][q])<btFabs(a[0][2])) { p=0;q=2; } 568 if(btFabs(a[p][q])<btFabs(a[1][2])) { p=1;q=2; } 569 if(btFabs(a[p][q])>accuracy) 570 570 { 571 572 573 574 571 const btScalar w=(a[q][q]-a[p][p])/(2*a[p][q]); 572 const btScalar z=btFabs(w); 573 const btScalar t=w/(z*(btSqrt(1+w*w)+z)); 574 if(t==t)/* [WARNING] let hope that one does not get thrown aways by some compilers... */ 575 575 { 576 577 578 579 580 576 const btScalar c=1/btSqrt(t*t+1); 577 const btScalar s=c*t; 578 mulPQ(a,c,s,p,q); 579 mulTPQ(a,c,s,p,q); 580 mulPQ(v,c,s,p,q); 581 581 } else break; 582 582 } else break; 583 583 } while((++iterations)<maxiterations); 584 585 { 586 587 } 588 584 if(values) 585 { 586 *values=btVector3(a[0][0],a[1][1],a[2][2]); 587 } 588 return(iterations); 589 589 } 590 590 private: 591 592 { 593 594 {a[q][0],a[q][1],a[q][2]}};595 596 597 598 599 } 600 601 { 602 603 {a[0][q],a[1][q],a[2][q]}};604 605 606 607 591 static inline void mulTPQ(btMatrix3x3& a,btScalar c,btScalar s,int p,int q) 592 { 593 const btScalar m[2][3]={ {a[p][0],a[p][1],a[p][2]}, 594 {a[q][0],a[q][1],a[q][2]}}; 595 int i; 596 597 for(i=0;i<3;++i) a[p][i]=c*m[0][i]-s*m[1][i]; 598 for(i=0;i<3;++i) a[q][i]=c*m[1][i]+s*m[0][i]; 599 } 600 static inline void mulPQ(btMatrix3x3& a,btScalar c,btScalar s,int p,int q) 601 { 602 const btScalar m[2][3]={ {a[0][p],a[1][p],a[2][p]}, 603 {a[0][q],a[1][q],a[2][q]}}; 604 int i; 605 606 for(i=0;i<3;++i) a[i][p]=c*m[0][i]-s*m[1][i]; 607 for(i=0;i<3;++i) a[i][q]=c*m[1][i]+s*m[0][i]; 608 608 } 609 609 }; … … 640 640 s.setIdentity(); 641 641 } 642 642 return(i); 643 643 } 644 644 … … 653 653 struct ClusterBase : btDbvt::ICollide 654 654 { 655 656 657 658 659 660 ClusterBase()661 { 662 663 664 665 666 667 } 668 669 btSoftBody::Body ba,btSoftBody::Body bb,670 btSoftBody::CJoint& joint)671 { 672 655 btScalar erp; 656 btScalar idt; 657 btScalar margin; 658 btScalar friction; 659 btScalar threshold; 660 ClusterBase() 661 { 662 erp =(btScalar)1; 663 idt =0; 664 margin =0; 665 friction =0; 666 threshold =(btScalar)0; 667 } 668 bool SolveContact( const btGjkEpaSolver2::sResults& res, 669 btSoftBody::Body ba,btSoftBody::Body bb, 670 btSoftBody::CJoint& joint) 671 { 672 if(res.distance<margin) 673 673 { 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 bb.invMass(),bb.invWorldInertia(),joint.m_rpos[1]);700 674 const btVector3 ra=res.witnesses[0]-ba.xform().getOrigin(); 675 const btVector3 rb=res.witnesses[1]-bb.xform().getOrigin(); 676 const btVector3 va=ba.velocity(ra); 677 const btVector3 vb=bb.velocity(rb); 678 const btVector3 vrel=va-vb; 679 const btScalar rvac=dot(vrel,res.normal); 680 const btScalar depth=res.distance-margin; 681 const btVector3 iv=res.normal*rvac; 682 const btVector3 fv=vrel-iv; 683 joint.m_bodies[0] = ba; 684 joint.m_bodies[1] = bb; 685 joint.m_refs[0] = ra*ba.xform().getBasis(); 686 joint.m_refs[1] = rb*bb.xform().getBasis(); 687 joint.m_rpos[0] = ra; 688 joint.m_rpos[1] = rb; 689 joint.m_cfm = 1; 690 joint.m_erp = 1; 691 joint.m_life = 0; 692 joint.m_maxlife = 0; 693 joint.m_split = 1; 694 joint.m_drift = depth*res.normal; 695 joint.m_normal = res.normal; 696 joint.m_delete = false; 697 joint.m_friction = fv.length2()<(-rvac*friction)?1:friction; 698 joint.m_massmatrix = ImpulseMatrix( ba.invMass(),ba.invWorldInertia(),joint.m_rpos[0], 699 bb.invMass(),bb.invWorldInertia(),joint.m_rpos[1]); 700 return(true); 701 701 } 702 702 return(false); 703 703 } 704 704 }; … … 708 708 struct CollideCL_RS : ClusterBase 709 709 { 710 711 712 713 { 714 715 716 717 718 719 rshape,prb->getInterpolationWorldTransform(),720 btVector3(1,0,0),res))710 btSoftBody* psb; 711 btRigidBody* prb; 712 void Process(const btDbvtNode* leaf) 713 { 714 btSoftBody::Cluster* cluster=(btSoftBody::Cluster*)leaf->data; 715 btSoftClusterCollisionShape cshape(cluster); 716 const btConvexShape* rshape=(const btConvexShape*)prb->getCollisionShape(); 717 btGjkEpaSolver2::sResults res; 718 if(btGjkEpaSolver2::SignedDistance( &cshape,btTransform::getIdentity(), 719 rshape,prb->getInterpolationWorldTransform(), 720 btVector3(1,0,0),res)) 721 721 { 722 723 722 btSoftBody::CJoint joint; 723 if(SolveContact(res,cluster,prb,joint)) 724 724 { 725 726 727 725 btSoftBody::CJoint* pj=new(btAlignedAlloc(sizeof(btSoftBody::CJoint),16)) btSoftBody::CJoint(); 726 *pj=joint;psb->m_joints.push_back(pj); 727 if(prb->isStaticOrKinematicObject()) 728 728 { 729 730 729 pj->m_erp *= psb->m_cfg.kSKHR_CL; 730 pj->m_split *= psb->m_cfg.kSK_SPLT_CL; 731 731 } 732 732 else 733 733 { 734 735 734 pj->m_erp *= psb->m_cfg.kSRHR_CL; 735 pj->m_split *= psb->m_cfg.kSR_SPLT_CL; 736 736 } 737 737 } 738 738 } 739 739 } 740 741 { 742 743 744 745 746 pr->getCollisionShape()->getMargin();747 748 749 750 751 752 753 754 755 740 void Process(btSoftBody* ps,btRigidBody* pr) 741 { 742 psb = ps; 743 prb = pr; 744 idt = ps->m_sst.isdt; 745 margin = ps->getCollisionShape()->getMargin()+ 746 pr->getCollisionShape()->getMargin(); 747 friction = btMin(psb->m_cfg.kDF,prb->getFriction()); 748 btVector3 mins; 749 btVector3 maxs; 750 751 ATTRIBUTE_ALIGNED16(btDbvtVolume) volume; 752 pr->getCollisionShape()->getAabb(pr->getInterpolationWorldTransform(),mins,maxs); 753 volume=btDbvtVolume::FromMM(mins,maxs); 754 volume.Expand(btVector3(1,1,1)*margin); 755 btDbvt::collideTV(ps->m_cdbvt.m_root,volume,*this); 756 756 } 757 757 }; … … 761 761 struct CollideCL_SS : ClusterBase 762 762 { 763 764 765 { 766 767 768 769 770 771 772 &csb,btTransform::getIdentity(),773 cla->m_com-clb->m_com,res))763 btSoftBody* bodies[2]; 764 void Process(const btDbvtNode* la,const btDbvtNode* lb) 765 { 766 btSoftBody::Cluster* cla=(btSoftBody::Cluster*)la->data; 767 btSoftBody::Cluster* clb=(btSoftBody::Cluster*)lb->data; 768 btSoftClusterCollisionShape csa(cla); 769 btSoftClusterCollisionShape csb(clb); 770 btGjkEpaSolver2::sResults res; 771 if(btGjkEpaSolver2::SignedDistance( &csa,btTransform::getIdentity(), 772 &csb,btTransform::getIdentity(), 773 cla->m_com-clb->m_com,res)) 774 774 { 775 776 775 btSoftBody::CJoint joint; 776 if(SolveContact(res,cla,clb,joint)) 777 777 { 778 779 780 781 778 btSoftBody::CJoint* pj=new(btAlignedAlloc(sizeof(btSoftBody::CJoint),16)) btSoftBody::CJoint(); 779 *pj=joint;bodies[0]->m_joints.push_back(pj); 780 pj->m_erp *= btMax(bodies[0]->m_cfg.kSSHR_CL,bodies[1]->m_cfg.kSSHR_CL); 781 pj->m_split *= (bodies[0]->m_cfg.kSS_SPLT_CL+bodies[1]->m_cfg.kSS_SPLT_CL)/2; 782 782 } 783 783 } 784 784 } 785 786 { 787 788 789 790 791 792 785 void Process(btSoftBody* psa,btSoftBody* psb) 786 { 787 idt = psa->m_sst.isdt; 788 margin = (psa->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin())/2; 789 friction = btMin(psa->m_cfg.kDF,psb->m_cfg.kDF); 790 bodies[0] = psa; 791 bodies[1] = psb; 792 btDbvt::collideTT(psa->m_cdbvt.m_root,psb->m_cdbvt.m_root,*this); 793 793 } 794 794 }; … … 798 798 struct CollideSDF_RS : btDbvt::ICollide 799 799 { 800 801 { 802 803 804 } 805 806 { 807 808 809 810 800 void Process(const btDbvtNode* leaf) 801 { 802 btSoftBody::Node* node=(btSoftBody::Node*)leaf->data; 803 DoNode(*node); 804 } 805 void DoNode(btSoftBody::Node& n) const 806 { 807 const btScalar m=n.m_im>0?dynmargin:stamargin; 808 btSoftBody::RContact c; 809 if( (!n.m_battach)&& 810 psb->checkContact(prb,n.m_x,m,c.m_cti)) 811 811 { 812 813 814 815 812 const btScalar ima=n.m_im; 813 const btScalar imb=prb->getInvMass(); 814 const btScalar ms=ima+imb; 815 if(ms>0) 816 816 { 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 817 const btTransform& wtr=prb->getInterpolationWorldTransform(); 818 const btMatrix3x3& iwi=prb->getInvInertiaTensorWorld(); 819 const btVector3 ra=n.m_x-wtr.getOrigin(); 820 const btVector3 va=prb->getVelocityInLocalPoint(ra)*psb->m_sst.sdt; 821 const btVector3 vb=n.m_x-n.m_q; 822 const btVector3 vr=vb-va; 823 const btScalar dn=dot(vr,c.m_cti.m_normal); 824 const btVector3 fv=vr-c.m_cti.m_normal*dn; 825 const btScalar fc=psb->m_cfg.kDF*prb->getFriction(); 826 c.m_node = &n; 827 c.m_c0 = ImpulseMatrix(psb->m_sst.sdt,ima,imb,iwi,ra); 828 c.m_c1 = ra; 829 c.m_c2 = ima*psb->m_sst.sdt; 830 c.m_c3 = fv.length2()<(btFabs(dn)*fc)?0:1-fc; 831 c.m_c4 = prb->isStaticOrKinematicObject()?psb->m_cfg.kKHR:psb->m_cfg.kCHR; 832 psb->m_rcontacts.push_back(c); 833 prb->activate(); 834 834 } 835 835 } 836 836 } 837 838 839 840 837 btSoftBody* psb; 838 btRigidBody* prb; 839 btScalar dynmargin; 840 btScalar stamargin; 841 841 }; 842 842 // … … 845 845 struct CollideVF_SS : btDbvt::ICollide 846 846 { 847 848 const btDbvtNode* lface)849 { 850 851 852 853 854 855 856 face->m_n[1]->m_x-o,857 face->m_n[2]->m_x-o,858 p,d);859 860 847 void Process(const btDbvtNode* lnode, 848 const btDbvtNode* lface) 849 { 850 btSoftBody::Node* node=(btSoftBody::Node*)lnode->data; 851 btSoftBody::Face* face=(btSoftBody::Face*)lface->data; 852 btVector3 o=node->m_x; 853 btVector3 p; 854 btScalar d=SIMD_INFINITY; 855 ProjectOrigin( face->m_n[0]->m_x-o, 856 face->m_n[1]->m_x-o, 857 face->m_n[2]->m_x-o, 858 p,d); 859 const btScalar m=mrg+(o-node->m_q).length()*2; 860 if(d<(m*m)) 861 861 { 862 863 864 865 866 867 868 862 const btSoftBody::Node* n[]={face->m_n[0],face->m_n[1],face->m_n[2]}; 863 const btVector3 w=BaryCoord(n[0]->m_x,n[1]->m_x,n[2]->m_x,p+o); 864 const btScalar ma=node->m_im; 865 btScalar mb=BaryEval(n[0]->m_im,n[1]->m_im,n[2]->m_im,w); 866 if( (n[0]->m_im<=0)|| 867 (n[1]->m_im<=0)|| 868 (n[2]->m_im<=0)) 869 869 { 870 870 mb=0; 871 871 } 872 873 872 const btScalar ms=ma+mb; 873 if(ms>0) 874 874 { 875 876 877 878 879 880 881 882 883 884 875 btSoftBody::SContact c; 876 c.m_normal = p/-btSqrt(d); 877 c.m_margin = m; 878 c.m_node = node; 879 c.m_face = face; 880 c.m_weights = w; 881 c.m_friction = btMax(psb[0]->m_cfg.kDF,psb[1]->m_cfg.kDF); 882 c.m_cfm[0] = ma/ms*psb[0]->m_cfg.kSHR; 883 c.m_cfm[1] = mb/ms*psb[1]->m_cfg.kSHR; 884 psb[0]->m_scontacts.push_back(c); 885 885 } 886 886 } 887 887 } 888 889 888 btSoftBody* psb[2]; 889 btScalar mrg; 890 890 }; 891 891 }; -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp
r1963 r1972 30 30 mem = btAlignedAlloc(sizeof(btSoftSoftCollisionAlgorithm::CreateFunc),16); 31 31 m_softSoftCreateFunc = new(mem) btSoftSoftCollisionAlgorithm::CreateFunc; 32 32 33 33 mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16); 34 34 m_softRigidConvexCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc; 35 35 36 36 mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16); 37 37 m_swappedSoftRigidConvexCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc; … … 41 41 mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc),16); 42 42 m_softRigidConcaveCreateFunc = new(mem) btSoftBodyConcaveCollisionAlgorithm::CreateFunc; 43 43 44 44 mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc),16); 45 45 m_swappedSoftRigidConcaveCreateFunc = new(mem) btSoftBodyConcaveCollisionAlgorithm::SwappedCreateFunc; … … 48 48 49 49 //replace pool by a new one, with potential larger size 50 50 51 51 if (m_ownsCollisionAlgorithmPool && m_collisionAlgorithmPool) 52 52 { 53 53 int curElemSize = m_collisionAlgorithmPool->getElementSize(); 54 54 ///calculate maximum element size, big enough to fit any collision algorithm in the memory pool 55 56 55 56 57 57 int maxSize0 = sizeof(btSoftSoftCollisionAlgorithm); 58 58 int maxSize1 = sizeof(btSoftRigidCollisionAlgorithm); … … 93 93 #endif 94 94 } 95 95 96 96 ///creation of soft-soft and soft-rigid, and otherwise fallback to base class implementation 97 97 btCollisionAlgorithmCreateFunc* btSoftBodyRigidBodyCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) -
code/branches/physics/src/bullet/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h
r1963 r1972 33 33 btCollisionAlgorithmCreateFunc* m_softRigidConcaveCreateFunc; 34 34 btCollisionAlgorithmCreateFunc* m_swappedSoftRigidConcaveCreateFunc; 35 35 36 36 public: 37 37 -
code/branches/physics/src/bullet/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp
r1963 r1972 36 36 btSoftRigidCollisionAlgorithm::~btSoftRigidCollisionAlgorithm() 37 37 { 38 38 39 39 //m_softBody->m_overlappingRigidBodies.remove(m_rigidCollisionObject); 40 40 41 41 /*if (m_ownManifold) 42 42 { 43 if (m_manifoldPtr)44 m_dispatcher->releaseManifold(m_manifoldPtr);43 if (m_manifoldPtr) 44 m_dispatcher->releaseManifold(m_manifoldPtr); 45 45 } 46 46 */ … … 59 59 btSoftBody* softBody = m_isSwapped? (btSoftBody*)body1 : (btSoftBody*)body0; 60 60 btCollisionObject* rigidCollisionObject = m_isSwapped? body0 : body1; 61 61 62 62 softBody->defaultCollisionHandler(rigidCollisionObject); 63 63 -
code/branches/physics/src/bullet/BulletSoftBody/btSoftRigidCollisionAlgorithm.h
r1963 r1972 29 29 class btSoftRigidCollisionAlgorithm : public btCollisionAlgorithm 30 30 { 31 32 31 // bool m_ownManifold; 32 // btPersistentManifold* m_manifoldPtr; 33 33 34 34 btSoftBody* m_softBody; … … 37 37 ///for rigid versus soft (instead of soft versus rigid), we use this swapped boolean 38 38 bool m_isSwapped; 39 39 40 40 public: 41 41 … … 53 53 } 54 54 55 55 56 56 struct CreateFunc :public btCollisionAlgorithmCreateFunc 57 57 { -
code/branches/physics/src/bullet/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
r1963 r1972 29 29 :btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration) 30 30 { 31 32 33 34 35 36 37 38 31 m_drawFlags = fDrawFlags::Std; 32 m_drawNodeTree = true; 33 m_drawFaceTree = false; 34 m_drawClusterTree = false; 35 m_sbi.m_broadphase = pairCache; 36 m_sbi.m_dispatcher = dispatcher; 37 m_sbi.m_sparsesdf.Initialize(); 38 m_sbi.m_sparsesdf.Reset(); 39 39 40 40 } 41 41 42 42 btSoftRigidDynamicsWorld::~btSoftRigidDynamicsWorld() 43 43 { … … 56 56 } 57 57 } 58 58 59 59 void btSoftRigidDynamicsWorld::internalSingleStepSimulation( btScalar timeStep) 60 60 { … … 72 72 { 73 73 BT_PROFILE("updateSoftBodies"); 74 74 75 75 for ( int i=0;i<m_softBodies.size();i++) 76 76 { … … 83 83 { 84 84 BT_PROFILE("solveSoftConstraints"); 85 85 86 86 if(m_softBodies.size()) 87 {87 { 88 88 btSoftBody::solveClusters(m_softBodies); 89 }90 89 } 90 91 91 for(int i=0;i<m_softBodies.size();++i) 92 92 { … … 101 101 102 102 btCollisionWorld::addCollisionObject(body, 103 btBroadphaseProxy::DefaultFilter,104 btBroadphaseProxy::AllFilter);103 btBroadphaseProxy::DefaultFilter, 104 btBroadphaseProxy::AllFilter); 105 105 106 106 } -
code/branches/physics/src/bullet/BulletSoftBody/btSoftRigidDynamicsWorld.h
r1963 r1972 24 24 class btSoftRigidDynamicsWorld : public btDiscreteDynamicsWorld 25 25 { 26 26 27 27 btSoftBodyArray m_softBodies; 28 28 int m_drawFlags; … … 33 33 34 34 protected: 35 35 36 36 virtual void predictUnconstraintMotion(btScalar timeStep); 37 37 38 38 virtual void internalSingleStepSimulation( btScalar timeStep); 39 39 … … 44 44 45 45 public: 46 46 47 47 btSoftRigidDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration); 48 48 49 49 virtual ~btSoftRigidDynamicsWorld(); 50 50 51 51 virtual void debugDrawWorld(); 52 52 53 53 void addSoftBody(btSoftBody* body); 54 54 55 55 void removeSoftBody(btSoftBody* body); 56 56 57 57 int getDrawFlags() const { return(m_drawFlags); } 58 58 void setDrawFlags(int f) { m_drawFlags=f; } … … 67 67 } 68 68 69 69 70 70 btSoftBodyArray& getSoftBodyArray() 71 71 { … … 77 77 return m_softBodies; 78 78 } 79 79 80 80 }; 81 81 -
code/branches/physics/src/bullet/BulletSoftBody/btSoftSoftCollisionAlgorithm.h
r1963 r1972 34 34 btSoftBody* m_softBody1; 35 35 36 36 37 37 public: 38 38 btSoftSoftCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) -
code/branches/physics/src/bullet/BulletSoftBody/btSparseSDF.h
r1963 r1972 24 24 template <const int DWORDLEN> 25 25 unsigned int HsiehHash(const void* pdata) 26 {26 { 27 27 const unsigned short* data=(const unsigned short*)pdata; 28 28 unsigned hash=DWORDLEN<<2,tmp; 29 29 for(int i=0;i<DWORDLEN;++i) 30 {30 { 31 31 hash += data[0]; 32 32 tmp = (data[1]<<11)^hash; … … 34 34 data += 2; 35 35 hash += hash>>11; 36 }36 } 37 37 hash^=hash<<3;hash+=hash>>5; 38 38 hash^=hash<<4;hash+=hash>>17; 39 39 hash^=hash<<25;hash+=hash>>6; 40 40 return(hash); 41 }41 } 42 42 43 43 template <const int CELLSIZE> 44 44 struct btSparseSdf 45 {45 { 46 46 // 47 47 // Inner types 48 48 // 49 49 struct IntFrac 50 {50 { 51 51 int b; 52 52 int i; 53 53 btScalar f; 54 };54 }; 55 55 struct Cell 56 {56 { 57 57 btScalar d[CELLSIZE+1][CELLSIZE+1][CELLSIZE+1]; 58 58 int c[3]; … … 61 61 btCollisionShape* pclient; 62 62 Cell* next; 63 };63 }; 64 64 // 65 65 // Fields 66 66 // 67 67 68 68 btAlignedObjectArray<Cell*> cells; 69 69 btScalar voxelsz; … … 72 72 int nprobes; 73 73 int nqueries; 74 74 75 75 // 76 76 // Methods 77 77 // 78 78 79 79 // 80 80 void Initialize(int hashsize=2383) 81 {81 { 82 82 cells.resize(hashsize,0); 83 83 Reset(); 84 }84 } 85 85 // 86 86 void Reset() 87 {87 { 88 88 for(int i=0,ni=cells.size();i<ni;++i) 89 {89 { 90 90 Cell* pc=cells[i]; 91 91 cells[i]=0; 92 92 while(pc) 93 {93 { 94 94 Cell* pn=pc->next; 95 95 delete pc; 96 96 pc=pn; 97 }98 }97 } 98 } 99 99 voxelsz =0.25; 100 100 puid =0; … … 102 102 nprobes =1; 103 103 nqueries =1; 104 }104 } 105 105 // 106 106 void GarbageCollect(int lifetime=256) 107 {107 { 108 108 const int life=puid-lifetime; 109 109 for(int i=0;i<cells.size();++i) 110 {110 { 111 111 Cell*& root=cells[i]; 112 112 Cell* pp=0; 113 113 Cell* pc=root; 114 114 while(pc) 115 {115 { 116 116 Cell* pn=pc->next; 117 117 if(pc->puid<life) 118 {118 { 119 119 if(pp) pp->next=pn; else root=pn; 120 120 delete pc;pc=pp;--ncells; 121 } 122 pp=pc;pc=pn; 121 123 } 122 pp=pc;pc=pn; 123 } 124 } 124 } 125 125 //printf("GC[%d]: %d cells, PpQ: %f\r\n",puid,ncells,nprobes/(btScalar)nqueries); 126 126 nqueries=1; 127 127 nprobes=1; 128 128 ++puid; /* TODO: Reset puid's when int range limit is reached */ 129 /* else setup a priority list... */130 }129 /* else setup a priority list... */ 130 } 131 131 // 132 132 int RemoveReferences(btCollisionShape* pcs) 133 {133 { 134 134 int refcount=0; 135 135 for(int i=0;i<cells.size();++i) 136 {136 { 137 137 Cell*& root=cells[i]; 138 138 Cell* pp=0; 139 139 Cell* pc=root; 140 140 while(pc) 141 {141 { 142 142 Cell* pn=pc->next; 143 143 if(pc->pclient==pcs) 144 {144 { 145 145 if(pp) pp->next=pn; else root=pn; 146 146 delete pc;pc=pp;++refcount; 147 } 148 pp=pc;pc=pn; 147 149 } 148 pp=pc;pc=pn; 149 } 150 } 150 } 151 151 return(refcount); 152 }152 } 153 153 // 154 154 btScalar Evaluate( const btVector3& x, 155 btCollisionShape* shape,156 btVector3& normal,157 btScalar margin)158 {155 btCollisionShape* shape, 156 btVector3& normal, 157 btScalar margin) 158 { 159 159 /* Lookup cell */ 160 160 const btVector3 scx=x/voxelsz; … … 167 167 ++nqueries; 168 168 while(c) 169 {169 { 170 170 ++nprobes; 171 171 if( (c->hash==h) && … … 174 174 (c->c[2]==iz.b) && 175 175 (c->pclient==shape)) 176 { break; }177 else178 { c=c->next; }179 }176 { break; } 177 else 178 { c=c->next; } 179 } 180 180 if(!c) 181 {181 { 182 182 ++nprobes; 183 183 ++ncells; … … 188 188 c->c[0]=ix.b;c->c[1]=iy.b;c->c[2]=iz.b; 189 189 BuildCell(*c); 190 }190 } 191 191 c->puid=puid; 192 192 /* Extract infos */ 193 193 const int o[]={ ix.i,iy.i,iz.i}; 194 194 const btScalar d[]={ c->d[o[0]+0][o[1]+0][o[2]+0], 195 c->d[o[0]+1][o[1]+0][o[2]+0],196 c->d[o[0]+1][o[1]+1][o[2]+0],197 c->d[o[0]+0][o[1]+1][o[2]+0],198 c->d[o[0]+0][o[1]+0][o[2]+1],199 c->d[o[0]+1][o[1]+0][o[2]+1],200 c->d[o[0]+1][o[1]+1][o[2]+1],201 c->d[o[0]+0][o[1]+1][o[2]+1]};195 c->d[o[0]+1][o[1]+0][o[2]+0], 196 c->d[o[0]+1][o[1]+1][o[2]+0], 197 c->d[o[0]+0][o[1]+1][o[2]+0], 198 c->d[o[0]+0][o[1]+0][o[2]+1], 199 c->d[o[0]+1][o[1]+0][o[2]+1], 200 c->d[o[0]+1][o[1]+1][o[2]+1], 201 c->d[o[0]+0][o[1]+1][o[2]+1]}; 202 202 /* Normal */ 203 #if 1203 #if 1 204 204 const btScalar gx[]={ d[1]-d[0],d[2]-d[3], 205 d[5]-d[4],d[6]-d[7]};205 d[5]-d[4],d[6]-d[7]}; 206 206 const btScalar gy[]={ d[3]-d[0],d[2]-d[1], 207 d[7]-d[4],d[6]-d[5]};207 d[7]-d[4],d[6]-d[5]}; 208 208 const btScalar gz[]={ d[4]-d[0],d[5]-d[1], 209 d[7]-d[3],d[6]-d[2]};209 d[7]-d[3],d[6]-d[2]}; 210 210 normal.setX(Lerp( Lerp(gx[0],gx[1],iy.f), 211 Lerp(gx[2],gx[3],iy.f),iz.f));211 Lerp(gx[2],gx[3],iy.f),iz.f)); 212 212 normal.setY(Lerp( Lerp(gy[0],gy[1],ix.f), 213 Lerp(gy[2],gy[3],ix.f),iz.f));213 Lerp(gy[2],gy[3],ix.f),iz.f)); 214 214 normal.setZ(Lerp( Lerp(gz[0],gz[1],ix.f), 215 Lerp(gz[2],gz[3],ix.f),iy.f));215 Lerp(gz[2],gz[3],ix.f),iy.f)); 216 216 normal = normal.normalized(); 217 #else217 #else 218 218 normal = btVector3(d[1]-d[0],d[3]-d[0],d[4]-d[0]).normalized(); 219 #endif219 #endif 220 220 /* Distance */ 221 221 const btScalar d0=Lerp(Lerp(d[0],d[1],ix.f), 222 Lerp(d[3],d[2],ix.f),iy.f);222 Lerp(d[3],d[2],ix.f),iy.f); 223 223 const btScalar d1=Lerp(Lerp(d[4],d[5],ix.f), 224 Lerp(d[7],d[6],ix.f),iy.f);224 Lerp(d[7],d[6],ix.f),iy.f); 225 225 return(Lerp(d0,d1,iz.f)-margin); 226 }226 } 227 227 // 228 228 void BuildCell(Cell& c) 229 {229 { 230 230 const btVector3 org=btVector3( (btScalar)c.c[0], 231 (btScalar)c.c[1],232 (btScalar)c.c[2]) *233 CELLSIZE*voxelsz;231 (btScalar)c.c[1], 232 (btScalar)c.c[2]) * 233 CELLSIZE*voxelsz; 234 234 for(int k=0;k<=CELLSIZE;++k) 235 {235 { 236 236 const btScalar z=voxelsz*k+org.z(); 237 237 for(int j=0;j<=CELLSIZE;++j) 238 {238 { 239 239 const btScalar y=voxelsz*j+org.y(); 240 240 for(int i=0;i<=CELLSIZE;++i) 241 {241 { 242 242 const btScalar x=voxelsz*i+org.x(); 243 243 c.d[i][j][k]=DistanceToShape( btVector3(x,y,z), 244 c.pclient); 244 c.pclient); 245 } 245 246 } 246 247 } 247 248 } 248 }249 249 // 250 250 static inline btScalar DistanceToShape(const btVector3& x, 251 btCollisionShape* shape)252 {251 btCollisionShape* shape) 252 { 253 253 btTransform unit; 254 254 unit.setIdentity(); 255 255 if(shape->isConvex()) 256 {256 { 257 257 btGjkEpaSolver2::sResults res; 258 258 btConvexShape* csh=static_cast<btConvexShape*>(shape); 259 259 return(btGjkEpaSolver2::SignedDistance(x,0,csh,unit,res)); 260 }260 } 261 261 return(0); 262 }262 } 263 263 // 264 264 static inline IntFrac Decompose(btScalar x) 265 {265 { 266 266 /* That one need a lot of improvements... */ 267 267 /* Remove test, faster floor... */ … … 273 273 r.i=(int)k;r.f=k-r.i;r.b-=o; 274 274 return(r); 275 }275 } 276 276 // 277 277 static inline btScalar Lerp(btScalar a,btScalar b,btScalar t) 278 {278 { 279 279 return(a+(b-a)*t); 280 }281 282 280 } 281 282 283 283 284 284 // 285 285 static inline unsigned int Hash(int x,int y,int z,btCollisionShape* shape) 286 {286 { 287 287 struct btS 288 288 { … … 292 292 293 293 btS myset; 294 294 295 295 myset.x=x;myset.y=y;myset.z=z;myset.p=shape; 296 296 const void* ptr = &myset; 297 297 298 298 unsigned int result = HsiehHash<sizeof(btS)/4> (ptr); 299 299 300 300 301 301 return result; 302 }302 } 303 303 }; 304 304 305 305 306 306 #endif -
code/branches/physics/src/bullet/CMakeLists.txt
r1963 r1972 1 if (CMAKE_SIZEOF_VOID_P MATCHES "8") 2 SUBDIRS( BulletSoftBody BulletCollision BulletDynamics LinearMath ) 3 else (CMAKE_SIZEOF_VOID_P MATCHES "8") 4 SUBDIRS( BulletMultiThreaded BulletSoftBody BulletCollision BulletDynamics LinearMath ) 5 endif (CMAKE_SIZEOF_VOID_P MATCHES "8") 1 INCLUDE_DIRECTORIES(.) 2 3 ADD_SUBDIRECTORY(BulletSoftBody) 4 ADD_SUBDIRECTORY(BulletCollision) 5 ADD_SUBDIRECTORY(BulletDynamics) 6 ADD_SUBDIRECTORY(BulletLinearMath) -
code/branches/physics/src/bullet/ChangeLog
r1963 r1972 5 5 See http://code.google.com/p/bullet/source/list for more complete log in Subversion 6 6 7 2008 October 108 - Moved aabb to btBroadphaseProxy, improves rayTest dramatically. Further raytest improvements using the broadphase acceleration structures are planned9 7 10 8 2008 October 3 -
code/branches/physics/src/bullet/LinearMath/btScalar.h
r1963 r1972 25 25 #include <float.h> 26 26 27 #define BT_BULLET_VERSION 27 327 #define BT_BULLET_VERSION 272 28 28 29 29 inline int btGetVersion()
Note: See TracChangeset
for help on using the changeset viewer.