Changeset 2430 for code/branches/physics/src/bullet
- Timestamp:
- Dec 13, 2008, 11:45:51 PM (16 years ago)
- Location:
- code/branches/physics/src/bullet
- Files:
-
- 8 added
- 5 deleted
- 135 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/physics/src/bullet/Bullet-C-Api.h
r2192 r2430 39 39 #endif 40 40 41 /* Particular physics SDK*/41 /** Particular physics SDK (C-API) */ 42 42 PL_DECLARE_HANDLE(plPhysicsSdkHandle); 43 43 44 /* Dynamics world, belonging to some physics SDK*/44 /** Dynamics world, belonging to some physics SDK (C-API)*/ 45 45 PL_DECLARE_HANDLE(plDynamicsWorldHandle); 46 46 47 /* Rigid Body that can be part of a Dynamics World*/47 /** Rigid Body that can be part of a Dynamics World (C-API)*/ 48 48 PL_DECLARE_HANDLE(plRigidBodyHandle); 49 49 50 /* Collision Shape/Geometry, property of a Rigid Body*/50 /** Collision Shape/Geometry, property of a Rigid Body (C-API)*/ 51 51 PL_DECLARE_HANDLE(plCollisionShapeHandle); 52 52 53 /* Constraint for Rigid Bodies*/53 /** Constraint for Rigid Bodies (C-API)*/ 54 54 PL_DECLARE_HANDLE(plConstraintHandle); 55 55 56 /* Triangle Mesh interface*/56 /** Triangle Mesh interface (C-API)*/ 57 57 PL_DECLARE_HANDLE(plMeshInterfaceHandle); 58 58 59 /* Broadphase Scene/Proxy Handles*/59 /** Broadphase Scene/Proxy Handles (C-API)*/ 60 60 PL_DECLARE_HANDLE(plCollisionBroadphaseHandle); 61 61 PL_DECLARE_HANDLE(plBroadphaseProxyHandle); 62 62 PL_DECLARE_HANDLE(plCollisionWorldHandle); 63 63 64 /* 64 /** 65 65 Create and Delete a Physics SDK 66 66 */ … … 69 69 extern void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk); 70 70 71 /* Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */71 /** Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */ 72 72 73 73 typedef void(*btBroadphaseCallback)(void* clientData, void* object1,void* object2); -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp
r2192 r2430 22 22 #include <assert.h> 23 23 24 btAxisSweep3::btAxisSweep3(const bt Point3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache)25 :btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache )24 btAxisSweep3::btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache, bool disableRaycastAccelerator) 25 :btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache,disableRaycastAccelerator) 26 26 { 27 27 // 1 handle is reserved as sentinel … … 31 31 32 32 33 bt32BitAxisSweep3::bt32BitAxisSweep3(const bt Point3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache)34 :btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache )33 bt32BitAxisSweep3::bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache , bool disableRaycastAccelerator) 34 :btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache,disableRaycastAccelerator) 35 35 { 36 36 // 1 handle is reserved as sentinel -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.h
r2192 r2430 20 20 #define AXIS_SWEEP_3_H 21 21 22 #include "LinearMath/btPoint3.h"23 22 #include "LinearMath/btVector3.h" 24 23 #include "btOverlappingPairCache.h" … … 26 25 #include "btBroadphaseProxy.h" 27 26 #include "btOverlappingPairCallback.h" 27 #include "btDbvtBroadphase.h" 28 28 29 29 //#define DEBUG_BROADPHASE 1 … … 62 62 BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12 63 63 // BP_FP_INT_TYPE m_uniqueId; 64 BP_FP_INT_TYPE m_pad; 65 64 btBroadphaseProxy* m_dbvtProxy;//for faster raycast 66 65 //void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject 67 66 … … 72 71 73 72 protected: 74 bt Point3 m_worldAabbMin; // overall system bounds75 bt Point3 m_worldAabbMax; // overall system bounds73 btVector3 m_worldAabbMin; // overall system bounds 74 btVector3 m_worldAabbMax; // overall system bounds 76 75 77 76 btVector3 m_quantize; // scaling factor for quantization … … 95 94 int m_invalidPair; 96 95 96 ///additional dynamic aabb structure, used to accelerate ray cast queries. 97 ///can be disabled using a optional argument in the constructor 98 btDbvtBroadphase* m_raycastAccelerator; 99 btOverlappingPairCache* m_nullPairCache; 100 101 97 102 // allocation/deallocation 98 103 BP_FP_INT_TYPE allocHandle(); … … 109 114 //void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB); 110 115 111 void quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const;116 112 117 113 118 void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); … … 118 123 public: 119 124 120 btAxisSweep3Internal(const bt Point3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0);125 btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0,bool disableRaycastAccelerator = false); 121 126 122 127 virtual ~btAxisSweep3Internal(); … … 129 134 virtual void calculateOverlappingPairs(btDispatcher* dispatcher); 130 135 131 BP_FP_INT_TYPE addHandle(const bt Point3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);136 BP_FP_INT_TYPE addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy); 132 137 void removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher); 133 void updateHandle(BP_FP_INT_TYPE handle, const bt Point3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher);138 void updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); 134 139 SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;} 140 141 void resetPool(); 135 142 136 143 void processAllOverlappingPairs(btOverlapCallback* callback); … … 140 147 virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); 141 148 virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); 149 virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; 150 151 virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)); 152 153 void quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const; 154 ///unQuantize should be conservative: aabbMin/aabbMax should be larger then 'getAabb' result 155 void unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; 142 156 143 157 bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); … … 218 232 219 233 Handle* handle = getHandle(handleId); 220 234 235 if (m_raycastAccelerator) 236 { 237 btBroadphaseProxy* rayProxy = m_raycastAccelerator->createProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,0); 238 handle->m_dbvtProxy = rayProxy; 239 } 221 240 return handle; 222 241 } … … 228 247 { 229 248 Handle* handle = static_cast<Handle*>(proxy); 249 if (m_raycastAccelerator) 250 m_raycastAccelerator->destroyProxy(handle->m_dbvtProxy,dispatcher); 230 251 removeHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), dispatcher); 231 252 } … … 235 256 { 236 257 Handle* handle = static_cast<Handle*>(proxy); 258 handle->m_aabbMin = aabbMin; 259 handle->m_aabbMax = aabbMax; 237 260 updateHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), aabbMin, aabbMax,dispatcher); 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 ) 261 if (m_raycastAccelerator) 262 m_raycastAccelerator->setAabb(handle->m_dbvtProxy,aabbMin,aabbMax,dispatcher); 263 264 } 265 266 template <typename BP_FP_INT_TYPE> 267 void btAxisSweep3Internal<BP_FP_INT_TYPE>::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax) 268 { 269 if (m_raycastAccelerator) 270 { 271 m_raycastAccelerator->rayTest(rayFrom,rayTo,rayCallback,aabbMin,aabbMax); 272 } else 273 { 274 //choose axis? 275 BP_FP_INT_TYPE axis = 0; 276 //for each proxy 277 for (BP_FP_INT_TYPE i=1;i<m_numHandles*2+1;i++) 278 { 279 if (m_pEdges[axis][i].IsMax()) 280 { 281 rayCallback.process(getHandle(m_pEdges[axis][i].m_handle)); 282 } 283 } 284 } 285 } 286 287 288 289 template <typename BP_FP_INT_TYPE> 290 void btAxisSweep3Internal<BP_FP_INT_TYPE>::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const 291 { 292 Handle* pHandle = static_cast<Handle*>(proxy); 293 aabbMin = pHandle->m_aabbMin; 294 aabbMax = pHandle->m_aabbMax; 295 } 296 297 298 template <typename BP_FP_INT_TYPE> 299 void btAxisSweep3Internal<BP_FP_INT_TYPE>::unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const 300 { 301 Handle* pHandle = static_cast<Handle*>(proxy); 302 303 unsigned short vecInMin[3]; 304 unsigned short vecInMax[3]; 305 306 vecInMin[0] = m_pEdges[0][pHandle->m_minEdges[0]].m_pos ; 307 vecInMax[0] = m_pEdges[0][pHandle->m_maxEdges[0]].m_pos +1 ; 308 vecInMin[1] = m_pEdges[1][pHandle->m_minEdges[1]].m_pos ; 309 vecInMax[1] = m_pEdges[1][pHandle->m_maxEdges[1]].m_pos +1 ; 310 vecInMin[2] = m_pEdges[2][pHandle->m_minEdges[2]].m_pos ; 311 vecInMax[2] = m_pEdges[2][pHandle->m_maxEdges[2]].m_pos +1 ; 312 313 aabbMin.setValue((btScalar)(vecInMin[0]) / (m_quantize.getX()),(btScalar)(vecInMin[1]) / (m_quantize.getY()),(btScalar)(vecInMin[2]) / (m_quantize.getZ())); 314 aabbMin += m_worldAabbMin; 315 316 aabbMax.setValue((btScalar)(vecInMax[0]) / (m_quantize.getX()),(btScalar)(vecInMax[1]) / (m_quantize.getY()),(btScalar)(vecInMax[2]) / (m_quantize.getZ())); 317 aabbMax += m_worldAabbMin; 318 } 319 320 321 322 323 template <typename BP_FP_INT_TYPE> 324 btAxisSweep3Internal<BP_FP_INT_TYPE>::btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache , bool disableRaycastAccelerator) 247 325 :m_bpHandleMask(handleMask), 248 326 m_handleSentinel(handleSentinel), … … 250 328 m_userPairCallback(0), 251 329 m_ownsPairCache(false), 252 m_invalidPair(0) 330 m_invalidPair(0), 331 m_raycastAccelerator(0) 253 332 { 254 333 BP_FP_INT_TYPE maxHandles = static_cast<BP_FP_INT_TYPE>(userMaxHandles+1);//need to add one sentinel handle … … 259 338 m_pairCache = new(ptr) btHashedOverlappingPairCache(); 260 339 m_ownsPairCache = true; 340 } 341 342 if (!disableRaycastAccelerator) 343 { 344 m_nullPairCache = new (btAlignedAlloc(sizeof(btNullPairCache),16)) btNullPairCache(); 345 m_raycastAccelerator = new (btAlignedAlloc(sizeof(btDbvtBroadphase),16)) btDbvtBroadphase(m_nullPairCache);//m_pairCache); 346 m_raycastAccelerator->m_deferedcollide = true;//don't add/remove pairs 261 347 } 262 348 … … 321 407 btAxisSweep3Internal<BP_FP_INT_TYPE>::~btAxisSweep3Internal() 322 408 { 323 409 if (m_raycastAccelerator) 410 { 411 m_nullPairCache->~btOverlappingPairCache(); 412 btAlignedFree(m_nullPairCache); 413 m_raycastAccelerator->~btDbvtBroadphase(); 414 btAlignedFree (m_raycastAccelerator); 415 } 416 324 417 for (int i = 2; i >= 0; i--) 325 418 { … … 336 429 337 430 template <typename BP_FP_INT_TYPE> 338 void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const bt Point3& point, int isMax) const431 void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const 339 432 { 340 433 #ifdef OLD_CLAMPING_METHOD 341 434 ///problem with this clamping method is that the floating point during quantization might still go outside the range [(0|isMax) .. (m_handleSentinel&m_bpHandleMask]|isMax] 342 435 ///see http://code.google.com/p/bullet/issues/detail?id=87 343 bt Point3 clampedPoint(point);436 btVector3 clampedPoint(point); 344 437 clampedPoint.setMax(m_worldAabbMin); 345 438 clampedPoint.setMin(m_worldAabbMax); … … 382 475 383 476 template <typename BP_FP_INT_TYPE> 384 BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::addHandle(const bt Point3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy)477 BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy) 385 478 { 386 479 // quantize the bounds … … 445 538 //explicitly remove the pairs containing the proxy 446 539 //we could do it also in the sortMinUp (passing true) 447 // todo: compare performance540 ///@todo: compare performance 448 541 if (!m_pairCache->hasDeferredRemoval()) 449 542 { … … 493 586 494 587 } 588 589 template <typename BP_FP_INT_TYPE> 590 void btAxisSweep3Internal<BP_FP_INT_TYPE>::resetPool() 591 { 592 if (m_numHandles == 0) 593 { 594 m_firstFreeHandle = 1; 595 { 596 for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < m_maxHandles; i++) 597 m_pHandles[i].SetNextFree(static_cast<BP_FP_INT_TYPE>(i + 1)); 598 m_pHandles[m_maxHandles - 1].SetNextFree(0); 599 } 600 } 601 } 602 495 603 496 604 extern int gOverlappingPairs; … … 621 729 622 730 template <typename BP_FP_INT_TYPE> 623 void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const bt Point3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher)731 void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher) 624 732 { 625 733 // assert(bounds.IsFinite()); … … 900 1008 public: 901 1009 902 btAxisSweep3(const bt Point3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0);1010 btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false); 903 1011 904 1012 }; … … 911 1019 public: 912 1020 913 bt32BitAxisSweep3(const bt Point3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0);1021 bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false); 914 1022 915 1023 }; -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
r2192 r2430 22 22 class btDispatcher; 23 23 #include "btBroadphaseProxy.h" 24 24 25 class btOverlappingPairCache; 26 27 28 29 struct btBroadphaseRayCallback 30 { 31 ///added some cached data to accelerate ray-AABB tests 32 btVector3 m_rayDirectionInverse; 33 unsigned int m_signs[3]; 34 btScalar m_lambda_max; 35 36 virtual ~btBroadphaseRayCallback() {} 37 virtual bool process(const btBroadphaseProxy* proxy) = 0; 38 }; 25 39 26 40 #include "LinearMath/btVector3.h" … … 37 51 virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)=0; 38 52 virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)=0; 39 53 virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const =0; 54 55 virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)) = 0; 56 40 57 ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb 41 58 virtual void calculateOverlappingPairs(btDispatcher* dispatcher)=0; -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
r2192 r2430 18 18 19 19 #include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE 20 #include "LinearMath/btVector3.h" 20 21 #include "LinearMath/btAlignedAllocator.h" 21 22 … … 24 25 /// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave 25 26 /// to facilitate type checking 27 /// CUSTOM_POLYHEDRAL_SHAPE_TYPE,CUSTOM_CONVEX_SHAPE_TYPE and CUSTOM_CONCAVE_SHAPE_TYPE can be used to extend Bullet without modifying source code 26 28 enum BroadphaseNativeTypes 27 29 { … … 33 35 CONVEX_HULL_SHAPE_PROXYTYPE, 34 36 CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE, 37 CUSTOM_POLYHEDRAL_SHAPE_TYPE, 35 38 //implicit convex shapes 36 39 IMPLICIT_CONVEX_SHAPES_START_HERE, … … 44 47 MINKOWSKI_SUM_SHAPE_PROXYTYPE, 45 48 MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE, 49 CUSTOM_CONVEX_SHAPE_TYPE, 46 50 //concave shapes 47 51 CONCAVE_SHAPES_START_HERE, … … 60 64 EMPTY_SHAPE_PROXYTYPE, 61 65 STATIC_PLANE_PROXYTYPE, 66 CUSTOM_CONCAVE_SHAPE_TYPE, 62 67 CONCAVE_SHAPES_END_HERE, 63 68 … … 88 93 DebrisFilter = 8, 89 94 SensorTrigger = 16, 95 CharacterFilter = 32, 90 96 AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger 91 97 }; … … 93 99 //Usually the client btCollisionObject or Rigidbody class 94 100 void* m_clientObject; 95 96 101 short int m_collisionFilterGroup; 97 102 short int m_collisionFilterMask; 98 99 103 void* m_multiSapParentProxy; 100 101 102 104 int m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc. 105 106 btVector3 m_aabbMin; 107 btVector3 m_aabbMax; 103 108 104 109 SIMD_FORCE_INLINE int getUid() const … … 112 117 } 113 118 114 btBroadphaseProxy( void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0)119 btBroadphaseProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0) 115 120 :m_clientObject(userPtr), 116 121 m_collisionFilterGroup(collisionFilterGroup), 117 m_collisionFilterMask(collisionFilterMask) 122 m_collisionFilterMask(collisionFilterMask), 123 m_aabbMin(aabbMin), 124 m_aabbMax(aabbMax) 118 125 { 119 126 m_multiSapParentProxy = multiSapParentProxy; … … 164 171 m_pProxy1(0), 165 172 m_algorithm(0), 166 m_ userInfo(0)173 m_internalInfo1(0) 167 174 { 168 175 } … … 174 181 m_pProxy1(other.m_pProxy1), 175 182 m_algorithm(other.m_algorithm), 176 m_ userInfo(other.m_userInfo)183 m_internalInfo1(other.m_internalInfo1) 177 184 { 178 185 } … … 193 200 194 201 m_algorithm = 0; 195 m_ userInfo= 0;202 m_internalInfo1 = 0; 196 203 197 204 } … … 201 208 202 209 mutable btCollisionAlgorithm* m_algorithm; 203 mutable void* m_userInfo;210 union { void* m_internalInfo1; int m_internalTmpValue;};//don't use this data, it will be removed in future version. 204 211 205 212 }; -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp
r2192 r2430 24 24 struct btDbvtNodeEnumerator : btDbvt::ICollide 25 25 { 26 tConstNodeArray nodes;27 void Process(const btDbvtNode* n) { nodes.push_back(n); }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 return(node->parent->childs[1]==node);33 return(node->parent->childs[1]==node); 34 34 } 35 35 36 36 // 37 37 static DBVT_INLINE btDbvtVolume merge( const btDbvtVolume& a, 38 39 { 40 #if DBVT_MERGE_IMPL==DBVT_IMPL_SSE41 DBVT_ALIGN char locals[sizeof(btDbvtAabbMm)];42 btDbvtVolume& res=*(btDbvtVolume*)locals;38 const btDbvtVolume& b) 39 { 40 #if (DBVT_MERGE_IMPL==DBVT_IMPL_SSE) 41 ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtAabbMm)]); 42 btDbvtVolume& res=*(btDbvtVolume*)locals; 43 43 #else 44 btDbvtVolume res;44 btDbvtVolume res; 45 45 #endif 46 Merge(a,b,res);47 return(res);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 const btVector3 edges=a.Lengths();54 return( edges.x()*edges.y()*edges.z()+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 if(node->isinternal())62 { 63 getmaxdepth(node->childs[0],depth+1,maxdepth);64 getmaxdepth(node->childs[0],depth+1,maxdepth);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 btAlignedFree(pdbvt->m_free);73 pdbvt->m_free=node;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 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);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 btDbvtNode* node;95 if(pdbvt->m_free)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 node->parent = parent;100 node->data = data;101 node->childs[1] = 0;102 return(node);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 btDbvtNode* node=createnode(pdbvt,parent,data);112 node->volume=volume;113 return(node);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 btDbvtNode* node=createnode(pdbvt,parent,data);124 Merge(volume0,volume1,node->volume);125 return(node);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 if(!pdbvt->m_root)134 { 135 pdbvt->m_root = leaf;136 leaf->parent = 0;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 if(!root->isleaf())141 { 142 do {143 root=root->childs[Select( leaf->volume,144 145 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 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)) 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 else 159 break; 160 node=prev; 161 } while(0!=(prev=node->parent)); 162 } 163 else 164 { 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 // 173 static btDbvtNode* removeleaf( btDbvt* pdbvt, 174 btDbvtNode* leaf) 175 { 176 if(leaf==pdbvt->m_root) 177 { 178 pdbvt->m_root=0; 179 return(0); 180 } 181 else 182 { 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; 157 194 Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume); 158 else 159 break; 160 node=prev; 161 } while(0!=(prev=node->parent)); 162 } 163 else 164 { 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 // 173 static btDbvtNode* removeleaf( btDbvt* pdbvt, 174 btDbvtNode* leaf) 175 { 176 if(leaf==pdbvt->m_root) 177 { 178 pdbvt->m_root=0; 179 return(0); 180 } 181 else 182 { 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)) 195 if(NotEqual(pb,prev->volume)) 196 196 { 197 prev=prev->parent;197 prev=prev->parent; 198 198 } else break; 199 199 } 200 return(prev?prev:pdbvt->m_root);200 return(prev?prev:pdbvt->m_root); 201 201 } 202 202 else 203 203 { 204 pdbvt->m_root=sibling;205 sibling->parent=0;206 deletenode(pdbvt,parent);207 return(pdbvt->m_root);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 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);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 leaves.push_back(root);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 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]);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 right.push_back(leaves[i]);244 right.push_back(leaves[i]); 245 245 } 246 246 } … … 250 250 { 251 251 #if DBVT_MERGE_IMPL==DBVT_IMPL_SSE 252 DBVT_ALIGN char locals[sizeof(btDbvtVolume)];253 btDbvtVolume& volume=*(btDbvtVolume*)locals;254 volume=leaves[0]->volume;252 ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtVolume)]); 253 btDbvtVolume& volume=*(btDbvtVolume*)locals; 254 volume=leaves[0]->volume; 255 255 #else 256 btDbvtVolume volume=leaves[0]->volume;256 btDbvtVolume volume=leaves[0]->volume; 257 257 #endif 258 for(int i=1,ni=leaves.size();i<ni;++i)259 { 260 Merge(volume,leaves[i]->volume,volume);261 } 262 return(volume);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 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)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 minsize = sz;281 minidx[0] = i;282 minidx[1] = j;280 minsize = sz; 281 minidx[0] = i; 282 minidx[1] = j; 283 283 } 284 284 } 285 285 } 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();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 static const btVector3 axis[]={btVector3(1,0,0),304 305 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)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 ++splitcount[j][dot(x,axis[j])>0?1:0];322 ++splitcount[j][dot(x,axis[j])>0?1:0]; 323 323 } 324 324 } 325 for( i=0;i<3;++i)326 { 327 if((splitcount[i][0]>0)&&(splitcount[i][1]>0))325 for( i=0;i<3;++i) 326 { 327 if((splitcount[i][0]>0)&&(splitcount[i][1]>0)) 328 328 { 329 const int midp=(int)btFabs(btScalar(splitcount[i][0]-splitcount[i][1]));330 if(midp<bestmidp)329 const int midp=(int)btFabs(btScalar(splitcount[i][0]-splitcount[i][1])); 330 if(midp<bestmidp) 331 331 { 332 bestaxis=i;333 bestmidp=midp;332 bestaxis=i; 333 bestmidp=midp; 334 334 } 335 335 } 336 336 } 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]);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 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)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 sets[i&1].push_back(leaves[i]);349 sets[i&1].push_back(leaves[i]); 350 350 } 351 351 } 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);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 bottomup(pdbvt,leaves);362 return(leaves[0]);363 } 364 } 365 return(leaves[0]);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 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);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 while(n&&(count--)) n=n->parent;400 return(n);399 while(n&&(count--)) n=n->parent; 400 return(n); 401 401 } 402 402 … … 406 406 407 407 // 408 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 419 { 420 clear();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 if(m_root) recursedeletenode(this,m_root);427 btAlignedFree(m_free);428 m_free=0;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 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];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 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);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 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;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 btDbvtNode* leaf=createnode(this,0,volume,data);480 insertleaf(this,m_root,leaf);481 ++m_leaves;482 return(leaf);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 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;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 insertleaf(this,root,leaf);500 } 501 502 // 503 void btDbvt::update(btDbvtNode* leaf, constbtDbvtVolume& volume)504 { 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;499 insertleaf(this,root,leaf); 500 } 501 502 // 503 void btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume) 504 { 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 leaf->volume=volume;517 insertleaf(this,root,leaf);518 } 519 520 // 521 bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity,btScalar margin)522 { 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 } 529 530 // 531 bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity)532 { 533 if(leaf->volume.Contain(volume)) return(false);534 volume.SignedExpand(velocity);535 update(leaf,volume);536 return(true);537 } 538 539 // 540 bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume volume,btScalar margin)541 { 542 if(leaf->volume.Contain(volume)) return(false);543 volume.Expand(btVector3(margin,margin,margin));544 update(leaf,volume);545 return(true);516 leaf->volume=volume; 517 insertleaf(this,root,leaf); 518 } 519 520 // 521 bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin) 522 { 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 } 529 530 // 531 bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity) 532 { 533 if(leaf->volume.Contain(volume)) return(false); 534 volume.SignedExpand(velocity); 535 update(leaf,volume); 536 return(true); 537 } 538 539 // 540 bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin) 541 { 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 removeleaf(this,leaf);552 deletenode(this,leaf);553 --m_leaves;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 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);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 iwriter->WriteLeaf(n,i,p);576 iwriter->WriteLeaf(n,i,p); 577 577 } 578 578 } … … 582 582 void btDbvt::clone(btDbvt& dest,IClone* iclone) const 583 583 { 584 dest.clear();585 if(m_root!=0)584 dest.clear(); 585 if(m_root!=0) 586 586 { 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;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 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));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 iclone->CloneLeaf(n);606 iclone->CloneLeaf(n); 607 607 } 608 608 } while(stack.size()>0); … … 613 613 int btDbvt::maxdepth(const btDbvtNode* node) 614 614 { 615 int depth=0;616 if(node) getmaxdepth(node,1,depth);617 return(depth);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 if(node->isinternal())624 return(countLeaves(node->childs[0])+countLeaves(node->childs[1]));623 if(node->isinternal()) 624 return(countLeaves(node->childs[0])+countLeaves(node->childs[1])); 625 625 else 626 return(1);626 return(1); 627 627 } 628 628 … … 630 630 void btDbvt::extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves) 631 631 { 632 if(node->isinternal())633 { 634 extractLeaves(node->childs[0],leaves);635 extractLeaves(node->childs[1],leaves);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 leaves.push_back(node);639 leaves.push_back(node); 640 640 } 641 641 } … … 658 658 659 659 Benchmarking dbvt... 660 661 662 663 664 665 660 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:: collideRAY: 6314 ms (0%),(332143 r/s)672 [7] btDbvt::rayTest: 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 struct NilPolicy : btDbvt::ICollide688 { 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)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 int m_pcount;699 btScalar m_depth;700 bool m_checksort;698 int m_pcount; 699 btScalar m_depth; 700 bool m_checksort; 701 701 }; 702 struct P14 : btDbvt::ICollide703 { 704 struct Node705 { 706 const btDbvtNode* leaf;707 btScalar depth;702 struct P14 : btDbvt::ICollide 703 { 704 struct Node 705 { 706 const btDbvtNode* leaf; 707 btScalar depth; 708 708 }; 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;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 struct P15 : btDbvt::ICollide724 { 725 struct Node726 { 727 const btDbvtNode* leaf;728 btScalar depth;723 struct P15 : btDbvt::ICollide 724 { 725 struct Node 726 { 727 const btDbvtNode* leaf; 728 btScalar depth; 729 729 }; 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;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 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);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 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 intersections787 bool cfgBenchmark1_Enable = cfgEnable;788 static const int cfgBenchmark1_Iterations = 8;789 static const int cfgBenchmark1_Reference = 3499;790 //[2] btDbvtVolume merges791 bool cfgBenchmark2_Enable = cfgEnable;792 static const int cfgBenchmark2_Iterations = 4;793 static const int cfgBenchmark2_Reference = 1945;794 //[3] btDbvt::collideTT795 bool cfgBenchmark3_Enable = cfgEnable;796 static const int cfgBenchmark3_Iterations = 512;797 static const int cfgBenchmark3_Reference = 5485;798 //[4] btDbvt::collideTT self799 bool cfgBenchmark4_Enable = cfgEnable;800 static const int cfgBenchmark4_Iterations = 512;801 static const int cfgBenchmark4_Reference = 2814;802 //[5] btDbvt::collideTT xform803 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,self808 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/remove818 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 notequal839 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 batch855 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] select860 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)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::rayTest 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 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)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 results[k]=Intersect(volumes[j],volumes[k]);891 results[k]=Intersect(volumes[j],volumes[k]); 892 892 } 893 893 } 894 894 } 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)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 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)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 Merge(volumes[j],volumes[k],results[k]);917 Merge(volumes[j],volumes[k],results[k]); 918 918 } 919 919 } 920 920 } 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)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 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)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 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)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 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)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 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)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 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)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::rayTest: "); 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::rayTest(dbvt.m_root,rayorg[j],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 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)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 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 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)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 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)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 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)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 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)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 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)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 results[k]=NotEqual(volumes[j],volumes[k]);1140 results[k]=NotEqual(volumes[j],volumes[k]); 1141 1141 } 1142 1142 } 1143 1143 } 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)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 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)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 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)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 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)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 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)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 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)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 const int idx=indices[k];1280 results[idx]=Select(volumes[idx],volumes[j],volumes[k]);1279 const int idx=indices[k]; 1280 results[idx]=Select(volumes[idx],volumes[j],volumes[k]); 1281 1281 } 1282 1282 } 1283 1283 } 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");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
r2192 r2430 21 21 #include "LinearMath/btVector3.h" 22 22 #include "LinearMath/btTransform.h" 23 #include "LinearMath/btAabbUtil2.h" 23 24 24 25 // … … 33 34 // Template implementation of ICollide 34 35 #ifdef WIN32 35 #if (defined (_MSC_VER) && _MSC_VER >= 1400) 36 #define DBVT_USE_TEMPLATE 1 37 #else 38 #define DBVT_USE_TEMPLATE 0 39 #endif 36 #if (defined (_MSC_VER) && _MSC_VER >= 1400) 37 #define DBVT_USE_TEMPLATE 1 40 38 #else 41 39 #define DBVT_USE_TEMPLATE 0 42 40 #endif 41 #else 42 #define DBVT_USE_TEMPLATE 0 43 #endif 43 44 44 45 // Use only intrinsics instead of inline asm … … 53 54 // Inlining 54 55 #define DBVT_INLINE SIMD_FORCE_INLINE 55 // Align56 #ifdef WIN3257 #define DBVT_ALIGN __declspec(align(16))58 #else59 #define DBVT_ALIGN60 #endif61 56 62 57 // Specific methods implementation … … 135 130 struct btDbvtAabbMm 136 131 { 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); 132 DBVT_INLINE btVector3 Center() const { return((mi+mx)/2); } 133 DBVT_INLINE btVector3 Lengths() const { return(mx-mi); } 134 DBVT_INLINE btVector3 Extents() const { return((mx-mi)/2); } 135 DBVT_INLINE const btVector3& Mins() const { return(mi); } 136 DBVT_INLINE const btVector3& Maxs() const { return(mx); } 137 static inline btDbvtAabbMm FromCE(const btVector3& c,const btVector3& e); 138 static inline btDbvtAabbMm FromCR(const btVector3& c,btScalar r); 139 static inline btDbvtAabbMm FromMM(const btVector3& mi,const btVector3& mx); 140 static inline btDbvtAabbMm FromPoints(const btVector3* pts,int n); 141 static inline btDbvtAabbMm FromPoints(const btVector3** ppts,int n); 142 DBVT_INLINE void Expand(const btVector3& e); 143 DBVT_INLINE void SignedExpand(const btVector3& e); 144 DBVT_INLINE bool Contain(const btDbvtAabbMm& a) const; 145 DBVT_INLINE int Classify(const btVector3& n,btScalar o,int s) const; 146 DBVT_INLINE btScalar ProjectMinimum(const btVector3& v,unsigned signs) const; 147 DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, 148 const btDbvtAabbMm& b); 149 DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, 150 const btDbvtAabbMm& b, 151 const btTransform& xform); 152 DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, 153 const btVector3& b); 154 155 DBVT_INLINE friend btScalar Proximity( const btDbvtAabbMm& a, 156 const btDbvtAabbMm& b); 157 DBVT_INLINE friend int Select( const btDbvtAabbMm& o, 158 const btDbvtAabbMm& a, 159 const btDbvtAabbMm& b); 160 DBVT_INLINE friend void Merge( const btDbvtAabbMm& a, 161 const btDbvtAabbMm& b, 162 btDbvtAabbMm& r); 163 DBVT_INLINE friend bool NotEqual( const btDbvtAabbMm& a, 164 const btDbvtAabbMm& b); 173 165 private: 174 DBVT_INLINE void AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const;166 DBVT_INLINE void AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const; 175 167 private: 176 btVector3 mi,mx;168 btVector3 mi,mx; 177 169 }; 178 170 … … 187 179 DBVT_INLINE bool isleaf() const { return(childs[1]==0); } 188 180 DBVT_INLINE bool isinternal() const { return(!isleaf()); } 189 union { 190 btDbvtNode* childs[2]; 191 void* data; 192 int dataAsInt; 193 }; 181 union 182 { 183 btDbvtNode* childs[2]; 184 void* data; 185 int dataAsInt; 186 }; 194 187 }; 195 188 … … 198 191 ///Unlike the btQuantizedBvh, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure. 199 192 struct btDbvt 200 193 { 201 194 /* Stack element */ 202 195 struct sStkNN 203 196 { 204 197 const btDbvtNode* a; 205 198 const btDbvtNode* b; 206 199 sStkNN() {} 207 200 sStkNN(const btDbvtNode* na,const btDbvtNode* nb) : a(na),b(nb) {} 208 201 }; 209 202 struct sStkNP 210 203 { 211 204 const btDbvtNode* node; 212 205 int mask; 213 206 sStkNP(const btDbvtNode* n,unsigned m) : node(n),mask(m) {} 214 207 }; 215 208 struct sStkNPS 216 209 { 217 210 const btDbvtNode* node; 218 211 int mask; … … 220 213 sStkNPS() {} 221 214 sStkNPS(const btDbvtNode* n,unsigned m,btScalar v) : node(n),mask(m),value(v) {} 222 215 }; 223 216 struct sStkCLN 224 217 { 225 218 const btDbvtNode* node; 226 219 btDbvtNode* parent; 227 220 sStkCLN(const btDbvtNode* n,btDbvtNode* p) : node(n),parent(p) {} 228 221 }; 229 222 // Policies/Interfaces 230 223 231 224 /* ICollide */ 232 225 struct ICollide 233 226 { 234 227 DBVT_VIRTUAL_DTOR(ICollide) 235 DBVT_VIRTUAL void Process(const btDbvtNode*,const btDbvtNode*) {}228 DBVT_VIRTUAL void Process(const btDbvtNode*,const btDbvtNode*) {} 236 229 DBVT_VIRTUAL void Process(const btDbvtNode*) {} 237 230 DBVT_VIRTUAL void Process(const btDbvtNode* n,btScalar) { Process(n); } 238 231 DBVT_VIRTUAL bool Descent(const btDbvtNode*) { return(true); } 239 232 DBVT_VIRTUAL bool AllLeaves(const btDbvtNode*) { return(true); } 240 233 }; 241 234 /* IWriter */ 242 235 struct IWriter 243 236 { 244 237 virtual ~IWriter() {} 245 238 virtual void Prepare(const btDbvtNode* root,int numnodes)=0; 246 239 virtual void WriteNode(const btDbvtNode*,int index,int parent,int child0,int child1)=0; 247 240 virtual void WriteLeaf(const btDbvtNode*,int index,int parent)=0; 248 241 }; 249 242 /* IClone */ 250 243 struct IClone 251 244 { 252 245 virtual ~IClone() {} 253 246 virtual void CloneLeaf(btDbvtNode*) {} 254 255 247 }; 248 256 249 // Constants 257 250 enum { 258 259 260 261 251 SIMPLE_STACKSIZE = 64, 252 DOUBLE_STACKSIZE = SIMPLE_STACKSIZE*2 253 }; 254 262 255 // Fields 263 256 btDbvtNode* m_root; … … 266 259 int m_leaves; 267 260 unsigned m_opath; 261 262 263 btAlignedObjectArray<sStkNN> m_stkStack; 264 265 268 266 // Methods 269 270 267 btDbvt(); 268 ~btDbvt(); 271 269 void clear(); 272 270 bool empty() const { return(0==m_root); } … … 276 274 btDbvtNode* insert(const btDbvtVolume& box,void* data); 277 275 void update(btDbvtNode* leaf,int lookahead=-1); 278 void update(btDbvtNode* leaf, constbtDbvtVolume& volume);279 bool update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity,btScalar margin);280 bool update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity);281 bool update(btDbvtNode* leaf,btDbvtVolume volume,btScalar margin);276 void update(btDbvtNode* leaf,btDbvtVolume& volume); 277 bool update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin); 278 bool update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity); 279 bool update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin); 282 280 void remove(btDbvtNode* leaf); 283 281 void write(IWriter* iwriter) const; … … 286 284 static int countLeaves(const btDbvtNode* node); 287 285 static void extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves); 288 286 #if DBVT_ENABLE_BENCHMARK 289 287 static void benchmark(); 290 288 #else 291 289 static void benchmark(){} 292 290 #endif 293 291 // DBVT_IPOLICY must support ICollide policy/interface 294 292 DBVT_PREFIX 295 static void enumNodes( const btDbvtNode* root,296 293 static void enumNodes( const btDbvtNode* root, 294 DBVT_IPOLICY); 297 295 DBVT_PREFIX 298 static void enumLeaves( const btDbvtNode* root,299 296 static void enumLeaves( const btDbvtNode* root, 297 DBVT_IPOLICY); 300 298 DBVT_PREFIX 301 static void collideTT( const btDbvtNode* root0, 302 const btDbvtNode* root1, 303 DBVT_IPOLICY); 299 void collideTT( const btDbvtNode* root0, 300 const btDbvtNode* root1, 301 DBVT_IPOLICY); 302 304 303 DBVT_PREFIX 305 static void collideTT( const btDbvtNode* root0,306 307 const btTransform& xform,308 DBVT_IPOLICY); 304 void collideTTpersistentStack( const btDbvtNode* root0, 305 const btDbvtNode* root1, 306 DBVT_IPOLICY); 307 309 308 DBVT_PREFIX 310 static void collideTT( const btDbvtNode* root0, 311 const btTransform& xform0, 312 const btDbvtNode* root1, 313 const btTransform& xform1, 314 DBVT_IPOLICY); 309 void collideTT( const btDbvtNode* root0, 310 const btDbvtNode* root1, 311 const btTransform& xform, 312 DBVT_IPOLICY); 315 313 DBVT_PREFIX 316 static void collideTV( const btDbvtNode* root, 317 const btDbvtVolume& volume, 318 DBVT_IPOLICY); 314 void collideTT( const btDbvtNode* root0, 315 const btTransform& xform0, 316 const btDbvtNode* root1, 317 const btTransform& xform1, 318 DBVT_IPOLICY); 319 319 DBVT_PREFIX 320 static void collideRAY( const btDbvtNode* root, 321 const btVector3& origin, 322 const btVector3& direction, 323 DBVT_IPOLICY); 320 void collideTV( const btDbvtNode* root, 321 const btDbvtVolume& volume, 322 DBVT_IPOLICY); 323 ///rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thread-safe (uses locking etc) 324 ///rayTest is slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time 324 325 DBVT_PREFIX 325 static void collideKDOP(const btDbvtNode* root, 326 const btVector3* normals, 327 const btScalar* offsets, 328 int count, 329 DBVT_IPOLICY); 326 static void rayTest( const btDbvtNode* root, 327 const btVector3& rayFrom, 328 const btVector3& rayTo, 329 DBVT_IPOLICY); 330 ///rayTestInternal is faster than rayTest, because it uses a persistent stack (to reduce dynamic memory allocations to a minimum) and it uses precomputed signs/rayInverseDirections 331 ///rayTestInternal is used by btDbvtBroadphase to accelerate world ray casts 330 332 DBVT_PREFIX 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); 333 void rayTestInternal( const btDbvtNode* root, 334 const btVector3& rayFrom, 335 const btVector3& rayTo, 336 const btVector3& rayDirectionInverse, 337 unsigned int signs[3], 338 btScalar lambda_max, 339 const btVector3& aabbMin, 340 const btVector3& aabbMax, 341 DBVT_IPOLICY) const; 342 338 343 DBVT_PREFIX 339 static void collideTU( const btDbvtNode* root, 340 DBVT_IPOLICY); 344 static void collideKDOP(const btDbvtNode* root, 345 const btVector3* normals, 346 const btScalar* offsets, 347 int count, 348 DBVT_IPOLICY); 349 DBVT_PREFIX 350 static void collideOCL( const btDbvtNode* root, 351 const btVector3* normals, 352 const btScalar* offsets, 353 const btVector3& sortaxis, 354 int count, 355 DBVT_IPOLICY, 356 bool fullsort=true); 357 DBVT_PREFIX 358 static void collideTU( const btDbvtNode* root, 359 DBVT_IPOLICY); 341 360 // Helpers 342 361 static DBVT_INLINE int nearest(const int* i,const btDbvt::sStkNPS* a,btScalar v,int l,int h) 343 362 { 344 363 int m=0; 345 364 while(l<h) 346 365 { 347 366 m=(l+h)>>1; 348 367 if(a[i[m]].value>=v) l=m+1; else h=m; 349 368 } 350 369 return(h); 351 370 } 352 371 static DBVT_INLINE int allocate( btAlignedObjectArray<int>& ifree, 353 354 355 372 btAlignedObjectArray<sStkNPS>& stock, 373 const sStkNPS& value) 374 { 356 375 int i; 357 376 if(ifree.size()>0) 358 359 360 377 { i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; } 378 else 379 { i=stock.size();stock.push_back(value); } 361 380 return(i); 362 381 } 363 382 // 364 365 366 383 private: 384 btDbvt(const btDbvt&) {} 385 }; 367 386 368 387 // … … 373 392 inline btDbvtAabbMm btDbvtAabbMm::FromCE(const btVector3& c,const btVector3& e) 374 393 { 375 btDbvtAabbMm box;376 box.mi=c-e;box.mx=c+e;377 return(box);378 } 379 394 btDbvtAabbMm box; 395 box.mi=c-e;box.mx=c+e; 396 return(box); 397 } 398 380 399 // 381 400 inline btDbvtAabbMm btDbvtAabbMm::FromCR(const btVector3& c,btScalar r) 382 401 { 383 return(FromCE(c,btVector3(r,r,r)));384 } 385 402 return(FromCE(c,btVector3(r,r,r))); 403 } 404 386 405 // 387 406 inline btDbvtAabbMm btDbvtAabbMm::FromMM(const btVector3& mi,const btVector3& mx) 388 407 { 389 btDbvtAabbMm box;390 box.mi=mi;box.mx=mx;391 return(box);392 } 393 408 btDbvtAabbMm box; 409 box.mi=mi;box.mx=mx; 410 return(box); 411 } 412 394 413 // 395 414 inline btDbvtAabbMm btDbvtAabbMm::FromPoints(const btVector3* pts,int n) 396 415 { 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]);416 btDbvtAabbMm box; 417 box.mi=box.mx=pts[0]; 418 for(int i=1;i<n;++i) 419 { 420 box.mi.setMin(pts[i]); 421 box.mx.setMax(pts[i]); 403 422 } 404 return(box);423 return(box); 405 424 } 406 425 … … 408 427 inline btDbvtAabbMm btDbvtAabbMm::FromPoints(const btVector3** ppts,int n) 409 428 { 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]);429 btDbvtAabbMm box; 430 box.mi=box.mx=*ppts[0]; 431 for(int i=1;i<n;++i) 432 { 433 box.mi.setMin(*ppts[i]); 434 box.mx.setMax(*ppts[i]); 416 435 } 417 return(box);436 return(box); 418 437 } 419 438 … … 421 440 DBVT_INLINE void btDbvtAabbMm::Expand(const btVector3& e) 422 441 { 423 mi-=e;mx+=e;424 } 425 442 mi-=e;mx+=e; 443 } 444 426 445 // 427 446 DBVT_INLINE void btDbvtAabbMm::SignedExpand(const btVector3& e) 428 447 { 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 448 if(e.x()>0) mx.setX(mx.x()+e[0]); else mi.setX(mi.x()+e[0]); 449 if(e.y()>0) mx.setY(mx.y()+e[1]); else mi.setY(mi.y()+e[1]); 450 if(e.z()>0) mx.setZ(mx.z()+e[2]); else mi.setZ(mi.z()+e[2]); 451 } 452 434 453 // 435 454 DBVT_INLINE bool btDbvtAabbMm::Contain(const btDbvtAabbMm& a) const 436 455 { 437 return( (mi.x()<=a.mi.x())&&456 return( (mi.x()<=a.mi.x())&& 438 457 (mi.y()<=a.mi.y())&& 439 458 (mi.z()<=a.mi.z())&& … … 446 465 DBVT_INLINE int btDbvtAabbMm::Classify(const btVector3& n,btScalar o,int s) const 447 466 { 448 btVector3 pi,px;449 switch(s)467 btVector3 pi,px; 468 switch(s) 450 469 { 451 470 case (0+0+0): px=btVector3(mi.x(),mi.y(),mi.z()); 452 471 pi=btVector3(mx.x(),mx.y(),mx.z());break; 453 472 case (1+0+0): px=btVector3(mx.x(),mi.y(),mi.z()); 454 473 pi=btVector3(mi.x(),mx.y(),mx.z());break; 455 474 case (0+2+0): px=btVector3(mi.x(),mx.y(),mi.z()); 456 475 pi=btVector3(mx.x(),mi.y(),mx.z());break; 457 476 case (1+2+0): px=btVector3(mx.x(),mx.y(),mi.z()); 458 477 pi=btVector3(mi.x(),mi.y(),mx.z());break; 459 478 case (0+0+4): px=btVector3(mi.x(),mi.y(),mx.z()); 460 479 pi=btVector3(mx.x(),mx.y(),mi.z());break; 461 480 case (1+0+4): px=btVector3(mx.x(),mi.y(),mx.z()); 462 481 pi=btVector3(mi.x(),mx.y(),mi.z());break; 463 482 case (0+2+4): px=btVector3(mi.x(),mx.y(),mx.z()); 464 483 pi=btVector3(mx.x(),mi.y(),mi.z());break; 465 484 case (1+2+4): px=btVector3(mx.x(),mx.y(),mx.z()); 466 485 pi=btVector3(mi.x(),mi.y(),mi.z());break; 467 486 } 468 if((dot(n,px)+o)<0) return(-1);469 if((dot(n,pi)+o)>=0) return(+1);470 return(0);487 if((dot(n,px)+o)<0) return(-1); 488 if((dot(n,pi)+o)>=0) return(+1); 489 return(0); 471 490 } 472 491 … … 474 493 DBVT_INLINE btScalar btDbvtAabbMm::ProjectMinimum(const btVector3& v,unsigned signs) const 475 494 { 476 const btVector3* b[]={&mx,&mi};477 const btVector3 p( b[(signs>>0)&1]->x(),478 479 480 return(dot(p,v));495 const btVector3* b[]={&mx,&mi}; 496 const btVector3 p( b[(signs>>0)&1]->x(), 497 b[(signs>>1)&1]->y(), 498 b[(signs>>2)&1]->z()); 499 return(dot(p,v)); 481 500 } 482 501 … … 484 503 DBVT_INLINE void btDbvtAabbMm::AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const 485 504 { 486 for(int i=0;i<3;++i)487 { 488 if(d[i]<0)505 for(int i=0;i<3;++i) 506 { 507 if(d[i]<0) 489 508 { smi+=mx[i]*d[i];smx+=mi[i]*d[i]; } 490 509 else … … 492 511 } 493 512 } 494 513 495 514 // 496 515 DBVT_INLINE bool Intersect( const btDbvtAabbMm& a, 497 516 const btDbvtAabbMm& b) 498 517 { 499 518 #if DBVT_INT0_IMPL == DBVT_IMPL_SSE 500 const __m128 rt(_mm_or_ps( _mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)),501 502 const __int32* pu((const __int32*)&rt);503 return((pu[0]|pu[1]|pu[2])==0);519 const __m128 rt(_mm_or_ps( _mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)), 520 _mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi)))); 521 const __int32* pu((const __int32*)&rt); 522 return((pu[0]|pu[1]|pu[2])==0); 504 523 #else 505 return( (a.mi.x()<=b.mx.x())&&524 return( (a.mi.x()<=b.mx.x())&& 506 525 (a.mx.x()>=b.mi.x())&& 507 526 (a.mi.y()<=b.mx.y())&& … … 514 533 // 515 534 DBVT_INLINE bool Intersect( const btDbvtAabbMm& a, 516 517 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);535 const btDbvtAabbMm& b, 536 const btTransform& xform) 537 { 538 const btVector3 d0=xform*b.Center()-a.Center(); 539 const btVector3 d1=d0*xform.getBasis(); 540 btScalar s0[2]={0,0}; 541 btScalar s1[2]={dot(xform.getOrigin(),d0),s1[0]}; 542 a.AddSpan(d0,s0[0],s0[1]); 543 b.AddSpan(d1,s1[0],s1[1]); 544 if(s0[0]>(s1[1])) return(false); 545 if(s0[1]<(s1[0])) return(false); 546 return(true); 528 547 } 529 548 530 549 // 531 550 DBVT_INLINE bool Intersect( const btDbvtAabbMm& a, 532 533 { 534 return( (b.x()>=a.mi.x())&&551 const btVector3& b) 552 { 553 return( (b.x()>=a.mi.x())&& 535 554 (b.y()>=a.mi.y())&& 536 555 (b.z()>=a.mi.z())&& … … 540 559 } 541 560 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 561 562 563 564 565 ////////////////////////////////////// 566 567 574 568 // 575 569 DBVT_INLINE btScalar Proximity( const btDbvtAabbMm& a, 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())); 580 } 570 const btDbvtAabbMm& b) 571 { 572 const btVector3 d=(a.mi+a.mx)-(b.mi+b.mx); 573 return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z())); 574 } 575 576 581 577 582 578 // 583 579 DBVT_INLINE int Select( const btDbvtAabbMm& o, 584 585 580 const btDbvtAabbMm& a, 581 const btDbvtAabbMm& b) 586 582 { 587 583 #if DBVT_SELECT_IMPL == DBVT_IMPL_SSE 588 static DBVT_ALIGN const unsigned __int32 mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff}; 589 // TODO: the intrinsic version is 11% slower 590 #if DBVT_USE_INTRINSIC_SSE 584 static ATTRIBUTE_ALIGNED16(const unsigned __int32) mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff}; 585 ///@todo: the intrinsic version is 11% slower 586 #if DBVT_USE_INTRINSIC_SSE 587 588 union btSSEUnion ///NOTE: if we use more intrinsics, move btSSEUnion into the LinearMath directory 589 { 590 __m128 ssereg; 591 float floats[4]; 592 int ints[4]; 593 }; 594 591 595 __m128 omi(_mm_load_ps(o.mi)); 592 596 omi=_mm_add_ps(omi,_mm_load_ps(o.mx)); … … 602 606 ami=_mm_add_ps(ami,t0); 603 607 ami=_mm_add_ss(ami,_mm_shuffle_ps(ami,ami,1)); 604 __m128 608 __m128 t1(_mm_movehl_ps(bmi,bmi)); 605 609 bmi=_mm_add_ps(bmi,t1); 606 610 bmi=_mm_add_ss(bmi,_mm_shuffle_ps(bmi,bmi,1)); 607 return(_mm_cmple_ss(bmi,ami).m128_u32[0]&1); 608 #else 609 DBVT_ALIGN __int32 r[1]; 611 612 btSSEUnion tmp; 613 tmp.ssereg = _mm_cmple_ss(bmi,ami); 614 return tmp.ints[0]&1; 615 616 #else 617 ATTRIBUTE_ALIGNED16(__int32 r[1]); 610 618 __asm 611 619 { 612 620 mov eax,o 613 mov ecx,a614 mov edx,b615 movaps xmm0,[eax]621 mov ecx,a 622 mov edx,b 623 movaps xmm0,[eax] 616 624 movaps xmm5,mask 617 addps xmm0,[eax+16]625 addps xmm0,[eax+16] 618 626 movaps xmm1,[ecx] 619 627 movaps xmm2,[edx] … … 621 629 addps xmm2,[edx+16] 622 630 subps xmm1,xmm0 623 subps xmm2,xmm0624 andps xmm1,xmm5625 andps xmm2,xmm5626 movhlps xmm3,xmm1627 movhlps xmm4,xmm2628 addps xmm1,xmm3629 addps xmm2,xmm4630 pshufd xmm3,xmm1,1631 pshufd xmm4,xmm2,1632 addss xmm1,xmm3633 addss xmm2,xmm4634 cmpless xmm2,xmm1635 movss r,xmm2636 631 subps xmm2,xmm0 632 andps xmm1,xmm5 633 andps xmm2,xmm5 634 movhlps xmm3,xmm1 635 movhlps xmm4,xmm2 636 addps xmm1,xmm3 637 addps xmm2,xmm4 638 pshufd xmm3,xmm1,1 639 pshufd xmm4,xmm2,1 640 addss xmm1,xmm3 641 addss xmm2,xmm4 642 cmpless xmm2,xmm1 643 movss r,xmm2 644 } 637 645 return(r[0]&1); 638 646 #endif 639 647 #else 640 return(Proximity(o,a)<Proximity(o,b)?0:1);648 return(Proximity(o,a)<Proximity(o,b)?0:1); 641 649 #endif 642 650 } … … 644 652 // 645 653 DBVT_INLINE void Merge( const btDbvtAabbMm& a, 646 647 654 const btDbvtAabbMm& b, 655 btDbvtAabbMm& r) 648 656 { 649 657 #if DBVT_MERGE_IMPL==DBVT_IMPL_SSE 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);658 __m128 ami(_mm_load_ps(a.mi)); 659 __m128 amx(_mm_load_ps(a.mx)); 660 __m128 bmi(_mm_load_ps(b.mi)); 661 __m128 bmx(_mm_load_ps(b.mx)); 662 ami=_mm_min_ps(ami,bmi); 663 amx=_mm_max_ps(amx,bmx); 664 _mm_store_ps(r.mi,ami); 665 _mm_store_ps(r.mx,amx); 658 666 #else 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];667 for(int i=0;i<3;++i) 668 { 669 if(a.mi[i]<b.mi[i]) r.mi[i]=a.mi[i]; else r.mi[i]=b.mi[i]; 670 if(a.mx[i]>b.mx[i]) r.mx[i]=a.mx[i]; else r.mx[i]=b.mx[i]; 663 671 } 664 672 #endif … … 667 675 // 668 676 DBVT_INLINE bool NotEqual( const btDbvtAabbMm& a, 669 670 { 671 return( (a.mi.x()!=b.mi.x())||677 const btDbvtAabbMm& b) 678 { 679 return( (a.mi.x()!=b.mi.x())|| 672 680 (a.mi.y()!=b.mi.y())|| 673 681 (a.mi.z()!=b.mi.z())|| … … 684 692 DBVT_PREFIX 685 693 inline void btDbvt::enumNodes( const btDbvtNode* root, 686 687 { 688 DBVT_CHECKTYPE689 policy.Process(root);690 if(root->isinternal())691 { 692 enumNodes(root->childs[0],policy);693 enumNodes(root->childs[1],policy);694 DBVT_IPOLICY) 695 { 696 DBVT_CHECKTYPE 697 policy.Process(root); 698 if(root->isinternal()) 699 { 700 enumNodes(root->childs[0],policy); 701 enumNodes(root->childs[1],policy); 694 702 } 695 703 } … … 698 706 DBVT_PREFIX 699 707 inline void btDbvt::enumLeaves( const btDbvtNode* root, 700 701 { 702 DBVT_CHECKTYPE703 if(root->isinternal())704 {705 enumLeaves(root->childs[0],policy);706 enumLeaves(root->childs[1],policy);707 }708 else709 {710 policy.Process(root);711 }708 DBVT_IPOLICY) 709 { 710 DBVT_CHECKTYPE 711 if(root->isinternal()) 712 { 713 enumLeaves(root->childs[0],policy); 714 enumLeaves(root->childs[1],policy); 715 } 716 else 717 { 718 policy.Process(root); 719 } 712 720 } 713 721 … … 715 723 DBVT_PREFIX 716 724 inline void btDbvt::collideTT( const btDbvtNode* root0, 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) 725 const btDbvtNode* root1, 726 DBVT_IPOLICY) 727 { 728 DBVT_CHECKTYPE 729 if(root0&&root1) 730 { 731 int depth=1; 732 int treshold=DOUBLE_STACKSIZE-4; 733 btAlignedObjectArray<sStkNN> stkStack; 734 stkStack.resize(DOUBLE_STACKSIZE); 735 stkStack[0]=sStkNN(root0,root1); 736 do { 737 sStkNN p=stkStack[--depth]; 738 if(depth>treshold) 739 { 740 stkStack.resize(stkStack.size()*2); 741 treshold=stkStack.size()-4; 742 } 743 if(p.a==p.b) 744 { 745 if(p.a->isinternal()) 746 { 747 stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]); 748 stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]); 749 stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]); 750 } 751 } 752 else if(Intersect(p.a->volume,p.b->volume)) 753 { 754 if(p.a->isinternal()) 755 { 756 if(p.b->isinternal()) 757 { 758 stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]); 759 stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]); 760 stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]); 761 stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]); 762 } 763 else 764 { 765 stkStack[depth++]=sStkNN(p.a->childs[0],p.b); 766 stkStack[depth++]=sStkNN(p.a->childs[1],p.b); 767 } 768 } 769 else 770 { 771 if(p.b->isinternal()) 772 { 773 stkStack[depth++]=sStkNN(p.a,p.b->childs[0]); 774 stkStack[depth++]=sStkNN(p.a,p.b->childs[1]); 775 } 776 else 777 { 778 policy.Process(p.a,p.b); 779 } 780 } 781 } 782 } while(depth); 783 } 784 } 785 786 787 788 DBVT_PREFIX 789 inline void btDbvt::collideTTpersistentStack( const btDbvtNode* root0, 790 const btDbvtNode* root1, 791 DBVT_IPOLICY) 792 { 793 DBVT_CHECKTYPE 794 if(root0&&root1) 795 { 796 int depth=1; 797 int treshold=DOUBLE_STACKSIZE-4; 798 799 m_stkStack.resize(DOUBLE_STACKSIZE); 800 m_stkStack[0]=sStkNN(root0,root1); 801 do { 802 sStkNN p=m_stkStack[--depth]; 803 if(depth>treshold) 804 { 805 m_stkStack.resize(m_stkStack.size()*2); 806 treshold=m_stkStack.size()-4; 807 } 808 if(p.a==p.b) 809 { 810 if(p.a->isinternal()) 811 { 812 m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]); 813 m_stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]); 814 m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]); 815 } 816 } 817 else if(Intersect(p.a->volume,p.b->volume)) 818 { 819 if(p.a->isinternal()) 820 { 821 if(p.b->isinternal()) 822 { 823 m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]); 824 m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]); 825 m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]); 826 m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]); 827 } 828 else 829 { 830 m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b); 831 m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b); 832 } 833 } 834 else 835 { 836 if(p.b->isinternal()) 837 { 838 m_stkStack[depth++]=sStkNN(p.a,p.b->childs[0]); 839 m_stkStack[depth++]=sStkNN(p.a,p.b->childs[1]); 840 } 841 else 842 { 843 policy.Process(p.a,p.b); 844 } 845 } 846 } 847 } while(depth); 848 } 849 } 850 851 852 // 853 DBVT_PREFIX 854 inline void btDbvt::collideTT( const btDbvtNode* root0, 855 const btDbvtNode* root1, 856 const btTransform& xform, 857 DBVT_IPOLICY) 858 { 859 DBVT_CHECKTYPE 860 if(root0&&root1) 861 { 862 int depth=1; 863 int treshold=DOUBLE_STACKSIZE-4; 864 btAlignedObjectArray<sStkNN> stkStack; 865 stkStack.resize(DOUBLE_STACKSIZE); 866 stkStack[0]=sStkNN(root0,root1); 867 do { 868 sStkNN p=stkStack[--depth]; 869 if(Intersect(p.a->volume,p.b->volume,xform)) 870 { 871 if(depth>treshold) 872 { 873 stkStack.resize(stkStack.size()*2); 874 treshold=stkStack.size()-4; 875 } 876 if(p.a->isinternal()) 877 { 878 if(p.b->isinternal()) 879 { 880 stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]); 881 stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]); 882 stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]); 883 stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]); 884 } 885 else 886 { 887 stkStack[depth++]=sStkNN(p.a->childs[0],p.b); 888 stkStack[depth++]=sStkNN(p.a->childs[1],p.b); 889 } 890 } 891 else 892 { 893 if(p.b->isinternal()) 894 { 895 stkStack[depth++]=sStkNN(p.a,p.b->childs[0]); 896 stkStack[depth++]=sStkNN(p.a,p.b->childs[1]); 897 } 898 else 899 { 900 policy.Process(p.a,p.b); 901 } 902 } 903 } 904 } while(depth); 905 } 906 } 907 908 // 909 DBVT_PREFIX 910 inline void btDbvt::collideTT( const btDbvtNode* root0, 911 const btTransform& xform0, 912 const btDbvtNode* root1, 913 const btTransform& xform1, 914 DBVT_IPOLICY) 915 { 916 const btTransform xform=xform0.inverse()*xform1; 917 collideTT(root0,root1,xform,policy); 918 } 919 920 // 921 DBVT_PREFIX 922 inline void btDbvt::collideTV( const btDbvtNode* root, 923 const btDbvtVolume& vol, 924 DBVT_IPOLICY) 925 { 926 DBVT_CHECKTYPE 927 if(root) 928 { 929 ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol); 930 btAlignedObjectArray<const btDbvtNode*> stack; 931 stack.resize(0); 932 stack.reserve(SIMPLE_STACKSIZE); 933 stack.push_back(root); 934 do { 935 const btDbvtNode* n=stack[stack.size()-1]; 936 stack.pop_back(); 937 if(Intersect(n->volume,volume)) 938 { 939 if(n->isinternal()) 940 { 941 stack.push_back(n->childs[0]); 942 stack.push_back(n->childs[1]); 943 } 944 else 945 { 946 policy.Process(n); 947 } 948 } 949 } while(stack.size()>0); 950 } 951 } 952 953 DBVT_PREFIX 954 inline void btDbvt::rayTestInternal( const btDbvtNode* root, 955 const btVector3& rayFrom, 956 const btVector3& rayTo, 957 const btVector3& rayDirectionInverse, 958 unsigned int signs[3], 959 btScalar lambda_max, 960 const btVector3& aabbMin, 961 const btVector3& aabbMax, 962 DBVT_IPOLICY) const 963 { 964 DBVT_CHECKTYPE 965 if(root) 966 { 967 btVector3 resultNormal; 968 969 int depth=1; 970 int treshold=DOUBLE_STACKSIZE-2; 971 btAlignedObjectArray<const btDbvtNode*> stack; 972 stack.resize(DOUBLE_STACKSIZE); 973 stack[0]=root; 974 btVector3 bounds[2]; 975 do 976 { 977 const btDbvtNode* node=stack[--depth]; 978 bounds[0] = node->volume.Mins()+aabbMin; 979 bounds[1] = node->volume.Maxs()+aabbMax; 980 btScalar tmin=1.f,lambda_min=0.f; 981 unsigned int result1=false; 982 result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max); 983 if(result1) 731 984 { 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()) 749 { 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]); 754 } 755 else 756 { 757 stack[depth++]=sStkNN(p.a->childs[0],p.b); 758 stack[depth++]=sStkNN(p.a->childs[1],p.b); 759 } 985 if(node->isinternal()) 986 { 987 if(depth>treshold) 988 { 989 stack.resize(stack.size()*2); 990 treshold=stack.size()-2; 991 } 992 stack[depth++]=node->childs[0]; 993 stack[depth++]=node->childs[1]; 760 994 } 761 995 else 762 996 { 763 if(p.b->isinternal()) 764 { 765 stack[depth++]=sStkNN(p.a,p.b->childs[0]); 766 stack[depth++]=sStkNN(p.a,p.b->childs[1]); 767 } 768 else 769 { 770 policy.Process(p.a,p.b); 771 } 997 policy.Process(node); 772 998 } 773 999 } … … 778 1004 // 779 1005 DBVT_PREFIX 780 inline void btDbvt::collideTT( const btDbvtNode* root0, 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]); 1006 inline void btDbvt::rayTest( const btDbvtNode* root, 1007 const btVector3& rayFrom, 1008 const btVector3& rayTo, 1009 DBVT_IPOLICY) 1010 { 1011 DBVT_CHECKTYPE 1012 if(root) 1013 { 1014 btVector3 rayDir = (rayTo-rayFrom); 1015 rayDir.normalize (); 1016 1017 ///what about division by zero? --> just set rayDirection[i] to INF/1e30 1018 btVector3 rayDirectionInverse; 1019 rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0]; 1020 rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1]; 1021 rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2]; 1022 unsigned int signs[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0}; 1023 1024 btScalar lambda_max = rayDir.dot(rayTo-rayFrom); 1025 1026 btVector3 resultNormal; 1027 1028 btAlignedObjectArray<const btDbvtNode*> stack; 1029 1030 int depth=1; 1031 int treshold=DOUBLE_STACKSIZE-2; 1032 1033 stack.resize(DOUBLE_STACKSIZE); 1034 stack[0]=root; 1035 btVector3 bounds[2]; 1036 do { 1037 const btDbvtNode* node=stack[--depth]; 1038 1039 bounds[0] = node->volume.Mins(); 1040 bounds[1] = node->volume.Maxs(); 1041 1042 btScalar tmin=1.f,lambda_min=0.f; 1043 unsigned int result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max); 1044 1045 #ifdef COMPARE_BTRAY_AABB2 1046 btScalar param=1.f; 1047 bool result2 = btRayAabb(rayFrom,rayTo,node->volume.Mins(),node->volume.Maxs(),param,resultNormal); 1048 btAssert(result1 == result2); 1049 #endif //TEST_BTRAY_AABB2 1050 1051 if(result1) 1052 { 1053 if(node->isinternal()) 1054 { 1055 if(depth>treshold) 1056 { 1057 stack.resize(stack.size()*2); 1058 treshold=stack.size()-2; 1059 } 1060 stack[depth++]=node->childs[0]; 1061 stack[depth++]=node->childs[1]; 810 1062 } 811 1063 else 812 1064 { 813 stack[depth++]=sStkNN(p.a->childs[0],p.b); 814 stack[depth++]=sStkNN(p.a->childs[1],p.b); 815 } 816 } 817 else 818 { 819 if(p.b->isinternal()) 820 { 821 stack[depth++]=sStkNN(p.a,p.b->childs[0]); 822 stack[depth++]=sStkNN(p.a,p.b->childs[1]); 823 } 824 else 825 { 826 policy.Process(p.a,p.b); 827 } 828 } 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 } 1065 policy.Process(node); 1066 } 1067 } 1068 } while(depth); 1069 1070 } 915 1071 } 916 1072 … … 923 1079 DBVT_IPOLICY) 924 1080 { 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) 1081 DBVT_CHECKTYPE 1082 if(root) 933 1083 { 934 signs[i]= ((normals[i].x()>=0)?1:0)+ 1084 const int inside=(1<<count)-1; 1085 btAlignedObjectArray<sStkNP> stack; 1086 int signs[sizeof(unsigned)*8]; 1087 btAssert(count<int (sizeof(signs)/sizeof(signs[0]))); 1088 for(int i=0;i<count;++i) 1089 { 1090 signs[i]= ((normals[i].x()>=0)?1:0)+ 935 1091 ((normals[i].y()>=0)?2:0)+ 936 1092 ((normals[i].z()>=0)?4:0); 1093 } 1094 stack.reserve(SIMPLE_STACKSIZE); 1095 stack.push_back(sStkNP(root,0)); 1096 do { 1097 sStkNP se=stack[stack.size()-1]; 1098 bool out=false; 1099 stack.pop_back(); 1100 for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1) 1101 { 1102 if(0==(se.mask&j)) 1103 { 1104 const int side=se.node->volume.Classify(normals[i],offsets[i],signs[i]); 1105 switch(side) 1106 { 1107 case -1: out=true;break; 1108 case +1: se.mask|=j;break; 1109 } 1110 } 1111 } 1112 if(!out) 1113 { 1114 if((se.mask!=inside)&&(se.node->isinternal())) 1115 { 1116 stack.push_back(sStkNP(se.node->childs[0],se.mask)); 1117 stack.push_back(sStkNP(se.node->childs[1],se.mask)); 1118 } 1119 else 1120 { 1121 if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy); 1122 } 1123 } 1124 } while(stack.size()); 937 1125 } 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 }955 }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 else964 {965 if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy);966 }967 }968 } while(stack.size());969 }970 1126 } 971 1127 … … 973 1129 DBVT_PREFIX 974 1130 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) 1131 const btVector3* normals, 1132 const btScalar* offsets, 1133 const btVector3& sortaxis, 1134 int count, 1135 DBVT_IPOLICY, 1136 bool fsort) 1137 { 1138 DBVT_CHECKTYPE 1139 if(root) 995 1140 { 996 signs[i]= ((normals[i].x()>=0)?1:0)+ 1141 const unsigned srtsgns=(sortaxis[0]>=0?1:0)+ 1142 (sortaxis[1]>=0?2:0)+ 1143 (sortaxis[2]>=0?4:0); 1144 const int inside=(1<<count)-1; 1145 btAlignedObjectArray<sStkNPS> stock; 1146 btAlignedObjectArray<int> ifree; 1147 btAlignedObjectArray<int> stack; 1148 int signs[sizeof(unsigned)*8]; 1149 btAssert(count<int (sizeof(signs)/sizeof(signs[0]))); 1150 for(int i=0;i<count;++i) 1151 { 1152 signs[i]= ((normals[i].x()>=0)?1:0)+ 997 1153 ((normals[i].y()>=0)?2:0)+ 998 1154 ((normals[i].z()>=0)?4:0); 1155 } 1156 stock.reserve(SIMPLE_STACKSIZE); 1157 stack.reserve(SIMPLE_STACKSIZE); 1158 ifree.reserve(SIMPLE_STACKSIZE); 1159 stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns)))); 1160 do { 1161 const int id=stack[stack.size()-1]; 1162 sStkNPS se=stock[id]; 1163 stack.pop_back();ifree.push_back(id); 1164 if(se.mask!=inside) 1165 { 1166 bool out=false; 1167 for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1) 1168 { 1169 if(0==(se.mask&j)) 1170 { 1171 const int side=se.node->volume.Classify(normals[i],offsets[i],signs[i]); 1172 switch(side) 1173 { 1174 case -1: out=true;break; 1175 case +1: se.mask|=j;break; 1176 } 1177 } 1178 } 1179 if(out) continue; 1180 } 1181 if(policy.Descent(se.node)) 1182 { 1183 if(se.node->isinternal()) 1184 { 1185 const btDbvtNode* pns[]={ se.node->childs[0],se.node->childs[1]}; 1186 sStkNPS nes[]={ sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)), 1187 sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))}; 1188 const int q=nes[0].value<nes[1].value?1:0; 1189 int j=stack.size(); 1190 if(fsort&&(j>0)) 1191 { 1192 /* Insert 0 */ 1193 j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size()); 1194 stack.push_back(0); 1195 #if DBVT_USE_MEMMOVE 1196 memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1)); 1197 #else 1198 for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1]; 1199 #endif 1200 stack[j]=allocate(ifree,stock,nes[q]); 1201 /* Insert 1 */ 1202 j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size()); 1203 stack.push_back(0); 1204 #if DBVT_USE_MEMMOVE 1205 memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1)); 1206 #else 1207 for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1]; 1208 #endif 1209 stack[j]=allocate(ifree,stock,nes[1-q]); 1210 } 1211 else 1212 { 1213 stack.push_back(allocate(ifree,stock,nes[q])); 1214 stack.push_back(allocate(ifree,stock,nes[1-q])); 1215 } 1216 } 1217 else 1218 { 1219 policy.Process(se.node,se.value); 1220 } 1221 } 1222 } while(stack.size()); 999 1223 } 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))1014 {1015 const int side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);1016 switch(side)1017 {1018 case -1: out=true;break;1019 case +1: se.mask|=j;break;1020 }1021 }1022 }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))1035 {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_MEMMOVE1040 memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));1041 #else1042 for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];1043 #endif1044 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_MEMMOVE1049 memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));1050 #else1051 for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];1052 #endif1053 stack[j]=allocate(ifree,stock,nes[1-q]);1054 }1055 else1056 {1057 stack.push_back(allocate(ifree,stock,nes[q]));1058 stack.push_back(allocate(ifree,stock,nes[1-q]));1059 }1060 }1061 else1062 {1063 policy.Process(se.node,se.value);1064 }1065 }1066 } while(stack.size());1067 }1068 1224 } 1069 1225 … … 1071 1227 DBVT_PREFIX 1072 1228 inline void btDbvt::collideTU( const btDbvtNode* root, 1073 1074 { 1075 DBVT_CHECKTYPE1076 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 else1089 { policy.Process(n); }1090 }1091 } while(stack.size()>0);1092 }1229 DBVT_IPOLICY) 1230 { 1231 DBVT_CHECKTYPE 1232 if(root) 1233 { 1234 btAlignedObjectArray<const btDbvtNode*> stack; 1235 stack.reserve(SIMPLE_STACKSIZE); 1236 stack.push_back(root); 1237 do { 1238 const btDbvtNode* n=stack[stack.size()-1]; 1239 stack.pop_back(); 1240 if(policy.Descent(n)) 1241 { 1242 if(n->isinternal()) 1243 { stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); } 1244 else 1245 { policy.Process(n); } 1246 } 1247 } while(stack.size()>0); 1248 } 1093 1249 } 1094 1250 -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp
r2192 r2430 27 27 #if DBVT_BP_PROFILE 28 28 struct ProfileScope 29 29 { 30 30 __forceinline ProfileScope(btClock& clock,unsigned long& value) : 31 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 item->links[0]=0;56 item->links[1]=list;57 if(list) list->links[0]=item;58 list=item;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 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];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 int n=0;74 while(root) { ++n;root=root->links[1]; }75 return(n);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 static const struct ZeroDummy : T {} zerodummy;83 value=zerodummy;82 static const struct ZeroDummy : T {} zerodummy; 83 value=zerodummy; 84 84 } 85 85 … … 91 91 struct btDbvtTreeCollider : btDbvt::ICollide 92 92 { 93 btDbvtBroadphase* pbp;94 btDbvtProxy* proxy;95 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 103 if(pa>pb) btSwap(pa,pb);104 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);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 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 137 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;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 clear(m_profiling);146 clear(m_profiling); 147 147 #endif 148 148 } … … 151 151 btDbvtBroadphase::~btDbvtBroadphase() 152 152 { 153 if(m_releasepaircache)154 {155 m_paircache->~btOverlappingPairCache();156 btAlignedFree(m_paircache);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( 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); 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 m_sets[0].collideTV(m_sets[0].m_root,aabb,collider); 186 m_sets[1].collideTV(m_sets[1].m_root,aabb,collider); 187 } 188 return(proxy); 186 189 } 187 190 188 191 // 189 192 void btDbvtBroadphase::destroyProxy( btBroadphaseProxy* absproxy, 190 191 { 192 btDbvtProxy* proxy=(btDbvtProxy*)absproxy;193 if(proxy->stage==STAGECOUNT)194 m_sets[1].remove(proxy->leaf);193 btDispatcher* dispatcher) 194 { 195 btDbvtProxy* proxy=(btDbvtProxy*)absproxy; 196 if(proxy->stage==STAGECOUNT) 197 m_sets[1].remove(proxy->leaf); 195 198 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; 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,const btVector3& aabbMin,const btVector3& aabbMax) 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].rayTestInternal( m_sets[0].m_root, 233 rayFrom, 234 rayTo, 235 rayCallback.m_rayDirectionInverse, 236 rayCallback.m_signs, 237 rayCallback.m_lambda_max, 238 aabbMin, 239 aabbMax, 240 callback); 241 242 m_sets[1].rayTestInternal( m_sets[1].m_root, 243 rayFrom, 244 rayTo, 245 rayCallback.m_rayDirectionInverse, 246 rayCallback.m_signs, 247 rayCallback.m_lambda_max, 248 aabbMin, 249 aabbMax, 250 callback); 251 201 252 } 202 253 203 254 // 204 255 void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy, 205 206 207 208 { 209 btDbvtProxy* proxy=(btDbvtProxy*)absproxy;210 ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax);256 const btVector3& aabbMin, 257 const btVector3& aabbMax, 258 btDispatcher* /*dispatcher*/) 259 { 260 btDbvtProxy* proxy=(btDbvtProxy*)absproxy; 261 ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax); 211 262 #if DBVT_BP_PREVENTFALSEUPDATE 212 if(NotEqual(aabb,proxy->leaf->volume))213 #endif 214 { 215 bool docollide=false;216 if(proxy->stage==STAGECOUNT)263 if(NotEqual(aabb,proxy->leaf->volume)) 264 #endif 265 { 266 bool docollide=false; 267 if(proxy->stage==STAGECOUNT) 217 268 {/* fixed -> dynamic set */ 218 m_sets[1].remove(proxy->leaf);219 proxy->leaf=m_sets[0].insert(aabb,proxy);220 docollide=true;269 m_sets[1].remove(proxy->leaf); 270 proxy->leaf=m_sets[0].insert(aabb,proxy); 271 docollide=true; 221 272 } 222 273 else 223 274 {/* dynamic set */ 224 ++m_updates_call;225 if(Intersect(proxy->leaf->volume,aabb))275 ++m_updates_call; 276 if(Intersect(proxy->leaf->volume,aabb)) 226 277 {/* Moving */ 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 ) 278 279 const btVector3 delta=aabbMin-proxy->m_aabbMin; 280 btVector3 velocity(((proxy->m_aabbMax-proxy->m_aabbMin)/2)*m_prediction); 281 if(delta[0]<0) velocity[0]=-velocity[0]; 282 if(delta[1]<0) velocity[1]=-velocity[1]; 283 if(delta[2]<0) velocity[2]=-velocity[2]; 284 if ( 285 #ifdef DBVT_BP_MARGIN 286 m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN) 287 #else 288 m_sets[0].update(proxy->leaf,aabb,velocity) 289 #endif 290 ) 239 291 { 240 ++m_updates_done;241 docollide=true;292 ++m_updates_done; 293 docollide=true; 242 294 } 243 295 } 244 296 else 245 297 {/* Teleporting */ 246 m_sets[0].update(proxy->leaf,aabb);247 ++m_updates_done;248 docollide=true;298 m_sets[0].update(proxy->leaf,aabb); 299 ++m_updates_done; 300 docollide=true; 249 301 } 250 302 } 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) 303 listremove(proxy,m_stageRoots[proxy->stage]); 304 proxy->m_aabbMin = aabbMin; 305 proxy->m_aabbMax = aabbMax; 306 proxy->stage = m_stageCurrent; 307 listappend(proxy,m_stageRoots[m_stageCurrent]); 308 if(docollide) 309 { 310 m_needcleanup=true; 311 if(!m_deferedcollide) 259 312 { 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);313 btDbvtTreeCollider collider(this); 314 m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider); 315 m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider); 263 316 } 264 317 } … … 269 322 void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) 270 323 { 271 collide(dispatcher);324 collide(dispatcher); 272 325 #if DBVT_BP_PROFILE 273 if(0==(m_pid%DBVT_BP_PROFILING_RATE))326 if(0==(m_pid%DBVT_BP_PROFILING_RATE)) 274 327 { 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 284 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();328 printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leaves,m_sets[0].m_leaves,m_paircache->getNumOverlappingPairs()); 329 unsigned int total=m_profiling.m_total; 330 if(total<=0) total=1; 331 printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE); 332 printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE); 333 printf("cleanup: %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE); 334 printf("total: %uus\r\n",total/DBVT_BP_PROFILING_RATE); 335 const unsigned long sum=m_profiling.m_ddcollide+ 336 m_profiling.m_fdcollide+ 337 m_profiling.m_cleanup; 338 printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE); 339 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)); 340 clear(m_profiling); 341 m_clock.reset(); 289 342 } 290 343 #endif … … 294 347 void btDbvtBroadphase::collide(btDispatcher* dispatcher) 295 348 { 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; 349 SPC(m_profiling.m_total); 350 /* optimize */ 351 m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100); 352 if(m_fixedleft) 353 { 354 const int count=1+(m_sets[1].m_leaves*m_fupdates)/100; 355 m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100); 356 m_fixedleft=btMax<int>(0,m_fixedleft-count); 357 } 358 /* dynamic -> fixed set */ 359 m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT; 360 btDbvtProxy* current=m_stageRoots[m_stageCurrent]; 361 if(current) 362 { 363 btDbvtTreeCollider collider(this); 364 do { 365 btDbvtProxy* next=current->links[1]; 366 listremove(current,m_stageRoots[current->stage]); 367 listappend(current,m_stageRoots[STAGECOUNT]); 368 #if DBVT_BP_ACCURATESLEEPING 369 m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher); 370 collider.proxy=current; 371 btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider); 372 btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider); 373 #endif 374 m_sets[0].remove(current->leaf); 375 ATTRIBUTE_ALIGNED16(btDbvtVolume) curAabb=btDbvtVolume::FromMM(current->m_aabbMin,current->m_aabbMax); 376 current->leaf = m_sets[1].insert(curAabb,current); 377 current->stage = STAGECOUNT; 378 current = next; 325 379 } while(current); 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)380 m_fixedleft=m_sets[1].m_leaves; 381 m_needcleanup=true; 382 } 383 /* collide dynamics */ 384 { 385 btDbvtTreeCollider collider(this); 386 if(m_deferedcollide) 387 { 388 SPC(m_profiling.m_fdcollide); 389 m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[1].m_root,collider); 390 } 391 if(m_deferedcollide) 392 { 393 SPC(m_profiling.m_ddcollide); 394 m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[0].m_root,collider); 395 } 396 } 397 /* clean up */ 398 if(m_needcleanup) 399 { 400 SPC(m_profiling.m_cleanup); 401 btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray(); 402 if(pairs.size()>0) 403 { 404 const int ci=pairs.size(); 405 int ni=btMin(ci,btMax<int>(m_newpairs,(ci*m_cupdates)/100)); 406 for(int i=0;i<ni;++i) 353 407 { 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))408 btBroadphasePair& p=pairs[(m_cid+i)%ci]; 409 btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0; 410 btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1; 411 if(!Intersect(pa->leaf->volume,pb->leaf->volume)) 358 412 { 359 360 if(pa>pb) btSwap(pa,pb);361 362 m_paircache->removeOverlappingPair(pa,pb,dispatcher);363 --ni;--i;413 #if DBVT_BP_SORTPAIRS 414 if(pa>pb) btSwap(pa,pb); 415 #endif 416 m_paircache->removeOverlappingPair(pa,pb,dispatcher); 417 --ni;--i; 364 418 } 365 419 } 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)420 if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0; 421 } 422 } 423 ++m_pid; 424 m_newpairs=1; 425 m_needcleanup=false; 426 if(m_updates_call>0) 373 427 { m_updates_ratio=m_updates_done/(btScalar)m_updates_call; } 374 428 else 375 429 { m_updates_ratio=0; } 376 m_updates_done/=2;377 m_updates_call/=2;430 m_updates_done/=2; 431 m_updates_call/=2; 378 432 } 379 433 … … 381 435 void btDbvtBroadphase::optimize() 382 436 { 383 m_sets[0].optimizeTopDown();384 m_sets[1].optimizeTopDown();437 m_sets[0].optimizeTopDown(); 438 m_sets[1].optimizeTopDown(); 385 439 } 386 440 … … 388 442 btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() 389 443 { 390 return(m_paircache);444 return(m_paircache); 391 445 } 392 446 … … 394 448 const btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() const 395 449 { 396 return(m_paircache);450 return(m_paircache); 397 451 } 398 452 … … 403 457 ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds; 404 458 405 if(!m_sets[0].empty())406 if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume,407 408 409 410 else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume;411 412 413 aabbMin=bounds.Mins();414 aabbMax=bounds.Maxs();459 if(!m_sets[0].empty()) 460 if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume, 461 m_sets[1].m_root->volume,bounds); 462 else 463 bounds=m_sets[0].m_root->volume; 464 else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume; 465 else 466 bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0); 467 aabbMin=bounds.Mins(); 468 aabbMax=bounds.Maxs(); 415 469 } 416 470 … … 423 477 424 478 struct btBroadphaseBenchmark 425 479 { 426 480 struct Experiment 427 481 { 428 482 const char* name; 429 483 int object_count; … … 433 487 btScalar speed; 434 488 btScalar amplitude; 435 489 }; 436 490 struct Object 437 491 { 438 492 btVector3 center; 439 493 btVector3 extents; … … 441 495 btScalar time; 442 496 void update(btScalar speed,btScalar amplitude,btBroadphaseInterface* pbi) 443 497 { 444 498 time += speed; 445 499 center[0] = btCos(time*(btScalar)2.17)*amplitude+ 446 500 btSin(time)*amplitude/2; 447 501 center[1] = btCos(time*(btScalar)1.38)*amplitude+ 448 502 btSin(time)*amplitude; 449 503 center[2] = btSin(time*(btScalar)0.777)*amplitude; 450 504 pbi->setAabb(proxy,center-extents,center+extents,0); 451 452 505 } 506 }; 453 507 static int UnsignedRand(int range=RAND_MAX-1) { return(rand()%(range+1)); } 454 508 static btScalar UnitRand() { return(UnsignedRand(16384)/(btScalar)16384); } 455 509 static void OutputTime(const char* name,btClock& c,unsigned count=0) 456 510 { 457 511 const unsigned long us=c.getTimeMicroseconds(); 458 512 const unsigned long ms=(us+500)/1000; … … 460 514 if(count>0) 461 515 printf("%s : %u us (%u ms), %.2f/s\r\n",name,us,ms,count/sec); 462 516 else 463 517 printf("%s : %u us (%u ms)\r\n",name,us,ms); 464 } 518 } 519 }; 520 521 void btDbvtBroadphase::benchmark(btBroadphaseInterface* pbi) 522 { 523 static const btBroadphaseBenchmark::Experiment experiments[]= 524 { 525 {"1024o.10%",1024,10,0,8192,(btScalar)0.005,(btScalar)100}, 526 /*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100}, 527 {"8192o.10%",8192,10,0,8192,(btScalar)0.005,(btScalar)100},*/ 465 528 }; 466 467 void btDbvtBroadphase::benchmark(btBroadphaseInterface* pbi) 468 { 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},*/ 474 }; 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) 529 static const int nexperiments=sizeof(experiments)/sizeof(experiments[0]); 530 btAlignedObjectArray<btBroadphaseBenchmark::Object*> objects; 531 btClock wallclock; 532 /* Begin */ 533 for(int iexp=0;iexp<nexperiments;++iexp) 534 { 535 const btBroadphaseBenchmark::Experiment& experiment=experiments[iexp]; 536 const int object_count=experiment.object_count; 537 const int update_count=(object_count*experiment.update_count)/100; 538 const int spawn_count=(object_count*experiment.spawn_count)/100; 539 const btScalar speed=experiment.speed; 540 const btScalar amplitude=experiment.amplitude; 541 printf("Experiment #%u '%s':\r\n",iexp,experiment.name); 542 printf("\tObjects: %u\r\n",object_count); 543 printf("\tUpdate: %u\r\n",update_count); 544 printf("\tSpawn: %u\r\n",spawn_count); 545 printf("\tSpeed: %f\r\n",speed); 546 printf("\tAmplitude: %f\r\n",amplitude); 547 srand(180673); 548 /* Create objects */ 549 wallclock.reset(); 550 objects.reserve(object_count); 551 for(int i=0;i<object_count;++i) 552 { 553 btBroadphaseBenchmark::Object* po=new btBroadphaseBenchmark::Object(); 554 po->center[0]=btBroadphaseBenchmark::UnitRand()*50; 555 po->center[1]=btBroadphaseBenchmark::UnitRand()*50; 556 po->center[2]=btBroadphaseBenchmark::UnitRand()*50; 557 po->extents[0]=btBroadphaseBenchmark::UnitRand()*2+2; 558 po->extents[1]=btBroadphaseBenchmark::UnitRand()*2+2; 559 po->extents[2]=btBroadphaseBenchmark::UnitRand()*2+2; 560 po->time=btBroadphaseBenchmark::UnitRand()*2000; 561 po->proxy=pbi->createProxy(po->center-po->extents,po->center+po->extents,0,po,1,1,0,0); 562 objects.push_back(po); 563 } 564 btBroadphaseBenchmark::OutputTime("\tInitialization",wallclock); 565 /* First update */ 566 wallclock.reset(); 567 for(int i=0;i<objects.size();++i) 568 { 569 objects[i]->update(speed,amplitude,pbi); 570 } 571 btBroadphaseBenchmark::OutputTime("\tFirst update",wallclock); 572 /* Updates */ 573 wallclock.reset(); 574 for(int i=0;i<experiment.iterations;++i) 575 { 576 for(int j=0;j<update_count;++j) 523 577 { 524 objects[j]->update(speed,amplitude,pbi);578 objects[j]->update(speed,amplitude,pbi); 525 579 } 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);580 pbi->calculateOverlappingPairs(0); 581 } 582 btBroadphaseBenchmark::OutputTime("\tUpdate",wallclock,experiment.iterations); 583 /* Clean up */ 584 wallclock.reset(); 585 for(int i=0;i<objects.size();++i) 586 { 587 pbi->destroyProxy(objects[i]->proxy,0); 588 delete objects[i]; 589 } 590 objects.resize(0); 591 btBroadphaseBenchmark::OutputTime("\tRelease",wallclock); 538 592 } 539 593 -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h
r2192 r2430 32 32 33 33 #if DBVT_BP_PROFILE 34 35 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 /* 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)43 /* Fields */ 44 //btDbvtAabbMm aabb; 45 btDbvtNode* leaf; 46 btDbvtProxy* links[2]; 47 int stage; 48 /* ctor */ 49 btDbvtProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) : 50 btBroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask) 51 51 { 52 links[0]=links[1]=0;52 links[0]=links[1]=0; 53 53 } 54 54 }; … … 61 61 struct btDbvtBroadphase : btBroadphaseInterface 62 62 { 63 /* Config */64 enum {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 /* Fields */70 btDbvt m_sets[2]; // Dbvt sets71 btDbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list72 btOverlappingPairCache* m_paircache; // Pair cache73 btScalar m_prediction; // Velocity prediction74 int m_stageCurrent; // Current stage75 int m_fupdates; // % of fixed updates per frame76 int m_dupdates; // % of dynamic updates per frame77 int m_cupdates; // % of cleanup updates per frame78 int m_newpairs; // Number of pairs created79 int m_fixedleft; // Fixed optimization left80 unsigned m_updates_call; // Number of updates call81 unsigned m_updates_done; // Number of updates done82 btScalar m_updates_ratio; // m_updates_done/m_updates_call83 int m_pid; // Parse id84 int m_cid; // Cleanup index85 int m_gid; // Gen id86 bool m_releasepaircache; // Release pair cache on delete87 bool m_deferedcollide; // Defere dynamic/static collision to collide call88 bool m_needcleanup; // Need to run cleanup?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 btClock m_clock;91 struct {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 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 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*); 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, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)); 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*); 114 117 }; 115 118 -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDispatcher.h
r2192 r2430 47 47 m_useEpa(true), 48 48 m_allowedCcdPenetration(btScalar(0.04)), 49 m_useConvexConservativeDistanceUtil(true), 50 m_convexConservativeDistanceThreshold(0.0f), 49 51 m_stackAllocator(0) 50 52 { … … 52 54 } 53 55 btScalar m_timeStep; 54 int m_stepCount;55 int m_dispatchFunc;56 int m_stepCount; 57 int m_dispatchFunc; 56 58 mutable btScalar m_timeOfImpact; 57 bool m_useContinuous;59 bool m_useContinuous; 58 60 class btIDebugDraw* m_debugDraw; 59 bool m_enableSatConvex;60 bool m_enableSPU;61 bool m_useEpa;61 bool m_enableSatConvex; 62 bool m_enableSPU; 63 bool m_useEpa; 62 64 btScalar m_allowedCcdPenetration; 65 bool m_useConvexConservativeDistanceUtil; 66 btScalar m_convexConservativeDistanceThreshold; 63 67 btStackAlloc* m_stackAllocator; 64 65 68 }; 66 69 -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp
r2192 r2430 150 150 151 151 152 void btMultiSapBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const 153 { 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, const btVector3& aabbMin,const btVector3& aabbMax) 160 { 161 for (int i=0;i<m_multiSapProxies.size();i++) 162 { 163 rayCallback.process(m_multiSapProxies[i]); 164 } 165 } 166 167 152 168 //#include <stdio.h> 153 169 … … 209 225 210 226 211 m_optimizedAabbTree->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax); 227 if (m_optimizedAabbTree) 228 m_optimizedAabbTree->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax); 229 212 230 int i; 213 231 -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h
r2192 r2430 27 27 typedef btAlignedObjectArray<btBroadphaseInterface*> btSapBroadphaseArray; 28 28 29 ///The btMultiSapBroadphase is a research project, not recommended to use in production. Use btAxisSweep3 or btDbvtBroadphase instead. 29 30 ///The btMultiSapBroadphase is a broadphase that contains multiple SAP broadphases. 30 31 ///The user can add SAP broadphases that cover the world. A btBroadphaseProxy can be in multiple child broadphases at the same time. … … 73 74 */ 74 75 btMultiSapProxy(const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask) 75 :btBroadphaseProxy( userPtr,collisionFilterGroup,collisionFilterMask),76 :btBroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask), 76 77 m_aabbMin(aabbMin), 77 78 m_aabbMax(aabbMax), … … 109 110 virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); 110 111 virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher); 112 virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; 113 114 virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0)); 111 115 112 116 void addToChildBroadphase(btMultiSapProxy* parentMultiSapProxy, btBroadphaseProxy* childProxy, btBroadphaseInterface* childBroadphase); -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
r2192 r2430 34 34 btHashedOverlappingPairCache::btHashedOverlappingPairCache(): 35 35 m_overlapFilterCallback(0), 36 m_blockedForChanges(false) 36 m_blockedForChanges(false), 37 m_ghostPairCallback(0) 37 38 { 38 39 int initialAllocatedSize= 2; … … 46 47 btHashedOverlappingPairCache::~btHashedOverlappingPairCache() 47 48 { 48 //todo/test: show we erase/delete data, or is it automatic49 49 } 50 50 … … 239 239 int oldCapacity = m_overlappingPairArray.capacity(); 240 240 void* mem = &m_overlappingPairArray.expand(); 241 242 //this is where we add an actual pair, so also call the 'ghost' 243 if (m_ghostPairCallback) 244 m_ghostPairCallback->addOverlappingPair(proxy0,proxy1); 245 241 246 int newCapacity = m_overlappingPairArray.capacity(); 242 247 … … 252 257 // pair->m_pProxy1 = proxy1; 253 258 pair->m_algorithm = 0; 254 pair->m_ userInfo= 0;259 pair->m_internalTmpValue = 0; 255 260 256 261 … … 283 288 cleanOverlappingPair(*pair,dispatcher); 284 289 285 void* userData = pair->m_ userInfo;290 void* userData = pair->m_internalInfo1; 286 291 287 292 btAssert(pair->m_pProxy0->getUid() == proxyId1); … … 317 322 318 323 int lastPairIndex = m_overlappingPairArray.size() - 1; 324 325 if (m_ghostPairCallback) 326 m_ghostPairCallback->removeOverlappingPair(proxy0, proxy1,dispatcher); 319 327 320 328 // If the removed pair is the last pair, we are done. … … 398 406 gOverlappingPairs--; 399 407 btBroadphasePair& pair = m_overlappingPairArray[findIndex]; 400 void* userData = pair.m_ userInfo;408 void* userData = pair.m_internalInfo1; 401 409 cleanOverlappingPair(pair,dispatcher); 410 if (m_ghostPairCallback) 411 m_ghostPairCallback->removeOverlappingPair(proxy0, proxy1,dispatcher); 402 412 403 413 m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.capacity()-1); … … 427 437 void* mem = &m_overlappingPairArray.expand(); 428 438 btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1); 439 429 440 gOverlappingPairs++; 430 441 gAddedPairs++; 442 443 if (m_ghostPairCallback) 444 m_ghostPairCallback->addOverlappingPair(proxy0, proxy1); 431 445 return pair; 432 446 … … 494 508 m_blockedForChanges(false), 495 509 m_hasDeferredRemoval(true), 496 m_overlapFilterCallback(0) 510 m_overlapFilterCallback(0), 511 m_ghostPairCallback(0) 497 512 { 498 513 int initialAllocatedSize= 2; … … 502 517 btSortedOverlappingPairCache::~btSortedOverlappingPairCache() 503 518 { 504 //todo/test: show we erase/delete data, or is it automatic505 519 } 506 520 -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
r2192 r2430 22 22 #include "btOverlappingPairCallback.h" 23 23 24 #include "LinearMath/btPoint3.h"25 24 #include "LinearMath/btAlignedObjectArray.h" 26 25 class btDispatcher; … … 83 82 84 83 virtual bool hasDeferredRemoval() = 0; 84 85 virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)=0; 85 86 86 87 }; … … 254 255 } 255 256 257 virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback) 258 { 259 m_ghostPairCallback = ghostPairCallback; 260 } 261 256 262 public: 257 263 258 264 btAlignedObjectArray<int> m_hashTable; 259 265 btAlignedObjectArray<int> m_next; 266 btOverlappingPairCallback* m_ghostPairCallback; 260 267 261 268 }; … … 280 287 //if set, use the callback instead of the built in filter in needBroadphaseCollision 281 288 btOverlapFilterCallback* m_overlapFilterCallback; 289 290 btOverlappingPairCallback* m_ghostPairCallback; 282 291 283 292 public: … … 356 365 } 357 366 358 359 }; 360 361 362 363 ///btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and testing. 367 virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback) 368 { 369 m_ghostPairCallback = ghostPairCallback; 370 } 371 372 373 }; 374 375 376 377 ///btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing. 364 378 class btNullPairCache : public btOverlappingPairCache 365 379 { … … 415 429 } 416 430 431 virtual void setInternalGhostPairCallback(btOverlappingPairCallback* /* ghostPairCallback */) 432 { 433 434 } 435 417 436 virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/) 418 437 { … … 428 447 { 429 448 } 449 430 450 431 451 -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
r2192 r2430 19 19 #include "LinearMath/btIDebugDraw.h" 20 20 21 22 btQuantizedBvh::btQuantizedBvh() : m_useQuantization(false), 21 #define RAYAABB2 22 23 btQuantizedBvh::btQuantizedBvh() : 24 m_bulletVersion(BT_BULLET_VERSION), 25 m_useQuantization(false), 23 26 //m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY) 24 27 m_traversalMode(TRAVERSAL_STACKLESS) 25 28 //m_traversalMode(TRAVERSAL_RECURSIVE) 26 29 ,m_subtreeHeaderCount(0) //PCK: add this line 27 { 28 30 { 31 m_bvhAabbMin.setValue(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY); 32 m_bvhAabbMax.setValue(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY); 29 33 } 30 34 … … 120 124 int curIndex = m_curNodeIndex; 121 125 122 assert(numIndices>0);126 btAssert(numIndices>0); 123 127 124 128 if (numIndices==1) … … 141 145 int internalNodeIndex = m_curNodeIndex; 142 146 143 setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin); 144 setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax); 147 //set the min aabb to 'inf' or a max value, and set the max aabb to a -inf/minimum value. 148 //the aabb will be expanded during buildTree/mergeInternalNodeAabb with actual node values 149 setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);//can't use btVector3(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY)) because of quantization 150 setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);//can't use btVector3(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY)) because of quantization 151 145 152 146 153 for (i=startIndex;i<endIndex;i++) … … 178 185 updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex); 179 186 } 187 } else 188 { 189 180 190 } 181 191 … … 339 349 int maxIterations = 0; 340 350 351 341 352 void btQuantizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const 342 353 { … … 353 364 { 354 365 //catch bugs in tree data 355 assert (walkIterations < m_curNodeIndex);366 btAssert (walkIterations < m_curNodeIndex); 356 367 357 368 walkIterations++; … … 435 446 436 447 448 void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const 449 { 450 btAssert(!m_useQuantization); 451 452 const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0]; 453 int escapeIndex, curIndex = 0; 454 int walkIterations = 0; 455 bool isLeafNode; 456 //PCK: unsigned instead of bool 457 unsigned aabbOverlap=0; 458 unsigned rayBoxOverlap=0; 459 btScalar lambda_max = 1.0; 460 461 /* Quick pruning by quantized box */ 462 btVector3 rayAabbMin = raySource; 463 btVector3 rayAabbMax = raySource; 464 rayAabbMin.setMin(rayTarget); 465 rayAabbMax.setMax(rayTarget); 466 467 /* Add box cast extents to bounding box */ 468 rayAabbMin += aabbMin; 469 rayAabbMax += aabbMax; 470 471 #ifdef RAYAABB2 472 btVector3 rayFrom = raySource; 473 btVector3 rayDir = (rayTarget-raySource); 474 rayDir.normalize (); 475 lambda_max = rayDir.dot(rayTarget-raySource); 476 ///what about division by zero? --> just set rayDirection[i] to 1.0 477 btVector3 rayDirectionInverse; 478 rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0]; 479 rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1]; 480 rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2]; 481 unsigned int sign[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0}; 482 #endif 483 484 btVector3 bounds[2]; 485 486 while (curIndex < m_curNodeIndex) 487 { 488 btScalar param = 1.0; 489 //catch bugs in tree data 490 btAssert (walkIterations < m_curNodeIndex); 491 492 walkIterations++; 493 494 bounds[0] = rootNode->m_aabbMinOrg; 495 bounds[1] = rootNode->m_aabbMaxOrg; 496 /* Add box cast extents */ 497 bounds[0] += aabbMin; 498 bounds[1] += aabbMax; 499 500 aabbOverlap = TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg); 501 //perhaps profile if it is worth doing the aabbOverlap test first 502 503 #ifdef RAYAABB2 504 ///careful with this check: need to check division by zero (above) and fix the unQuantize method 505 ///thanks Joerg/hiker for the reproduction case! 506 ///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858 507 rayBoxOverlap = aabbOverlap ? btRayAabb2 (raySource, rayDirectionInverse, sign, bounds, param, 0.0f, lambda_max) : false; 508 509 #else 510 btVector3 normal; 511 rayBoxOverlap = btRayAabb(raySource, rayTarget,bounds[0],bounds[1],param, normal); 512 #endif 513 514 isLeafNode = rootNode->m_escapeIndex == -1; 515 516 //PCK: unsigned instead of bool 517 if (isLeafNode && (rayBoxOverlap != 0)) 518 { 519 nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex); 520 } 521 522 //PCK: unsigned instead of bool 523 if ((rayBoxOverlap != 0) || isLeafNode) 524 { 525 rootNode++; 526 curIndex++; 527 } else 528 { 529 escapeIndex = rootNode->m_escapeIndex; 530 rootNode += escapeIndex; 531 curIndex += escapeIndex; 532 } 533 } 534 if (maxIterations < walkIterations) 535 maxIterations = walkIterations; 536 537 } 538 437 539 438 540 … … 455 557 456 558 btScalar lambda_max = 1.0; 457 #define RAYAABB2 559 458 560 #ifdef RAYAABB2 459 561 btVector3 rayFrom = raySource; … … 503 605 504 606 //catch bugs in tree data 505 assert (walkIterations < subTreeSize);607 btAssert (walkIterations < subTreeSize); 506 608 507 609 walkIterations++; … … 534 636 ///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858 535 637 638 //BT_PROFILE("btRayAabb2"); 536 639 rayBoxOverlap = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0f, lambda_max); 640 537 641 #else 538 642 rayBoxOverlap = true;//btRayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal); … … 598 702 599 703 //catch bugs in tree data 600 assert (walkIterations < subTreeSize);704 btAssert (walkIterations < subTreeSize); 601 705 602 706 walkIterations++; … … 653 757 void btQuantizedBvh::reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const 654 758 { 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 } 759 reportBoxCastOverlappingNodex(nodeCallback,raySource,rayTarget,btVector3(0,0,0),btVector3(0,0,0)); 667 760 } 668 761 … … 670 763 void btQuantizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const 671 764 { 672 bool fast_path = m_useQuantization && m_traversalMode == TRAVERSAL_STACKLESS; 673 if (fast_path) 765 //always use stackless 766 767 if (m_useQuantization) 674 768 { 675 769 walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex); 676 } else { 677 /* Slow path: 678 Construct the bounding box for the entire box cast and send that down the tree */ 770 } 771 else 772 { 773 walkStacklessTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex); 774 } 775 /* 776 { 777 //recursive traversal 679 778 btVector3 qaabbMin = raySource; 680 779 btVector3 qaabbMax = raySource; … … 685 784 reportAabbOverlappingNodex(nodeCallback,qaabbMin,qaabbMax); 686 785 } 786 */ 787 687 788 } 688 789 … … 744 845 bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian) 745 846 { 746 assert(m_subtreeHeaderCount == m_SubtreeHeaders.size());847 btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size()); 747 848 m_subtreeHeaderCount = m_SubtreeHeaders.size(); 748 849 … … 1038 1139 m_bvhAabbMin(self.m_bvhAabbMin), 1039 1140 m_bvhAabbMax(self.m_bvhAabbMax), 1040 m_bvhQuantization(self.m_bvhQuantization) 1041 { 1042 1043 1044 } 1045 1046 1047 1141 m_bvhQuantization(self.m_bvhQuantization), 1142 m_bulletVersion(BT_BULLET_VERSION) 1143 { 1144 1145 } 1146 1147 1148 -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.h
r2192 r2430 159 159 ATTRIBUTE_ALIGNED16(class) btQuantizedBvh 160 160 { 161 protected:162 163 NodeArray m_leafNodes;164 NodeArray m_contiguousNodes;165 166 QuantizedNodeArray m_quantizedLeafNodes;167 168 QuantizedNodeArray m_quantizedContiguousNodes;169 170 int m_curNodeIndex;171 172 173 //quantization data174 bool m_useQuantization;175 btVector3 m_bvhAabbMin;176 btVector3 m_bvhAabbMax;177 btVector3 m_bvhQuantization;178 161 public: 179 BT_DECLARE_ALIGNED_ALLOCATOR();180 181 162 enum btTraversalMode 182 163 { … … 185 166 TRAVERSAL_RECURSIVE 186 167 }; 168 187 169 protected: 188 170 171 172 btVector3 m_bvhAabbMin; 173 btVector3 m_bvhAabbMax; 174 btVector3 m_bvhQuantization; 175 176 int m_bulletVersion; //for serialization versioning. It could also be used to detect endianess. 177 178 int m_curNodeIndex; 179 //quantization data 180 bool m_useQuantization; 181 182 183 184 NodeArray m_leafNodes; 185 NodeArray m_contiguousNodes; 186 QuantizedNodeArray m_quantizedLeafNodes; 187 QuantizedNodeArray m_quantizedContiguousNodes; 188 189 189 btTraversalMode m_traversalMode; 190 191 190 BvhSubtreeInfoArray m_SubtreeHeaders; 192 191 193 192 //This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray 194 193 int m_subtreeHeaderCount; 194 195 196 195 197 196 198 … … 297 299 void walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const; 298 300 void walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const; 301 void walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const; 299 302 300 303 ///tree traversal designed for small-memory processors like PS3 SPU … … 308 311 309 312 310 #define USE_BANCHLESS 1 311 #ifdef USE_BANCHLESS 312 //This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360) 313 SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const 314 { 315 return static_cast<unsigned int>(btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0]) 316 & (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2]) 317 & (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])), 318 1, 0)); 319 } 320 #else 321 SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const 322 { 323 bool overlap = true; 324 overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; 325 overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap; 326 overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; 327 return overlap; 328 } 329 #endif //USE_BANCHLESS 313 330 314 331 315 void updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex); 332 316 333 317 public: 318 319 BT_DECLARE_ALIGNED_ALLOCATOR(); 320 334 321 btQuantizedBvh(); 335 322 … … 364 351 ///Make sure rounding is done in a way that unQuantize(quantizeWithClamp(...)) is conservative 365 352 ///end-points always set the first bit, so that they are sorted properly (so that neighbouring AABBs overlap properly) 366 /// todo: double-check this353 ///@todo: double-check this 367 354 if (isMax) 368 355 { -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
r2192 r2430 56 56 m_numHandles = 0; 57 57 m_firstFreeHandle = 0; 58 m_LastHandleIndex = -1; 58 59 59 60 … … 89 90 return 0; //should never happen, but don't let the game crash ;-) 90 91 } 91 assert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]);92 btAssert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]); 92 93 93 94 int newHandleIndex = allocHandle(); … … 138 139 } 139 140 141 void btSimpleBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const 142 { 143 const btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy); 144 aabbMin = sbp->m_aabbMin; 145 aabbMax = sbp->m_aabbMax; 146 } 147 140 148 void btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* /*dispatcher*/) 141 149 { 142 150 btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy); 143 sbp->m_min = aabbMin; 144 sbp->m_max = aabbMax; 145 } 146 147 151 sbp->m_aabbMin = aabbMin; 152 sbp->m_aabbMax = aabbMax; 153 } 154 155 void btSimpleBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin,const btVector3& aabbMax) 156 { 157 for (int i=0; i <= m_LastHandleIndex; i++) 158 { 159 btSimpleBroadphaseProxy* proxy = &m_pHandles[i]; 160 if(!proxy->m_clientObject) 161 { 162 continue; 163 } 164 rayCallback.process(proxy); 165 } 166 } 148 167 149 168 … … 155 174 bool btSimpleBroadphase::aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1) 156 175 { 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];176 return proxy0->m_aabbMin[0] <= proxy1->m_aabbMax[0] && proxy1->m_aabbMin[0] <= proxy0->m_aabbMax[0] && 177 proxy0->m_aabbMin[1] <= proxy1->m_aabbMax[1] && proxy1->m_aabbMin[1] <= proxy0->m_aabbMax[1] && 178 proxy0->m_aabbMin[2] <= proxy1->m_aabbMax[2] && proxy1->m_aabbMin[2] <= proxy0->m_aabbMax[2]; 160 179 161 180 } … … 177 196 //first check for new overlapping pairs 178 197 int i,j; 179 180 198 if (m_numHandles >= 0) 181 199 { 182 183 for (i=0; i<m_numHandles;i++)200 int new_largest_index = -1; 201 for (i=0; i <= m_LastHandleIndex; i++) 184 202 { 185 203 btSimpleBroadphaseProxy* proxy0 = &m_pHandles[i]; 186 187 for (j=i+1;j<m_numHandles;j++) 204 if(!proxy0->m_clientObject) 205 { 206 continue; 207 } 208 new_largest_index = i; 209 for (j=i+1; j <= m_LastHandleIndex; j++) 188 210 { 189 211 btSimpleBroadphaseProxy* proxy1 = &m_pHandles[j]; 190 212 btAssert(proxy0 != proxy1); 213 if(!proxy1->m_clientObject) 214 { 215 continue; 216 } 191 217 192 218 btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0); … … 212 238 } 213 239 240 m_LastHandleIndex = new_largest_index; 241 214 242 if (m_ownsPairCache && m_pairCache->hasDeferredRemoval()) 215 243 { -
code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
r2192 r2430 23 23 struct btSimpleBroadphaseProxy : public btBroadphaseProxy 24 24 { 25 btVector3 m_min;26 btVector3 m_max;27 25 int m_nextFree; 28 26 … … 32 30 btSimpleBroadphaseProxy() {}; 33 31 34 btSimpleBroadphaseProxy(const btPoint3& minpt,const btPoint3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,void* multiSapProxy) 35 :btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy), 36 m_min(minpt),m_max(maxpt) 32 btSimpleBroadphaseProxy(const btVector3& minpt,const btVector3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,void* multiSapProxy) 33 :btBroadphaseProxy(minpt,maxpt,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy) 37 34 { 38 35 (void)shapeType; … … 57 54 int m_numHandles; // number of active handles 58 55 int m_maxHandles; // max number of handles 56 int m_LastHandleIndex; 59 57 60 58 btSimpleBroadphaseProxy* m_pHandles; // handles pool … … 69 67 m_firstFreeHandle = m_pHandles[freeHandle].GetNextFree(); 70 68 m_numHandles++; 69 if(freeHandle > m_LastHandleIndex) 70 { 71 m_LastHandleIndex = freeHandle; 72 } 71 73 return freeHandle; 72 74 } … … 76 78 int handle = int(proxy-m_pHandles); 77 79 btAssert(handle >= 0 && handle < m_maxHandles); 78 80 if(handle == m_LastHandleIndex) 81 { 82 m_LastHandleIndex--; 83 } 79 84 proxy->SetNextFree(m_firstFreeHandle); 80 85 m_firstFreeHandle = handle; 86 87 proxy->m_clientObject = 0; 81 88 82 89 m_numHandles--; … … 93 100 { 94 101 btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(proxy); 102 return proxy0; 103 } 104 105 inline const btSimpleBroadphaseProxy* getSimpleProxyFromProxy(btBroadphaseProxy* proxy) const 106 { 107 const btSimpleBroadphaseProxy* proxy0 = static_cast<const btSimpleBroadphaseProxy*>(proxy); 95 108 return proxy0; 96 109 } … … 118 131 virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); 119 132 virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher); 133 virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; 134 135 virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0)); 120 136 121 137 btOverlappingPairCache* getOverlappingPairCache() -
code/branches/physics/src/bullet/BulletCollision/CMakeLists.txt
r2192 r2430 1 ADD_LIBRARY(LibBulletCollision 2 BroadphaseCollision/btAxisSweep3.cpp 3 BroadphaseCollision/btAxisSweep3.h 4 BroadphaseCollision/btBroadphaseProxy.cpp 5 BroadphaseCollision/btBroadphaseProxy.h 6 BroadphaseCollision/btCollisionAlgorithm.cpp 7 BroadphaseCollision/btCollisionAlgorithm.h 8 BroadphaseCollision/btDispatcher.cpp 9 BroadphaseCollision/btDispatcher.h 10 BroadphaseCollision/btDbvtBroadphase.cpp 11 BroadphaseCollision/btDbvtBroadphase.h 12 BroadphaseCollision/btDbvt.cpp 13 BroadphaseCollision/btDbvt.h 14 BroadphaseCollision/btMultiSapBroadphase.cpp 15 BroadphaseCollision/btMultiSapBroadphase.h 16 BroadphaseCollision/btOverlappingPairCache.cpp 17 BroadphaseCollision/btOverlappingPairCache.h 18 BroadphaseCollision/btOverlappingPairCallback.h 19 BroadphaseCollision/btQuantizedBvh.cpp 20 BroadphaseCollision/btQuantizedBvh.h 21 BroadphaseCollision/btSimpleBroadphase.cpp 22 BroadphaseCollision/btSimpleBroadphase.h 23 CollisionDispatch/btCollisionDispatcher.cpp 24 CollisionDispatch/btCollisionDispatcher.h 25 CollisionDispatch/btCollisionObject.cpp 26 CollisionDispatch/btCollisionObject.h 27 CollisionDispatch/btCollisionWorld.cpp 28 CollisionDispatch/btCollisionWorld.h 29 CollisionDispatch/btCompoundCollisionAlgorithm.cpp 30 CollisionDispatch/btCompoundCollisionAlgorithm.h 31 CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp 32 CollisionDispatch/btConvexConcaveCollisionAlgorithm.h 33 CollisionDispatch/btDefaultCollisionConfiguration.cpp 34 CollisionDispatch/btDefaultCollisionConfiguration.h 35 CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp 36 CollisionDispatch/btSphereSphereCollisionAlgorithm.h 37 CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp 38 CollisionDispatch/btBoxBoxCollisionAlgorithm.h 39 CollisionDispatch/btBoxBoxDetector.cpp 40 CollisionDispatch/btBoxBoxDetector.h 41 CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp 42 CollisionDispatch/btSphereBoxCollisionAlgorithm.h 43 CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp 44 CollisionDispatch/btConvexPlaneCollisionAlgorithm.h 45 CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp 46 CollisionDispatch/btSphereTriangleCollisionAlgorithm.h 47 CollisionDispatch/btConvexConvexAlgorithm.cpp 48 CollisionDispatch/btConvexConvexAlgorithm.h 49 CollisionDispatch/btEmptyCollisionAlgorithm.cpp 50 CollisionDispatch/btEmptyCollisionAlgorithm.h 51 CollisionDispatch/btManifoldResult.cpp 52 CollisionDispatch/btManifoldResult.h 53 CollisionDispatch/btSimulationIslandManager.cpp 54 CollisionDispatch/btSimulationIslandManager.h 55 CollisionDispatch/btUnionFind.cpp 56 CollisionDispatch/btUnionFind.h 57 CollisionDispatch/SphereTriangleDetector.cpp 58 CollisionDispatch/SphereTriangleDetector.h 59 CollisionShapes/btBoxShape.cpp 60 CollisionShapes/btBoxShape.h 61 CollisionShapes/btBvhTriangleMeshShape.cpp 62 CollisionShapes/btBvhTriangleMeshShape.h 63 CollisionShapes/btCapsuleShape.cpp 64 CollisionShapes/btCapsuleShape.h 65 CollisionShapes/btCollisionShape.cpp 66 CollisionShapes/btCollisionShape.h 67 CollisionShapes/btCompoundShape.cpp 68 CollisionShapes/btCompoundShape.h 69 CollisionShapes/btConcaveShape.cpp 70 CollisionShapes/btConcaveShape.h 71 CollisionShapes/btConeShape.cpp 72 CollisionShapes/btConeShape.h 73 CollisionShapes/btConvexHullShape.cpp 74 CollisionShapes/btConvexHullShape.h 75 CollisionShapes/btConvexPointCloudShape.cpp 76 CollisionShapes/btConvexPointCloudShape.h 77 CollisionShapes/btConvexShape.cpp 78 CollisionShapes/btConvexShape.h 79 CollisionShapes/btConvexInternalShape.cpp 80 CollisionShapes/btConvexInternalShape.h 81 CollisionShapes/btConvexTriangleMeshShape.cpp 82 CollisionShapes/btConvexTriangleMeshShape.h 83 CollisionShapes/btCylinderShape.cpp 84 CollisionShapes/btCylinderShape.h 85 CollisionShapes/btEmptyShape.cpp 86 CollisionShapes/btEmptyShape.h 87 CollisionShapes/btHeightfieldTerrainShape.cpp 88 CollisionShapes/btHeightfieldTerrainShape.h 89 CollisionShapes/btMinkowskiSumShape.cpp 90 CollisionShapes/btMinkowskiSumShape.h 91 CollisionShapes/btMaterial.h 92 CollisionShapes/btMultimaterialTriangleMeshShape.cpp 93 CollisionShapes/btMultimaterialTriangleMeshShape.h 94 CollisionShapes/btMultiSphereShape.cpp 95 CollisionShapes/btMultiSphereShape.h 96 CollisionShapes/btOptimizedBvh.cpp 97 CollisionShapes/btOptimizedBvh.h 98 CollisionShapes/btPolyhedralConvexShape.cpp 99 CollisionShapes/btPolyhedralConvexShape.h 100 CollisionShapes/btScaledBvhTriangleMeshShape.cpp 101 CollisionShapes/btScaledBvhTriangleMeshShape.h 102 CollisionShapes/btTetrahedronShape.cpp 103 CollisionShapes/btTetrahedronShape.h 104 CollisionShapes/btSphereShape.cpp 105 CollisionShapes/btSphereShape.h 106 CollisionShapes/btShapeHull.h 107 CollisionShapes/btShapeHull.cpp 108 CollisionShapes/btStaticPlaneShape.cpp 109 CollisionShapes/btStaticPlaneShape.h 110 CollisionShapes/btStridingMeshInterface.cpp 111 CollisionShapes/btStridingMeshInterface.h 112 CollisionShapes/btTriangleCallback.cpp 113 CollisionShapes/btTriangleCallback.h 114 CollisionShapes/btTriangleBuffer.cpp 115 CollisionShapes/btTriangleBuffer.h 116 CollisionShapes/btTriangleIndexVertexArray.cpp 117 CollisionShapes/btTriangleIndexVertexArray.h 118 CollisionShapes/btTriangleIndexVertexMaterialArray.h 119 CollisionShapes/btTriangleIndexVertexMaterialArray.cpp 120 CollisionShapes/btTriangleMesh.cpp 121 CollisionShapes/btTriangleMesh.h 122 CollisionShapes/btTriangleMeshShape.cpp 123 CollisionShapes/btTriangleMeshShape.h 124 CollisionShapes/btUniformScalingShape.cpp 125 CollisionShapes/btUniformScalingShape.h 126 NarrowPhaseCollision/btContinuousConvexCollision.cpp 127 NarrowPhaseCollision/btContinuousConvexCollision.h 128 NarrowPhaseCollision/btGjkEpa.cpp 129 NarrowPhaseCollision/btGjkEpa.h 130 NarrowPhaseCollision/btGjkEpa2.cpp 131 NarrowPhaseCollision/btGjkEpa2.h 132 NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp 133 NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h 134 NarrowPhaseCollision/btConvexCast.cpp 135 NarrowPhaseCollision/btConvexCast.h 136 NarrowPhaseCollision/btGjkConvexCast.cpp 137 NarrowPhaseCollision/btGjkConvexCast.h 138 NarrowPhaseCollision/btGjkPairDetector.cpp 139 NarrowPhaseCollision/btGjkPairDetector.h 140 NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp 141 NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h 142 NarrowPhaseCollision/btPersistentManifold.cpp 143 NarrowPhaseCollision/btPersistentManifold.h 144 NarrowPhaseCollision/btRaycastCallback.cpp 145 NarrowPhaseCollision/btRaycastCallback.h 146 NarrowPhaseCollision/btSubSimplexConvexCast.cpp 147 NarrowPhaseCollision/btSubSimplexConvexCast.h 148 NarrowPhaseCollision/btVoronoiSimplexSolver.cpp 149 NarrowPhaseCollision/btVoronoiSimplexSolver.h 1 SET(BulletCollision_SRCS 2 BroadphaseCollision/btAxisSweep3.cpp 3 BroadphaseCollision/btBroadphaseProxy.cpp 4 BroadphaseCollision/btCollisionAlgorithm.cpp 5 BroadphaseCollision/btDispatcher.cpp 6 BroadphaseCollision/btDbvtBroadphase.cpp 7 BroadphaseCollision/btDbvt.cpp 8 BroadphaseCollision/btMultiSapBroadphase.cpp 9 BroadphaseCollision/btOverlappingPairCache.cpp 10 BroadphaseCollision/btQuantizedBvh.cpp 11 BroadphaseCollision/btSimpleBroadphase.cpp 12 CollisionDispatch/btActivatingCollisionAlgorithm.cpp 13 CollisionDispatch/btCollisionDispatcher.cpp 14 CollisionDispatch/btCollisionObject.cpp 15 CollisionDispatch/btCollisionWorld.cpp 16 CollisionDispatch/btCompoundCollisionAlgorithm.cpp 17 CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp 18 CollisionDispatch/btDefaultCollisionConfiguration.cpp 19 CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp 20 CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp 21 CollisionDispatch/btBoxBoxDetector.cpp 22 CollisionDispatch/btGhostObject.cpp 23 CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp 24 CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp 25 CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp 26 CollisionDispatch/btConvexConvexAlgorithm.cpp 27 CollisionDispatch/btEmptyCollisionAlgorithm.cpp 28 CollisionDispatch/btManifoldResult.cpp 29 CollisionDispatch/btSimulationIslandManager.cpp 30 CollisionDispatch/btUnionFind.cpp 31 CollisionDispatch/SphereTriangleDetector.cpp 32 CollisionShapes/btBoxShape.cpp 33 CollisionShapes/btBvhTriangleMeshShape.cpp 34 CollisionShapes/btCapsuleShape.cpp 35 CollisionShapes/btCollisionShape.cpp 36 CollisionShapes/btCompoundShape.cpp 37 CollisionShapes/btConcaveShape.cpp 38 CollisionShapes/btConeShape.cpp 39 CollisionShapes/btConvexHullShape.cpp 40 CollisionShapes/btConvexPointCloudShape.cpp 41 CollisionShapes/btConvexShape.cpp 42 CollisionShapes/btConvexInternalShape.cpp 43 CollisionShapes/btConvexTriangleMeshShape.cpp 44 CollisionShapes/btCylinderShape.cpp 45 CollisionShapes/btEmptyShape.cpp 46 CollisionShapes/btHeightfieldTerrainShape.cpp 47 CollisionShapes/btMinkowskiSumShape.cpp 48 CollisionShapes/btMultimaterialTriangleMeshShape.cpp 49 CollisionShapes/btMultiSphereShape.cpp 50 CollisionShapes/btOptimizedBvh.cpp 51 CollisionShapes/btPolyhedralConvexShape.cpp 52 CollisionShapes/btScaledBvhTriangleMeshShape.cpp 53 CollisionShapes/btTetrahedronShape.cpp 54 CollisionShapes/btSphereShape.cpp 55 CollisionShapes/btShapeHull.cpp 56 CollisionShapes/btStaticPlaneShape.cpp 57 CollisionShapes/btStridingMeshInterface.cpp 58 CollisionShapes/btTriangleCallback.cpp 59 CollisionShapes/btTriangleBuffer.cpp 60 CollisionShapes/btTriangleIndexVertexArray.cpp 61 CollisionShapes/btTriangleIndexVertexMaterialArray.cpp 62 CollisionShapes/btTriangleMesh.cpp 63 CollisionShapes/btTriangleMeshShape.cpp 64 CollisionShapes/btUniformScalingShape.cpp 65 Gimpact/btContactProcessing.cpp 66 Gimpact/btGImpactShape.cpp 67 Gimpact/gim_contact.cpp 68 Gimpact/btGImpactBvh.cpp 69 Gimpact/btGenericPoolAllocator.cpp 70 Gimpact/gim_memory.cpp 71 Gimpact/btGImpactCollisionAlgorithm.cpp 72 Gimpact/btTriangleShapeEx.cpp 73 Gimpact/gim_tri_collision.cpp 74 Gimpact/btGImpactQuantizedBvh.cpp 75 Gimpact/gim_box_set.cpp 76 NarrowPhaseCollision/btContinuousConvexCollision.cpp 77 NarrowPhaseCollision/btGjkEpa2.cpp 78 NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp 79 NarrowPhaseCollision/btConvexCast.cpp 80 NarrowPhaseCollision/btGjkConvexCast.cpp 81 NarrowPhaseCollision/btGjkPairDetector.cpp 82 NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp 83 NarrowPhaseCollision/btPersistentManifold.cpp 84 NarrowPhaseCollision/btRaycastCallback.cpp 85 NarrowPhaseCollision/btSubSimplexConvexCast.cpp 86 NarrowPhaseCollision/btVoronoiSimplexSolver.cpp 150 87 ) 88 89 ADD_LIBRARY(BulletCollision ${BulletCollision_SRCS}) -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
r2192 r2430 20 20 21 21 22 SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle )22 SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle,btScalar contactBreakingThreshold) 23 23 :m_sphere(sphere), 24 m_triangle(triangle) 24 m_triangle(triangle), 25 m_contactBreakingThreshold(contactBreakingThreshold) 25 26 { 26 27 … … 41 42 btTransform sphereInTr = transformB.inverseTimes(transformA); 42 43 43 if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact ))44 if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact,m_contactBreakingThreshold)) 44 45 { 45 46 if (swapResults) … … 94 95 95 96 ///combined discrete/continuous sphere-triangle 96 bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact )97 bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold) 97 98 { 98 99 … … 116 117 } 117 118 118 ///todo: move this gContactBreakingThreshold into a proper structure 119 extern btScalar gContactBreakingThreshold; 120 121 btScalar contactMargin = gContactBreakingThreshold; 119 btScalar contactMargin = contactBreakingThreshold; 122 120 bool isInsideContactPlane = distanceFromPlane < r + contactMargin; 123 121 bool isInsideShellPlane = distanceFromPlane < r; … … 141 139 for (int i = 0; i < m_triangle->getNumEdges(); i++) { 142 140 143 bt Point3 pa;144 bt Point3 pb;141 btVector3 pa; 142 btVector3 pb; 145 143 146 144 m_triangle->getEdge(i,pa,pb); -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
r2192 r2430 18 18 19 19 #include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" 20 #include "LinearMath/btPoint3.h" 20 21 21 22 22 … … 31 31 virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false); 32 32 33 SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle );33 SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle, btScalar contactBreakingThreshold); 34 34 35 35 virtual ~SphereTriangleDetector() {}; … … 37 37 private: 38 38 39 bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact );39 bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold); 40 40 bool pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p ); 41 41 bool facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal); … … 43 43 btSphereShape* m_sphere; 44 44 btTriangleShape* m_triangle; 45 45 btScalar m_contactBreakingThreshold; 46 46 47 47 }; -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
r2192 r2430 23 23 24 24 btBoxBoxCollisionAlgorithm::btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* obj0,btCollisionObject* obj1) 25 : bt CollisionAlgorithm(ci),25 : btActivatingCollisionAlgorithm(ci,obj0,obj1), 26 26 m_ownManifold(false), 27 27 m_manifoldPtr(mf) -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h
r2192 r2430 17 17 #define BOX_BOX__COLLISION_ALGORITHM_H 18 18 19 #include " BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"19 #include "btActivatingCollisionAlgorithm.h" 20 20 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" 21 21 #include "BulletCollision/BroadphaseCollision/btDispatcher.h" … … 25 25 26 26 ///box-box collision detection 27 class btBoxBoxCollisionAlgorithm : public bt CollisionAlgorithm27 class btBoxBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm 28 28 { 29 29 bool m_ownManifold; … … 32 32 public: 33 33 btBoxBoxCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) 34 : bt CollisionAlgorithm(ci) {}34 : btActivatingCollisionAlgorithm(ci) {} 35 35 36 36 virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp
r2192 r2430 208 208 } 209 209 q = p[n*2-2]*p[1] - p[0]*p[n*2-1]; 210 a = 1.f/(btScalar(3.0)*(a+q)); 210 if (btFabs(a+q) > SIMD_EPSILON) 211 { 212 a = 1.f/(btScalar(3.0)*(a+q)); 213 } else 214 { 215 a=1e30f; 216 } 211 217 cx = a*(cx + q*(p[n*2-2]+p[0])); 212 218 cy = a*(cy + q*(p[n*2-1]+p[1])); -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionConfiguration.h
r2192 r2430 23 23 ///btCollisionConfiguration allows to configure Bullet collision detection 24 24 ///stack allocator size, default collision algorithms and persistent manifold pool size 25 /// todo: describe the meaning25 ///@todo: describe the meaning 26 26 class btCollisionConfiguration 27 27 { -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h
r2192 r2430 18 18 19 19 #include "LinearMath/btAlignedObjectArray.h" 20 typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;21 20 class btCollisionAlgorithm; 22 21 class btCollisionObject; -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
r2192 r2430 58 58 59 59 60 } ;60 } 61 61 62 62 … … 79 79 btCollisionObject* body0 = (btCollisionObject*)b0; 80 80 btCollisionObject* body1 = (btCollisionObject*)b1; 81 82 btScalar contactBreakingThreshold = btMin(gContactBreakingThreshold,btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold())); 81 83 82 84 void* mem = 0; … … 90 92 91 93 } 92 btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0 );94 btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0,contactBreakingThreshold); 93 95 manifold->m_index1a = m_manifoldsPtr.size(); 94 96 m_manifoldsPtr.push_back(manifold); -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h
r2192 r2430 30 30 #include "LinearMath/btMotionState.h" 31 31 #include "LinearMath/btAlignedAllocator.h" 32 32 #include "LinearMath/btAlignedObjectArray.h" 33 34 35 typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray; 33 36 34 37 … … 72 75 void* m_userObjectPointer; 73 76 74 ///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody etc.77 ///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc. 75 78 ///do not assign your own m_internalType unless you write a new dynamics object class. 76 79 int m_internalType; … … 104 107 CF_KINEMATIC_OBJECT= 2, 105 108 CF_NO_CONTACT_RESPONSE = 4, 106 CF_CUSTOM_MATERIAL_CALLBACK = 8//this allows per-triangle material (friction/restitution) 109 CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution) 110 CF_CHARACTER_OBJECT = 16 107 111 }; 108 112 … … 111 115 CO_COLLISION_OBJECT =1, 112 116 CO_RIGID_BODY, 113 CO_SOFT_BODY 117 CO_SOFT_BODY, 118 ///CO_GHOST_OBJECT keeps track of all objects overlapping its AABB and that pass its collision filter 119 ///It is useful for collision sensors, explosion objects, character controller etc. 120 CO_GHOST_OBJECT 114 121 }; 115 122 … … 177 184 } 178 185 179 int getActivationState() const { return m_activationState1;}186 SIMD_FORCE_INLINE int getActivationState() const { return m_activationState1;} 180 187 181 188 void setActivationState(int newState); … … 194 201 void activate(bool forceActivation = false); 195 202 196 inlinebool isActive() const203 SIMD_FORCE_INLINE bool isActive() const 197 204 { 198 205 return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION)); … … 238 245 239 246 240 btBroadphaseProxy* getBroadphaseHandle()247 SIMD_FORCE_INLINE btBroadphaseProxy* getBroadphaseHandle() 241 248 { 242 249 return m_broadphaseHandle; 243 250 } 244 251 245 const btBroadphaseProxy* getBroadphaseHandle() const252 SIMD_FORCE_INLINE const btBroadphaseProxy* getBroadphaseHandle() const 246 253 { 247 254 return m_broadphaseHandle; … … 289 296 } 290 297 291 constint getIslandTag() const298 SIMD_FORCE_INLINE int getIslandTag() const 292 299 { 293 300 return m_islandTag1; … … 299 306 } 300 307 301 constint getCompanionId() const308 SIMD_FORCE_INLINE int getCompanionId() const 302 309 { 303 310 return m_companionId; … … 309 316 } 310 317 311 constbtScalar getHitFraction() const318 SIMD_FORCE_INLINE btScalar getHitFraction() const 312 319 { 313 320 return m_hitFraction; … … 320 327 321 328 322 constint getCollisionFlags() const329 SIMD_FORCE_INLINE int getCollisionFlags() const 323 330 { 324 331 return m_collisionFlags; -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
r2192 r2430 33 33 #include "LinearMath/btStackAlloc.h" 34 34 35 //#define USE_BRUTEFORCE_RAYBROADPHASE 1 36 //RECALCULATE_AABB is slower, but benefit is that you don't need to call 'stepSimulation' or 'updateAabbs' before using a rayTest 37 //#define RECALCULATE_AABB_RAYCAST 1 35 38 36 39 //When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor) … … 114 117 } 115 118 119 120 116 121 void btCollisionWorld::updateAabbs() 117 122 { … … 126 131 if (colObj->isActive()) 127 132 { 128 bt Point3 minAabb,maxAabb;133 btVector3 minAabb,maxAabb; 129 134 colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb); 130 135 //need to increase the aabb for contact thresholds … … 227 232 if (collisionShape->isConvex()) 228 233 { 234 // BT_PROFILE("rayTestConvex"); 229 235 btConvexCast::CastResult castResult; 230 236 castResult.m_fraction = resultCallback.m_closestHitFraction; … … 270 276 if (collisionShape->isConcave()) 271 277 { 278 // BT_PROFILE("rayTestConcave"); 272 279 if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE) 273 280 { … … 318 325 } else 319 326 { 320 btTriangleMeshShape* triangleMesh = (btTriangleMeshShape*)collisionShape; 327 //generic (slower) case 328 btConcaveShape* concaveShape = (btConcaveShape*)collisionShape; 321 329 322 330 btTransform worldTocollisionObject = colObjWorldTransform.inverse(); … … 331 339 btCollisionWorld::RayResultCallback* m_resultCallback; 332 340 btCollisionObject* m_collisionObject; 333 bt TriangleMeshShape* m_triangleMesh;341 btConcaveShape* m_triangleMesh; 334 342 335 343 BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to, 336 btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,bt TriangleMeshShape* triangleMesh):344 btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh): 337 345 btTriangleRaycastCallback(from,to), 338 346 m_resultCallback(resultCallback), … … 364 372 365 373 366 BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject, triangleMesh);374 BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,concaveShape); 367 375 rcb.m_hitFraction = resultCallback.m_closestHitFraction; 368 376 … … 372 380 rayAabbMaxLocal.setMax(rayToLocal); 373 381 374 triangleMesh->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);382 concaveShape->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal); 375 383 } 376 384 } else { 377 //todo: use AABB tree or other BVH acceleration structure! 385 // BT_PROFILE("rayTestCompound"); 386 ///@todo: use AABB tree or other BVH acceleration structure, see btDbvt 378 387 if (collisionShape->isCompound()) 379 388 { … … 409 418 if (collisionShape->isConvex()) 410 419 { 420 //BT_PROFILE("convexSweepConvex"); 411 421 btConvexCast::CastResult castResult; 412 422 castResult.m_allowedPenetration = allowedPenetration; 413 castResult.m_fraction = btScalar(1.);//??423 castResult.m_fraction = resultCallback.m_closestHitFraction;//btScalar(1.);//?? 414 424 415 425 btConvexShape* convexShape = (btConvexShape*) collisionShape; … … 453 463 if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE) 454 464 { 465 //BT_PROFILE("convexSweepbtBvhTriangleMesh"); 455 466 btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape; 456 467 btTransform worldTocollisionObject = colObjWorldTransform.inverse(); … … 509 520 } else 510 521 { 511 btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape; 522 //BT_PROFILE("convexSweepConcave"); 523 btConcaveShape* concaveShape = (btConcaveShape*)collisionShape; 512 524 btTransform worldTocollisionObject = colObjWorldTransform.inverse(); 513 525 btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin(); … … 521 533 btCollisionWorld::ConvexResultCallback* m_resultCallback; 522 534 btCollisionObject* m_collisionObject; 523 bt TriangleMeshShape* m_triangleMesh;535 btConcaveShape* m_triangleMesh; 524 536 525 537 BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to, 526 btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,bt TriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):538 btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& triangleToWorld): 527 539 btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()), 528 540 m_resultCallback(resultCallback), … … 557 569 }; 558 570 559 BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject, triangleMesh, colObjWorldTransform);571 BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,concaveShape, colObjWorldTransform); 560 572 tccb.m_hitFraction = resultCallback.m_closestHitFraction; 561 573 btVector3 boxMinLocal, boxMaxLocal; … … 568 580 rayAabbMinLocal += boxMinLocal; 569 581 rayAabbMaxLocal += boxMaxLocal; 570 triangleMesh->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);582 concaveShape->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal); 571 583 } 572 584 } else { 573 // todo: use AABB tree or other BVH acceleration structure!585 ///@todo : use AABB tree or other BVH acceleration structure! 574 586 if (collisionShape->isCompound()) 575 587 { 588 BT_PROFILE("convexSweepCompound"); 576 589 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape); 577 590 int i=0; … … 597 610 } 598 611 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++) 612 613 struct btSingleRayCallback : public btBroadphaseRayCallback 614 { 615 616 btVector3 m_rayFromWorld; 617 btVector3 m_rayToWorld; 618 btTransform m_rayFromTrans; 619 btTransform m_rayToTrans; 620 btVector3 m_hitNormal; 621 622 const btCollisionWorld* m_world; 623 btCollisionWorld::RayResultCallback& m_resultCallback; 624 625 btSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btCollisionWorld* world,btCollisionWorld::RayResultCallback& resultCallback) 626 :m_rayFromWorld(rayFromWorld), 627 m_rayToWorld(rayToWorld), 628 m_world(world), 629 m_resultCallback(resultCallback) 630 { 631 m_rayFromTrans.setIdentity(); 632 m_rayFromTrans.setOrigin(m_rayFromWorld); 633 m_rayToTrans.setIdentity(); 634 m_rayToTrans.setOrigin(m_rayToWorld); 635 636 btVector3 rayDir = (rayToWorld-rayFromWorld); 637 638 rayDir.normalize (); 639 ///what about division by zero? --> just set rayDirection[i] to INF/1e30 640 m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0]; 641 m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1]; 642 m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2]; 643 m_signs[0] = m_rayDirectionInverse[0] < 0.0; 644 m_signs[1] = m_rayDirectionInverse[1] < 0.0; 645 m_signs[2] = m_rayDirectionInverse[2] < 0.0; 646 647 m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld); 648 649 } 650 651 652 653 virtual bool process(const btBroadphaseProxy* proxy) 614 654 { 615 655 ///terminate further ray tests, once the closestHitFraction reached zero 616 if (resultCallback.m_closestHitFraction == btScalar(0.f)) 617 break; 618 619 btCollisionObject* collisionObject= m_collisionObjects[i]; 656 if (m_resultCallback.m_closestHitFraction == btScalar(0.f)) 657 return false; 658 659 btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; 660 620 661 //only perform raycast if filterMask matches 621 if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) { 662 if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) 663 { 622 664 //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); 665 //btVector3 collisionObjectAabbMin,collisionObjectAabbMax; 666 667 #ifdef RECALCULATE_AABB 623 668 btVector3 collisionObjectAabbMin,collisionObjectAabbMax; 624 669 collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax); 625 626 btScalar hitLambda = resultCallback.m_closestHitFraction; 627 btVector3 hitNormal; 628 if (btRayAabb(rayFromWorld,rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal)) 629 { 630 rayTestSingle(rayFromTrans,rayToTrans, 670 #else 671 //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax); 672 const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin; 673 const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax; 674 #endif 675 //btScalar hitLambda = m_resultCallback.m_closestHitFraction; 676 //culling already done by broadphase 677 //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal)) 678 { 679 m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans, 631 680 collisionObject, 632 681 collisionObject->getCollisionShape(), 633 682 collisionObject->getWorldTransform(), 634 resultCallback);683 m_resultCallback); 635 684 } 636 685 } 637 638 } 639 640 } 641 642 void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback) const 643 { 686 return true; 687 } 688 }; 689 690 void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const 691 { 692 BT_PROFILE("rayTest"); 693 /// use the broadphase to accelerate the search for objects, based on their aabb 694 /// and for each object with ray-aabb overlap, perform an exact ray test 695 btSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback); 696 697 #ifndef USE_BRUTEFORCE_RAYBROADPHASE 698 m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB); 699 #else 700 for (int i=0;i<this->getNumCollisionObjects();i++) 701 { 702 rayCB.process(m_collisionObjects[i]->getBroadphaseHandle()); 703 } 704 #endif //USE_BRUTEFORCE_RAYBROADPHASE 705 706 } 707 708 709 struct btSingleSweepCallback : public btBroadphaseRayCallback 710 { 711 712 btTransform m_convexFromTrans; 713 btTransform m_convexToTrans; 714 btVector3 m_hitNormal; 715 const btCollisionWorld* m_world; 716 btCollisionWorld::ConvexResultCallback& m_resultCallback; 717 btScalar m_allowedCcdPenetration; 718 const btConvexShape* m_castShape; 719 720 721 btSingleSweepCallback(const btConvexShape* castShape, const btTransform& convexFromTrans,const btTransform& convexToTrans,const btCollisionWorld* world,btCollisionWorld::ConvexResultCallback& resultCallback,btScalar allowedPenetration) 722 :m_convexFromTrans(convexFromTrans), 723 m_convexToTrans(convexToTrans), 724 m_world(world), 725 m_resultCallback(resultCallback), 726 m_allowedCcdPenetration(allowedPenetration), 727 m_castShape(castShape) 728 { 729 btVector3 unnormalizedRayDir = (m_convexToTrans.getOrigin()-m_convexFromTrans.getOrigin()); 730 btVector3 rayDir = unnormalizedRayDir.normalized(); 731 ///what about division by zero? --> just set rayDirection[i] to INF/1e30 732 m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0]; 733 m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1]; 734 m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2]; 735 m_signs[0] = m_rayDirectionInverse[0] < 0.0; 736 m_signs[1] = m_rayDirectionInverse[1] < 0.0; 737 m_signs[2] = m_rayDirectionInverse[2] < 0.0; 738 739 m_lambda_max = rayDir.dot(unnormalizedRayDir); 740 741 } 742 743 virtual bool process(const btBroadphaseProxy* proxy) 744 { 745 ///terminate further convex sweep tests, once the closestHitFraction reached zero 746 if (m_resultCallback.m_closestHitFraction == btScalar(0.f)) 747 return false; 748 749 btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; 750 751 //only perform raycast if filterMask matches 752 if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) { 753 //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); 754 m_world->objectQuerySingle(m_castShape, m_convexFromTrans,m_convexToTrans, 755 collisionObject, 756 collisionObject->getCollisionShape(), 757 collisionObject->getWorldTransform(), 758 m_resultCallback, 759 m_allowedCcdPenetration); 760 } 761 762 return true; 763 } 764 }; 765 766 767 768 void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const 769 { 770 771 BT_PROFILE("convexSweepTest"); 772 /// use the broadphase to accelerate the search for objects, based on their aabb 773 /// and for each object with ray-aabb overlap, perform an exact ray test 774 /// unfortunately the implementation for rayTest and convexSweepTest duplicated, albeit practically identical 775 776 777 644 778 btTransform convexFromTrans,convexToTrans; 645 779 convexFromTrans = convexFromWorld; … … 650 784 btVector3 linVel, angVel; 651 785 btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel); 786 btVector3 zeroLinVel; 787 zeroLinVel.setValue(0,0,0); 652 788 btTransform R; 653 789 R.setIdentity (); 654 790 R.setRotation (convexFromTrans.getRotation()); 655 castShape->calculateTemporalAabb (R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax); 656 } 657 791 castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax); 792 } 793 794 #ifndef USE_BRUTEFORCE_RAYBROADPHASE 795 796 btSingleSweepCallback convexCB(castShape,convexFromWorld,convexToWorld,this,resultCallback,allowedCcdPenetration); 797 798 m_broadphasePairCache->rayTest(convexFromTrans.getOrigin(),convexToTrans.getOrigin(),convexCB,castShapeAabbMin,castShapeAabbMax); 799 800 #else 658 801 /// go over all objects, and if the ray intersects their aabb + cast shape aabb, 659 802 // do a ray-shape query using convexCaster (CCD) … … 677 820 collisionObject->getWorldTransform(), 678 821 resultCallback, 679 getDispatchInfo().m_allowedCcdPenetration);822 allowedCcdPenetration); 680 823 } 681 824 } 682 825 } 683 684 } 826 #endif //USE_BRUTEFORCE_RAYBROADPHASE 827 } -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h
r2192 r2430 1 1 /* 2 2 Bullet Continuous Collision Detection and Physics Library 3 Copyright (c) 2003-2006 Erwin Coumans http:// continuousphysics.com/Bullet/3 Copyright (c) 2003-2006 Erwin Coumans http://bulletphysics.com/Bullet/ 4 4 5 5 This software is provided 'as-is', without any express or implied warranty. … … 23 23 * Bullet is a Collision Detection and Rigid Body Dynamics Library. The Library is Open Source and free for commercial use, under the ZLib license ( http://opensource.org/licenses/zlib-license.php ). 24 24 * 25 * There is the Physics Forum for Feedback and bteral Collision Detection and Physics discussions.26 * Please visit http://www. continuousphysics.com/Bullet/phpBB2/index.php25 * There is the Physics Forum for feedback and general Collision Detection and Physics discussions. 26 * Please visit http://www.bulletphysics.com 27 27 * 28 28 * @section install_sec Installation 29 29 * 30 30 * @subsection step1 Step 1: Download 31 * You can download the Bullet Physics Library from our website: http://www.continuousphysics.com/Bullet/31 * You can download the Bullet Physics Library from the Google Code repository: http://code.google.com/p/bullet/downloads/list 32 32 * @subsection step2 Step 2: Building 33 33 * Bullet comes with autogenerated Project Files for Microsoft Visual Studio 6, 7, 7.1 and 8. 34 34 * The main Workspace/Solution is located in Bullet/msvc/8/wksbullet.sln (replace 8 with your version). 35 35 * 36 * Under other platforms, like Linux or Mac OS-X, Bullet can be build using either using make, cmake, http://www.cmake.org , or jam, http://www.perforce.com/jam/jam.html . cmake can autogenerate Xcode, KDevelop, MSVC and other build systems. just run cmake . in the root of Bullet.36 * Under other platforms, like Linux or Mac OS-X, Bullet can be build using either using make, cmake, http://www.cmake.org , or jam, http://www.perforce.com/jam/jam.html . cmake can autogenerate Xcode, KDevelop, MSVC and other build systems. just run cmake . in the root of Bullet. 37 37 * So if you are not using MSVC or cmake, you can run ./autogen.sh ./configure to create both Makefile and Jamfile and then run make or jam. 38 38 * Jam is a build system that can build the library, demos and also autogenerate the MSVC Project Files. 39 * If you don't have jam installed, you can make jam from the included jam-2.5 sources, or download jam from ftp://ftp.perforce.com/ pub/jam/39 * If you don't have jam installed, you can make jam from the included jam-2.5 sources, or download jam from ftp://ftp.perforce.com/jam 40 40 * 41 41 * @subsection step3 Step 3: Testing demos … … 72 72 #include "LinearMath/btTransform.h" 73 73 #include "btCollisionObject.h" 74 #include "btCollisionDispatcher.h" //for definition of btCollisionObjectArray74 #include "btCollisionDispatcher.h" 75 75 #include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" 76 76 #include "LinearMath/btAlignedObjectArray.h" … … 108 108 } 109 109 110 const btBroadphaseInterface* getBroadphase() const 111 { 112 return m_broadphasePairCache; 113 } 114 110 115 btBroadphaseInterface* getBroadphase() 111 116 { … … 131 136 virtual void updateAabbs(); 132 137 138 133 139 virtual void setDebugDrawer(btIDebugDraw* debugDrawer) 134 140 { … … 348 354 // convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback 349 355 // This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback. 350 void convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback ) const;356 void convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = btScalar(0.)) const; 351 357 352 358 -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
r2192 r2430 22 22 23 23 btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped) 24 :bt CollisionAlgorithm(ci),24 :btActivatingCollisionAlgorithm(ci,body0,body1), 25 25 m_isSwapped(isSwapped), 26 26 m_sharedManifold(ci.m_manifold) -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
r2192 r2430 17 17 #define COMPOUND_COLLISION_ALGORITHM_H 18 18 19 #include " BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"19 #include "btActivatingCollisionAlgorithm.h" 20 20 #include "BulletCollision/BroadphaseCollision/btDispatcher.h" 21 21 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" … … 29 29 30 30 /// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes 31 class btCompoundCollisionAlgorithm : public bt CollisionAlgorithm31 class btCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm 32 32 { 33 33 btAlignedObjectArray<btCollisionAlgorithm*> m_childCollisionAlgorithms; -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
r2192 r2430 28 28 29 29 btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped) 30 : bt CollisionAlgorithm(ci),30 : btActivatingCollisionAlgorithm(ci,body0,body1), 31 31 m_isSwapped(isSwapped), 32 32 m_btConvexTriangleCallback(ci.m_dispatcher1,body0,body1,isSwapped) … … 73 73 { 74 74 m_dispatcher->clearManifold(m_manifoldPtr); 75 } ;75 } 76 76 77 77 … … 94 94 95 95 ///debug drawing of the overlapping triangles 96 if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && m_dispatchInfoPtr->m_debugDraw->getDebugMode() > 0)96 if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe )) 97 97 { 98 98 btVector3 color(255,255,0); -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
r2192 r2430 17 17 #define CONVEX_CONCAVE_COLLISION_ALGORITHM_H 18 18 19 #include " BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"19 #include "btActivatingCollisionAlgorithm.h" 20 20 #include "BulletCollision/BroadphaseCollision/btDispatcher.h" 21 21 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" … … 35 35 btVector3 m_aabbMax ; 36 36 37 37 38 btManifoldResult* m_resultOut; 38 39 39 btDispatcher* m_dispatcher; 40 40 const btDispatcherInfo* m_dispatchInfoPtr; … … 71 71 72 72 /// btConvexConcaveCollisionAlgorithm supports collision between convex shapes and (concave) trianges meshes. 73 class btConvexConcaveCollisionAlgorithm : public bt CollisionAlgorithm73 class btConvexConcaveCollisionAlgorithm : public btActivatingCollisionAlgorithm 74 74 { 75 75 … … 77 77 78 78 btConvexTriangleCallback m_btConvexTriangleCallback; 79 79 80 80 81 -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
r2192 r2430 39 39 #include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" 40 40 41 #include "BulletCollision/NarrowPhaseCollision/btGjkEpa .h"41 #include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" 42 42 #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" 43 43 … … 61 61 62 62 btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver) 63 : btCollisionAlgorithm(ci), 64 m_gjkPairDetector(0,0,simplexSolver,pdSolver), 63 : btActivatingCollisionAlgorithm(ci,body0,body1), 64 m_simplexSolver(simplexSolver), 65 m_pdSolver(pdSolver), 65 66 m_ownManifold (false), 66 67 m_manifoldPtr(mf), 67 68 m_lowLevelOfDetail(false) 69 #ifdef USE_SEPDISTANCE_UTIL2 70 ,m_sepDistance((static_cast<btConvexShape*>(body0->getCollisionShape()))->getAngularMotionDisc(), 71 (static_cast<btConvexShape*>(body1->getCollisionShape()))->getAngularMotionDisc()) 72 #endif 68 73 { 69 74 (void)body0; 70 75 (void)body1; 71 72 73 76 } 74 77 … … 108 111 resultOut->setPersistentManifold(m_manifoldPtr); 109 112 110 #ifdef USE_BT_GJKEPA 111 btConvexShape* shape0(static_cast<btConvexShape*>(body0->getCollisionShape())); 112 btConvexShape* shape1(static_cast<btConvexShape*>(body1->getCollisionShape())); 113 const btScalar radialmargin(0/*shape0->getMargin()+shape1->getMargin()*/); 114 btGjkEpaSolver::sResults results; 115 if(btGjkEpaSolver::Collide( shape0,body0->getWorldTransform(), 116 shape1,body1->getWorldTransform(), 117 radialmargin,results)) 118 { 119 dispatchInfo.m_debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0)); 120 resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth); 121 } 122 #else 113 123 114 124 115 btConvexShape* min0 = static_cast<btConvexShape*>(body0->getCollisionShape()); 125 116 btConvexShape* min1 = static_cast<btConvexShape*>(body1->getCollisionShape()); 117 118 #ifdef USE_SEPDISTANCE_UTIL2 119 m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(),body1->getWorldTransform()); 120 if (!dispatchInfo.m_useConvexConservativeDistanceUtil || m_sepDistance.getConservativeSeparatingDistance()<=0.f) 121 #endif //USE_SEPDISTANCE_UTIL2 122 123 { 124 126 125 127 126 btGjkPairDetector::ClosestPointInput input; 128 127 128 btGjkPairDetector gjkPairDetector(min0,min1,m_simplexSolver,m_pdSolver); 129 129 //TODO: if (dispatchInfo.m_useContinuous) 130 m_gjkPairDetector.setMinkowskiA(min0); 131 m_gjkPairDetector.setMinkowskiB(min1); 132 input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold(); 133 input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared; 130 gjkPairDetector.setMinkowskiA(min0); 131 gjkPairDetector.setMinkowskiB(min1); 132 133 #ifdef USE_SEPDISTANCE_UTIL2 134 if (dispatchInfo.m_useConvexConservativeDistanceUtil) 135 { 136 input.m_maximumDistanceSquared = 1e30f; 137 } else 138 #endif //USE_SEPDISTANCE_UTIL2 139 { 140 input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold(); 141 input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared; 142 } 143 134 144 input.m_stackAlloc = dispatchInfo.m_stackAllocator; 135 136 // input.m_maximumDistanceSquared = btScalar(1e30);137 138 145 input.m_transformA = body0->getWorldTransform(); 139 146 input.m_transformB = body1->getWorldTransform(); 140 141 m_gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); 142 #endif 147 148 gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); 149 150 btScalar sepDist = gjkPairDetector.getCachedSeparatingDistance()+dispatchInfo.m_convexConservativeDistanceThreshold; 151 152 #ifdef USE_SEPDISTANCE_UTIL2 153 if (dispatchInfo.m_useConvexConservativeDistanceUtil) 154 { 155 m_sepDistance.initSeparatingDistance(gjkPairDetector.getCachedSeparatingAxis(),sepDist,body0->getWorldTransform(),body1->getWorldTransform()); 156 } 157 #endif //USE_SEPDISTANCE_UTIL2 158 159 160 } 143 161 144 162 if (m_ownManifold) -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
r2192 r2430 17 17 #define CONVEX_CONVEX_ALGORITHM_H 18 18 19 #include " BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"19 #include "btActivatingCollisionAlgorithm.h" 20 20 #include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" 21 21 #include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" … … 24 24 #include "btCollisionCreateFunc.h" 25 25 #include "btCollisionDispatcher.h" 26 #include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil 26 27 27 28 class btConvexPenetrationDepthSolver; 28 29 30 ///Enabling USE_SEPDISTANCE_UTIL2 requires 100% reliable distance computation. However, when using large size ratios GJK can be imprecise 31 ///so the distance is not conservative. In that case, enabling this USE_SEPDISTANCE_UTIL2 would result in failing/missing collisions. 32 ///Either improve GJK for large size ratios (testing a 100 units versus a 0.1 unit object) or only enable the util 33 ///for certain pairs that have a small size ratio 34 ///#define USE_SEPDISTANCE_UTIL2 1 35 29 36 ///ConvexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations. 30 class btConvexConvexAlgorithm : public bt CollisionAlgorithm37 class btConvexConvexAlgorithm : public btActivatingCollisionAlgorithm 31 38 { 32 btGjkPairDetector m_gjkPairDetector; 33 public: 39 #ifdef USE_SEPDISTANCE_UTIL2 40 btConvexSeparatingDistanceUtil m_sepDistance; 41 #endif 42 btSimplexSolverInterface* m_simplexSolver; 43 btConvexPenetrationDepthSolver* m_pdSolver; 34 44 45 35 46 bool m_ownManifold; 36 47 btPersistentManifold* m_manifoldPtr; 37 48 bool m_lowLevelOfDetail; 49 50 ///cache separating vector to speedup collision detection 38 51 39 52 -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp
r2192 r2430 101 101 int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm); 102 102 int maxSize3 = sizeof(btCompoundCollisionAlgorithm); 103 int maxSize4 = sizeof(btEmptyAlgorithm);104 103 int sl = sizeof(btConvexSeparatingDistanceUtil); 104 sl = sizeof(btGjkPairDetector); 105 105 int collisionAlgorithmMaxElementSize = btMax(maxSize,maxSize2); 106 106 collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3); 107 collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize4);108 107 109 108 if (constructionInfo.m_stackAlloc) -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h
r2192 r2430 34 34 m_persistentManifoldPool(0), 35 35 m_collisionAlgorithmPool(0), 36 m_defaultMaxPersistentManifoldPoolSize( 65535),37 m_defaultMaxCollisionAlgorithmPoolSize( 65535),38 m_defaultStackAllocatorSize( 5*1024*1024)36 m_defaultMaxPersistentManifoldPoolSize(4096), 37 m_defaultMaxCollisionAlgorithmPoolSize(4096), 38 m_defaultStackAllocatorSize(0) 39 39 { 40 40 } … … 45 45 ///btCollisionConfiguration allows to configure Bullet collision detection 46 46 ///stack allocator, pool memory allocators 47 /// todo: describe the meaning47 ///@todo: describe the meaning 48 48 class btDefaultCollisionConfiguration : public btCollisionConfiguration 49 49 { -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btManifoldResult.cpp
r2192 r2430 94 94 newPt.m_index1 = m_index1; 95 95 96 /// todo, check this for any side effects96 ///@todo, check this for any side effects 97 97 if (insertIndex >= 0) 98 98 { -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
r2192 r2430 144 144 145 145 146 void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollision ObjectArray& collisionObjects)146 void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld) 147 147 { 148 148 149 149 BT_PROFILE("islandUnionFindAndQuickSort"); 150 150 151 btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray(); 152 151 153 m_islandmanifold.resize(0); 152 154 … … 239 241 { 240 242 colObj0->setActivationState( WANTS_DEACTIVATION); 243 colObj0->setDeactivationTime(0.f); 241 244 } 242 245 } … … 263 266 btCollisionObject* colObj1 = static_cast<btCollisionObject*>(manifold->getBody1()); 264 267 265 // todo: check sleeping conditions!268 ///@todo: check sleeping conditions! 266 269 if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) || 267 270 ((colObj1) && colObj1->getActivationState() != ISLAND_SLEEPING)) … … 288 291 289 292 290 // 291 // todo: this is random access, it can be walked 'cache friendly'! 292 // 293 void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback) 294 { 295 296 buildIslands(dispatcher,collisionObjects); 293 ///@todo: this is random access, it can be walked 'cache friendly'! 294 void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld, IslandCallback* callback) 295 { 296 btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray(); 297 298 buildIslands(dispatcher,collisionWorld); 297 299 298 300 int endIslandIndex=1; -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.h
r2192 r2430 20 20 #include "btCollisionCreateFunc.h" 21 21 #include "LinearMath/btAlignedObjectArray.h" 22 22 #include "btCollisionObject.h" 23 23 24 24 class btCollisionObject; … … 62 62 }; 63 63 64 void buildAndProcessIslands(btDispatcher* dispatcher,btCollision ObjectArray& collisionObjects, IslandCallback* callback);64 void buildAndProcessIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld, IslandCallback* callback); 65 65 66 void buildIslands(btDispatcher* dispatcher,btCollision ObjectArray& collisionObjects);66 void buildIslands(btDispatcher* dispatcher,btCollisionWorld* colWorld); 67 67 68 68 }; -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
r2192 r2430 22 22 23 23 btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped) 24 : bt CollisionAlgorithm(ci),24 : btActivatingCollisionAlgorithm(ci,col0,col1), 25 25 m_ownManifold(false), 26 26 m_manifoldPtr(mf), -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h
r2192 r2430 17 17 #define SPHERE_BOX_COLLISION_ALGORITHM_H 18 18 19 #include " BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"19 #include "btActivatingCollisionAlgorithm.h" 20 20 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" 21 21 #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" … … 27 27 /// btSphereBoxCollisionAlgorithm provides sphere-box collision detection. 28 28 /// Other features are frame-coherency (persistent data) and collision response. 29 class btSphereBoxCollisionAlgorithm : public bt CollisionAlgorithm29 class btSphereBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm 30 30 { 31 31 bool m_ownManifold; -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
r2192 r2430 20 20 21 21 btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1) 22 : bt CollisionAlgorithm(ci),22 : btActivatingCollisionAlgorithm(ci,col0,col1), 23 23 m_ownManifold(false), 24 24 m_manifoldPtr(mf) -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h
r2192 r2430 17 17 #define SPHERE_SPHERE_COLLISION_ALGORITHM_H 18 18 19 #include " BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"19 #include "btActivatingCollisionAlgorithm.h" 20 20 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" 21 21 #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" … … 27 27 /// Other features are frame-coherency (persistent data) and collision response. 28 28 /// Also provides the most basic sample for custom/user btCollisionAlgorithm 29 class btSphereSphereCollisionAlgorithm : public bt CollisionAlgorithm29 class btSphereSphereCollisionAlgorithm : public btActivatingCollisionAlgorithm 30 30 { 31 31 bool m_ownManifold; … … 36 36 37 37 btSphereSphereCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) 38 : bt CollisionAlgorithm(ci) {}38 : btActivatingCollisionAlgorithm(ci) {} 39 39 40 40 virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
r2192 r2430 23 23 24 24 btSphereTriangleCollisionAlgorithm::btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1,bool swapped) 25 : bt CollisionAlgorithm(ci),25 : btActivatingCollisionAlgorithm(ci,col0,col1), 26 26 m_ownManifold(false), 27 27 m_manifoldPtr(mf), … … 57 57 /// report a contact. internally this will be kept persistent, and contact reduction is done 58 58 resultOut->setPersistentManifold(m_manifoldPtr); 59 SphereTriangleDetector detector(sphere,triangle );59 SphereTriangleDetector detector(sphere,triangle, m_manifoldPtr->getContactBreakingThreshold()); 60 60 61 61 btDiscreteCollisionDetectorInterface::ClosestPointInput input; 62 input.m_maximumDistanceSquared = btScalar(1e30);// todo: tighter bounds62 input.m_maximumDistanceSquared = btScalar(1e30);///@todo: tighter bounds 63 63 input.m_transformA = sphereObj->getWorldTransform(); 64 64 input.m_transformB = triObj->getWorldTransform(); -
code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
r2192 r2430 17 17 #define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H 18 18 19 #include " BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"19 #include "btActivatingCollisionAlgorithm.h" 20 20 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" 21 21 #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" … … 26 26 /// Other features are frame-coherency (persistent data) and collision response. 27 27 /// Also provides the most basic sample for custom/user btCollisionAlgorithm 28 class btSphereTriangleCollisionAlgorithm : public bt CollisionAlgorithm28 class btSphereTriangleCollisionAlgorithm : public btActivatingCollisionAlgorithm 29 29 { 30 30 bool m_ownManifold; … … 36 36 37 37 btSphereTriangleCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) 38 : bt CollisionAlgorithm(ci) {}38 : btActivatingCollisionAlgorithm(ci) {} 39 39 40 40 virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btBoxShape.h
r2192 r2430 20 20 #include "btCollisionMargin.h" 21 21 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" 22 #include "LinearMath/bt Point3.h"22 #include "LinearMath/btVector3.h" 23 23 #include "LinearMath/btMinMax.h" 24 24 … … 118 118 virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; 119 119 120 virtual void getPlane(btVector3& planeNormal,bt Point3& planeSupport,int i ) const120 virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const 121 121 { 122 122 //this plane might not be aligned... … … 191 191 192 192 193 virtual void getEdge(int i,bt Point3& pa,btPoint3& pb) const193 virtual void getEdge(int i,btVector3& pa,btVector3& pb) const 194 194 //virtual void getEdge(int i,Edge& edge) const 195 195 { … … 262 262 263 263 264 virtual bool isInside(const bt Point3& pt,btScalar tolerance) const264 virtual bool isInside(const btVector3& pt,btScalar tolerance) const 265 265 { 266 266 btVector3 halfExtents = getHalfExtentsWithoutMargin(); -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
r2192 r2430 144 144 { 145 145 int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; 146 147 btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride); 148 149 m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); 146 147 if (type == PHY_FLOAT) 148 { 149 float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); 150 151 m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); 152 } 153 else 154 { 155 double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); 156 157 m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ()); 158 } 150 159 } 151 160 … … 205 214 int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; 206 215 207 btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride); 208 209 m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); 216 if (type == PHY_FLOAT) 217 { 218 float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); 219 220 m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); 221 } 222 else 223 { 224 double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); 225 226 m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ()); 227 } 210 228 } 211 229 … … 282 300 printf("%d ,",graphicsindex); 283 301 #endif //DEBUG_TRIANGLE_MESH 284 btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride); 285 286 m_triangle[j] = btVector3( 287 graphicsbase[0]*meshScaling.getX(), 288 graphicsbase[1]*meshScaling.getY(), 289 graphicsbase[2]*meshScaling.getZ()); 302 if (type == PHY_FLOAT) 303 { 304 float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); 305 306 m_triangle[j] = btVector3( 307 graphicsbase[0]*meshScaling.getX(), 308 graphicsbase[1]*meshScaling.getY(), 309 graphicsbase[2]*meshScaling.getZ()); 310 } 311 else 312 { 313 double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); 314 315 m_triangle[j] = btVector3( 316 btScalar(graphicsbase[0])*meshScaling.getX(), 317 btScalar(graphicsbase[1])*meshScaling.getY(), 318 btScalar(graphicsbase[2])*meshScaling.getZ()); 319 } 290 320 #ifdef DEBUG_TRIANGLE_MESH 291 321 printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z()); -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCapsuleShape.h
r2192 r2430 50 50 halfExtents += btVector3(getMargin(),getMargin(),getMargin()); 51 51 btMatrix3x3 abs_b = t.getBasis().absolute(); 52 bt Point3 center = t.getOrigin();52 btVector3 center = t.getOrigin(); 53 53 btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents)); 54 54 -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCollisionShape.cpp
r2192 r2430 43 43 } 44 44 45 btScalar btCollisionShape::getContactBreakingThreshold() const 46 { 47 ///@todo make this 0.1 configurable 48 return getAngularMotionDisc() * btScalar(0.1); 49 } 45 50 btScalar btCollisionShape::getAngularMotionDisc() const 46 51 { 52 ///@todo cache this value, to improve performance 47 53 btVector3 center; 48 54 btScalar disc; … … 66 72 // add linear motion 67 73 btVector3 linMotion = linvel*timeStep; 68 // todo: simd would have a vector max/min operation, instead of per-element access74 ///@todo: simd would have a vector max/min operation, instead of per-element access 69 75 if (linMotion.x() > btScalar(0.)) 70 76 temporalAabbMaxx += linMotion.x(); -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCollisionShape.h
r2192 r2430 20 20 #include "LinearMath/btVector3.h" 21 21 #include "LinearMath/btMatrix3x3.h" 22 #include "LinearMath/btPoint3.h"23 22 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types 24 23 … … 47 46 ///getAngularMotionDisc returns the maximus radius needed for Conservative Advancement to handle time-of-impact with rotations. 48 47 virtual btScalar getAngularMotionDisc() const; 48 49 virtual btScalar getContactBreakingThreshold() const; 49 50 50 51 -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCompoundShape.cpp
r2192 r2430 18 18 #include "BulletCollision/BroadphaseCollision/btDbvt.h" 19 19 20 btCompoundShape::btCompoundShape( )20 btCompoundShape::btCompoundShape(bool enableDynamicAabbTree) 21 21 : m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)), 22 22 m_localAabbMax(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)), … … 26 26 { 27 27 m_shapeType = COMPOUND_SHAPE_PROXYTYPE; 28 void* mem = btAlignedAlloc(sizeof(btDbvt),16); 29 m_dynamicAabbTree = new(mem) btDbvt(); 30 btAssert(mem==m_dynamicAabbTree); 28 29 if (enableDynamicAabbTree) 30 { 31 void* mem = btAlignedAlloc(sizeof(btDbvt),16); 32 m_dynamicAabbTree = new(mem) btDbvt(); 33 btAssert(mem==m_dynamicAabbTree); 34 } 31 35 } 32 36 … … 77 81 } 78 82 83 void btCompoundShape::updateChildTransform(int childIndex, const btTransform& newChildTransform) 84 { 85 m_children[childIndex].m_transform = newChildTransform; 86 87 if (m_dynamicAabbTree) 88 { 89 ///update the dynamic aabb tree 90 btVector3 localAabbMin,localAabbMax; 91 m_children[childIndex].m_childShape->getAabb(newChildTransform,localAabbMin,localAabbMax); 92 ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax); 93 int index = m_children.size()-1; 94 m_dynamicAabbTree->update(m_children[childIndex].m_node,bounds); 95 } 96 97 recalculateLocalAabb(); 98 } 99 79 100 void btCompoundShape::removeChildShapeByIndex(int childShapeIndex) 80 101 { … … 88 109 89 110 } 111 112 90 113 91 114 void btCompoundShape::removeChildShape(btCollisionShape* shape) … … 100 123 m_children.pop_back(); 101 124 //remove it from the m_dynamicAabbTree too 125 //@todo: this leads to problems due to caching in the btCompoundCollisionAlgorithm 126 //so effectively, removeChildShape is broken at the moment 102 127 //m_dynamicAabbTree->remove(m_aabbProxies[i]); 103 128 //m_aabbProxies.swap(i,m_children.size()-1); … … 142 167 btMatrix3x3 abs_b = trans.getBasis().absolute(); 143 168 144 bt Point3 center = trans(localCenter);169 btVector3 center = trans(localCenter); 145 170 146 171 btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents), … … 181 206 btScalar totalMass = 0; 182 207 btVector3 center(0, 0, 0); 183 for (int k = 0; k < n; k++) 208 int k; 209 210 for (k = 0; k < n; k++) 184 211 { 185 212 center += m_children[k].m_transform.getOrigin() * masses[k]; … … 190 217 191 218 btMatrix3x3 tensor(0, 0, 0, 0, 0, 0, 0, 0, 0); 192 for ( intk = 0; k < n; k++)219 for ( k = 0; k < n; k++) 193 220 { 194 221 btVector3 i; -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCompoundShape.h
r2192 r2430 47 47 } 48 48 49 /// btCompoundShape allows to store multiple other btCollisionShapes49 /// The btCompoundShape allows to store multiple other btCollisionShapes 50 50 /// This allows for moving concave collision objects. This is more general then the static concave btBvhTriangleMeshShape. 51 /// It has an (optional) dynamic aabb tree to accelerate early rejection tests. 52 /// @todo: This aabb tree can also be use to speed up ray tests on btCompoundShape, see http://code.google.com/p/bullet/issues/detail?id=25 53 /// Currently, removal of child shapes is only supported when disabling the aabb tree (pass 'false' in the constructor of btCompoundShape) 51 54 ATTRIBUTE_ALIGNED16(class) btCompoundShape : public btCollisionShape 52 55 { 53 //btAlignedObjectArray<btTransform> m_childTransforms;54 //btAlignedObjectArray<btCollisionShape*> m_childShapes;55 56 btAlignedObjectArray<btCompoundShapeChild> m_children; 56 57 btVector3 m_localAabbMin; 57 58 btVector3 m_localAabbMax; 58 59 59 //btOptimizedBvh* m_aabbTree;60 60 btDbvt* m_dynamicAabbTree; 61 61 … … 63 63 BT_DECLARE_ALIGNED_ALLOCATOR(); 64 64 65 btCompoundShape( );65 btCompoundShape(bool enableDynamicAabbTree = true); 66 66 67 67 virtual ~btCompoundShape(); … … 89 89 } 90 90 91 btTransform getChildTransform(int index)91 btTransform& getChildTransform(int index) 92 92 { 93 93 return m_children[index].m_transform; 94 94 } 95 const btTransform getChildTransform(int index) const95 const btTransform& getChildTransform(int index) const 96 96 { 97 97 return m_children[index].m_transform; 98 98 } 99 100 ///set a new transform for a child, and update internal data structures (local aabb and dynamic tree) 101 void updateChildTransform(int childIndex, const btTransform& newChildTransform); 99 102 100 103 -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConcaveShape.h
r2192 r2430 21 21 #include "btTriangleCallback.h" 22 22 23 /// PHY_ScalarType enumerates possible scalar types. 24 /// See the btStridingMeshInterface or btHeightfieldTerrainShape for its use 25 typedef enum PHY_ScalarType { 26 PHY_FLOAT, 27 PHY_DOUBLE, 28 PHY_INTEGER, 29 PHY_SHORT, 30 PHY_FIXEDPOINT88, 31 PHY_UCHAR 32 } PHY_ScalarType; 23 33 24 34 ///The btConcaveShape class provides an interface for non-moving (static) concave shapes. -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConeShape.cpp
r2192 r2430 15 15 16 16 #include "btConeShape.h" 17 #include "LinearMath/btPoint3.h"18 17 19 18 -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexHullShape.cpp
r2192 r2430 23 23 { 24 24 m_shapeType = CONVEX_HULL_SHAPE_PROXYTYPE; 25 m_ points.resize(numPoints);25 m_unscaledPoints.resize(numPoints); 26 26 27 27 unsigned char* pointsBaseAddress = (unsigned char*)points; … … 29 29 for (int i=0;i<numPoints;i++) 30 30 { 31 bt Point3* point = (btPoint3*)(pointsBaseAddress + i*stride);32 m_ points[i] = point[0];31 btVector3* point = (btVector3*)(pointsBaseAddress + i*stride); 32 m_unscaledPoints[i] = point[0]; 33 33 } 34 34 … … 45 45 } 46 46 47 void btConvexHullShape::addPoint(const bt Point3& point)47 void btConvexHullShape::addPoint(const btVector3& point) 48 48 { 49 m_ points.push_back(point);49 m_unscaledPoints.push_back(point); 50 50 recalcLocalAabb(); 51 51 … … 69 69 70 70 71 for (int i=0;i<m_ points.size();i++)71 for (int i=0;i<m_unscaledPoints.size();i++) 72 72 { 73 bt Point3 vtx = m_points[i] * m_localScaling;73 btVector3 vtx = m_unscaledPoints[i] * m_localScaling; 74 74 75 75 newDot = vec.dot(vtx); … … 93 93 } 94 94 } 95 for (int i=0;i<m_ points.size();i++)95 for (int i=0;i<m_unscaledPoints.size();i++) 96 96 { 97 bt Point3 vtx = m_points[i] * m_localScaling;97 btVector3 vtx = getScaledPoint(i); 98 98 99 99 for (int j=0;j<numVectors;j++) … … 146 146 int btConvexHullShape::getNumVertices() const 147 147 { 148 return m_ points.size();148 return m_unscaledPoints.size(); 149 149 } 150 150 151 151 int btConvexHullShape::getNumEdges() const 152 152 { 153 return m_ points.size();153 return m_unscaledPoints.size(); 154 154 } 155 155 156 void btConvexHullShape::getEdge(int i,bt Point3& pa,btPoint3& pb) const156 void btConvexHullShape::getEdge(int i,btVector3& pa,btVector3& pb) const 157 157 { 158 158 159 int index0 = i%m_ points.size();160 int index1 = (i+1)%m_ points.size();161 pa = m_points[index0]*m_localScaling;162 pb = m_points[index1]*m_localScaling;159 int index0 = i%m_unscaledPoints.size(); 160 int index1 = (i+1)%m_unscaledPoints.size(); 161 pa = getScaledPoint(index0); 162 pb = getScaledPoint(index1); 163 163 } 164 164 165 void btConvexHullShape::getVertex(int i,bt Point3& vtx) const165 void btConvexHullShape::getVertex(int i,btVector3& vtx) const 166 166 { 167 vtx = m_points[i]*m_localScaling;167 vtx = getScaledPoint(i); 168 168 } 169 169 … … 173 173 } 174 174 175 void btConvexHullShape::getPlane(btVector3& ,bt Point3& ,int ) const175 void btConvexHullShape::getPlane(btVector3& ,btVector3& ,int ) const 176 176 { 177 177 … … 180 180 181 181 //not yet 182 bool btConvexHullShape::isInside(const bt Point3& ,btScalar ) const182 bool btConvexHullShape::isInside(const btVector3& ,btScalar ) const 183 183 { 184 184 assert(0); -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexHullShape.h
r2192 r2430 25 25 ATTRIBUTE_ALIGNED16(class) btConvexHullShape : public btPolyhedralConvexShape 26 26 { 27 btAlignedObjectArray<bt Point3> m_points;27 btAlignedObjectArray<btVector3> m_unscaledPoints; 28 28 29 29 public: … … 34 34 ///It is easier to not pass any points in the constructor, and just add one point at a time, using addPoint. 35 35 ///btConvexHullShape make an internal copy of the points. 36 btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(bt Point3));36 btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(btVector3)); 37 37 38 void addPoint(const bt Point3& point);38 void addPoint(const btVector3& point); 39 39 40 btPoint3* getPoints() 40 41 btVector3* getUnscaledPoints() 41 42 { 42 return &m_ points[0];43 return &m_unscaledPoints[0]; 43 44 } 44 45 45 const bt Point3* getPoints() const46 const btVector3* getUnscaledPoints() const 46 47 { 47 return &m_ points[0];48 return &m_unscaledPoints[0]; 48 49 } 49 50 50 int getNumPoints() const 51 ///getPoints is obsolete, please use getUnscaledPoints 52 const btVector3* getPoints() const 51 53 { 52 return m_points.size(); 54 return getUnscaledPoints(); 55 } 56 57 58 59 60 SIMD_FORCE_INLINE btVector3 getScaledPoint(int i) const 61 { 62 return m_unscaledPoints[i] * m_localScaling; 63 } 64 65 SIMD_FORCE_INLINE int getNumPoints() const 66 { 67 return m_unscaledPoints.size(); 53 68 } 54 69 … … 65 80 virtual int getNumVertices() const; 66 81 virtual int getNumEdges() const; 67 virtual void getEdge(int i,bt Point3& pa,btPoint3& pb) const;68 virtual void getVertex(int i,bt Point3& vtx) const;82 virtual void getEdge(int i,btVector3& pa,btVector3& pb) const; 83 virtual void getVertex(int i,btVector3& vtx) const; 69 84 virtual int getNumPlanes() const; 70 virtual void getPlane(btVector3& planeNormal,bt Point3& planeSupport,int i ) const;71 virtual bool isInside(const bt Point3& pt,btScalar tolerance) const;85 virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const; 86 virtual bool isInside(const btVector3& pt,btScalar tolerance) const; 72 87 73 88 ///in case we receive negative scaling -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.cpp
r2192 r2430 18 18 19 19 20 20 21 btConvexInternalShape::btConvexInternalShape() 21 : btConvexShape (),m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),22 : m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)), 22 23 m_collisionMargin(CONVEX_DISTANCE_MARGIN) 23 24 { … … 49 50 minAabb[i] = tmp[i]-margin; 50 51 } 51 }; 52 } 53 52 54 53 55 … … 71 73 72 74 #else 75 btAssert(0); 73 76 return btVector3(0,0,0); 74 77 #endif //__SPU__ -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.h
r2192 r2430 31 31 } 32 32 33 34 33 virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; 35 #ifndef __SPU__36 virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0;37 38 //notice that the vectors should be unit length39 virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0;40 #endif //#ifndef __SPU__41 34 42 35 const btVector3& getImplicitShapeDimensions() const -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
r2192 r2430 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 38 20 void btConvexPointCloudShape::setLocalScaling(const btVector3& scaling) 39 21 { … … 42 24 } 43 25 26 #ifndef __SPU__ 44 27 btVector3 btConvexPointCloudShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const 45 28 { … … 61 44 for (int i=0;i<m_numPoints;i++) 62 45 { 63 bt Point3 vtx = m_points[i] * m_localScaling;46 btVector3 vtx = getScaledPoint(i); 64 47 65 48 newDot = vec.dot(vtx); … … 85 68 for (int i=0;i<m_numPoints;i++) 86 69 { 87 bt Point3 vtx = m_points[i] * m_localScaling;70 btVector3 vtx = getScaledPoint(i); 88 71 89 72 for (int j=0;j<numVectors;j++) … … 125 108 126 109 127 110 #endif 128 111 129 112 … … 144 127 } 145 128 146 void btConvexPointCloudShape::getEdge(int i,bt Point3& pa,btPoint3& pb) const129 void btConvexPointCloudShape::getEdge(int i,btVector3& pa,btVector3& pb) const 147 130 { 148 131 btAssert (0); 149 132 } 150 133 151 void btConvexPointCloudShape::getVertex(int i,bt Point3& vtx) const134 void btConvexPointCloudShape::getVertex(int i,btVector3& vtx) const 152 135 { 153 vtx = m_ points[i]*m_localScaling;136 vtx = m_unscaledPoints[i]*m_localScaling; 154 137 } 155 138 … … 159 142 } 160 143 161 void btConvexPointCloudShape::getPlane(btVector3& ,bt Point3& ,int ) const144 void btConvexPointCloudShape::getPlane(btVector3& ,btVector3& ,int ) const 162 145 { 163 146 … … 166 149 167 150 //not yet 168 bool btConvexPointCloudShape::isInside(const bt Point3& ,btScalar ) const151 bool btConvexPointCloudShape::isInside(const btVector3& ,btScalar ) const 169 152 { 170 153 assert(0); -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.h
r2192 r2430 24 24 ATTRIBUTE_ALIGNED16(class) btConvexPointCloudShape : public btPolyhedralConvexShape 25 25 { 26 btVector3* m_ points;26 btVector3* m_unscaledPoints; 27 27 int m_numPoints; 28 28 29 public: 29 30 BT_DECLARE_ALIGNED_ALLOCATOR(); 30 31 31 btConvexPointCloudShape(btVector3* points,int numPoints); 32 btConvexPointCloudShape(btVector3* points,int numPoints, const btVector3& localScaling,bool computeAabb = true) 33 { 34 m_localScaling = localScaling; 35 m_shapeType = CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE; 36 m_unscaledPoints = points; 37 m_numPoints = numPoints; 32 38 33 void setPoints (btVector3* points, int numPoints); 34 35 btPoint3* getPoints() 36 { 37 return m_points; 39 if (computeAabb) 40 recalcLocalAabb(); 38 41 } 39 42 40 const btPoint3* getPoints() const43 void setPoints (btVector3* points, int numPoints, bool computeAabb = true) 41 44 { 42 return m_points; 45 m_unscaledPoints = points; 46 m_numPoints = numPoints; 47 48 if (computeAabb) 49 recalcLocalAabb(); 43 50 } 44 51 45 int getNumPoints() const 52 SIMD_FORCE_INLINE btVector3* getUnscaledPoints() 53 { 54 return m_unscaledPoints; 55 } 56 57 SIMD_FORCE_INLINE const btVector3* getUnscaledPoints() const 58 { 59 return m_unscaledPoints; 60 } 61 62 SIMD_FORCE_INLINE int getNumPoints() const 46 63 { 47 64 return m_numPoints; 48 65 } 49 66 67 SIMD_FORCE_INLINE btVector3 getScaledPoint( int index) const 68 { 69 return m_unscaledPoints[index] * m_localScaling; 70 } 71 72 #ifndef __SPU__ 50 73 virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; 51 74 virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; 52 75 virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; 76 #endif 53 77 54 78 … … 58 82 virtual int getNumVertices() const; 59 83 virtual int getNumEdges() const; 60 virtual void getEdge(int i,bt Point3& pa,btPoint3& pb) const;61 virtual void getVertex(int i,bt Point3& vtx) const;84 virtual void getEdge(int i,btVector3& pa,btVector3& pb) const; 85 virtual void getVertex(int i,btVector3& vtx) const; 62 86 virtual int getNumPlanes() const; 63 virtual void getPlane(btVector3& planeNormal,bt Point3& planeSupport,int i ) const;64 virtual bool isInside(const bt Point3& pt,btScalar tolerance) const;87 virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const; 88 virtual bool isInside(const btVector3& pt,btScalar tolerance) const; 65 89 66 90 ///in case we receive negative scaling -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexShape.cpp
r2192 r2430 15 15 16 16 #include "btConvexShape.h" 17 #include "btConvexInternalShape.h"18 17 #include "btTriangleShape.h" 19 18 #include "btSphereShape.h" … … 23 22 #include "btConvexPointCloudShape.h" 24 23 25 static btVector3 convexHullSupport (const btVector3& localDir, const btVector3* points, int numPoints) 24 btConvexShape::btConvexShape () 25 { 26 } 27 28 btConvexShape::~btConvexShape() 29 { 30 31 } 32 33 34 35 static btVector3 convexHullSupport (const btVector3& localDir, const btVector3* points, int numPoints, const btVector3& localScaling) 26 36 { 27 37 btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.)); … … 42 52 for (int i=0;i<numPoints;i++) 43 53 { 44 bt Point3 vtx = points[i];// * m_localScaling;54 btVector3 vtx = points[i] * localScaling; 45 55 46 56 newDot = vec.dot(vtx); … … 62 72 return btVector3(0,0,0); 63 73 } 64 break;65 74 case BOX_SHAPE_PROXYTYPE: 66 75 { 67 bt ConvexInternalShape* convexShape = (btConvexInternalShape*)this;76 btBoxShape* convexShape = (btBoxShape*)this; 68 77 const btVector3& halfExtents = convexShape->getImplicitShapeDimensions(); 69 78 … … 72 81 btFsels(localDir.z(), halfExtents.z(), -halfExtents.z())); 73 82 } 74 break;75 83 case TRIANGLE_SHAPE_PROXYTYPE: 76 84 { … … 82 90 return btVector3(sup.getX(),sup.getY(),sup.getZ()); 83 91 } 84 break;85 92 case CYLINDER_SHAPE_PROXYTYPE: 86 93 { … … 143 150 } 144 151 } 145 break;146 152 case CAPSULE_SHAPE_PROXYTYPE: 147 153 { … … 200 206 return btVector3(supVec.getX(),supVec.getY(),supVec.getZ()); 201 207 } 202 break;203 208 case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: 204 209 { 205 210 btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this; 206 btVector3* points = convexPointCloudShape->get Points ();211 btVector3* points = convexPointCloudShape->getUnscaledPoints (); 207 212 int numPoints = convexPointCloudShape->getNumPoints (); 208 return convexHullSupport (localDir, points, numPoints );213 return convexHullSupport (localDir, points, numPoints,convexPointCloudShape->getLocalScalingNV()); 209 214 } 210 215 case CONVEX_HULL_SHAPE_PROXYTYPE: 211 216 { 212 217 btConvexHullShape* convexHullShape = (btConvexHullShape*)this; 213 bt Point3* points = convexHullShape->getPoints();218 btVector3* points = convexHullShape->getUnscaledPoints(); 214 219 int numPoints = convexHullShape->getNumPoints (); 215 return convexHullSupport (localDir, points, numPoints); 216 } 217 break; 220 return convexHullSupport (localDir, points, numPoints,convexHullShape->getLocalScalingNV()); 221 } 218 222 default: 219 223 #ifndef __SPU__ … … 222 226 btAssert (0); 223 227 #endif 224 break;225 228 } 226 229 227 230 // should never reach here 228 231 btAssert (0); 229 return bt Point3 (btScalar(0.0f), btScalar(0.0f), btScalar(0.0f));232 return btVector3 (btScalar(0.0f), btScalar(0.0f), btScalar(0.0f)); 230 233 } 231 234 … … 238 241 } 239 242 localDirNorm.normalize (); 240 switch (m_shapeType) 241 { 242 case SPHERE_SHAPE_PROXYTYPE: 243 { 244 return btVector3(0,0,0) + getMarginNonVirtual() * localDirNorm; 245 } 246 break; 247 case BOX_SHAPE_PROXYTYPE: 248 { 249 btConvexInternalShape* convexShape = (btConvexInternalShape*)this; 250 const btVector3& halfExtents = convexShape->getImplicitShapeDimensions(); 251 252 return btVector3(localDir.getX() < 0.0f ? -halfExtents.x() : halfExtents.x(), 253 localDir.getY() < 0.0f ? -halfExtents.y() : halfExtents.y(), 254 localDir.getZ() < 0.0f ? -halfExtents.z() : halfExtents.z()) + getMarginNonVirtual() * localDirNorm; 255 } 256 break; 257 case TRIANGLE_SHAPE_PROXYTYPE: 258 { 259 btTriangleShape* triangleShape = (btTriangleShape*)this; 260 btVector3 dir(localDir.getX(),localDir.getY(),localDir.getZ()); 261 btVector3* vertices = &triangleShape->m_vertices1[0]; 262 btVector3 dots(dir.dot(vertices[0]), dir.dot(vertices[1]), dir.dot(vertices[2])); 263 btVector3 sup = vertices[dots.maxAxis()]; 264 return btVector3(sup.getX(),sup.getY(),sup.getZ()) + getMarginNonVirtual() * localDirNorm; 265 } 266 break; 267 case CYLINDER_SHAPE_PROXYTYPE: 268 { 269 btCylinderShape* cylShape = (btCylinderShape*)this; 270 //mapping of halfextents/dimension onto radius/height depends on how cylinder local orientation is (upAxis) 271 272 btVector3 halfExtents = cylShape->getImplicitShapeDimensions(); 273 btVector3 v(localDir.getX(),localDir.getY(),localDir.getZ()); 274 int cylinderUpAxis = cylShape->getUpAxis(); 275 int XX(1),YY(0),ZZ(2); 276 277 switch (cylinderUpAxis) 278 { 279 case 0: 280 { 281 XX = 1; 282 YY = 0; 283 ZZ = 2; 284 } 285 break; 286 case 1: 287 { 288 XX = 0; 289 YY = 1; 290 ZZ = 2; 291 } 292 break; 293 case 2: 294 { 295 XX = 0; 296 YY = 2; 297 ZZ = 1; 298 299 } 300 break; 301 default: 302 btAssert(0); 303 break; 304 }; 305 306 btScalar radius = halfExtents[XX]; 307 btScalar halfHeight = halfExtents[cylinderUpAxis]; 308 309 btVector3 tmp; 310 btScalar d ; 311 312 btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); 313 if (s != btScalar(0.0)) 314 { 315 d = radius / s; 316 tmp[XX] = v[XX] * d; 317 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; 318 tmp[ZZ] = v[ZZ] * d; 319 return btVector3(tmp.getX(),tmp.getY(),tmp.getZ()) + getMarginNonVirtual() * localDirNorm; 320 } else { 321 tmp[XX] = radius; 322 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; 323 tmp[ZZ] = btScalar(0.0); 324 return btVector3(tmp.getX(),tmp.getY(),tmp.getZ()) + getMarginNonVirtual() * localDirNorm; 325 } 326 } 327 break; 328 case CAPSULE_SHAPE_PROXYTYPE: 329 { 330 btVector3 vec0(localDir.getX(),localDir.getY(),localDir.getZ()); 331 332 btCapsuleShape* capsuleShape = (btCapsuleShape*)this; 333 btVector3 halfExtents = capsuleShape->getImplicitShapeDimensions(); 334 btScalar halfHeight = capsuleShape->getHalfHeight(); 335 int capsuleUpAxis = capsuleShape->getUpAxis(); 336 337 btScalar radius = capsuleShape->getRadius(); 338 btVector3 supVec(0,0,0); 339 340 btScalar maxDot(btScalar(-1e30)); 341 342 btVector3 vec = vec0; 343 btScalar lenSqr = vec.length2(); 344 if (lenSqr < btScalar(0.0001)) 345 { 346 vec.setValue(1,0,0); 347 } else 348 { 349 btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); 350 vec *= rlen; 351 } 352 btVector3 vtx; 353 btScalar newDot; 354 { 355 btVector3 pos(0,0,0); 356 pos[capsuleUpAxis] = halfHeight; 357 358 vtx = pos +vec*(radius); 359 newDot = vec.dot(vtx); 360 if (newDot > maxDot) 361 { 362 maxDot = newDot; 363 supVec = vtx; 364 } 365 } 366 { 367 btVector3 pos(0,0,0); 368 pos[capsuleUpAxis] = -halfHeight; 369 370 vtx = pos +vec*(radius); 371 newDot = vec.dot(vtx); 372 if (newDot > maxDot) 373 { 374 maxDot = newDot; 375 supVec = vtx; 376 } 377 } 378 return btVector3(supVec.getX(),supVec.getY(),supVec.getZ()) + getMarginNonVirtual() * localDirNorm; 379 } 380 break; 381 case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: 382 { 383 btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this; 384 btVector3* points = convexPointCloudShape->getPoints (); 385 int numPoints = convexPointCloudShape->getNumPoints (); 386 return convexHullSupport (localDir, points, numPoints) + getMarginNonVirtual() * localDirNorm; 387 } 388 case CONVEX_HULL_SHAPE_PROXYTYPE: 389 { 390 btConvexHullShape* convexHullShape = (btConvexHullShape*)this; 391 btPoint3* points = convexHullShape->getPoints (); 392 int numPoints = convexHullShape->getNumPoints (); 393 return convexHullSupport (localDir, points, numPoints) + getMarginNonVirtual() * localDirNorm; 394 } 395 break; 396 default: 397 #ifndef __SPU__ 398 return this->localGetSupportingVertex (localDir); 399 #else 400 btAssert (0); 401 #endif 402 break; 403 } 404 405 // should never reach here 406 btAssert (0); 407 return btPoint3 (btScalar(0.0f), btScalar(0.0f), btScalar(0.0f)); 243 244 return localGetSupportVertexWithoutMarginNonVirtual(localDirNorm)+ getMarginNonVirtual() * localDirNorm; 408 245 } 409 246 … … 418 255 return sphereShape->getRadius (); 419 256 } 420 break;421 257 case BOX_SHAPE_PROXYTYPE: 422 258 { 423 bt ConvexInternalShape* convexShape = (btConvexInternalShape*)this;259 btBoxShape* convexShape = (btBoxShape*)this; 424 260 return convexShape->getMarginNV (); 425 261 } 426 break;427 262 case TRIANGLE_SHAPE_PROXYTYPE: 428 263 { … … 430 265 return triangleShape->getMarginNV (); 431 266 } 432 break;433 267 case CYLINDER_SHAPE_PROXYTYPE: 434 268 { … … 436 270 return cylShape->getMarginNV(); 437 271 } 438 break;439 272 case CAPSULE_SHAPE_PROXYTYPE: 440 273 { … … 442 275 return capsuleShape->getMarginNV(); 443 276 } 444 break;445 277 case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: 446 278 /* fall through */ … … 450 282 return convexHullShape->getMarginNV(); 451 283 } 452 break;453 284 default: 454 285 #ifndef __SPU__ … … 457 288 btAssert (0); 458 289 #endif 459 break;460 290 } 461 291 … … 484 314 case BOX_SHAPE_PROXYTYPE: 485 315 { 486 bt ConvexInternalShape* convexShape = (btConvexInternalShape*)this;316 btBoxShape* convexShape = (btBoxShape*)this; 487 317 float margin=convexShape->getMarginNonVirtual(); 488 318 btVector3 halfExtents = convexShape->getImplicitShapeDimensions(); 489 319 halfExtents += btVector3(margin,margin,margin); 490 320 btMatrix3x3 abs_b = t.getBasis().absolute(); 491 bt Point3 center = t.getOrigin();321 btVector3 center = t.getOrigin(); 492 322 btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents)); 493 323 … … 496 326 break; 497 327 } 498 break;499 328 case TRIANGLE_SHAPE_PROXYTYPE: 500 329 { … … 524 353 halfExtents += btVector3(capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual()); 525 354 btMatrix3x3 abs_b = t.getBasis().absolute(); 526 bt Point3 center = t.getOrigin();355 btVector3 center = t.getOrigin(); 527 356 btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents)); 528 357 aabbMin = center - extent; -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexShape.h
r2192 r2430 25 25 #include "LinearMath/btAlignedAllocator.h" 26 26 27 //todo: get rid of this btConvexCastResult thing!28 struct btConvexCastResult;29 27 #define MAX_PREFERRED_PENETRATION_DIRECTIONS 10 30 28 … … 39 37 BT_DECLARE_ALIGNED_ALLOCATOR(); 40 38 41 btConvexShape () 42 { 43 } 39 btConvexShape (); 44 40 45 virtual ~btConvexShape() 46 { 41 virtual ~btConvexShape(); 47 42 48 }43 virtual btVector3 localGetSupportingVertex(const btVector3& vec)const = 0; 49 44 50 51 virtual btVector3 localGetSupportingVertex(const btVector3& vec)const =0; 52 #ifndef __SPU__ 53 virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0; 54 55 //notice that the vectors should be unit length 56 virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0; 57 #endif //#ifndef __SPU__ 45 //////// 46 #ifndef __SPU__ 47 virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const=0; 48 #endif //#ifndef __SPU__ 58 49 59 50 btVector3 localGetSupportVertexWithoutMarginNonVirtual (const btVector3& vec) const; … … 61 52 btScalar getMarginNonVirtual () const; 62 53 void getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; 54 55 56 //notice that the vectors should be unit length 57 virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0; 63 58 64 59 ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version … … 78 73 virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const=0; 79 74 75 76 77 80 78 }; 81 79 -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp
r2192 r2430 109 109 } 110 110 111 // todo: could do the batch inside the callback!111 ///@todo: could do the batch inside the callback! 112 112 113 113 … … 164 164 } 165 165 166 void btConvexTriangleMeshShape::getEdge(int ,bt Point3& ,btPoint3& ) const166 void btConvexTriangleMeshShape::getEdge(int ,btVector3& ,btVector3& ) const 167 167 { 168 168 btAssert(0); 169 169 } 170 170 171 void btConvexTriangleMeshShape::getVertex(int ,bt Point3& ) const171 void btConvexTriangleMeshShape::getVertex(int ,btVector3& ) const 172 172 { 173 173 btAssert(0); … … 179 179 } 180 180 181 void btConvexTriangleMeshShape::getPlane(btVector3& ,bt Point3& ,int ) const181 void btConvexTriangleMeshShape::getPlane(btVector3& ,btVector3& ,int ) const 182 182 { 183 183 btAssert(0); … … 185 185 186 186 //not yet 187 bool btConvexTriangleMeshShape::isInside(const bt Point3& ,btScalar ) const187 bool btConvexTriangleMeshShape::isInside(const btVector3& ,btScalar ) const 188 188 { 189 189 btAssert(0); … … 270 270 btVector3 b = triangle[1] - center; 271 271 btVector3 c = triangle[2] - center; 272 btVector3 abc = a + b + c;273 272 btScalar volNeg = -btFabs(a.triple(b, c)) * btScalar(1. / 6); 274 273 for (int j = 0; j < 3; j++) … … 276 275 for (int k = 0; k <= j; k++) 277 276 { 278 i[j][k] = i[k][j] = volNeg * (center[j] * center[k] 279 + btScalar(0.25) * (center[j] * abc[k] + center[k] * abc[j]) 280 + btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k]) 277 i[j][k] = i[k][j] = volNeg * (btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k]) 281 278 + btScalar(0.05) * (a[j] * b[k] + a[k] * b[j] + a[j] * c[k] + a[k] * c[j] + b[j] * c[k] + b[k] * c[j])); 282 279 } -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
r2192 r2430 35 35 virtual int getNumVertices() const; 36 36 virtual int getNumEdges() const; 37 virtual void getEdge(int i,bt Point3& pa,btPoint3& pb) const;38 virtual void getVertex(int i,bt Point3& vtx) const;37 virtual void getEdge(int i,btVector3& pa,btVector3& pb) const; 38 virtual void getVertex(int i,btVector3& vtx) const; 39 39 virtual int getNumPlanes() const; 40 virtual void getPlane(btVector3& planeNormal,bt Point3& planeSupport,int i ) const;41 virtual bool isInside(const bt Point3& pt,btScalar tolerance) const;40 virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const; 41 virtual bool isInside(const btVector3& pt,btScalar tolerance) const; 42 42 43 43 -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCylinderShape.cpp
r2192 r2430 14 14 */ 15 15 #include "btCylinderShape.h" 16 #include "LinearMath/btPoint3.h"17 16 18 17 btCylinderShape::btCylinderShape (const btVector3& halfExtents) -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btEmptyShape.h
r2192 r2430 57 57 } 58 58 59 virtual void processAllTriangles(btTriangleCallback* ,const btVector3& ,const btVector3& ) const 60 { 61 } 59 62 60 63 protected: -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
r2192 r2430 19 19 20 20 21 22 btHeightfieldTerrainShape::btHeightfieldTerrainShape 23 ( 24 int heightStickWidth, int heightStickLength, void* heightfieldData, 25 btScalar heightScale, btScalar minHeight, btScalar maxHeight,int upAxis, 26 PHY_ScalarType hdt, bool flipQuadEdges 27 ) 28 { 29 initialize(heightStickWidth, heightStickLength, heightfieldData, 30 heightScale, minHeight, maxHeight, upAxis, hdt, 31 flipQuadEdges); 32 } 33 34 35 21 36 btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength,void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges) 22 : btConcaveShape (), m_heightStickWidth(heightStickWidth), 23 m_heightStickLength(heightStickLength), 24 m_maxHeight(maxHeight), 25 m_width((btScalar)heightStickWidth-1), 26 m_length((btScalar)heightStickLength-1), 27 m_heightfieldDataUnknown(heightfieldData), 28 m_useFloatData(useFloatData), 29 m_flipQuadEdges(flipQuadEdges), 30 m_useDiamondSubdivision(false), 31 m_upAxis(upAxis), 32 m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)) 33 { 37 { 38 // legacy constructor: support only float or unsigned char, 39 // and min height is zero 40 PHY_ScalarType hdt = (useFloatData) ? PHY_FLOAT : PHY_UCHAR; 41 btScalar minHeight = 0.0; 42 43 // previously, height = uchar * maxHeight / 65535. 44 // So to preserve legacy behavior, heightScale = maxHeight / 65535 45 btScalar heightScale = maxHeight / 65535; 46 47 initialize(heightStickWidth, heightStickLength, heightfieldData, 48 heightScale, minHeight, maxHeight, upAxis, hdt, 49 flipQuadEdges); 50 } 51 52 53 54 void btHeightfieldTerrainShape::initialize 55 ( 56 int heightStickWidth, int heightStickLength, void* heightfieldData, 57 btScalar heightScale, btScalar minHeight, btScalar maxHeight, int upAxis, 58 PHY_ScalarType hdt, bool flipQuadEdges 59 ) 60 { 61 // validation 62 btAssert(heightStickWidth > 1 && "bad width"); 63 btAssert(heightStickLength > 1 && "bad length"); 64 btAssert(heightfieldData && "null heightfield data"); 65 // btAssert(heightScale) -- do we care? Trust caller here 66 btAssert(minHeight <= maxHeight && "bad min/max height"); 67 btAssert(upAxis >= 0 && upAxis < 3 && 68 "bad upAxis--should be in range [0,2]"); 69 btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT && 70 "Bad height data type enum"); 71 72 // initialize member variables 34 73 m_shapeType = TERRAIN_SHAPE_PROXYTYPE; 35 36 btScalar quantizationMargin = 1.f; 37 38 //enlarge the AABB to avoid division by zero when initializing the quantization values 39 btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin); 40 41 btVector3 halfExtents(0,0,0); 42 74 m_heightStickWidth = heightStickWidth; 75 m_heightStickLength = heightStickLength; 76 m_minHeight = minHeight; 77 m_maxHeight = maxHeight; 78 m_width = (btScalar) (heightStickWidth - 1); 79 m_length = (btScalar) (heightStickLength - 1); 80 m_heightScale = heightScale; 81 m_heightfieldDataUnknown = heightfieldData; 82 m_heightDataType = hdt; 83 m_flipQuadEdges = flipQuadEdges; 84 m_useDiamondSubdivision = false; 85 m_upAxis = upAxis; 86 m_localScaling.setValue(btScalar(1.), btScalar(1.), btScalar(1.)); 87 88 // determine min/max axis-aligned bounding box (aabb) values 43 89 switch (m_upAxis) 44 90 { 45 91 case 0: 46 92 { 47 halfExtents.setValue( 48 btScalar(m_maxHeight), 49 btScalar(m_width), //?? don't know if this should change 50 btScalar(m_length)); 93 m_localAabbMin.setValue(m_minHeight, 0, 0); 94 m_localAabbMax.setValue(m_maxHeight, m_width, m_length); 51 95 break; 52 96 } 53 97 case 1: 54 98 { 55 halfExtents.setValue( 56 btScalar(m_width), 57 btScalar(m_maxHeight), 58 btScalar(m_length)); 99 m_localAabbMin.setValue(0, m_minHeight, 0); 100 m_localAabbMax.setValue(m_width, m_maxHeight, m_length); 59 101 break; 60 102 }; 61 103 case 2: 62 104 { 63 halfExtents.setValue( 64 btScalar(m_width), 65 btScalar(m_length), 66 btScalar(m_maxHeight) 67 ); 105 m_localAabbMin.setValue(0, 0, m_minHeight); 106 m_localAabbMax.setValue(m_width, m_length, m_maxHeight); 68 107 break; 69 108 } … … 71 110 { 72 111 //need to get valid m_upAxis 73 btAssert(0); 74 } 75 } 76 77 halfExtents*= btScalar(0.5); 78 79 m_localAabbMin = -halfExtents - clampValue; 80 m_localAabbMax = halfExtents + clampValue; 81 btVector3 aabbSize = m_localAabbMax - m_localAabbMin; 82 83 } 112 btAssert(0 && "Bad m_upAxis"); 113 } 114 } 115 116 // remember origin (defined as exact middle of aabb) 117 m_localOrigin = btScalar(0.5) * (m_localAabbMin + m_localAabbMax); 118 } 119 84 120 85 121 … … 93 129 { 94 130 btVector3 halfExtents = (m_localAabbMax-m_localAabbMin)* m_localScaling * btScalar(0.5); 95 halfExtents += btVector3(getMargin(),getMargin(),getMargin()); 131 132 btVector3 localOrigin(0, 0, 0); 133 localOrigin[m_upAxis] = (m_minHeight + m_maxHeight) * btScalar(0.5); 134 localOrigin *= m_localScaling; 96 135 97 136 btMatrix3x3 abs_b = t.getBasis().absolute(); 98 bt Point3 center = t.getOrigin();137 btVector3 center = t.getOrigin(); 99 138 btVector3 extent = btVector3(abs_b[0].dot(halfExtents), 100 139 abs_b[1].dot(halfExtents), 101 140 abs_b[2].dot(halfExtents)); 102 141 extent += btVector3(getMargin(),getMargin(),getMargin()); 103 142 104 143 aabbMin = center - extent; 105 144 aabbMax = center + extent; 106 107 108 145 } 109 146 … … 111 148 { 112 149 btScalar val = 0.f; 113 if (m_useFloatData)150 switch (m_heightDataType) 114 151 { 115 val = m_heightfieldDataFloat[(y*m_heightStickWidth)+x]; 116 } else 117 { 118 //assume unsigned short int 119 unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_heightStickWidth)+x]; 120 val = heightFieldValue* (m_maxHeight/btScalar(65535)); 121 } 152 case PHY_FLOAT: 153 { 154 val = m_heightfieldDataFloat[(y*m_heightStickWidth)+x]; 155 break; 156 } 157 158 case PHY_UCHAR: 159 { 160 unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_heightStickWidth)+x]; 161 val = heightFieldValue * m_heightScale; 162 break; 163 } 164 165 case PHY_SHORT: 166 { 167 short hfValue = m_heightfieldDataShort[(y * m_heightStickWidth) + x]; 168 val = hfValue * m_heightScale; 169 break; 170 } 171 172 default: 173 { 174 btAssert(!"Bad m_heightDataType"); 175 } 176 } 177 122 178 return val; 123 179 } … … 179 235 180 236 237 238 static inline int 239 getQuantized 240 ( 241 float x 242 ) 243 { 244 if (x < 0.0) { 245 return (int) (x - 0.5); 246 } 247 return (int) (x + 0.5); 248 } 249 250 251 252 /// given input vector, return quantized version 253 /** 254 This routine is basically determining the gridpoint indices for a given 255 input vector, answering the question: "which gridpoint is closest to the 256 provided point?". 257 258 "with clamp" means that we restrict the point to be in the heightfield's 259 axis-aligned bounding box. 260 */ 181 261 void btHeightfieldTerrainShape::quantizeWithClamp(int* out, const btVector3& point,int /*isMax*/) const 182 262 { … … 185 265 clampedPoint.setMin(m_localAabbMax); 186 266 187 btVector3 v = (clampedPoint);// - m_bvhAabbMin) * m_bvhQuantization;188 189 //TODO: optimization: check out how to removed this btFabs267 out[0] = getQuantized(clampedPoint.getX()); 268 out[1] = getQuantized(clampedPoint.getY()); 269 out[2] = getQuantized(clampedPoint.getZ()); 190 270 191 out[0] = (int)(v.getX() + v.getX() / btFabs(v.getX())* btScalar(0.5) ); 192 out[1] = (int)(v.getY() + v.getY() / btFabs(v.getY())* btScalar(0.5) ); 193 out[2] = (int)(v.getZ() + v.getZ() / btFabs(v.getZ())* btScalar(0.5) ); 194 195 } 196 197 271 } 272 273 274 275 /// process all triangles within the provided axis-aligned bounding box 276 /** 277 basic algorithm: 278 - convert input aabb to local coordinates (scale down and shift for local origin) 279 - convert input aabb to a range of heightfield grid points (quantize) 280 - iterate over all triangles in that subset of the grid 281 */ 198 282 void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const 199 283 { 200 (void)callback; 201 (void)aabbMax; 202 (void)aabbMin; 284 // scale down the input aabb's so they are in local (non-scaled) coordinates 285 btVector3 localAabbMin = aabbMin*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]); 286 btVector3 localAabbMax = aabbMax*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]); 287 288 // account for local origin 289 localAabbMin += m_localOrigin; 290 localAabbMax += m_localOrigin; 203 291 204 292 //quantize the aabbMin and aabbMax, and adjust the start/end ranges 205 206 293 int quantizedAabbMin[3]; 207 294 int quantizedAabbMax[3]; 208 209 btVector3 localAabbMin = aabbMin*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);210 btVector3 localAabbMax = aabbMax*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);211 212 295 quantizeWithClamp(quantizedAabbMin, localAabbMin,0); 213 296 quantizeWithClamp(quantizedAabbMax, localAabbMax,1); 214 297 215 298 // expand the min/max quantized values 299 // this is to catch the case where the input aabb falls between grid points! 300 for (int i = 0; i < 3; ++i) { 301 quantizedAabbMin[i]--; 302 quantizedAabbMax[i]++; 303 } 216 304 217 305 int startX=0; … … 224 312 case 0: 225 313 { 226 quantizedAabbMin[1]+=m_heightStickWidth/2-1;227 quantizedAabbMax[1]+=m_heightStickWidth/2+1;228 quantizedAabbMin[2]+=m_heightStickLength/2-1;229 quantizedAabbMax[2]+=m_heightStickLength/2+1;230 231 314 if (quantizedAabbMin[1]>startX) 232 315 startX = quantizedAabbMin[1]; … … 241 324 case 1: 242 325 { 243 quantizedAabbMin[0]+=m_heightStickWidth/2-1;244 quantizedAabbMax[0]+=m_heightStickWidth/2+1;245 quantizedAabbMin[2]+=m_heightStickLength/2-1;246 quantizedAabbMax[2]+=m_heightStickLength/2+1;247 248 326 if (quantizedAabbMin[0]>startX) 249 327 startX = quantizedAabbMin[0]; … … 258 336 case 2: 259 337 { 260 quantizedAabbMin[0]+=m_heightStickWidth/2-1;261 quantizedAabbMax[0]+=m_heightStickWidth/2+1;262 quantizedAabbMin[1]+=m_heightStickLength/2-1;263 quantizedAabbMax[1]+=m_heightStickLength/2+1;264 265 338 if (quantizedAabbMin[0]>startX) 266 339 startX = quantizedAabbMin[0]; -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
r2192 r2430 19 19 #include "btConcaveShape.h" 20 20 21 ///The btHeightfieldTerrainShape simulates a 2D heightfield terrain collision shape. You can also use the more general btBvhTriangleMeshShape instead. 22 ///An example implementation of btHeightfieldTerrainShape is provided in Demos/VehicleDemo/VehicleDemo.cpp 21 ///btHeightfieldTerrainShape simulates a 2D heightfield terrain 22 /** 23 The caller is responsible for maintaining the heightfield array; this 24 class does not make a copy. 25 26 The heightfield can be dynamic so long as the min/max height values 27 capture the extremes (heights must always be in that range). 28 29 The local origin of the heightfield is assumed to be the exact 30 center (as determined by width and length and height, with each 31 axis multiplied by the localScaling). 32 33 Most (but not all) rendering and heightfield libraries assume upAxis = 1 34 (that is, the y-axis is "up"). This class allows any of the 3 coordinates 35 to be "up". Make sure your choice of axis is consistent with your rendering 36 system. 37 38 The heightfield heights are determined from the data type used for the 39 heightfieldData array. 40 41 - PHY_UCHAR: height at a point is the uchar value at the 42 grid point, multipled by heightScale. uchar isn't recommended 43 because of its inability to deal with negative values, and 44 low resolution (8-bit). 45 46 - PHY_SHORT: height at a point is the short int value at that grid 47 point, multipled by heightScale. 48 49 - PHY_FLOAT: height at a point is the float value at that grid 50 point. heightScale is ignored when using the float heightfield 51 data type. 52 53 Whatever the caller specifies as minHeight and maxHeight will be honored. 54 The class will not inspect the heightfield to discover the actual minimum 55 or maximum heights. These values are used to determine the heightfield's 56 axis-aligned bounding box, multiplied by localScaling. 57 58 For usage and testing see the TerrainDemo. 59 */ 23 60 class btHeightfieldTerrainShape : public btConcaveShape 24 61 { … … 26 63 btVector3 m_localAabbMin; 27 64 btVector3 m_localAabbMax; 28 65 btVector3 m_localOrigin; 66 29 67 ///terrain data 30 68 int m_heightStickWidth; 31 69 int m_heightStickLength; 70 btScalar m_minHeight; 32 71 btScalar m_maxHeight; 33 72 btScalar m_width; 34 73 btScalar m_length; 74 btScalar m_heightScale; 35 75 union 36 76 { 37 77 unsigned char* m_heightfieldDataUnsignedChar; 78 short* m_heightfieldDataShort; 38 79 btScalar* m_heightfieldDataFloat; 39 80 void* m_heightfieldDataUnknown; 40 81 }; 41 42 bool m_useFloatData;82 83 PHY_ScalarType m_heightDataType; 43 84 bool m_flipQuadEdges; 44 85 bool m_useDiamondSubdivision; … … 52 93 void getVertex(int x,int y,btVector3& vertex) const; 53 94 54 inline bool testQuantizedAabbAgainstQuantizedAabb(int* aabbMin1, int* aabbMax1,const int* aabbMin2,const int* aabbMax2) const 55 { 56 bool overlap = true; 57 overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; 58 overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap; 59 overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; 60 return overlap; 61 } 95 96 97 /// protected initialization 98 /** 99 Handles the work of constructors so that public constructors can be 100 backwards-compatible without a lot of copy/paste. 101 */ 102 void initialize(int heightStickWidth, int heightStickLength, 103 void* heightfieldData, btScalar heightScale, 104 btScalar minHeight, btScalar maxHeight, int upAxis, 105 PHY_ScalarType heightDataType, bool flipQuadEdges); 62 106 63 107 public: 64 btHeightfieldTerrainShape(int heightStickWidth,int heightStickHeight,void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges); 108 /// preferred constructor 109 /** 110 This constructor supports a range of heightfield 111 data types, and allows for a non-zero minimum height value. 112 heightScale is needed for any integer-based heightfield data types. 113 */ 114 btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength, 115 void* heightfieldData, btScalar heightScale, 116 btScalar minHeight, btScalar maxHeight, 117 int upAxis, PHY_ScalarType heightDataType, 118 bool flipQuadEdges); 119 120 /// legacy constructor 121 /** 122 The legacy constructor assumes the heightfield has a minimum height 123 of zero. Only unsigned char or floats are supported. For legacy 124 compatibility reasons, heightScale is calculated as maxHeight / 65535 125 (and is only used when useFloatData = false). 126 */ 127 btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength,void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges); 65 128 66 129 virtual ~btHeightfieldTerrainShape(); -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp
r2192 r2430 36 36 void btMinkowskiSumShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const 37 37 { 38 // todo: could make recursive use of batching. probably this shape is not used frequently.38 ///@todo: could make recursive use of batching. probably this shape is not used frequently. 39 39 for (int i=0;i<numVectors;i++) 40 40 { -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.cpp
r2192 r2430 320 320 321 321 int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; 322 btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);323 #ifdef DEBUG_PATCH_COLORS 324 btVector3 mycolor = color[index&3];325 graphicsbase[8] = mycolor.getX();326 graphicsbase[9] = mycolor.getY();327 graphicsbase[10] = mycolor.getZ();328 #endif //DEBUG_PATCH_COLORS 329 330 331 triangleVerts[j] = btVector3(332 graphicsbase[0]*meshScaling.getX(),333 graphicsbase[1]*meshScaling.getY(),334 graphicsbase[2]*meshScaling.getZ());322 if (type == PHY_FLOAT) 323 { 324 float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); 325 triangleVerts[j] = btVector3( 326 graphicsbase[0]*meshScaling.getX(), 327 graphicsbase[1]*meshScaling.getY(), 328 graphicsbase[2]*meshScaling.getZ()); 329 } 330 else 331 { 332 double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); 333 triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*meshScaling.getX()), btScalar(graphicsbase[1]*meshScaling.getY()), btScalar(graphicsbase[2]*meshScaling.getZ())); 334 } 335 335 } 336 336 -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
r2192 r2430 16 16 #include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h" 17 17 18 btPolyhedralConvexShape::btPolyhedralConvexShape() 19 :btConvexInternalShape(), 18 btPolyhedralConvexShape::btPolyhedralConvexShape() :btConvexInternalShape(), 20 19 m_localAabbMin(1,1,1), 21 20 m_localAabbMax(-1,-1,-1), … … 25 24 26 25 } 27 28 26 29 27 -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
r2192 r2430 17 17 #define BU_SHAPE 18 18 19 #include "LinearMath/btPoint3.h"20 19 #include "LinearMath/btMatrix3x3.h" 21 20 #include "LinearMath/btAabbUtil2.h" … … 32 31 bool m_isLocalAabbValid; 33 32 34 btPolyhedralConvexShape();35 33 public: 36 34 37 35 btPolyhedralConvexShape(); 38 36 39 37 //brute force implementations 38 40 39 virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; 41 40 virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; 41 42 42 43 43 virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; 44 44 45 46 void setCachedLocalAabb (const btVector3& aabbMin, const btVector3& aabbMax) 47 { 48 m_isLocalAabbValid = true; 49 m_localAabbMin = aabbMin; 50 m_localAabbMax = aabbMax; 51 } 52 53 inline void getCachedLocalAabb (btVector3& aabbMin, btVector3& aabbMax) const 54 { 55 btAssert(m_isLocalAabbValid); 56 aabbMin = m_localAabbMin; 57 aabbMax = m_localAabbMax; 58 } 45 59 46 60 inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const … … 61 75 virtual int getNumVertices() const = 0 ; 62 76 virtual int getNumEdges() const = 0; 63 virtual void getEdge(int i,bt Point3& pa,btPoint3& pb) const = 0;64 virtual void getVertex(int i,bt Point3& vtx) const = 0;77 virtual void getEdge(int i,btVector3& pa,btVector3& pb) const = 0; 78 virtual void getVertex(int i,btVector3& vtx) const = 0; 65 79 virtual int getNumPlanes() const = 0; 66 virtual void getPlane(btVector3& planeNormal,bt Point3& planeSupport,int i ) const = 0;80 virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const = 0; 67 81 // virtual int getIndex(int i) const = 0 ; 68 82 69 virtual bool isInside(const bt Point3& pt,btScalar tolerance) const = 0;83 virtual bool isInside(const btVector3& pt,btScalar tolerance) const = 0; 70 84 71 85 /// optional Hull is for optional Separating Axis Test Hull collision detection, see Hull.cpp -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp
r2192 r2430 16 16 #include "btScaledBvhTriangleMeshShape.h" 17 17 18 btScaledBvhTriangleMeshShape::btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape, btVector3localScaling)18 btScaledBvhTriangleMeshShape::btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling) 19 19 :m_localScaling(localScaling),m_bvhTriMeshShape(childShape) 20 20 { … … 35 35 public: 36 36 37 btScaledTriangleCallback(btTriangleCallback* originalCallback, btVector3localScaling)37 btScaledTriangleCallback(btTriangleCallback* originalCallback,const btVector3& localScaling) 38 38 :m_originalCallback(originalCallback), 39 39 m_localScaling(localScaling) … … 94 94 btMatrix3x3 abs_b = trans.getBasis().absolute(); 95 95 96 bt Point3 center = trans(localCenter);96 btVector3 center = trans(localCenter); 97 97 98 98 btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents), -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h
r2192 r2430 33 33 34 34 35 btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape, btVector3localScaling);35 btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling); 36 36 37 37 virtual ~btScaledBvhTriangleMeshShape(); -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btSphereShape.cpp
r2192 r2430 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 }28 20 29 21 btVector3 btSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btSphereShape.h
r2192 r2430 28 28 BT_DECLARE_ALIGNED_ALLOCATOR(); 29 29 30 btSphereShape (btScalar radius); 31 30 btSphereShape (btScalar radius) : btConvexInternalShape () 31 { 32 m_shapeType = SPHERE_SHAPE_PROXYTYPE; 33 m_implicitShapeDimensions.setX(radius); 34 m_collisionMargin = radius; 35 } 32 36 33 37 virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.h
r2192 r2430 19 19 #include "LinearMath/btVector3.h" 20 20 #include "btTriangleCallback.h" 21 #include "btConcaveShape.h" 21 22 22 /// PHY_ScalarType enumerates possible scalar types. 23 /// See the btStridingMeshInterface for its use 24 typedef enum PHY_ScalarType { 25 PHY_FLOAT, 26 PHY_DOUBLE, 27 PHY_INTEGER, 28 PHY_SHORT, 29 PHY_FIXEDPOINT88 30 } PHY_ScalarType; 23 31 24 32 25 /// The btStridingMeshInterface is the interface class for high performance generic access to triangle meshes, used in combination with btBvhTriangleMeshShape and some other collision shapes. … … 78 71 79 72 virtual bool hasPremadeAabb() const { return false; } 80 virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const {} 81 virtual void getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const {} 73 virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const 74 { 75 (void) aabbMin; 76 (void) aabbMax; 77 } 78 virtual void getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const 79 { 80 (void) aabbMin; 81 (void) aabbMax; 82 } 82 83 83 84 const btVector3& getScaling() const { -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.cpp
r2192 r2430 23 23 } 24 24 25 btBU_Simplex1to4::btBU_Simplex1to4(const bt Point3& pt0) : btPolyhedralConvexShape (),26 m_numVertices(0) 27 { 28 m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE; 29 addVertex(pt0); 30 } 31 32 btBU_Simplex1to4::btBU_Simplex1to4(const bt Point3& pt0,const btPoint3& pt1) : btPolyhedralConvexShape (),25 btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0) : btPolyhedralConvexShape (), 26 m_numVertices(0) 27 { 28 m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE; 29 addVertex(pt0); 30 } 31 32 btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1) : btPolyhedralConvexShape (), 33 33 m_numVertices(0) 34 34 { … … 38 38 } 39 39 40 btBU_Simplex1to4::btBU_Simplex1to4(const bt Point3& pt0,const btPoint3& pt1,const btPoint3& pt2) : btPolyhedralConvexShape (),40 btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2) : btPolyhedralConvexShape (), 41 41 m_numVertices(0) 42 42 { … … 47 47 } 48 48 49 btBU_Simplex1to4::btBU_Simplex1to4(const bt Point3& pt0,const btPoint3& pt1,const btPoint3& pt2,const btPoint3& pt3) : btPolyhedralConvexShape (),49 btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2,const btVector3& pt3) : btPolyhedralConvexShape (), 50 50 m_numVertices(0) 51 51 { … … 61 61 62 62 63 void btBU_Simplex1to4::addVertex(const bt Point3& pt)63 void btBU_Simplex1to4::addVertex(const btVector3& pt) 64 64 { 65 65 m_vertices[m_numVertices++] = pt; … … 93 93 } 94 94 95 void btBU_Simplex1to4::getEdge(int i,bt Point3& pa,btPoint3& pb) const95 void btBU_Simplex1to4::getEdge(int i,btVector3& pa,btVector3& pb) const 96 96 { 97 97 … … 157 157 } 158 158 159 void btBU_Simplex1to4::getVertex(int i,bt Point3& vtx) const159 void btBU_Simplex1to4::getVertex(int i,btVector3& vtx) const 160 160 { 161 161 vtx = m_vertices[i]; … … 184 184 185 185 186 void btBU_Simplex1to4::getPlane(btVector3&, bt Point3& ,int ) const186 void btBU_Simplex1to4::getPlane(btVector3&, btVector3& ,int ) const 187 187 { 188 188 … … 194 194 } 195 195 196 bool btBU_Simplex1to4::isInside(const bt Point3& ,btScalar ) const196 bool btBU_Simplex1to4::isInside(const btVector3& ,btScalar ) const 197 197 { 198 198 return false; -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.h
r2192 r2430 28 28 29 29 int m_numVertices; 30 bt Point3 m_vertices[4];30 btVector3 m_vertices[4]; 31 31 32 32 public: 33 33 btBU_Simplex1to4(); 34 34 35 btBU_Simplex1to4(const bt Point3& pt0);36 btBU_Simplex1to4(const bt Point3& pt0,const btPoint3& pt1);37 btBU_Simplex1to4(const bt Point3& pt0,const btPoint3& pt1,const btPoint3& pt2);38 btBU_Simplex1to4(const bt Point3& pt0,const btPoint3& pt1,const btPoint3& pt2,const btPoint3& pt3);35 btBU_Simplex1to4(const btVector3& pt0); 36 btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1); 37 btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2); 38 btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2,const btVector3& pt3); 39 39 40 40 … … 46 46 47 47 48 void addVertex(const bt Point3& pt);48 void addVertex(const btVector3& pt); 49 49 50 50 //PolyhedralConvexShape interface … … 54 54 virtual int getNumEdges() const; 55 55 56 virtual void getEdge(int i,bt Point3& pa,btPoint3& pb) const;56 virtual void getEdge(int i,btVector3& pa,btVector3& pb) const; 57 57 58 virtual void getVertex(int i,bt Point3& vtx) const;58 virtual void getVertex(int i,btVector3& vtx) const; 59 59 60 60 virtual int getNumPlanes() const; 61 61 62 virtual void getPlane(btVector3& planeNormal,bt Point3& planeSupport,int i) const;62 virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i) const; 63 63 64 64 virtual int getIndex(int i) const; 65 65 66 virtual bool isInside(const bt Point3& pt,btScalar tolerance) const;66 virtual bool isInside(const btVector3& pt,btScalar tolerance) const; 67 67 68 68 -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.h
r2192 r2430 29 29 }; 30 30 31 /// btTriangleBuffercan be useful to collect and store overlapping triangles between AABB and concave objects that support 'processAllTriangles'31 ///The btTriangleBuffer callback can be useful to collect and store overlapping triangles between AABB and concave objects that support 'processAllTriangles' 32 32 ///Example usage of this class: 33 33 /// btTriangleBuffer triBuf; -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleMesh.cpp
r2192 r2430 75 75 } 76 76 77 int btTriangleMesh::findOrAddVertex(const btVector3& vertex) 77 78 int btTriangleMesh::findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices) 78 79 { 79 80 //return index of new/existing vertex 80 // todo: could use acceleration structure for this81 ///@todo: could use acceleration structure for this 81 82 if (m_use4componentVertices) 82 83 { 83 for (int i=0;i< m_4componentVertices.size();i++) 84 { 85 if ((m_4componentVertices[i]-vertex).length2() <= m_weldingThreshold) 84 if (removeDuplicateVertices) 86 85 { 87 return i; 86 for (int i=0;i< m_4componentVertices.size();i++) 87 { 88 if ((m_4componentVertices[i]-vertex).length2() <= m_weldingThreshold) 89 { 90 return i; 91 } 88 92 } 89 93 } … … 97 101 { 98 102 99 for (int i=0;i< m_3componentVertices.size();i+=3)103 if (removeDuplicateVertices) 100 104 { 101 btVector3 vtx(m_3componentVertices[i],m_3componentVertices[i+1],m_3componentVertices[i+2]); 102 if ((vtx-vertex).length2() <= m_weldingThreshold) 105 for (int i=0;i< m_3componentVertices.size();i+=3) 103 106 { 104 return i/3; 107 btVector3 vtx(m_3componentVertices[i],m_3componentVertices[i+1],m_3componentVertices[i+2]); 108 if ((vtx-vertex).length2() <= m_weldingThreshold) 109 { 110 return i/3; 111 } 105 112 } 106 113 } 107 114 m_3componentVertices.push_back(vertex.getX()); 108 115 m_3componentVertices.push_back(vertex.getY()); … … 115 122 } 116 123 117 void btTriangleMesh::addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2 )124 void btTriangleMesh::addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2,bool removeDuplicateVertices) 118 125 { 119 126 m_indexedMeshes[0].m_numTriangles++; 120 121 addIndex(findOrAddVertex(vertex0)); 122 addIndex(findOrAddVertex(vertex1)); 123 addIndex(findOrAddVertex(vertex2)); 127 addIndex(findOrAddVertex(vertex0,removeDuplicateVertices)); 128 addIndex(findOrAddVertex(vertex1,removeDuplicateVertices)); 129 addIndex(findOrAddVertex(vertex2,removeDuplicateVertices)); 124 130 } 125 131 -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleMesh.h
r2192 r2430 26 26 ///If you want to share triangle/index data between graphics mesh and collision mesh (btBvhTriangleMeshShape), you can directly use btTriangleIndexVertexArray or derive your own class from btStridingMeshInterface. 27 27 ///Performance of btTriangleMesh and btTriangleIndexVertexArray used in a btBvhTriangleMeshShape is the same. 28 ///It has a brute-force option to weld together closeby vertices.29 28 class btTriangleMesh : public btTriangleIndexVertexArray 30 29 { … … 43 42 btTriangleMesh (bool use32bitIndices=true,bool use4componentVertices=true); 44 43 45 int findOrAddVertex(const btVector3& vertex );44 int findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices); 46 45 void addIndex(int index); 47 46 … … 55 54 return m_use4componentVertices; 56 55 } 57 58 void addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2); 56 ///By default addTriangle won't search for duplicate vertices, because the search is very slow for large triangle meshes. 57 ///In general it is better to directly use btTriangleIndexVertexArray instead. 58 void addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2, bool removeDuplicateVertices=false); 59 59 60 60 int getNumTriangles() const; -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
r2192 r2430 54 54 btMatrix3x3 abs_b = trans.getBasis().absolute(); 55 55 56 bt Point3 center = trans(localCenter);56 btVector3 center = trans(localCenter); 57 57 58 58 btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents), -
code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleShape.h
r2192 r2430 47 47 } 48 48 49 virtual void getEdge(int i,bt Point3& pa,btPoint3& pb) const49 virtual void getEdge(int i,btVector3& pa,btVector3& pb) const 50 50 { 51 51 getVertex(i,pa); … … 89 89 90 90 91 virtual void getPlane(btVector3& planeNormal,bt Point3& planeSupport,int i) const91 virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i) const 92 92 { 93 93 getPlaneEquation(i,planeNormal,planeSupport); … … 105 105 } 106 106 107 virtual void getPlaneEquation(int i, btVector3& planeNormal,bt Point3& planeSupport) const107 virtual void getPlaneEquation(int i, btVector3& planeNormal,btVector3& planeSupport) const 108 108 { 109 109 (void)i; … … 119 119 } 120 120 121 virtual bool isInside(const bt Point3& pt,btScalar tolerance) const121 virtual bool isInside(const btVector3& pt,btScalar tolerance) const 122 122 { 123 123 btVector3 normal; … … 133 133 for (i=0;i<3;i++) 134 134 { 135 bt Point3 pa,pb;135 btVector3 pa,pb; 136 136 getEdge(i,pa,pb); 137 137 btVector3 edge = pb-pa; -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
r2192 r2430 22 22 #include "btSimplexSolverInterface.h" 23 23 class btConvexShape; 24 #include "LinearMath/btPoint3.h"25 24 class btTransform; 26 25 … … 34 33 const btConvexShape* convexA,const btConvexShape* convexB, 35 34 const btTransform& transA,const btTransform& transB, 36 btVector3& v, bt Point3& pa, btPoint3& pb,35 btVector3& v, btVector3& pa, btVector3& pb, 37 36 class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc 38 37 ) = 0; -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp
r2192 r2430 38 38 { 39 39 40 // Config40 // Config 41 41 42 42 /* GJK */ … … 59 59 60 60 61 // Shorthands62 typedef unsigned int U;63 typedef unsigned char U1;64 65 // MinkowskiDiff66 struct MinkowskiDiff61 // Shorthands 62 typedef unsigned int U; 63 typedef unsigned char U1; 64 65 // MinkowskiDiff 66 struct MinkowskiDiff 67 67 { 68 const btConvexShape* m_shapes[2];69 btMatrix3x3 m_toshape1;70 btTransform m_toshape0;71 btVector3 (btConvexShape::*Ls)(const btVector3&) const;72 void EnableMargin(bool enable)73 { 74 if(enable)75 Ls=&btConvexShape::localGetSupportVertexNonVirtual;68 const btConvexShape* m_shapes[2]; 69 btMatrix3x3 m_toshape1; 70 btTransform m_toshape0; 71 btVector3 (btConvexShape::*Ls)(const btVector3&) const; 72 void EnableMargin(bool enable) 73 { 74 if(enable) 75 Ls=&btConvexShape::localGetSupportVertexNonVirtual; 76 76 else 77 Ls=&btConvexShape::localGetSupportVertexWithoutMarginNonVirtual;77 Ls=&btConvexShape::localGetSupportVertexWithoutMarginNonVirtual; 78 78 } 79 inline btVector3 Support0(const btVector3& d) const80 { 81 return(((m_shapes[0])->*(Ls))(d));79 inline btVector3 Support0(const btVector3& d) const 80 { 81 return(((m_shapes[0])->*(Ls))(d)); 82 82 } 83 inline btVector3 Support1(const btVector3& d) const84 { 85 return(m_toshape0*((m_shapes[1])->*(Ls))(m_toshape1*d));83 inline btVector3 Support1(const btVector3& d) const 84 { 85 return(m_toshape0*((m_shapes[1])->*(Ls))(m_toshape1*d)); 86 86 } 87 inline btVector3 Support(const btVector3& d) const88 { 89 return(Support0(d)-Support1(-d));87 inline btVector3 Support(const btVector3& d) const 88 { 89 return(Support0(d)-Support1(-d)); 90 90 } 91 btVector3 Support(const btVector3& d,U index) const92 { 93 if(index)94 return(Support1(d));91 btVector3 Support(const btVector3& d,U index) const 92 { 93 if(index) 94 return(Support1(d)); 95 95 else 96 return(Support0(d));96 return(Support0(d)); 97 97 } 98 98 }; 99 99 100 typedef MinkowskiDiff tShape; 101 102 103 // GJK 104 struct GJK 105 { 106 /* Types */ 107 struct sSV 100 typedef MinkowskiDiff tShape; 101 102 103 // GJK 104 struct GJK 108 105 { 109 btVector3 d,w; 110 }; 111 struct sSimplex 112 { 113 sSV* c[4]; 114 btScalar p[4]; 115 U rank; 116 }; 117 struct eStatus { enum _ { 118 Valid, 119 Inside, 120 Failed };}; 121 /* Fields */ 122 tShape m_shape; 123 btVector3 m_ray; 124 btScalar m_distance; 125 sSimplex m_simplices[2]; 126 sSV m_store[4]; 127 sSV* m_free[4]; 128 U m_nfree; 129 U m_current; 130 sSimplex* m_simplex; 131 eStatus::_ m_status; 132 /* Methods */ 133 GJK() 134 { 135 Initialize(); 136 } 137 void Initialize() 138 { 139 m_ray = btVector3(0,0,0); 140 m_nfree = 0; 141 m_status = eStatus::Failed; 142 m_current = 0; 143 m_distance = 0; 144 } 145 eStatus::_ Evaluate(const tShape& shapearg,const btVector3& guess) 146 { 147 U iterations=0; 148 btScalar sqdist=0; 149 btScalar alpha=0; 150 btVector3 lastw[4]; 151 U clastw=0; 152 /* Initialize solver */ 153 m_free[0] = &m_store[0]; 154 m_free[1] = &m_store[1]; 155 m_free[2] = &m_store[2]; 156 m_free[3] = &m_store[3]; 157 m_nfree = 4; 158 m_current = 0; 159 m_status = eStatus::Valid; 160 m_shape = shapearg; 161 m_distance = 0; 162 /* Initialize simplex */ 163 m_simplices[0].rank = 0; 164 m_ray = guess; 165 const btScalar sqrl= m_ray.length2(); 166 appendvertice(m_simplices[0],sqrl>0?-m_ray:btVector3(1,0,0)); 167 m_simplices[0].p[0] = 1; 168 m_ray = m_simplices[0].c[0]->w; 169 sqdist = sqrl; 170 lastw[0] = 171 lastw[1] = 172 lastw[2] = 173 lastw[3] = m_ray; 174 /* Loop */ 175 do { 176 const U next=1-m_current; 177 sSimplex& cs=m_simplices[m_current]; 178 sSimplex& ns=m_simplices[next]; 179 /* Check zero */ 180 const btScalar rl=m_ray.length(); 181 if(rl<GJK_MIN_DISTANCE) 182 {/* Touching or inside */ 183 m_status=eStatus::Inside; 184 break; 185 } 186 /* Append new vertice in -'v' direction */ 187 appendvertice(cs,-m_ray); 188 const btVector3& w=cs.c[cs.rank-1]->w; 189 bool found=false; 190 for(U i=0;i<4;++i) 191 { 192 if((w-lastw[i]).length2()<GJK_DUPLICATED_EPS) 193 { found=true;break; } 194 } 195 if(found) 196 {/* Return old simplex */ 197 removevertice(m_simplices[m_current]); 198 break; 199 } 200 else 201 {/* Update lastw */ 202 lastw[clastw=(clastw+1)&3]=w; 203 } 204 /* Check for termination */ 205 const btScalar omega=dot(m_ray,w)/rl; 206 alpha=btMax(omega,alpha); 207 if(((rl-alpha)-(GJK_ACCURARY*rl))<=0) 208 {/* Return old simplex */ 209 removevertice(m_simplices[m_current]); 210 break; 211 } 212 /* Reduce simplex */ 213 btScalar weights[4]; 214 U mask=0; 215 switch(cs.rank) 216 { 217 case 2: sqdist=projectorigin( cs.c[0]->w, 218 cs.c[1]->w, 219 weights,mask);break; 220 case 3: sqdist=projectorigin( cs.c[0]->w, 221 cs.c[1]->w, 222 cs.c[2]->w, 223 weights,mask);break; 224 case 4: sqdist=projectorigin( cs.c[0]->w, 225 cs.c[1]->w, 226 cs.c[2]->w, 227 cs.c[3]->w, 228 weights,mask);break; 229 } 230 if(sqdist>=0) 231 {/* Valid */ 232 ns.rank = 0; 233 m_ray = btVector3(0,0,0); 234 m_current = next; 235 for(U i=0,ni=cs.rank;i<ni;++i) 236 { 237 if(mask&(1<<i)) 238 { 239 ns.c[ns.rank] = cs.c[i]; 240 ns.p[ns.rank++] = weights[i]; 241 m_ray += cs.c[i]->w*weights[i]; 106 /* Types */ 107 struct sSV 108 { 109 btVector3 d,w; 110 }; 111 struct sSimplex 112 { 113 sSV* c[4]; 114 btScalar p[4]; 115 U rank; 116 }; 117 struct eStatus { enum _ { 118 Valid, 119 Inside, 120 Failed };}; 121 /* Fields */ 122 tShape m_shape; 123 btVector3 m_ray; 124 btScalar m_distance; 125 sSimplex m_simplices[2]; 126 sSV m_store[4]; 127 sSV* m_free[4]; 128 U m_nfree; 129 U m_current; 130 sSimplex* m_simplex; 131 eStatus::_ m_status; 132 /* Methods */ 133 GJK() 134 { 135 Initialize(); 136 } 137 void Initialize() 138 { 139 m_ray = btVector3(0,0,0); 140 m_nfree = 0; 141 m_status = eStatus::Failed; 142 m_current = 0; 143 m_distance = 0; 144 } 145 eStatus::_ Evaluate(const tShape& shapearg,const btVector3& guess) 146 { 147 U iterations=0; 148 btScalar sqdist=0; 149 btScalar alpha=0; 150 btVector3 lastw[4]; 151 U clastw=0; 152 /* Initialize solver */ 153 m_free[0] = &m_store[0]; 154 m_free[1] = &m_store[1]; 155 m_free[2] = &m_store[2]; 156 m_free[3] = &m_store[3]; 157 m_nfree = 4; 158 m_current = 0; 159 m_status = eStatus::Valid; 160 m_shape = shapearg; 161 m_distance = 0; 162 /* Initialize simplex */ 163 m_simplices[0].rank = 0; 164 m_ray = guess; 165 const btScalar sqrl= m_ray.length2(); 166 appendvertice(m_simplices[0],sqrl>0?-m_ray:btVector3(1,0,0)); 167 m_simplices[0].p[0] = 1; 168 m_ray = m_simplices[0].c[0]->w; 169 sqdist = sqrl; 170 lastw[0] = 171 lastw[1] = 172 lastw[2] = 173 lastw[3] = m_ray; 174 /* Loop */ 175 do { 176 const U next=1-m_current; 177 sSimplex& cs=m_simplices[m_current]; 178 sSimplex& ns=m_simplices[next]; 179 /* Check zero */ 180 const btScalar rl=m_ray.length(); 181 if(rl<GJK_MIN_DISTANCE) 182 {/* Touching or inside */ 183 m_status=eStatus::Inside; 184 break; 185 } 186 /* Append new vertice in -'v' direction */ 187 appendvertice(cs,-m_ray); 188 const btVector3& w=cs.c[cs.rank-1]->w; 189 bool found=false; 190 for(U i=0;i<4;++i) 191 { 192 if((w-lastw[i]).length2()<GJK_DUPLICATED_EPS) 193 { found=true;break; } 194 } 195 if(found) 196 {/* Return old simplex */ 197 removevertice(m_simplices[m_current]); 198 break; 242 199 } 243 200 else 244 { 245 m_free[m_nfree++] = cs.c[i]; 246 } 247 } 248 if(mask==15) m_status=eStatus::Inside; 249 } 250 else 251 {/* Return old simplex */ 252 removevertice(m_simplices[m_current]); 253 break; 254 } 255 m_status=((++iterations)<GJK_MAX_ITERATIONS)?m_status:eStatus::Failed; 256 } while(m_status==eStatus::Valid); 257 m_simplex=&m_simplices[m_current]; 258 switch(m_status) 259 { 260 case eStatus::Valid: m_distance=m_ray.length();break; 261 case eStatus::Inside: m_distance=0;break; 262 } 263 return(m_status); 264 } 265 bool EncloseOrigin() 266 { 267 switch(m_simplex->rank) 268 { 269 case 1: 270 { 271 for(U i=0;i<3;++i) 272 { 273 btVector3 axis=btVector3(0,0,0); 274 axis[i]=1; 275 appendvertice(*m_simplex, axis); 276 if(EncloseOrigin()) return(true); 277 removevertice(*m_simplex); 278 appendvertice(*m_simplex,-axis); 279 if(EncloseOrigin()) return(true); 280 removevertice(*m_simplex); 281 } 282 } 283 break; 284 case 2: 285 { 286 const btVector3 d=m_simplex->c[1]->w-m_simplex->c[0]->w; 287 for(U i=0;i<3;++i) 288 { 289 btVector3 axis=btVector3(0,0,0); 290 axis[i]=1; 291 const btVector3 p=cross(d,axis); 292 if(p.length2()>0) 293 { 294 appendvertice(*m_simplex, p); 295 if(EncloseOrigin()) return(true); 296 removevertice(*m_simplex); 297 appendvertice(*m_simplex,-p); 298 if(EncloseOrigin()) return(true); 299 removevertice(*m_simplex); 300 } 301 } 302 } 303 break; 304 case 3: 305 { 306 const btVector3 n=cross(m_simplex->c[1]->w-m_simplex->c[0]->w, 307 m_simplex->c[2]->w-m_simplex->c[0]->w); 308 if(n.length2()>0) 309 { 310 appendvertice(*m_simplex,n); 311 if(EncloseOrigin()) return(true); 312 removevertice(*m_simplex); 313 appendvertice(*m_simplex,-n); 314 if(EncloseOrigin()) return(true); 315 removevertice(*m_simplex); 316 } 317 } 318 break; 319 case 4: 320 { 321 if(btFabs(det( m_simplex->c[0]->w-m_simplex->c[3]->w, 201 {/* Update lastw */ 202 lastw[clastw=(clastw+1)&3]=w; 203 } 204 /* Check for termination */ 205 const btScalar omega=dot(m_ray,w)/rl; 206 alpha=btMax(omega,alpha); 207 if(((rl-alpha)-(GJK_ACCURARY*rl))<=0) 208 {/* Return old simplex */ 209 removevertice(m_simplices[m_current]); 210 break; 211 } 212 /* Reduce simplex */ 213 btScalar weights[4]; 214 U mask=0; 215 switch(cs.rank) 216 { 217 case 2: sqdist=projectorigin( cs.c[0]->w, 218 cs.c[1]->w, 219 weights,mask);break; 220 case 3: sqdist=projectorigin( cs.c[0]->w, 221 cs.c[1]->w, 222 cs.c[2]->w, 223 weights,mask);break; 224 case 4: sqdist=projectorigin( cs.c[0]->w, 225 cs.c[1]->w, 226 cs.c[2]->w, 227 cs.c[3]->w, 228 weights,mask);break; 229 } 230 if(sqdist>=0) 231 {/* Valid */ 232 ns.rank = 0; 233 m_ray = btVector3(0,0,0); 234 m_current = next; 235 for(U i=0,ni=cs.rank;i<ni;++i) 236 { 237 if(mask&(1<<i)) 238 { 239 ns.c[ns.rank] = cs.c[i]; 240 ns.p[ns.rank++] = weights[i]; 241 m_ray += cs.c[i]->w*weights[i]; 242 } 243 else 244 { 245 m_free[m_nfree++] = cs.c[i]; 246 } 247 } 248 if(mask==15) m_status=eStatus::Inside; 249 } 250 else 251 {/* Return old simplex */ 252 removevertice(m_simplices[m_current]); 253 break; 254 } 255 m_status=((++iterations)<GJK_MAX_ITERATIONS)?m_status:eStatus::Failed; 256 } while(m_status==eStatus::Valid); 257 m_simplex=&m_simplices[m_current]; 258 switch(m_status) 259 { 260 case eStatus::Valid: m_distance=m_ray.length();break; 261 case eStatus::Inside: m_distance=0;break; 262 } 263 return(m_status); 264 } 265 bool EncloseOrigin() 266 { 267 switch(m_simplex->rank) 268 { 269 case 1: 270 { 271 for(U i=0;i<3;++i) 272 { 273 btVector3 axis=btVector3(0,0,0); 274 axis[i]=1; 275 appendvertice(*m_simplex, axis); 276 if(EncloseOrigin()) return(true); 277 removevertice(*m_simplex); 278 appendvertice(*m_simplex,-axis); 279 if(EncloseOrigin()) return(true); 280 removevertice(*m_simplex); 281 } 282 } 283 break; 284 case 2: 285 { 286 const btVector3 d=m_simplex->c[1]->w-m_simplex->c[0]->w; 287 for(U i=0;i<3;++i) 288 { 289 btVector3 axis=btVector3(0,0,0); 290 axis[i]=1; 291 const btVector3 p=cross(d,axis); 292 if(p.length2()>0) 293 { 294 appendvertice(*m_simplex, p); 295 if(EncloseOrigin()) return(true); 296 removevertice(*m_simplex); 297 appendvertice(*m_simplex,-p); 298 if(EncloseOrigin()) return(true); 299 removevertice(*m_simplex); 300 } 301 } 302 } 303 break; 304 case 3: 305 { 306 const btVector3 n=cross(m_simplex->c[1]->w-m_simplex->c[0]->w, 307 m_simplex->c[2]->w-m_simplex->c[0]->w); 308 if(n.length2()>0) 309 { 310 appendvertice(*m_simplex,n); 311 if(EncloseOrigin()) return(true); 312 removevertice(*m_simplex); 313 appendvertice(*m_simplex,-n); 314 if(EncloseOrigin()) return(true); 315 removevertice(*m_simplex); 316 } 317 } 318 break; 319 case 4: 320 { 321 if(btFabs(det( m_simplex->c[0]->w-m_simplex->c[3]->w, 322 322 m_simplex->c[1]->w-m_simplex->c[3]->w, 323 323 m_simplex->c[2]->w-m_simplex->c[3]->w))>0) 324 return(true); 325 } 326 break; 327 } 328 return(false); 329 } 330 /* Internals */ 331 void getsupport(const btVector3& d,sSV& sv) const 332 { 333 sv.d = d/d.length(); 334 sv.w = m_shape.Support(sv.d); 335 } 336 void removevertice(sSimplex& simplex) 337 { 338 m_free[m_nfree++]=simplex.c[--simplex.rank]; 339 } 340 void appendvertice(sSimplex& simplex,const btVector3& v) 341 { 342 simplex.p[simplex.rank]=0; 343 simplex.c[simplex.rank]=m_free[--m_nfree]; 344 getsupport(v,*simplex.c[simplex.rank++]); 345 } 346 static btScalar det(const btVector3& a,const btVector3& b,const btVector3& c) 347 { 348 return( a.y()*b.z()*c.x()+a.z()*b.x()*c.y()- 349 a.x()*b.z()*c.y()-a.y()*b.x()*c.z()+ 350 a.x()*b.y()*c.z()-a.z()*b.y()*c.x()); 351 } 352 static btScalar projectorigin( const btVector3& a, 353 const btVector3& b, 354 btScalar* w,U& m) 355 { 356 const btVector3 d=b-a; 357 const btScalar l=d.length2(); 358 if(l>GJK_SIMPLEX2_EPS) 359 { 360 const btScalar t(l>0?-dot(a,d)/l:0); 361 if(t>=1) { w[0]=0;w[1]=1;m=2;return(b.length2()); } 362 else if(t<=0) { w[0]=1;w[1]=0;m=1;return(a.length2()); } 363 else { w[0]=1-(w[1]=t);m=3;return((a+d*t).length2()); } 364 } 365 return(-1); 366 } 367 static btScalar projectorigin( const btVector3& a, 368 const btVector3& b, 369 const btVector3& c, 370 btScalar* w,U& m) 371 { 372 static const U imd3[]={1,2,0}; 373 const btVector3* vt[]={&a,&b,&c}; 374 const btVector3 dl[]={a-b,b-c,c-a}; 375 const btVector3 n=cross(dl[0],dl[1]); 376 const btScalar l=n.length2(); 377 if(l>GJK_SIMPLEX3_EPS) 378 { 379 btScalar mindist=-1; 380 btScalar subw[2]; 381 U subm; 382 for(U i=0;i<3;++i) 383 { 384 if(dot(*vt[i],cross(dl[i],n))>0) 385 { 386 const U j=imd3[i]; 387 const btScalar subd(projectorigin(*vt[i],*vt[j],subw,subm)); 388 if((mindist<0)||(subd<mindist)) 389 { 390 mindist = subd; 391 m = static_cast<U>(((subm&1)?1<<i:0)+((subm&2)?1<<j:0)); 392 w[i] = subw[0]; 393 w[j] = subw[1]; 394 w[imd3[j]] = 0; 395 } 324 return(true); 325 } 326 break; 396 327 } 397 } 398 if(mindist<0) 399 { 400 const btScalar d=dot(a,n); 401 const btScalar s=btSqrt(l); 402 const btVector3 p=n*(d/l); 403 mindist = p.length2(); 404 m = 7; 405 w[0] = (cross(dl[1],b-p)).length()/s; 406 w[1] = (cross(dl[2],c-p)).length()/s; 407 w[2] = 1-(w[0]+w[1]); 408 } 409 return(mindist); 410 } 411 return(-1); 412 } 413 static btScalar projectorigin( const btVector3& a, 414 const btVector3& b, 415 const btVector3& c, 416 const btVector3& d, 417 btScalar* w,U& m) 418 { 419 static const U imd3[]={1,2,0}; 420 const btVector3* vt[]={&a,&b,&c,&d}; 421 const btVector3 dl[]={a-d,b-d,c-d}; 422 const btScalar vl=det(dl[0],dl[1],dl[2]); 423 const bool ng=(vl*dot(a,cross(b-c,a-b)))<=0; 424 if(ng&&(btFabs(vl)>GJK_SIMPLEX4_EPS)) 425 { 426 btScalar mindist=-1; 427 btScalar subw[3]; 428 U subm; 429 for(U i=0;i<3;++i) 430 { 431 const U j=imd3[i]; 432 const btScalar s=vl*dot(d,cross(dl[i],dl[j])); 433 if(s>0) 434 { 435 const btScalar subd=projectorigin(*vt[i],*vt[j],d,subw,subm); 436 if((mindist<0)||(subd<mindist)) 437 { 438 mindist = subd; 439 m = static_cast<U>((subm&1?1<<i:0)+ 328 return(false); 329 } 330 /* Internals */ 331 void getsupport(const btVector3& d,sSV& sv) const 332 { 333 sv.d = d/d.length(); 334 sv.w = m_shape.Support(sv.d); 335 } 336 void removevertice(sSimplex& simplex) 337 { 338 m_free[m_nfree++]=simplex.c[--simplex.rank]; 339 } 340 void appendvertice(sSimplex& simplex,const btVector3& v) 341 { 342 simplex.p[simplex.rank]=0; 343 simplex.c[simplex.rank]=m_free[--m_nfree]; 344 getsupport(v,*simplex.c[simplex.rank++]); 345 } 346 static btScalar det(const btVector3& a,const btVector3& b,const btVector3& c) 347 { 348 return( a.y()*b.z()*c.x()+a.z()*b.x()*c.y()- 349 a.x()*b.z()*c.y()-a.y()*b.x()*c.z()+ 350 a.x()*b.y()*c.z()-a.z()*b.y()*c.x()); 351 } 352 static btScalar projectorigin( const btVector3& a, 353 const btVector3& b, 354 btScalar* w,U& m) 355 { 356 const btVector3 d=b-a; 357 const btScalar l=d.length2(); 358 if(l>GJK_SIMPLEX2_EPS) 359 { 360 const btScalar t(l>0?-dot(a,d)/l:0); 361 if(t>=1) { w[0]=0;w[1]=1;m=2;return(b.length2()); } 362 else if(t<=0) { w[0]=1;w[1]=0;m=1;return(a.length2()); } 363 else { w[0]=1-(w[1]=t);m=3;return((a+d*t).length2()); } 364 } 365 return(-1); 366 } 367 static btScalar projectorigin( const btVector3& a, 368 const btVector3& b, 369 const btVector3& c, 370 btScalar* w,U& m) 371 { 372 static const U imd3[]={1,2,0}; 373 const btVector3* vt[]={&a,&b,&c}; 374 const btVector3 dl[]={a-b,b-c,c-a}; 375 const btVector3 n=cross(dl[0],dl[1]); 376 const btScalar l=n.length2(); 377 if(l>GJK_SIMPLEX3_EPS) 378 { 379 btScalar mindist=-1; 380 btScalar subw[2]; 381 U subm; 382 for(U i=0;i<3;++i) 383 { 384 if(dot(*vt[i],cross(dl[i],n))>0) 385 { 386 const U j=imd3[i]; 387 const btScalar subd(projectorigin(*vt[i],*vt[j],subw,subm)); 388 if((mindist<0)||(subd<mindist)) 389 { 390 mindist = subd; 391 m = static_cast<U>(((subm&1)?1<<i:0)+((subm&2)?1<<j:0)); 392 w[i] = subw[0]; 393 w[j] = subw[1]; 394 w[imd3[j]] = 0; 395 } 396 } 397 } 398 if(mindist<0) 399 { 400 const btScalar d=dot(a,n); 401 const btScalar s=btSqrt(l); 402 const btVector3 p=n*(d/l); 403 mindist = p.length2(); 404 m = 7; 405 w[0] = (cross(dl[1],b-p)).length()/s; 406 w[1] = (cross(dl[2],c-p)).length()/s; 407 w[2] = 1-(w[0]+w[1]); 408 } 409 return(mindist); 410 } 411 return(-1); 412 } 413 static btScalar projectorigin( const btVector3& a, 414 const btVector3& b, 415 const btVector3& c, 416 const btVector3& d, 417 btScalar* w,U& m) 418 { 419 static const U imd3[]={1,2,0}; 420 const btVector3* vt[]={&a,&b,&c,&d}; 421 const btVector3 dl[]={a-d,b-d,c-d}; 422 const btScalar vl=det(dl[0],dl[1],dl[2]); 423 const bool ng=(vl*dot(a,cross(b-c,a-b)))<=0; 424 if(ng&&(btFabs(vl)>GJK_SIMPLEX4_EPS)) 425 { 426 btScalar mindist=-1; 427 btScalar subw[3]; 428 U subm; 429 for(U i=0;i<3;++i) 430 { 431 const U j=imd3[i]; 432 const btScalar s=vl*dot(d,cross(dl[i],dl[j])); 433 if(s>0) 434 { 435 const btScalar subd=projectorigin(*vt[i],*vt[j],d,subw,subm); 436 if((mindist<0)||(subd<mindist)) 437 { 438 mindist = subd; 439 m = static_cast<U>((subm&1?1<<i:0)+ 440 440 (subm&2?1<<j:0)+ 441 441 (subm&4?8:0)); 442 w[i] = subw[0]; 443 w[j] = subw[1]; 444 w[imd3[j]] = 0; 445 w[3] = subw[2]; 446 } 442 w[i] = subw[0]; 443 w[j] = subw[1]; 444 w[imd3[j]] = 0; 445 w[3] = subw[2]; 446 } 447 } 448 } 449 if(mindist<0) 450 { 451 mindist = 0; 452 m = 15; 453 w[0] = det(c,b,d)/vl; 454 w[1] = det(a,c,d)/vl; 455 w[2] = det(b,a,d)/vl; 456 w[3] = 1-(w[0]+w[1]+w[2]); 457 } 458 return(mindist); 447 459 } 448 } 449 if(mindist<0) 450 { 451 mindist = 0; 452 m = 15; 453 w[0] = det(c,b,d)/vl; 454 w[1] = det(a,c,d)/vl; 455 w[2] = det(b,a,d)/vl; 456 w[3] = 1-(w[0]+w[1]+w[2]); 457 } 458 return(mindist); 459 } 460 return(-1); 461 } 462 }; 463 464 // EPA 465 struct EPA 466 { 467 /* Types */ 468 typedef GJK::sSV sSV; 469 struct sFace 460 return(-1); 461 } 462 }; 463 464 // EPA 465 struct EPA 470 466 { 471 btVector3 n; 472 btScalar d; 473 btScalar p; 474 sSV* c[3]; 475 sFace* f[3]; 476 sFace* l[2]; 477 U1 e[3]; 478 U1 pass; 479 }; 480 struct sList 481 { 482 sFace* root; 483 U count; 484 sList() : root(0),count(0) {} 485 }; 486 struct sHorizon 487 { 488 sFace* cf; 489 sFace* ff; 490 U nf; 491 sHorizon() : cf(0),ff(0),nf(0) {} 492 }; 493 struct eStatus { enum _ { 494 Valid, 495 Touching, 496 Degenerated, 497 NonConvex, 498 InvalidHull, 499 OutOfFaces, 500 OutOfVertices, 501 AccuraryReached, 502 FallBack, 503 Failed };}; 504 /* Fields */ 505 eStatus::_ m_status; 506 GJK::sSimplex m_result; 507 btVector3 m_normal; 508 btScalar m_depth; 509 sSV m_sv_store[EPA_MAX_VERTICES]; 510 sFace m_fc_store[EPA_MAX_FACES]; 511 U m_nextsv; 512 sList m_hull; 513 sList m_stock; 514 /* Methods */ 515 EPA() 516 { 517 Initialize(); 518 } 519 520 521 static inline void bind(sFace* fa,U ea,sFace* fb,U eb) 522 { 523 fa->e[ea]=(U1)eb;fa->f[ea]=fb; 524 fb->e[eb]=(U1)ea;fb->f[eb]=fa; 525 } 526 static inline void append(sList& list,sFace* face) 527 { 528 face->l[0] = 0; 529 face->l[1] = list.root; 530 if(list.root) list.root->l[0]=face; 531 list.root = face; 532 ++list.count; 533 } 534 static inline void remove(sList& list,sFace* face) 535 { 536 if(face->l[1]) face->l[1]->l[0]=face->l[0]; 537 if(face->l[0]) face->l[0]->l[1]=face->l[1]; 538 if(face==list.root) list.root=face->l[1]; 539 --list.count; 540 } 541 542 543 void Initialize() 544 { 545 m_status = eStatus::Failed; 546 m_normal = btVector3(0,0,0); 547 m_depth = 0; 548 m_nextsv = 0; 549 for(U i=0;i<EPA_MAX_FACES;++i) 550 { 551 append(m_stock,&m_fc_store[EPA_MAX_FACES-i-1]); 552 } 553 } 554 eStatus::_ Evaluate(GJK& gjk,const btVector3& guess) 555 { 556 GJK::sSimplex& simplex=*gjk.m_simplex; 557 if((simplex.rank>1)&&gjk.EncloseOrigin()) 558 { 559 560 /* Clean up */ 561 while(m_hull.root) 562 { 563 sFace* f = m_hull.root; 564 remove(m_hull,f); 565 append(m_stock,f); 566 } 567 m_status = eStatus::Valid; 568 m_nextsv = 0; 569 /* Orient simplex */ 570 if(gjk.det( simplex.c[0]->w-simplex.c[3]->w, 571 simplex.c[1]->w-simplex.c[3]->w, 572 simplex.c[2]->w-simplex.c[3]->w)<0) 573 { 574 btSwap(simplex.c[0],simplex.c[1]); 575 btSwap(simplex.p[0],simplex.p[1]); 576 } 577 /* Build initial hull */ 578 sFace* tetra[]={newface(simplex.c[0],simplex.c[1],simplex.c[2],true), 467 /* Types */ 468 typedef GJK::sSV sSV; 469 struct sFace 470 { 471 btVector3 n; 472 btScalar d; 473 btScalar p; 474 sSV* c[3]; 475 sFace* f[3]; 476 sFace* l[2]; 477 U1 e[3]; 478 U1 pass; 479 }; 480 struct sList 481 { 482 sFace* root; 483 U count; 484 sList() : root(0),count(0) {} 485 }; 486 struct sHorizon 487 { 488 sFace* cf; 489 sFace* ff; 490 U nf; 491 sHorizon() : cf(0),ff(0),nf(0) {} 492 }; 493 struct eStatus { enum _ { 494 Valid, 495 Touching, 496 Degenerated, 497 NonConvex, 498 InvalidHull, 499 OutOfFaces, 500 OutOfVertices, 501 AccuraryReached, 502 FallBack, 503 Failed };}; 504 /* Fields */ 505 eStatus::_ m_status; 506 GJK::sSimplex m_result; 507 btVector3 m_normal; 508 btScalar m_depth; 509 sSV m_sv_store[EPA_MAX_VERTICES]; 510 sFace m_fc_store[EPA_MAX_FACES]; 511 U m_nextsv; 512 sList m_hull; 513 sList m_stock; 514 /* Methods */ 515 EPA() 516 { 517 Initialize(); 518 } 519 520 521 static inline void bind(sFace* fa,U ea,sFace* fb,U eb) 522 { 523 fa->e[ea]=(U1)eb;fa->f[ea]=fb; 524 fb->e[eb]=(U1)ea;fb->f[eb]=fa; 525 } 526 static inline void append(sList& list,sFace* face) 527 { 528 face->l[0] = 0; 529 face->l[1] = list.root; 530 if(list.root) list.root->l[0]=face; 531 list.root = face; 532 ++list.count; 533 } 534 static inline void remove(sList& list,sFace* face) 535 { 536 if(face->l[1]) face->l[1]->l[0]=face->l[0]; 537 if(face->l[0]) face->l[0]->l[1]=face->l[1]; 538 if(face==list.root) list.root=face->l[1]; 539 --list.count; 540 } 541 542 543 void Initialize() 544 { 545 m_status = eStatus::Failed; 546 m_normal = btVector3(0,0,0); 547 m_depth = 0; 548 m_nextsv = 0; 549 for(U i=0;i<EPA_MAX_FACES;++i) 550 { 551 append(m_stock,&m_fc_store[EPA_MAX_FACES-i-1]); 552 } 553 } 554 eStatus::_ Evaluate(GJK& gjk,const btVector3& guess) 555 { 556 GJK::sSimplex& simplex=*gjk.m_simplex; 557 if((simplex.rank>1)&&gjk.EncloseOrigin()) 558 { 559 560 /* Clean up */ 561 while(m_hull.root) 562 { 563 sFace* f = m_hull.root; 564 remove(m_hull,f); 565 append(m_stock,f); 566 } 567 m_status = eStatus::Valid; 568 m_nextsv = 0; 569 /* Orient simplex */ 570 if(gjk.det( simplex.c[0]->w-simplex.c[3]->w, 571 simplex.c[1]->w-simplex.c[3]->w, 572 simplex.c[2]->w-simplex.c[3]->w)<0) 573 { 574 btSwap(simplex.c[0],simplex.c[1]); 575 btSwap(simplex.p[0],simplex.p[1]); 576 } 577 /* Build initial hull */ 578 sFace* tetra[]={newface(simplex.c[0],simplex.c[1],simplex.c[2],true), 579 579 newface(simplex.c[1],simplex.c[0],simplex.c[3],true), 580 580 newface(simplex.c[2],simplex.c[1],simplex.c[3],true), 581 581 newface(simplex.c[0],simplex.c[2],simplex.c[3],true)}; 582 if(m_hull.count==4) 583 { 584 sFace* best=findbest(); 585 sFace outer=*best; 586 U pass=0; 587 U iterations=0; 588 bind(tetra[0],0,tetra[1],0); 589 bind(tetra[0],1,tetra[2],0); 590 bind(tetra[0],2,tetra[3],0); 591 bind(tetra[1],1,tetra[3],2); 592 bind(tetra[1],2,tetra[2],1); 593 bind(tetra[2],2,tetra[3],1); 594 m_status=eStatus::Valid; 595 for(;iterations<EPA_MAX_ITERATIONS;++iterations) 596 { 597 if(m_nextsv<EPA_MAX_VERTICES) 598 { 599 sHorizon horizon; 600 sSV* w=&m_sv_store[m_nextsv++]; 601 bool valid=true; 602 best->pass = (U1)(++pass); 603 gjk.getsupport(best->n,*w); 604 const btScalar wdist=dot(best->n,w->w)-best->d; 605 if(wdist>EPA_ACCURACY) 582 if(m_hull.count==4) 583 { 584 sFace* best=findbest(); 585 sFace outer=*best; 586 U pass=0; 587 U iterations=0; 588 bind(tetra[0],0,tetra[1],0); 589 bind(tetra[0],1,tetra[2],0); 590 bind(tetra[0],2,tetra[3],0); 591 bind(tetra[1],1,tetra[3],2); 592 bind(tetra[1],2,tetra[2],1); 593 bind(tetra[2],2,tetra[3],1); 594 m_status=eStatus::Valid; 595 for(;iterations<EPA_MAX_ITERATIONS;++iterations) 606 596 { 607 for(U j=0;(j<3)&&valid;++j) 608 { 609 valid&=expand( pass,w, 597 if(m_nextsv<EPA_MAX_VERTICES) 598 { 599 sHorizon horizon; 600 sSV* w=&m_sv_store[m_nextsv++]; 601 bool valid=true; 602 best->pass = (U1)(++pass); 603 gjk.getsupport(best->n,*w); 604 const btScalar wdist=dot(best->n,w->w)-best->d; 605 if(wdist>EPA_ACCURACY) 606 { 607 for(U j=0;(j<3)&&valid;++j) 608 { 609 valid&=expand( pass,w, 610 610 best->f[j],best->e[j], 611 611 horizon); 612 } 613 if(valid&&(horizon.nf>=3)) 614 { 615 bind(horizon.cf,1,horizon.ff,2); 616 remove(m_hull,best); 617 append(m_stock,best); 618 best=findbest(); 619 if(best->p>=outer.p) outer=*best; 620 } else { m_status=eStatus::InvalidHull;break; } 621 } else { m_status=eStatus::AccuraryReached;break; } 622 } else { m_status=eStatus::OutOfVertices;break; } 612 } 613 if(valid&&(horizon.nf>=3)) 614 { 615 bind(horizon.cf,1,horizon.ff,2); 616 remove(m_hull,best); 617 append(m_stock,best); 618 best=findbest(); 619 if(best->p>=outer.p) outer=*best; 620 } else { m_status=eStatus::InvalidHull;break; } 621 } else { m_status=eStatus::AccuraryReached;break; } 622 } else { m_status=eStatus::OutOfVertices;break; } 623 } 624 const btVector3 projection=outer.n*outer.d; 625 m_normal = outer.n; 626 m_depth = outer.d; 627 m_result.rank = 3; 628 m_result.c[0] = outer.c[0]; 629 m_result.c[1] = outer.c[1]; 630 m_result.c[2] = outer.c[2]; 631 m_result.p[0] = cross( outer.c[1]->w-projection, 632 outer.c[2]->w-projection).length(); 633 m_result.p[1] = cross( outer.c[2]->w-projection, 634 outer.c[0]->w-projection).length(); 635 m_result.p[2] = cross( outer.c[0]->w-projection, 636 outer.c[1]->w-projection).length(); 637 const btScalar sum=m_result.p[0]+m_result.p[1]+m_result.p[2]; 638 m_result.p[0] /= sum; 639 m_result.p[1] /= sum; 640 m_result.p[2] /= sum; 641 return(m_status); 642 } 623 643 } 624 const btVector3 projection=outer.n*outer.d; 625 m_normal = outer.n; 626 m_depth = outer.d; 627 m_result.rank = 3; 628 m_result.c[0] = outer.c[0]; 629 m_result.c[1] = outer.c[1]; 630 m_result.c[2] = outer.c[2]; 631 m_result.p[0] = cross( outer.c[1]->w-projection, 632 outer.c[2]->w-projection).length(); 633 m_result.p[1] = cross( outer.c[2]->w-projection, 634 outer.c[0]->w-projection).length(); 635 m_result.p[2] = cross( outer.c[0]->w-projection, 636 outer.c[1]->w-projection).length(); 637 const btScalar sum=m_result.p[0]+m_result.p[1]+m_result.p[2]; 638 m_result.p[0] /= sum; 639 m_result.p[1] /= sum; 640 m_result.p[2] /= sum; 641 return(m_status); 642 } 643 } 644 /* Fallback */ 645 m_status = eStatus::FallBack; 646 m_normal = -guess; 647 const btScalar nl=m_normal.length(); 648 if(nl>0) 649 m_normal = m_normal/nl; 650 else 651 m_normal = btVector3(1,0,0); 652 m_depth = 0; 653 m_result.rank=1; 654 m_result.c[0]=simplex.c[0]; 655 m_result.p[0]=1; 656 return(m_status); 644 /* Fallback */ 645 m_status = eStatus::FallBack; 646 m_normal = -guess; 647 const btScalar nl=m_normal.length(); 648 if(nl>0) 649 m_normal = m_normal/nl; 650 else 651 m_normal = btVector3(1,0,0); 652 m_depth = 0; 653 m_result.rank=1; 654 m_result.c[0]=simplex.c[0]; 655 m_result.p[0]=1; 656 return(m_status); 657 } 658 sFace* newface(sSV* a,sSV* b,sSV* c,bool forced) 659 { 660 if(m_stock.root) 661 { 662 sFace* face=m_stock.root; 663 remove(m_stock,face); 664 append(m_hull,face); 665 face->pass = 0; 666 face->c[0] = a; 667 face->c[1] = b; 668 face->c[2] = c; 669 face->n = cross(b->w-a->w,c->w-a->w); 670 const btScalar l=face->n.length(); 671 const bool v=l>EPA_ACCURACY; 672 face->p = btMin(btMin( 673 dot(a->w,cross(face->n,a->w-b->w)), 674 dot(b->w,cross(face->n,b->w-c->w))), 675 dot(c->w,cross(face->n,c->w-a->w))) / 676 (v?l:1); 677 face->p = face->p>=-EPA_INSIDE_EPS?0:face->p; 678 if(v) 679 { 680 face->d = dot(a->w,face->n)/l; 681 face->n /= l; 682 if(forced||(face->d>=-EPA_PLANE_EPS)) 683 { 684 return(face); 685 } else m_status=eStatus::NonConvex; 686 } else m_status=eStatus::Degenerated; 687 remove(m_hull,face); 688 append(m_stock,face); 689 return(0); 690 } 691 m_status=m_stock.root?eStatus::OutOfVertices:eStatus::OutOfFaces; 692 return(0); 693 } 694 sFace* findbest() 695 { 696 sFace* minf=m_hull.root; 697 btScalar mind=minf->d*minf->d; 698 btScalar maxp=minf->p; 699 for(sFace* f=minf->l[1];f;f=f->l[1]) 700 { 701 const btScalar sqd=f->d*f->d; 702 if((f->p>=maxp)&&(sqd<mind)) 703 { 704 minf=f; 705 mind=sqd; 706 maxp=f->p; 707 } 708 } 709 return(minf); 710 } 711 bool expand(U pass,sSV* w,sFace* f,U e,sHorizon& horizon) 712 { 713 static const U i1m3[]={1,2,0}; 714 static const U i2m3[]={2,0,1}; 715 if(f->pass!=pass) 716 { 717 const U e1=i1m3[e]; 718 if((dot(f->n,w->w)-f->d)<-EPA_PLANE_EPS) 719 { 720 sFace* nf=newface(f->c[e1],f->c[e],w,false); 721 if(nf) 722 { 723 bind(nf,0,f,e); 724 if(horizon.cf) bind(horizon.cf,1,nf,2); else horizon.ff=nf; 725 horizon.cf=nf; 726 ++horizon.nf; 727 return(true); 728 } 729 } 730 else 731 { 732 const U e2=i2m3[e]; 733 f->pass = (U1)pass; 734 if( expand(pass,w,f->f[e1],f->e[e1],horizon)&& 735 expand(pass,w,f->f[e2],f->e[e2],horizon)) 736 { 737 remove(m_hull,f); 738 append(m_stock,f); 739 return(true); 740 } 741 } 742 } 743 return(false); 744 } 745 746 }; 747 748 // 749 static void Initialize( const btConvexShape* shape0,const btTransform& wtrs0, 750 const btConvexShape* shape1,const btTransform& wtrs1, 751 btGjkEpaSolver2::sResults& results, 752 tShape& shape, 753 bool withmargins) 754 { 755 /* Results */ 756 results.witnesses[0] = 757 results.witnesses[1] = btVector3(0,0,0); 758 results.status = btGjkEpaSolver2::sResults::Separated; 759 /* Shape */ 760 shape.m_shapes[0] = shape0; 761 shape.m_shapes[1] = shape1; 762 shape.m_toshape1 = wtrs1.getBasis().transposeTimes(wtrs0.getBasis()); 763 shape.m_toshape0 = wtrs0.inverseTimes(wtrs1); 764 shape.EnableMargin(withmargins); 657 765 } 658 sFace* newface(sSV* a,sSV* b,sSV* c,bool forced)659 {660 if(m_stock.root)661 {662 sFace* face=m_stock.root;663 remove(m_stock,face);664 append(m_hull,face);665 face->pass = 0;666 face->c[0] = a;667 face->c[1] = b;668 face->c[2] = c;669 face->n = cross(b->w-a->w,c->w-a->w);670 const btScalar l=face->n.length();671 const bool v=l>EPA_ACCURACY;672 face->p = btMin(btMin(673 dot(a->w,cross(face->n,a->w-b->w)),674 dot(b->w,cross(face->n,b->w-c->w))),675 dot(c->w,cross(face->n,c->w-a->w))) /676 (v?l:1);677 face->p = face->p>=-EPA_INSIDE_EPS?0:face->p;678 if(v)679 {680 face->d = dot(a->w,face->n)/l;681 face->n /= l;682 if(forced||(face->d>=-EPA_PLANE_EPS))683 {684 return(face);685 } else m_status=eStatus::NonConvex;686 } else m_status=eStatus::Degenerated;687 remove(m_hull,face);688 append(m_stock,face);689 return(0);690 }691 m_status=m_stock.root?eStatus::OutOfVertices:eStatus::OutOfFaces;692 return(0);693 }694 sFace* findbest()695 {696 sFace* minf=m_hull.root;697 btScalar mind=minf->d*minf->d;698 btScalar maxp=minf->p;699 for(sFace* f=minf->l[1];f;f=f->l[1])700 {701 const btScalar sqd=f->d*f->d;702 if((f->p>=maxp)&&(sqd<mind))703 {704 minf=f;705 mind=sqd;706 maxp=f->p;707 }708 }709 return(minf);710 }711 bool expand(U pass,sSV* w,sFace* f,U e,sHorizon& horizon)712 {713 static const U i1m3[]={1,2,0};714 static const U i2m3[]={2,0,1};715 if(f->pass!=pass)716 {717 const U e1=i1m3[e];718 if((dot(f->n,w->w)-f->d)<-EPA_PLANE_EPS)719 {720 sFace* nf=newface(f->c[e1],f->c[e],w,false);721 if(nf)722 {723 bind(nf,0,f,e);724 if(horizon.cf) bind(horizon.cf,1,nf,2); else horizon.ff=nf;725 horizon.cf=nf;726 ++horizon.nf;727 return(true);728 }729 }730 else731 {732 const U e2=i2m3[e];733 f->pass = (U1)pass;734 if( expand(pass,w,f->f[e1],f->e[e1],horizon)&&735 expand(pass,w,f->f[e2],f->e[e2],horizon))736 {737 remove(m_hull,f);738 append(m_stock,f);739 return(true);740 }741 }742 }743 return(false);744 }745 746 };747 748 //749 static void Initialize( const btConvexShape* shape0,const btTransform& wtrs0,750 const btConvexShape* shape1,const btTransform& wtrs1,751 btGjkEpaSolver2::sResults& results,752 tShape& shape,753 bool withmargins)754 {755 /* Results */756 results.witnesses[0] =757 results.witnesses[1] = btVector3(0,0,0);758 results.status = btGjkEpaSolver2::sResults::Separated;759 /* Shape */760 shape.m_shapes[0] = shape0;761 shape.m_shapes[1] = shape1;762 shape.m_toshape1 = wtrs1.getBasis().transposeTimes(wtrs0.getBasis());763 shape.m_toshape0 = wtrs0.inverseTimes(wtrs1);764 shape.EnableMargin(withmargins);765 }766 766 767 767 } … … 776 776 int btGjkEpaSolver2::StackSizeRequirement() 777 777 { 778 return(sizeof(GJK)+sizeof(EPA));778 return(sizeof(GJK)+sizeof(EPA)); 779 779 } 780 780 781 781 // 782 782 bool btGjkEpaSolver2::Distance( const btConvexShape* shape0, 783 784 785 786 787 783 const btTransform& wtrs0, 784 const btConvexShape* shape1, 785 const btTransform& wtrs1, 786 const btVector3& guess, 787 sResults& results) 788 788 { 789 tShape shape;790 Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,false);791 GJK gjk;792 GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,guess);793 if(gjk_status==GJK::eStatus::Valid)789 tShape shape; 790 Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,false); 791 GJK gjk; 792 GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,guess); 793 if(gjk_status==GJK::eStatus::Valid) 794 794 { 795 btVector3 w0=btVector3(0,0,0);796 btVector3 w1=btVector3(0,0,0);797 for(U i=0;i<gjk.m_simplex->rank;++i)798 { 799 const btScalar p=gjk.m_simplex->p[i];800 w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p;801 w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p;795 btVector3 w0=btVector3(0,0,0); 796 btVector3 w1=btVector3(0,0,0); 797 for(U i=0;i<gjk.m_simplex->rank;++i) 798 { 799 const btScalar p=gjk.m_simplex->p[i]; 800 w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p; 801 w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p; 802 802 } 803 results.witnesses[0] = wtrs0*w0;804 results.witnesses[1] = wtrs0*w1;805 results.normal = w0-w1;806 results.distance = results.normal.length();807 results.normal /= results.distance>GJK_MIN_DISTANCE?results.distance:1;808 return(true);803 results.witnesses[0] = wtrs0*w0; 804 results.witnesses[1] = wtrs0*w1; 805 results.normal = w0-w1; 806 results.distance = results.normal.length(); 807 results.normal /= results.distance>GJK_MIN_DISTANCE?results.distance:1; 808 return(true); 809 809 } 810 810 else 811 811 { 812 results.status = gjk_status==GJK::eStatus::Inside?813 814 815 return(false);812 results.status = gjk_status==GJK::eStatus::Inside? 813 sResults::Penetrating : 814 sResults::GJK_Failed ; 815 return(false); 816 816 } 817 817 } … … 819 819 // 820 820 bool btGjkEpaSolver2::Penetration( const btConvexShape* shape0, 821 822 823 824 825 826 821 const btTransform& wtrs0, 822 const btConvexShape* shape1, 823 const btTransform& wtrs1, 824 const btVector3& guess, 825 sResults& results, 826 bool usemargins) 827 827 { 828 tShape shape;829 Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,usemargins);830 GJK gjk;831 GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,-guess);832 switch(gjk_status)828 tShape shape; 829 Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,usemargins); 830 GJK gjk; 831 GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,-guess); 832 switch(gjk_status) 833 833 { 834 834 case GJK::eStatus::Inside: 835 835 { 836 EPA epa;837 EPA::eStatus::_ epa_status=epa.Evaluate(gjk,-guess);838 if(epa_status!=EPA::eStatus::Failed)839 { 840 btVector3 w0=btVector3(0,0,0);841 for(U i=0;i<epa.m_result.rank;++i)842 { 843 w0+=shape.Support(epa.m_result.c[i]->d,0)*epa.m_result.p[i];836 EPA epa; 837 EPA::eStatus::_ epa_status=epa.Evaluate(gjk,-guess); 838 if(epa_status!=EPA::eStatus::Failed) 839 { 840 btVector3 w0=btVector3(0,0,0); 841 for(U i=0;i<epa.m_result.rank;++i) 842 { 843 w0+=shape.Support(epa.m_result.c[i]->d,0)*epa.m_result.p[i]; 844 844 } 845 results.status = sResults::Penetrating;846 results.witnesses[0] = wtrs0*w0;847 results.witnesses[1] = wtrs0*(w0-epa.m_normal*epa.m_depth);848 results.normal = -epa.m_normal;849 results.distance = -epa.m_depth;850 return(true);845 results.status = sResults::Penetrating; 846 results.witnesses[0] = wtrs0*w0; 847 results.witnesses[1] = wtrs0*(w0-epa.m_normal*epa.m_depth); 848 results.normal = -epa.m_normal; 849 results.distance = -epa.m_depth; 850 return(true); 851 851 } else results.status=sResults::EPA_Failed; 852 852 } 853 break;853 break; 854 854 case GJK::eStatus::Failed: 855 results.status=sResults::GJK_Failed;856 break;855 results.status=sResults::GJK_Failed; 856 break; 857 857 } 858 return(false);858 return(false); 859 859 } 860 860 … … 866 866 sResults& results) 867 867 { 868 tShape shape;869 btSphereShape shape1(margin);870 btTransform wtrs1(btQuaternion(0,0,0,1),position);871 Initialize(shape0,wtrs0,&shape1,wtrs1,results,shape,false);872 GJK gjk;873 GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,btVector3(1,1,1));874 if(gjk_status==GJK::eStatus::Valid)868 tShape shape; 869 btSphereShape shape1(margin); 870 btTransform wtrs1(btQuaternion(0,0,0,1),position); 871 Initialize(shape0,wtrs0,&shape1,wtrs1,results,shape,false); 872 GJK gjk; 873 GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,btVector3(1,1,1)); 874 if(gjk_status==GJK::eStatus::Valid) 875 875 { 876 btVector3 w0=btVector3(0,0,0);877 btVector3 w1=btVector3(0,0,0);878 for(U i=0;i<gjk.m_simplex->rank;++i)879 { 880 const btScalar p=gjk.m_simplex->p[i];881 w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p;882 w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p;876 btVector3 w0=btVector3(0,0,0); 877 btVector3 w1=btVector3(0,0,0); 878 for(U i=0;i<gjk.m_simplex->rank;++i) 879 { 880 const btScalar p=gjk.m_simplex->p[i]; 881 w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p; 882 w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p; 883 883 } 884 results.witnesses[0] = wtrs0*w0;885 results.witnesses[1] = wtrs0*w1;886 const btVector3 delta= results.witnesses[1]-887 888 const btScalar margin= shape0->getMargin()+889 shape1.getMargin();890 const btScalar length= delta.length();891 results.normal = delta/length;892 results.witnesses[0] += results.normal*margin;893 return(length-margin);884 results.witnesses[0] = wtrs0*w0; 885 results.witnesses[1] = wtrs0*w1; 886 const btVector3 delta= results.witnesses[1]- 887 results.witnesses[0]; 888 const btScalar margin= shape0->getMarginNonVirtual()+ 889 shape1.getMarginNonVirtual(); 890 const btScalar length= delta.length(); 891 results.normal = delta/length; 892 results.witnesses[0] += results.normal*margin; 893 return(length-margin); 894 894 } 895 895 else 896 896 { 897 if(gjk_status==GJK::eStatus::Inside)898 { 899 if(Penetration(shape0,wtrs0,&shape1,wtrs1,gjk.m_ray,results))900 { 901 const btVector3 delta= results.witnesses[0]-902 903 const btScalar length= delta.length();904 if (length >= SIMD_EPSILON)905 results.normal = delta/length;906 return(-length);897 if(gjk_status==GJK::eStatus::Inside) 898 { 899 if(Penetration(shape0,wtrs0,&shape1,wtrs1,gjk.m_ray,results)) 900 { 901 const btVector3 delta= results.witnesses[0]- 902 results.witnesses[1]; 903 const btScalar length= delta.length(); 904 if (length >= SIMD_EPSILON) 905 results.normal = delta/length; 906 return(-length); 907 907 } 908 908 } 909 909 } 910 return(SIMD_INFINITY);910 return(SIMD_INFINITY); 911 911 } 912 912 … … 919 919 sResults& results) 920 920 { 921 if(!Distance(shape0,wtrs0,shape1,wtrs1,guess,results))922 return(Penetration(shape0,wtrs0,shape1,wtrs1,guess,results,false));921 if(!Distance(shape0,wtrs0,shape1,wtrs1,guess,results)) 922 return(Penetration(shape0,wtrs0,shape1,wtrs1,guess,results,false)); 923 923 else 924 return(true);924 return(true); 925 925 } 926 926 -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
r2192 r2430 19 19 #include "btGjkEpaPenetrationDepthSolver.h" 20 20 21 #ifndef __SPU__22 //#define USE_ORIGINAL_GJK 123 #endif24 25 #ifdef USE_ORIGINAL_GJK26 #include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h"27 #endif28 21 29 22 #include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" … … 32 25 const btConvexShape* pConvexA, const btConvexShape* pConvexB, 33 26 const btTransform& transformA, const btTransform& transformB, 34 btVector3& v, bt Point3& wWitnessOnA, btPoint3& wWitnessOnB,27 btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB, 35 28 class btIDebugDraw* debugDraw, btStackAlloc* stackAlloc ) 36 29 { … … 42 35 const btScalar radialmargin(btScalar(0.)); 43 36 44 //#define USE_ORIGINAL_GJK 145 #ifdef USE_ORIGINAL_GJK46 btGjkEpaSolver::sResults results;47 if(btGjkEpaSolver::Collide( pConvexA,transformA,48 pConvexB,transformB,49 radialmargin,stackAlloc,results))50 #else51 37 btVector3 guessVector(transformA.getOrigin()-transformB.getOrigin()); 52 38 btGjkEpaSolver2::sResults results; … … 55 41 guessVector,results)) 56 42 57 #endif58 43 { 59 44 // debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0)); -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
r2192 r2430 29 29 const btConvexShape* pConvexA, const btConvexShape* pConvexB, 30 30 const btTransform& transformA, const btTransform& transformB, 31 btVector3& v, bt Point3& wWitnessOnA, btPoint3& wWitnessOnB,31 btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB, 32 32 class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc ); 33 33 -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
r2192 r2430 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__ … … 54 54 void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults) 55 55 { 56 m_cachedSeparatingDistance = 0.f; 57 56 58 btScalar distance=btScalar(0.); 57 59 btVector3 normalInB(btScalar(0.),btScalar(0.),btScalar(0.)); … … 63 65 localTransB.getOrigin() -= positionOffset; 64 66 65 67 #ifdef __SPU__ 66 68 btScalar marginA = m_minkowskiA->getMarginNonVirtual(); 67 69 btScalar marginB = m_minkowskiB->getMarginNonVirtual(); 68 70 #else 71 btScalar marginA = m_minkowskiA->getMargin(); 72 btScalar marginB = m_minkowskiB->getMargin(); 69 73 #ifdef TEST_NON_VIRTUAL 70 btScalar marginAv = m_minkowskiA->getMargin(); 71 btScalar marginBv = m_minkowskiB->getMargin(); 72 74 btScalar marginAv = m_minkowskiA->getMarginNonVirtual(); 75 btScalar marginBv = m_minkowskiB->getMarginNonVirtual(); 73 76 btAssert(marginA == marginAv); 74 77 btAssert(marginB == marginBv); 75 78 #endif //TEST_NON_VIRTUAL 79 #endif 80 81 76 82 77 83 gNumGjkChecks++; … … 118 124 btVector3 seperatingAxisInB = m_cachedSeparatingAxis* input.m_transformB.getBasis(); 119 125 126 #ifdef __SPU__ 127 btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA); 128 btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB); 129 #else 130 btVector3 pInA = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA); 131 btVector3 qInB = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB); 120 132 #ifdef TEST_NON_VIRTUAL 121 133 btVector3 pInAv = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA); 122 134 btVector3 qInBv = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB); 123 #endif124 btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);125 btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);126 #ifdef TEST_NON_VIRTUAL127 135 btAssert((pInAv-pInA).length() < 0.0001); 128 136 btAssert((qInBv-qInB).length() < 0.0001); 129 137 #endif // 130 131 btPoint3 pWorld = localTransA(pInA); 132 btPoint3 qWorld = localTransB(qInB); 138 #endif //__SPU__ 139 140 btVector3 pWorld = localTransA(pInA); 141 btVector3 qWorld = localTransB(qInB); 133 142 134 143 #ifdef DEBUG_SPU_COLLISION_DETECTION … … 332 341 spu_printf("output 1\n"); 333 342 #endif 343 m_cachedSeparatingAxis = normalInB; 344 m_cachedSeparatingDistance = distance; 345 334 346 output.addContactPoint( 335 347 normalInB, -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
r2192 r2430 21 21 22 22 #include "btDiscreteCollisionDetectorInterface.h" 23 #include "LinearMath/btPoint3.h"24 23 #include "BulletCollision/CollisionShapes/btCollisionMargin.h" 25 24 … … 39 38 const btConvexShape* m_minkowskiB; 40 39 bool m_ignoreMargin; 40 btScalar m_cachedSeparatingDistance; 41 41 42 42 … … 69 69 } 70 70 71 const btVector3& getCachedSeparatingAxis() const 72 { 73 return m_cachedSeparatingAxis; 74 } 75 btScalar getCachedSeparatingDistance() const 76 { 77 return m_cachedSeparatingDistance; 78 } 79 71 80 void setPenetrationDepthSolver(btConvexPenetrationDepthSolver* penetrationDepthSolver) 72 81 { -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
r2192 r2430 33 33 m_appliedImpulse(0.f), 34 34 m_lateralFrictionInitialized(false), 35 m_appliedImpulseLateral1(0.f), 36 m_appliedImpulseLateral2(0.f), 35 37 m_lifeTime(0) 36 38 { -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
r2192 r2430 71 71 const btConvexShape* convexA,const btConvexShape* convexB, 72 72 const btTransform& transA,const btTransform& transB, 73 btVector3& v, bt Point3& pa, btPoint3& pb,73 btVector3& v, btVector3& pa, btVector3& pb, 74 74 class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc 75 75 ) -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
r2192 r2430 28 28 const btConvexShape* convexA,const btConvexShape* convexB, 29 29 const btTransform& transA,const btTransform& transB, 30 btVector3& v, bt Point3& pa, btPoint3& pb,30 btVector3& v, btVector3& pa, btVector3& pb, 31 31 class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc 32 32 ); -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
r2192 r2430 17 17 #include "btPersistentManifold.h" 18 18 #include "LinearMath/btTransform.h" 19 #include <assert.h> 19 20 20 21 21 btScalar gContactBreakingThreshold = btScalar(0.02); … … 67 67 } 68 68 } 69 assert(occurance<=0);69 btAssert(occurance<=0); 70 70 #endif //DEBUG_PERSISTENCY 71 71 … … 165 165 int btPersistentManifold::addManifoldPoint(const btManifoldPoint& newPoint) 166 166 { 167 assert(validContactDistance(newPoint));167 btAssert(validContactDistance(newPoint)); 168 168 169 169 int insertIndex = getNumContacts(); … … 191 191 btScalar btPersistentManifold::getContactBreakingThreshold() const 192 192 { 193 return gContactBreakingThreshold;193 return m_contactBreakingThreshold; 194 194 } 195 195 -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
r2192 r2430 25 25 struct btCollisionResult; 26 26 27 /// contact breaking and merging threshold27 ///maximum contact breaking and merging threshold 28 28 extern btScalar gContactBreakingThreshold; 29 29 … … 55 55 int m_cachedPoints; 56 56 57 btScalar m_contactBreakingThreshold; 58 57 59 58 60 /// sort cached points so most isolated points come first … … 69 71 btPersistentManifold(); 70 72 71 btPersistentManifold(void* body0,void* body1,int bla) 72 : m_body0(body0),m_body1(body1),m_cachedPoints(0) 73 btPersistentManifold(void* body0,void* body1,int , btScalar contactBreakingThreshold) 74 : m_body0(body0),m_body1(body1),m_cachedPoints(0), 75 m_contactBreakingThreshold(contactBreakingThreshold) 73 76 { 74 (void)bla;77 75 78 } 76 79 … … 107 110 } 108 111 109 /// 112 ///@todo: get this margin from the current physics / collision environment 110 113 btScalar getContactBreakingThreshold() const; 111 114 -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h
r2192 r2430 20 20 21 21 #include "LinearMath/btVector3.h" 22 #include "LinearMath/btPoint3.h"23 22 24 23 #define NO_VIRTUAL_INTERFACE 1 … … 38 37 virtual void reset() = 0; 39 38 40 virtual void addVertex(const btVector3& w, const bt Point3& p, const btPoint3& q) = 0;39 virtual void addVertex(const btVector3& w, const btVector3& p, const btVector3& q) = 0; 41 40 42 41 virtual bool closest(btVector3& v) = 0; … … 46 45 virtual bool fullSimplex() const = 0; 47 46 48 virtual int getSimplex(bt Point3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const = 0;47 virtual int getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const = 0; 49 48 50 49 virtual bool inSimplex(const btVector3& w) = 0; … … 54 53 virtual bool emptySimplex() const = 0; 55 54 56 virtual void compute_points(bt Point3& p1, btPoint3& p2) = 0;55 virtual void compute_points(btVector3& p1, btVector3& p2) = 0; 57 56 58 57 virtual int numVertices() const =0; -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
r2192 r2430 78 78 79 79 //add a vertex 80 void btVoronoiSimplexSolver::addVertex(const btVector3& w, const bt Point3& p, const btPoint3& q)80 void btVoronoiSimplexSolver::addVertex(const btVector3& w, const btVector3& p, const btVector3& q) 81 81 { 82 82 m_lastW = w; … … 268 268 269 269 //return the current simplex 270 int btVoronoiSimplexSolver::getSimplex(bt Point3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const270 int btVoronoiSimplexSolver::getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const 271 271 { 272 272 int i; … … 315 315 } 316 316 317 void btVoronoiSimplexSolver::compute_points(bt Point3& p1, btPoint3& p2)317 void btVoronoiSimplexSolver::compute_points(btVector3& p1, btVector3& p2) 318 318 { 319 319 updateClosestVectorAndPoints(); … … 326 326 327 327 328 bool btVoronoiSimplexSolver::closestPtPointTriangle(const bt Point3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c,btSubSimplexClosestResult& result)328 bool btVoronoiSimplexSolver::closestPtPointTriangle(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c,btSubSimplexClosestResult& result) 329 329 { 330 330 result.m_usedVertices.reset(); … … 426 426 427 427 /// Test if point p and d lie on opposite sides of plane through abc 428 int btVoronoiSimplexSolver::pointOutsideOfPlane(const bt Point3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d)428 int btVoronoiSimplexSolver::pointOutsideOfPlane(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d) 429 429 { 430 430 btVector3 normal = (b-a).cross(c-a); … … 453 453 454 454 455 bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const bt Point3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d, btSubSimplexClosestResult& finalResult)455 bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, btSubSimplexClosestResult& finalResult) 456 456 { 457 457 btSubSimplexClosestResult tempResult; … … 487 487 { 488 488 closestPtPointTriangle(p, a, b, c,tempResult); 489 bt Point3 q = tempResult.m_closestPointOnSimplex;489 btVector3 q = tempResult.m_closestPointOnSimplex; 490 490 491 491 btScalar sqDist = (q - p).dot( q - p); … … 514 514 { 515 515 closestPtPointTriangle(p, a, c, d,tempResult); 516 bt Point3 q = tempResult.m_closestPointOnSimplex;516 btVector3 q = tempResult.m_closestPointOnSimplex; 517 517 //convert result bitmask! 518 518 … … 542 542 { 543 543 closestPtPointTriangle(p, a, d, b,tempResult); 544 bt Point3 q = tempResult.m_closestPointOnSimplex;544 btVector3 q = tempResult.m_closestPointOnSimplex; 545 545 //convert result bitmask! 546 546 … … 570 570 { 571 571 closestPtPointTriangle(p, b, d, c,tempResult); 572 bt Point3 q = tempResult.m_closestPointOnSimplex;572 btVector3 q = tempResult.m_closestPointOnSimplex; 573 573 //convert result bitmask! 574 574 btScalar sqDist = (q - p).dot( q - p); -
code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
r2192 r2430 51 51 struct btSubSimplexClosestResult 52 52 { 53 bt Point3 m_closestPointOnSimplex;53 btVector3 m_closestPointOnSimplex; 54 54 //MASK for m_usedVertices 55 55 //stores the simplex vertex-usage, using the MASK, … … 98 98 99 99 btVector3 m_simplexVectorW[VORONOI_SIMPLEX_MAX_VERTS]; 100 bt Point3 m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS];101 bt Point3 m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS];100 btVector3 m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS]; 101 btVector3 m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS]; 102 102 103 103 104 104 105 bt Point3 m_cachedP1;106 bt Point3 m_cachedP2;105 btVector3 m_cachedP1; 106 btVector3 m_cachedP2; 107 107 btVector3 m_cachedV; 108 108 btVector3 m_lastW; … … 117 117 bool updateClosestVectorAndPoints(); 118 118 119 bool closestPtPointTetrahedron(const bt Point3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d, btSubSimplexClosestResult& finalResult);120 int pointOutsideOfPlane(const bt Point3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d);121 bool closestPtPointTriangle(const bt Point3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c,btSubSimplexClosestResult& result);119 bool closestPtPointTetrahedron(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, btSubSimplexClosestResult& finalResult); 120 int pointOutsideOfPlane(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d); 121 bool closestPtPointTriangle(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c,btSubSimplexClosestResult& result); 122 122 123 123 public: … … 125 125 void reset(); 126 126 127 void addVertex(const btVector3& w, const bt Point3& p, const btPoint3& q);127 void addVertex(const btVector3& w, const btVector3& p, const btVector3& q); 128 128 129 129 … … 137 137 } 138 138 139 int getSimplex(bt Point3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const;139 int getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const; 140 140 141 141 bool inSimplex(const btVector3& w); … … 145 145 bool emptySimplex() const ; 146 146 147 void compute_points(bt Point3& p1, btPoint3& p2) ;147 void compute_points(btVector3& p1, btVector3& p2) ; 148 148 149 149 int numVertices() const -
code/branches/physics/src/bullet/BulletDynamics/CMakeLists.txt
r2192 r2430 1 ADD_LIBRARY(LibBulletDynamics 2 1 SET(BulletDynamics_SRCS 3 2 ConstraintSolver/btContactConstraint.cpp 4 ConstraintSolver/btContactConstraint.h5 3 ConstraintSolver/btConeTwistConstraint.cpp 6 ConstraintSolver/btConeTwistConstraint.h7 4 ConstraintSolver/btGeneric6DofConstraint.cpp 8 ConstraintSolver/btGeneric6DofConstraint.h9 5 ConstraintSolver/btHingeConstraint.cpp 10 ConstraintSolver/btHingeConstraint.h11 6 ConstraintSolver/btPoint2PointConstraint.cpp 12 ConstraintSolver/btPoint2PointConstraint.h13 7 ConstraintSolver/btSequentialImpulseConstraintSolver.cpp 14 ConstraintSolver/btSequentialImpulseConstraintSolver.h15 8 ConstraintSolver/btSliderConstraint.cpp 16 ConstraintSolver/btSliderConstraint.h17 9 ConstraintSolver/btSolve2LinearConstraint.cpp 18 ConstraintSolver/btSolve2LinearConstraint.h19 10 ConstraintSolver/btTypedConstraint.cpp 20 ConstraintSolver/btTypedConstraint.h21 11 Dynamics/Bullet-C-API.cpp 22 12 Dynamics/btDiscreteDynamicsWorld.cpp 23 Dynamics/btDiscreteDynamicsWorld.h24 13 Dynamics/btSimpleDynamicsWorld.cpp 25 Dynamics/btSimpleDynamicsWorld.h26 14 Dynamics/btRigidBody.cpp 27 Dynamics/btRigidBody.h28 15 Vehicle/btRaycastVehicle.cpp 29 Vehicle/btRaycastVehicle.h30 16 Vehicle/btWheelInfo.cpp 31 Vehicle/btWheelInfo.h17 Character/btKinematicCharacterController.cpp 32 18 ) 19 20 ADD_LIBRARY(BulletDynamics ${BulletDynamics_SRCS}) -
code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
r2192 r2430 21 21 #define CONETWISTCONSTRAINT_H 22 22 23 #include " ../../LinearMath/btVector3.h"23 #include "LinearMath/btVector3.h" 24 24 #include "btJacobianEntry.h" 25 25 #include "btTypedConstraint.h" -
code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
r2192 r2430 426 426 427 427 return btScalar(0.); 428 } ;429 428 } 429 -
code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.h
r2192 r2430 17 17 #define CONTACT_CONSTRAINT_H 18 18 19 // todo: make into a proper class working with the iterative constraint solver19 ///@todo: make into a proper class working with the iterative constraint solver 20 20 21 21 class btRigidBody; -
code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
r2192 r2430 22 22 SOLVER_FRICTION_SEPARATE = 2, 23 23 SOLVER_USE_WARMSTARTING = 4, 24 SOLVER_CACHE_FRIENDLY = 8 24 SOLVER_USE_FRICTION_WARMSTARTING = 8, 25 SOLVER_CACHE_FRIENDLY = 16 25 26 }; 26 27 … … 45 46 46 47 int m_solverMode; 48 int m_restingContactRestitutionThreshold; 47 49 48 50 … … 69 71 m_linearSlop = btScalar(0.0); 70 72 m_warmstartingFactor=btScalar(0.85); 71 m_solverMode = SOLVER_RANDMIZE_ORDER | SOLVER_CACHE_FRIENDLY | SOLVER_USE_WARMSTARTING; 73 m_solverMode = SOLVER_CACHE_FRIENDLY | SOLVER_RANDMIZE_ORDER | SOLVER_USE_WARMSTARTING; 74 m_restingContactRestitutionThreshold = 2;//resting contact lifetime threshold to disable restitution 72 75 } 73 76 }; -
code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
r2192 r2430 27 27 28 28 29 static const btScalar kSign[] = { btScalar(1.0), btScalar(-1.0), btScalar(1.0) };30 static const int kAxisA[] = { 1, 0, 0 };31 static const int kAxisB[] = { 2, 2, 1 };32 29 #define GENERIC_D6_DISABLE_WARMSTARTING 1 33 30 … … 157 154 btScalar clippedMotorImpulse; 158 155 159 // todo: should clip against accumulated impulse156 ///@todo: should clip against accumulated impulse 160 157 if (unclippedMotorImpulse>0.0f) 161 158 { -
code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
r2192 r2430 324 324 getRigidBodyB().computeAngularImpulseDenominator(normal); 325 325 // scale for mass and relaxation 326 //todo: expose this 0.9 factor to developer327 326 velrelOrthog *= (btScalar(1.)/denom) * m_relaxationFactor; 328 327 } -
code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
r2192 r2430 438 438 439 439 440 voidbtSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation)440 btSolverConstraint& btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation) 441 441 { 442 442 … … 492 492 solverConstraint.m_jacDiagABInv = denom; 493 493 494 494 return solverConstraint; 495 495 } 496 496 … … 719 719 720 720 solverConstraint.m_friction = cp.m_combinedFriction; 721 solverConstraint.m_restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution); 722 if (solverConstraint.m_restitution <= btScalar(0.)) 721 722 723 if (cp.m_lifeTime>infoGlobal.m_restingContactRestitutionThreshold) 723 724 { 724 725 solverConstraint.m_restitution = 0.f; 725 }; 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 } 726 734 727 735 … … 761 769 cp.m_lateralFrictionDir1 /= btSqrt(lat_rel_vel); 762 770 addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); 763 cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB); 764 cp.m_lateralFrictionDir2.normalize();//?? 765 addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); 771 if(infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING) 772 { 773 cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB); 774 cp.m_lateralFrictionDir2.normalize();//?? 775 addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); 776 cp.m_lateralFrictionInitialized = true; 777 } 766 778 } else 767 779 { 768 780 //re-calculate friction direction every frame, todo: check if this is really needed 769 770 781 btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2); 771 782 addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); 772 783 addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); 784 if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING) 785 { 786 cp.m_lateralFrictionInitialized = true; 787 } 773 788 } 774 cp.m_lateralFrictionInitialized = true;775 789 776 790 } else 777 791 { 778 792 addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); 779 addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); 793 if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING) 794 addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); 780 795 } 781 796 797 if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING) 782 798 { 783 btSolverConstraint& frictionConstraint1 = m_tmpSolverFrictionConstraintPool[solverConstraint.m_frictionIndex];784 if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)785 799 { 786 frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor; 787 if (rb0) 788 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(frictionConstraint1.m_contactNormal*rb0->getInvMass(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse); 789 if (rb1) 790 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(frictionConstraint1.m_contactNormal*rb1->getInvMass(),frictionConstraint1.m_angularComponentB,-frictionConstraint1.m_appliedImpulse); 791 } else 800 btSolverConstraint& frictionConstraint1 = m_tmpSolverFrictionConstraintPool[solverConstraint.m_frictionIndex]; 801 if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) 802 { 803 frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor; 804 if (rb0) 805 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(frictionConstraint1.m_contactNormal*rb0->getInvMass(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse); 806 if (rb1) 807 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(frictionConstraint1.m_contactNormal*rb1->getInvMass(),frictionConstraint1.m_angularComponentB,-frictionConstraint1.m_appliedImpulse); 808 } else 809 { 810 frictionConstraint1.m_appliedImpulse = 0.f; 811 } 812 } 792 813 { 793 frictionConstraint1.m_appliedImpulse = 0.f; 794 } 795 } 796 { 797 btSolverConstraint& frictionConstraint2 = m_tmpSolverFrictionConstraintPool[solverConstraint.m_frictionIndex+1]; 798 if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) 799 { 800 frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor; 801 if (rb0) 802 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(frictionConstraint2.m_contactNormal*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse); 803 if (rb1) 804 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(frictionConstraint2.m_contactNormal*rb1->getInvMass(),frictionConstraint2.m_angularComponentB,-frictionConstraint2.m_appliedImpulse); 805 } else 806 { 807 frictionConstraint2.m_appliedImpulse = 0.f; 814 btSolverConstraint& frictionConstraint2 = m_tmpSolverFrictionConstraintPool[solverConstraint.m_frictionIndex+1]; 815 if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) 816 { 817 frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor; 818 if (rb0) 819 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(frictionConstraint2.m_contactNormal*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse); 820 if (rb1) 821 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(frictionConstraint2.m_contactNormal*rb1->getInvMass(),frictionConstraint2.m_angularComponentB,-frictionConstraint2.m_appliedImpulse); 822 } else 823 { 824 frictionConstraint2.m_appliedImpulse = 0.f; 825 } 808 826 } 809 827 } … … 833 851 int numFrictionPool = m_tmpSolverFrictionConstraintPool.size(); 834 852 835 /// todo: use stack allocator for such temporarily memory, same for solver bodies/constraints853 ///@todo: use stack allocator for such temporarily memory, same for solver bodies/constraints 836 854 m_orderTmpConstraintPool.resize(numConstraintPool); 837 855 m_orderFrictionConstraintPool.resize(numFrictionPool); … … 985 1003 btAssert(pt); 986 1004 pt->m_appliedImpulse = solveManifold.m_appliedImpulse; 987 pt->m_appliedImpulseLateral1 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse; 988 pt->m_appliedImpulseLateral1 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse; 1005 if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING) 1006 { 1007 pt->m_appliedImpulseLateral1 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse; 1008 pt->m_appliedImpulseLateral2 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse; 1009 } 989 1010 990 1011 //do a callback here? … … 1221 1242 cpd->m_penetration = cp.getDistance();///btScalar(info.m_numIterations); 1222 1243 cpd->m_friction = cp.m_combinedFriction; 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 }; 1244 if (cp.m_lifeTime>info.m_restingContactRestitutionThreshold) 1245 { 1246 cpd->m_restitution = 0.f; 1247 } else 1248 { 1249 cpd->m_restitution = restitutionCurve(rel_vel, combinedRestitution); 1250 if (cpd->m_restitution <= btScalar(0.)) 1251 { 1252 cpd->m_restitution = btScalar(0.0); 1253 }; 1254 } 1229 1255 1230 1256 //restitution and penetration work in same direction so -
code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
r2192 r2430 24 24 25 25 26 /// btSequentialImpulseConstraintSolver uses a Propagation Method and Sequentially applies impulses27 /// 28 /// 29 /// 26 ///The btSequentialImpulseConstraintSolver uses a Propagation Method and Sequentially applies impulses 27 ///The approach is the 3D version of Erin Catto's GDC 2006 tutorial. See http://www.gphysics.com 28 ///Although Sequential Impulse is more intuitive, it is mathematically equivalent to Projected Successive Overrelaxation (iterative LCP) 29 ///Applies impulses for combined restitution and penetration recovery and to simulate friction 30 30 class btSequentialImpulseConstraintSolver : public btConstraintSolver 31 31 { … … 42 42 btScalar solveFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer); 43 43 void prepareConstraints(btPersistentManifold* manifoldPtr, const btContactSolverInfo& info,btIDebugDraw* debugDrawer); 44 voidaddFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation);44 btSolverConstraint& addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation); 45 45 46 46 ContactSolverFunc m_contactDispatch[MAX_CONTACT_SOLVER_TYPES][MAX_CONTACT_SOLVER_TYPES]; -
code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btSolverBody.h
r2192 r2430 25 25 26 26 27 /// btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance.27 ///The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance. 28 28 ATTRIBUTE_ALIGNED16 (struct) btSolverBody 29 29 { 30 30 BT_DECLARE_ALIGNED_ALLOCATOR(); 31 31 32 btMatrix3x3 m_worldInvInertiaTensor; 33 32 34 btVector3 m_angularVelocity; 35 btVector3 m_linearVelocity; 36 btVector3 m_centerOfMassPosition; 37 btVector3 m_pushVelocity; 38 btVector3 m_turnVelocity; 39 33 40 float m_angularFactor; 34 41 float m_invMass; 35 42 float m_friction; 36 43 btRigidBody* m_originalBody; 37 btVector3 m_linearVelocity;38 btVector3 m_centerOfMassPosition;39 40 btVector3 m_pushVelocity;41 btVector3 m_turnVelocity;42 44 43 45 -
code/branches/physics/src/bullet/BulletDynamics/Dynamics/Bullet-C-API.cpp
r2192 r2430 39 39 #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" 40 40 #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" 41 #include "BulletCollision/NarrowPhaseCollision/btGjkEpa .h"41 #include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" 42 42 #include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h" 43 43 #include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" … … 256 256 btAssert(colShape->getShapeType()==CONVEX_HULL_SHAPE_PROXYTYPE); 257 257 btConvexHullShape* convexHullShape = reinterpret_cast<btConvexHullShape*>( cshape); 258 convexHullShape->addPoint(bt Point3(x,y,z));258 convexHullShape->addPoint(btVector3(x,y,z)); 259 259 260 260 } -
code/branches/physics/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
r2192 r2430 52 52 #include "BulletDynamics/Vehicle/btVehicleRaycaster.h" 53 53 #include "BulletDynamics/Vehicle/btWheelInfo.h" 54 //character 55 #include "BulletDynamics/Character/btCharacterControllerInterface.h" 56 54 57 #include "LinearMath/btIDebugDraw.h" 55 58 #include "LinearMath/btQuickprof.h" … … 126 129 void btDiscreteDynamicsWorld::debugDrawWorld() 127 130 { 131 BT_PROFILE("debugDrawWorld"); 128 132 129 133 if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints) … … 151 155 int i; 152 156 153 //todo: iterate over awake simulation islands!154 157 for ( i=0;i<m_collisionObjects.size();i++) 155 158 { … … 180 183 if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb)) 181 184 { 182 bt Point3 minAabb,maxAabb;185 btVector3 minAabb,maxAabb; 183 186 btVector3 colorvec(1,0,0); 184 187 colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb); … … 221 224 void btDiscreteDynamicsWorld::clearForces() 222 225 { 223 // todo: iterate over awake simulation islands!226 ///@todo: iterate over awake simulation islands! 224 227 for ( int i=0;i<m_collisionObjects.size();i++) 225 228 { … … 237 240 void btDiscreteDynamicsWorld::applyGravity() 238 241 { 239 // todo: iterate over awake simulation islands!242 ///@todo: iterate over awake simulation islands! 240 243 for ( int i=0;i<m_collisionObjects.size();i++) 241 244 { … … 251 254 252 255 256 void btDiscreteDynamicsWorld::synchronizeSingleMotionState(btRigidBody* body) 257 { 258 btAssert(body); 259 260 if (body->getMotionState() && !body->isStaticOrKinematicObject()) 261 { 262 //we need to call the update at least once, even for sleeping objects 263 //otherwise the 'graphics' transform never updates properly 264 ///@todo: add 'dirty' flag 265 //if (body->getActivationState() != ISLAND_SLEEPING) 266 { 267 btTransform interpolatedTransform; 268 btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(), 269 body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime*body->getHitFraction(),interpolatedTransform); 270 body->getMotionState()->setWorldTransform(interpolatedTransform); 271 } 272 } 273 } 274 253 275 254 276 void btDiscreteDynamicsWorld::synchronizeMotionStates() 255 277 { 278 BT_PROFILE("synchronizeMotionStates"); 256 279 { 257 280 //todo: iterate over awake simulation islands! … … 261 284 262 285 btRigidBody* body = btRigidBody::upcast(colObj); 263 if (body && body->getMotionState() && !body->isStaticOrKinematicObject()) 264 { 265 //we need to call the update at least once, even for sleeping objects 266 //otherwise the 'graphics' transform never updates properly 267 //so todo: add 'dirty' flag 268 //if (body->getActivationState() != ISLAND_SLEEPING) 269 { 270 btTransform interpolatedTransform; 271 btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(), 272 body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime*body->getHitFraction(),interpolatedTransform); 273 body->getMotionState()->setWorldTransform(interpolatedTransform); 274 } 275 } 286 if (body) 287 synchronizeSingleMotionState(body); 276 288 } 277 289 } … … 393 405 ///update vehicle simulation 394 406 updateVehicles(timeStep); 395 407 408 updateCharacters(timeStep); 396 409 397 410 updateActivationState( timeStep ); … … 469 482 } 470 483 484 void btDiscreteDynamicsWorld::updateCharacters(btScalar timeStep) 485 { 486 BT_PROFILE("updateCharacters"); 487 488 for ( int i=0;i<m_characters.size();i++) 489 { 490 btCharacterControllerInterface* character = m_characters[i]; 491 character->preStep (this); 492 character->playerStep (this,timeStep); 493 } 494 } 495 496 497 471 498 void btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep) 472 499 { … … 532 559 m_vehicles.remove(vehicle); 533 560 } 561 562 void btDiscreteDynamicsWorld::addCharacter(btCharacterControllerInterface* character) 563 { 564 m_characters.push_back(character); 565 } 566 567 void btDiscreteDynamicsWorld::removeCharacter(btCharacterControllerInterface* character) 568 { 569 m_characters.remove(character); 570 } 571 534 572 535 573 SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs) … … 665 703 666 704 /// solve all the constraints for this island 667 m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld() ->getCollisionObjectArray(),&solverCallback);705 m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld(),&solverCallback); 668 706 669 707 m_constraintSolver->allSolved(solverInfo, m_debugDrawer, m_stackAlloc); … … 730 768 { 731 769 if (convexResult.m_hitCollisionObject == m_me) 732 return 1.0; 770 return 1.0f; 771 772 //ignore result if there is no contact response 773 if(!convexResult.m_hitCollisionObject->hasContactResponse()) 774 return 1.0f; 733 775 734 776 btVector3 linVelA,linVelB; … … 751 793 752 794 ///don't do CCD when the collision filters are not matching 753 if (! btCollisionWorld::ClosestConvexResultCallback::needsCollision(proxy0))795 if (!ClosestConvexResultCallback::needsCollision(proxy0)) 754 796 return false; 755 797 … … 808 850 btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape()); 809 851 btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape()); 852 853 sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup; 854 sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask; 855 810 856 convexSweepTest(&tmpSphere,body->getWorldTransform(),predictedTrans,sweepResults); 811 857 if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f)) … … 827 873 828 874 875 876 829 877 void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) 830 878 { … … 838 886 if (!body->isStaticOrKinematicObject()) 839 887 { 840 if (body->isActive()) 841 { 842 body->integrateVelocities( timeStep); 843 //damping 844 body->applyDamping(timeStep); 845 846 body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform()); 847 } 888 889 body->integrateVelocities( timeStep); 890 //damping 891 body->applyDamping(timeStep); 892 893 body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform()); 848 894 } 849 895 } … … 1097 1143 btConcaveShape* concaveMesh = (btConcaveShape*) shape; 1098 1144 1099 // todo pass camera, for some culling1145 ///@todo pass camera, for some culling? no -> we are not a graphics lib 1100 1146 btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30)); 1101 1147 btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); … … 1126 1172 for (i=0;i<polyshape->getNumEdges();i++) 1127 1173 { 1128 bt Point3 a,b;1174 btVector3 a,b; 1129 1175 polyshape->getEdge(i,a,b); 1130 1176 btVector3 wa = worldTransform * a; -
code/branches/physics/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
r2192 r2430 27 27 28 28 class btRaycastVehicle; 29 class btCharacterControllerInterface; 29 30 class btIDebugDraw; 30 31 #include "LinearMath/btAlignedObjectArray.h" … … 43 44 btAlignedObjectArray<btTypedConstraint*> m_constraints; 44 45 45 46 46 btVector3 m_gravity; 47 47 … … 55 55 56 56 btAlignedObjectArray<btRaycastVehicle*> m_vehicles; 57 58 btAlignedObjectArray<btCharacterControllerInterface*> m_characters; 59 57 60 58 61 int m_profileTimings; … … 62 65 virtual void integrateTransforms(btScalar timeStep); 63 66 64 v oid calculateSimulationIslands();67 virtual void calculateSimulationIslands(); 65 68 66 v oid solveConstraints(btContactSolverInfo& solverInfo);69 virtual void solveConstraints(btContactSolverInfo& solverInfo); 67 70 68 71 void updateActivationState(btScalar timeStep); … … 70 73 void updateVehicles(btScalar timeStep); 71 74 75 void updateCharacters(btScalar timeStep); 76 72 77 void startProfiling(btScalar timeStep); 73 78 74 79 virtual void internalSingleStepSimulation( btScalar timeStep); 75 80 76 void synchronizeMotionStates();77 81 78 v oid saveKinematicState(btScalar timeStep);82 virtual void saveKinematicState(btScalar timeStep); 79 83 80 84 void debugDrawSphere(btScalar radius, const btTransform& transform, const btVector3& color); 85 81 86 82 87 public: … … 92 97 93 98 94 v oid addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false);99 virtual void synchronizeMotionStates(); 95 100 96 void removeConstraint(btTypedConstraint* constraint); 101 ///this can be useful to synchronize a single rigid body -> graphics object 102 void synchronizeSingleMotionState(btRigidBody* body); 97 103 98 v oid addVehicle(btRaycastVehicle* vehicle);104 virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false); 99 105 100 void removeVehicle(btRaycastVehicle* vehicle); 106 virtual void removeConstraint(btTypedConstraint* constraint); 107 108 virtual void addVehicle(btRaycastVehicle* vehicle); 109 110 virtual void removeVehicle(btRaycastVehicle* vehicle); 111 112 virtual void addCharacter(btCharacterControllerInterface* character); 113 114 virtual void removeCharacter(btCharacterControllerInterface* character); 115 101 116 102 117 btSimulationIslandManager* getSimulationIslandManager() … … 114 129 return this; 115 130 } 116 117 131 118 132 virtual void setGravity(const btVector3& gravity); … … 153 167 virtual void setNumTasks(int numTasks) 154 168 { 169 (void) numTasks; 155 170 } 156 171 -
code/branches/physics/src/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h
r2192 r2430 24 24 class btConstraintSolver; 25 25 class btDynamicsWorld; 26 class btCharacterControllerInterface; 26 27 27 28 /// Type for the callback for each tick … … 76 77 virtual void removeVehicle(btRaycastVehicle* vehicle) {(void)vehicle;} 77 78 79 virtual void addCharacter(btCharacterControllerInterface* character) {(void)character;} 80 81 virtual void removeCharacter(btCharacterControllerInterface* character) {(void)character;} 82 83 78 84 //once a rigidbody is added to the dynamics world, it will get this gravity assigned 79 85 //existing rigidbodies in the world get gravity assigned too, during this method 80 86 virtual void setGravity(const btVector3& gravity) = 0; 81 87 virtual btVector3 getGravity () const = 0; 88 89 virtual void synchronizeMotionStates() = 0; 82 90 83 91 virtual void addRigidBody(btRigidBody* body) = 0; -
code/branches/physics/src/bullet/BulletDynamics/Dynamics/btRigidBody.h
r2192 r2430 18 18 19 19 #include "LinearMath/btAlignedObjectArray.h" 20 #include "LinearMath/btPoint3.h"21 20 #include "LinearMath/btTransform.h" 22 21 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" … … 32 31 33 32 34 /// btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape.33 ///The btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape. 35 34 ///It is recommended for performance and memory use to share btCollisionShape objects whenever possible. 36 35 ///There are 3 types of rigid bodies: … … 76 75 77 76 78 /// btRigidBodyConstructionInfoprovides information to create a rigid body. Setting mass to zero creates a fixed (non-dynamic) rigid body.77 ///The btRigidBodyConstructionInfo structure provides information to create a rigid body. Setting mass to zero creates a fixed (non-dynamic) rigid body. 79 78 ///For dynamic objects, you can use the collision shape to approximate the local inertia tensor, otherwise use the zero vector (default argument) 80 79 ///You can use the motion state to synchronize the world transform between physics and graphics objects. … … 304 303 void updateInertiaTensor(); 305 304 306 const bt Point3& getCenterOfMassPosition() const {305 const btVector3& getCenterOfMassPosition() const { 307 306 return m_worldTransform.getOrigin(); 308 307 } … … 322 321 inline void setLinearVelocity(const btVector3& lin_vel) 323 322 { 324 assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT);325 323 m_linearVelocity = lin_vel; 326 324 } 327 325 328 inline void setAngularVelocity(const btVector3& ang_vel) { 329 assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT); 330 { 331 m_angularVelocity = ang_vel; 332 } 326 inline void setAngularVelocity(const btVector3& ang_vel) 327 { 328 m_angularVelocity = ang_vel; 333 329 } 334 330 … … 354 350 355 351 356 SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const bt Point3& pos, const btVector3& normal) const352 SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btVector3& pos, const btVector3& normal) const 357 353 { 358 354 btVector3 r0 = pos - getCenterOfMassPosition(); -
code/branches/physics/src/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
r2192 r2430 98 98 void btSimpleDynamicsWorld::clearForces() 99 99 { 100 // todo: iterate over awake simulation islands!100 ///@todo: iterate over awake simulation islands! 101 101 for ( int i=0;i<m_collisionObjects.size();i++) 102 102 { … … 157 157 if (body->isActive() && (!body->isStaticObject())) 158 158 { 159 bt Point3 minAabb,maxAabb;159 btVector3 minAabb,maxAabb; 160 160 colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb); 161 161 btBroadphaseInterface* bp = getBroadphase(); … … 211 211 void btSimpleDynamicsWorld::synchronizeMotionStates() 212 212 { 213 // todo: iterate over awake simulation islands!213 ///@todo: iterate over awake simulation islands! 214 214 for ( int i=0;i<m_collisionObjects.size();i++) 215 215 { -
code/branches/physics/src/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
r2192 r2430 23 23 class btConstraintSolver; 24 24 25 /// btSimpleDynamicsWorld serves as unit-test and to verify more complicated and optimized dynamics worlds.25 ///The btSimpleDynamicsWorld serves as unit-test and to verify more complicated and optimized dynamics worlds. 26 26 ///Please use btDiscreteDynamicsWorld instead (or btContinuousDynamicsWorld once it is finished). 27 27 class btSimpleDynamicsWorld : public btDynamicsWorld … … 61 61 virtual void updateAabbs(); 62 62 63 v oid synchronizeMotionStates();63 virtual void synchronizeMotionStates(); 64 64 65 65 virtual void setConstraintSolver(btConstraintSolver* solver); -
code/branches/physics/src/bullet/BulletDynamics/Vehicle/btRaycastVehicle.cpp
r2192 r2430 189 189 wheel.m_raycastInfo.m_isInContact = true; 190 190 191 wheel.m_raycastInfo.m_groundObject = &s_fixedObject;// todo for driving on dynamic/movable objects!;191 wheel.m_raycastInfo.m_groundObject = &s_fixedObject;///@todo for driving on dynamic/movable objects!; 192 192 //wheel.m_raycastInfo.m_groundObject = object; 193 193 … … 692 692 btVector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel]; 693 693 694 rel_pos[ 2] *= wheelInfo.m_rollInfluence;694 rel_pos[m_indexForwardAxis] *= wheelInfo.m_rollInfluence; 695 695 m_chassisBody->applyImpulse(sideImp,rel_pos); 696 696 -
code/branches/physics/src/bullet/CMakeLists.txt
r2192 r2430 1 ADD_SUBDIRECTORY(BulletSoftBody)2 1 ADD_SUBDIRECTORY(BulletCollision) 3 2 ADD_SUBDIRECTORY(BulletDynamics) -
code/branches/physics/src/bullet/ChangeLog
r2192 r2430 4 4 Todo: update changelog from April - July 2008 5 5 See http://code.google.com/p/bullet/source/list for more complete log in Subversion 6 7 2008 November 12 8 - Add compound shape export to BulletColladaConverter 9 Thanks to JamesH for the report: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=12&t=2840 10 - Fix compiler build for Visual Studio 6 11 Thanks to JoF for the report: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2841 12 13 2008 November 11 14 - Add CProfileManager::dumpAll() to dump performance statistics to console using printf. 15 - Add support for interaction between btSoftBody and btCollisionObject/btGhostObject 16 17 2008 November 8 18 - Fix PosixThreadSupport 19 - Add improved btHeightfieldTerrainShape support and new Demos/TerrainDemo 20 Thanks to tomva, http://code.google.com/p/bullet/issues/detail?id=63&can=1 21 - Moved kinematic character controller from Demos/CharacterDemo into src/BulletDynamics/Character/btKinematicCharacterController.cpp 22 23 2008 November 6 24 - reduced default memory pool allocation from 40Mb to 3Mb. This should be more suitable for all platforms, including iPhone 25 - improved CUDA broadphase 26 - IBM Cell SDK 3.x support, fix ibmsdk Makefiles 27 - improved CMake support with 'install' and 'framework option 28 29 2008 November 4 30 - add btAxisSweep::resetPool to avoid non-determinism due to shuffled linked list 31 Thanks to Ole for the contribution, 32 33 2008 October 30 34 - disabled btTriangleMesh duplicate search by default, it is extremely slow 35 - added Extras/IFF binary chunk serialization library as preparation for in-game native platform serialization (planned COLLADA DOM -> IFF converter) 36 37 2008 October 20 38 - added SCE Physics Effects box-box collision detection for SPU/BulletMultiThreaded version 39 See Bullet/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp 40 Thanks to Sony Computer Entertainment Japan, SCEI for the contribution 41 42 2008 October 17 43 - Added btGhostObject support, this helps character controller, explosions, triggers and other local spatial queries 44 45 2008 October 10 46 - Moved aabb to btBroadphaseProxy, improves rayTest dramatically. Further raytest improvements using the broadphase acceleration structures are planned 47 - Moved BulletMultiThreaded from Extras to /src/BulletMultiThreaded for better integration 6 48 7 49 -
code/branches/physics/src/bullet/LinearMath/CMakeLists.txt
r2192 r2430 1 ADD_LIBRARY(LibLinearMath 2 btAlignedObjectArray.h 3 btList.h 4 btPoolAllocator.h 5 btRandom.h 6 btVector3.h 7 btDefaultMotionState.h 8 btMatrix3x3.h 9 btQuadWord.h 10 btHashMap.h 11 btScalar.h 12 btAabbUtil2.h 13 btConvexHull.h 1 SET(LinearMath_SRCS 14 2 btConvexHull.cpp 15 btMinMax.h16 btQuaternion.h17 btStackAlloc.h18 btGeometryUtil.h19 btMotionState.h20 btTransform.h21 btAlignedAllocator.h22 btIDebugDraw.h23 btPoint3.h24 btQuickprof.h25 btTransformUtil.h26 3 btQuickprof.cpp 27 4 btGeometryUtil.cpp … … 29 6 ) 30 7 8 ADD_LIBRARY(LinearMath ${LinearMath_SRCS}) -
code/branches/physics/src/bullet/LinearMath/btAabbUtil2.h
r2192 r2430 22 22 #include "btMinMax.h" 23 23 24 25 24 26 SIMD_FORCE_INLINE void AabbExpand (btVector3& aabbMin, 25 27 btVector3& aabbMax, … … 31 33 } 32 34 35 /// conservative test for overlap between two aabbs 36 SIMD_FORCE_INLINE bool TestPointAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1, 37 const btVector3 &point) 38 { 39 bool overlap = true; 40 overlap = (aabbMin1.getX() > point.getX() || aabbMax1.getX() < point.getX()) ? false : overlap; 41 overlap = (aabbMin1.getZ() > point.getZ() || aabbMax1.getZ() < point.getZ()) ? false : overlap; 42 overlap = (aabbMin1.getY() > point.getY() || aabbMax1.getY() < point.getY()) ? false : overlap; 43 return overlap; 44 } 45 33 46 34 47 /// conservative test for overlap between two aabbs … … 37 50 { 38 51 bool overlap = true; 39 overlap = (aabbMin1 [0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;40 overlap = (aabbMin1 [2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;41 overlap = (aabbMin1 [1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;52 overlap = (aabbMin1.getX() > aabbMax2.getX() || aabbMax1.getX() < aabbMin2.getX()) ? false : overlap; 53 overlap = (aabbMin1.getZ() > aabbMax2.getZ() || aabbMax1.getZ() < aabbMin2.getZ()) ? false : overlap; 54 overlap = (aabbMin1.getY() > aabbMax2.getY() || aabbMax1.getY() < aabbMin2.getY()) ? false : overlap; 42 55 return overlap; 43 56 } … … 72 85 (p.getZ() > halfExtent.getZ() ? 0x20 : 0x0); 73 86 } 87 74 88 75 89 … … 83 97 { 84 98 btScalar tmax, tymin, tymax, tzmin, tzmax; 85 tmin = (bounds[raySign[0]] [0] - rayFrom[0]) * rayInvDirection[0];86 tmax = (bounds[1-raySign[0]] [0] - rayFrom[0]) * rayInvDirection[0];87 tymin = (bounds[raySign[1]] [1] - rayFrom[1]) * rayInvDirection[1];88 tymax = (bounds[1-raySign[1]] [1] - rayFrom[1]) * rayInvDirection[1];99 tmin = (bounds[raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX(); 100 tmax = (bounds[1-raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX(); 101 tymin = (bounds[raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY(); 102 tymax = (bounds[1-raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY(); 89 103 90 104 if ( (tmin > tymax) || (tymin > tmax) ) … … 97 111 tmax = tymax; 98 112 99 tzmin = (bounds[raySign[2]] [2] - rayFrom[2]) * rayInvDirection[2];100 tzmax = (bounds[1-raySign[2]] [2] - rayFrom[2]) * rayInvDirection[2];113 tzmin = (bounds[raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ(); 114 tzmax = (bounds[1-raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ(); 101 115 102 116 if ( (tmin > tzmax) || (tzmin > tmax) ) … … 197 211 } 198 212 213 #define USE_BANCHLESS 1 214 #ifdef USE_BANCHLESS 215 //This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360) 216 SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) 217 { 218 return static_cast<unsigned int>(btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0]) 219 & (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2]) 220 & (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])), 221 1, 0)); 222 } 223 #else 224 SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) 225 { 226 bool overlap = true; 227 overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; 228 overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap; 229 overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; 230 return overlap; 231 } 232 #endif //USE_BANCHLESS 199 233 200 234 #endif -
code/branches/physics/src/bullet/LinearMath/btConvexHull.cpp
r2192 r2430 343 343 } 344 344 345 class Tri;346 347 348 349 class Tri: public int3345 class btHullTriangle; 346 347 348 349 class btHullTriangle : public int3 350 350 { 351 351 public: … … 354 354 int vmax; 355 355 btScalar rise; 356 Tri(int a,int b,int c):int3(a,b,c),n(-1,-1,-1)356 btHullTriangle(int a,int b,int c):int3(a,b,c),n(-1,-1,-1) 357 357 { 358 358 vmax=-1; 359 359 rise = btScalar(0.0); 360 360 } 361 ~ Tri()361 ~btHullTriangle() 362 362 { 363 363 } … … 366 366 367 367 368 int & Tri::neib(int a,int b)368 int &btHullTriangle::neib(int a,int b) 369 369 { 370 370 static int er=-1; … … 380 380 return er; 381 381 } 382 void HullLibrary::b2bfix( Tri* s,Tri*t)382 void HullLibrary::b2bfix(btHullTriangle* s,btHullTriangle*t) 383 383 { 384 384 int i; … … 396 396 } 397 397 398 void HullLibrary::removeb2b( Tri* s,Tri*t)398 void HullLibrary::removeb2b(btHullTriangle* s,btHullTriangle*t) 399 399 { 400 400 b2bfix(s,t); … … 404 404 } 405 405 406 void HullLibrary::checkit( Tri*t)406 void HullLibrary::checkit(btHullTriangle *t) 407 407 { 408 408 (void)t; … … 428 428 } 429 429 430 Tri* HullLibrary::allocateTriangle(int a,int b,int c)431 { 432 void* mem = btAlignedAlloc(sizeof( Tri),16);433 Tri* tr = new (mem)Tri(a,b,c);430 btHullTriangle* HullLibrary::allocateTriangle(int a,int b,int c) 431 { 432 void* mem = btAlignedAlloc(sizeof(btHullTriangle),16); 433 btHullTriangle* tr = new (mem)btHullTriangle(a,b,c); 434 434 tr->id = m_tris.size(); 435 435 m_tris.push_back(tr); … … 438 438 } 439 439 440 void HullLibrary::deAllocateTriangle( Tri* tri)440 void HullLibrary::deAllocateTriangle(btHullTriangle* tri) 441 441 { 442 442 btAssert(m_tris[tri->id]==tri); 443 443 m_tris[tri->id]=NULL; 444 tri->~ Tri();444 tri->~btHullTriangle(); 445 445 btAlignedFree(tri); 446 446 } 447 447 448 448 449 void HullLibrary::extrude( Tri*t0,int v)449 void HullLibrary::extrude(btHullTriangle *t0,int v) 450 450 { 451 451 int3 t= *t0; 452 452 int n = m_tris.size(); 453 Tri* ta = allocateTriangle(v,t[1],t[2]);453 btHullTriangle* ta = allocateTriangle(v,t[1],t[2]); 454 454 ta->n = int3(t0->n[0],n+1,n+2); 455 455 m_tris[t0->n[0]]->neib(t[1],t[2]) = n+0; 456 Tri* tb = allocateTriangle(v,t[2],t[0]);456 btHullTriangle* tb = allocateTriangle(v,t[2],t[0]); 457 457 tb->n = int3(t0->n[1],n+2,n+0); 458 458 m_tris[t0->n[1]]->neib(t[2],t[0]) = n+1; 459 Tri* tc = allocateTriangle(v,t[0],t[1]);459 btHullTriangle* tc = allocateTriangle(v,t[0],t[1]); 460 460 tc->n = int3(t0->n[2],n+0,n+1); 461 461 m_tris[t0->n[2]]->neib(t[0],t[1]) = n+2; … … 470 470 } 471 471 472 Tri* HullLibrary::extrudable(btScalar epsilon)472 btHullTriangle* HullLibrary::extrudable(btScalar epsilon) 473 473 { 474 474 int i; 475 Tri*t=NULL;475 btHullTriangle *t=NULL; 476 476 for(i=0;i<m_tris.size();i++) 477 477 { … … 551 551 552 552 btVector3 center = (verts[p[0]]+verts[p[1]]+verts[p[2]]+verts[p[3]]) / btScalar(4.0); // a valid interior point 553 Tri*t0 = allocateTriangle(p[2],p[3],p[1]); t0->n=int3(2,3,1);554 Tri*t1 = allocateTriangle(p[3],p[2],p[0]); t1->n=int3(3,2,0);555 Tri*t2 = allocateTriangle(p[0],p[1],p[3]); t2->n=int3(0,1,3);556 Tri*t3 = allocateTriangle(p[1],p[0],p[2]); t3->n=int3(1,0,2);553 btHullTriangle *t0 = allocateTriangle(p[2],p[3],p[1]); t0->n=int3(2,3,1); 554 btHullTriangle *t1 = allocateTriangle(p[3],p[2],p[0]); t1->n=int3(3,2,0); 555 btHullTriangle *t2 = allocateTriangle(p[0],p[1],p[3]); t2->n=int3(0,1,3); 556 btHullTriangle *t3 = allocateTriangle(p[1],p[0],p[2]); t3->n=int3(1,0,2); 557 557 isextreme[p[0]]=isextreme[p[1]]=isextreme[p[2]]=isextreme[p[3]]=1; 558 558 checkit(t0);checkit(t1);checkit(t2);checkit(t3); … … 560 560 for(j=0;j<m_tris.size();j++) 561 561 { 562 Tri*t=m_tris[j];562 btHullTriangle *t=m_tris[j]; 563 563 btAssert(t); 564 564 btAssert(t->vmax<0); … … 567 567 t->rise = dot(n,verts[t->vmax]-verts[(*t)[0]]); 568 568 } 569 Tri*te;569 btHullTriangle *te; 570 570 vlimit-=4; 571 571 while(vlimit >0 && ((te=extrudable(epsilon)) != 0)) … … 595 595 if(above(verts,nt,center,btScalar(0.01)*epsilon) || cross(verts[nt[1]]-verts[nt[0]],verts[nt[2]]-verts[nt[1]]).length()< epsilon*epsilon*btScalar(0.1) ) 596 596 { 597 Tri*nb = m_tris[m_tris[j]->n[0]];597 btHullTriangle *nb = m_tris[m_tris[j]->n[0]]; 598 598 btAssert(nb);btAssert(!hasvert(*nb,v));btAssert(nb->id<j); 599 599 extrude(nb,v); … … 604 604 while(j--) 605 605 { 606 Tri*t=m_tris[j];606 btHullTriangle *t=m_tris[j]; 607 607 if(!t) continue; 608 608 if(t->vmax>=0) break; -
code/branches/physics/src/bullet/LinearMath/btConvexHull.h
r2192 r2430 138 138 ConvexH() 139 139 { 140 int i;141 i=0;142 140 } 143 141 ~ConvexH() 144 142 { 145 int i;146 i=0;147 143 } 148 144 btAlignedObjectArray<btVector3> vertices; … … 189 185 { 190 186 191 btAlignedObjectArray<class Tri*> m_tris;187 btAlignedObjectArray<class btHullTriangle*> m_tris; 192 188 193 189 public: … … 204 200 bool ComputeHull(unsigned int vcount,const btVector3 *vertices,PHullResult &result,unsigned int vlimit); 205 201 206 class Tri* allocateTriangle(int a,int b,int c);207 void deAllocateTriangle( Tri*);208 void b2bfix( Tri* s,Tri*t);209 210 void removeb2b( Tri* s,Tri*t);211 212 void checkit( Tri*t);213 214 Tri* extrudable(btScalar epsilon);202 class btHullTriangle* allocateTriangle(int a,int b,int c); 203 void deAllocateTriangle(btHullTriangle*); 204 void b2bfix(btHullTriangle* s,btHullTriangle*t); 205 206 void removeb2b(btHullTriangle* s,btHullTriangle*t); 207 208 void checkit(btHullTriangle *t); 209 210 btHullTriangle* extrudable(btScalar epsilon); 215 211 216 212 int calchull(btVector3 *verts,int verts_count, TUIntArray& tris_out, int &tris_count,int vlimit); … … 222 218 class ConvexH* ConvexHCrop(ConvexH& convex,const btPlane& slice); 223 219 224 void extrude(class Tri* t0,int v);220 void extrude(class btHullTriangle* t0,int v); 225 221 226 222 ConvexH* test_cube(); -
code/branches/physics/src/bullet/LinearMath/btMatrix3x3.h
r2192 r2430 24 24 25 25 26 / //The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with btQuaternion, btTransform and btVector3.27 ///Make sure to only include a pure orthogonal matrix without scaling. 26 /**@brief The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with btQuaternion, btTransform and btVector3. 27 * Make sure to only include a pure orthogonal matrix without scaling. */ 28 28 class btMatrix3x3 { 29 29 public: 30 /** @brief No initializaion constructor */ 30 31 btMatrix3x3 () {} 31 32 32 33 // explicit btMatrix3x3(const btScalar *m) { setFromOpenGLSubMatrix(m); } 33 34 35 /**@brief Constructor from Quaternion */ 34 36 explicit btMatrix3x3(const btQuaternion& q) { setRotation(q); } 35 37 /* … … 40 42 } 41 43 */ 44 /** @brief Constructor with row major formatting */ 42 45 btMatrix3x3(const btScalar& xx, const btScalar& xy, const btScalar& xz, 43 46 const btScalar& yx, const btScalar& yy, const btScalar& yz, … … 48 51 zx, zy, zz); 49 52 } 50 53 /** @brief Copy constructor */ 51 54 SIMD_FORCE_INLINE btMatrix3x3 (const btMatrix3x3& other) 52 55 { … … 55 58 m_el[2] = other.m_el[2]; 56 59 } 57 60 /** @brief Assignment Operator */ 58 61 SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& other) 59 62 { … … 64 67 } 65 68 69 /** @brief Get a column of the matrix as a vector 70 * @param i Column number 0 indexed */ 66 71 SIMD_FORCE_INLINE btVector3 getColumn(int i) const 67 72 { … … 70 75 71 76 72 77 /** @brief Get a row of the matrix as a vector 78 * @param i Row number 0 indexed */ 73 79 SIMD_FORCE_INLINE const btVector3& getRow(int i) const 74 80 { 81 btFullAssert(0 <= i && i < 3); 75 82 return m_el[i]; 76 83 } 77 84 78 85 /** @brief Get a mutable reference to a row of the matrix as a vector 86 * @param i Row number 0 indexed */ 79 87 SIMD_FORCE_INLINE btVector3& operator[](int i) 80 88 { … … 83 91 } 84 92 93 /** @brief Get a const reference to a row of the matrix as a vector 94 * @param i Row number 0 indexed */ 85 95 SIMD_FORCE_INLINE const btVector3& operator[](int i) const 86 96 { … … 89 99 } 90 100 101 /** @brief Multiply by the target matrix on the right 102 * @param m Rotation matrix to be applied 103 * Equivilant to this = this * m */ 91 104 btMatrix3x3& operator*=(const btMatrix3x3& m); 92 105 93 106 /** @brief Set from a carray of btScalars 107 * @param m A pointer to the beginning of an array of 9 btScalars */ 94 108 void setFromOpenGLSubMatrix(const btScalar *m) 95 109 { … … 99 113 100 114 } 101 115 /** @brief Set the values of the matrix explicitly (row major) 116 * @param xx Top left 117 * @param xy Top Middle 118 * @param xz Top Right 119 * @param yx Middle Left 120 * @param yy Middle Middle 121 * @param yz Middle Right 122 * @param zx Bottom Left 123 * @param zy Bottom Middle 124 * @param zz Bottom Right*/ 102 125 void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz, 103 126 const btScalar& yx, const btScalar& yy, const btScalar& yz, … … 108 131 m_el[2].setValue(zx,zy,zz); 109 132 } 110 133 134 /** @brief Set the matrix from a quaternion 135 * @param q The Quaternion to match */ 111 136 void setRotation(const btQuaternion& q) 112 137 { … … 124 149 125 150 126 151 /** @brief Set the matrix from euler angles using YPR around YXZ respectively 152 * @param yaw Yaw about Y axis 153 * @param pitch Pitch about X axis 154 * @param roll Roll about Z axis 155 */ 127 156 void setEulerYPR(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) 128 157 { 129 130 btScalar cy(btCos(yaw)); 131 btScalar sy(btSin(yaw)); 132 btScalar cp(btCos(pitch)); 133 btScalar sp(btSin(pitch)); 134 btScalar cr(btCos(roll)); 135 btScalar sr(btSin(roll)); 136 btScalar cc = cy * cr; 137 btScalar cs = cy * sr; 138 btScalar sc = sy * cr; 139 btScalar ss = sy * sr; 140 setValue(cc - sp * ss, -cs - sp * sc, -sy * cp, 141 cp * sr, cp * cr, -sp, 142 sc + sp * cs, -ss + sp * cc, cy * cp); 143 144 } 145 146 /** 147 * setEulerZYX 148 * @param euler a const reference to a btVector3 of euler angles 158 setEulerZYX(roll, pitch, yaw); 159 } 160 161 /** @brief Set the matrix from euler angles YPR around ZYX axes 162 * @param eulerX Roll about X axis 163 * @param eulerY Pitch around Y axis 164 * @param eulerZ Yaw aboud Z axis 165 * 149 166 * These angles are used to produce a rotation matrix. The euler 150 167 * angles are applied in ZYX order. I.e a vector is first rotated 151 168 * about X then Y and then Z 152 169 **/ 153 154 void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) { 170 void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) { 171 ///@todo proposed to reverse this since it's labeled zyx but takes arguments xyz and it will match all other parts of the code 155 172 btScalar ci ( btCos(eulerX)); 156 173 btScalar cj ( btCos(eulerY)); … … 169 186 } 170 187 188 /**@brief Set the matrix to the identity */ 171 189 void setIdentity() 172 190 { … … 175 193 btScalar(0.0), btScalar(0.0), btScalar(1.0)); 176 194 } 177 195 /**@brief Fill the values of the matrix into a 9 element array 196 * @param m The array to be filled */ 178 197 void getOpenGLSubMatrix(btScalar *m) const 179 198 { … … 192 211 } 193 212 213 /**@brief Get the matrix represented as a quaternion 214 * @param q The quaternion which will be set */ 194 215 void getRotation(btQuaternion& q) const 195 216 { … … 225 246 q.setValue(temp[0],temp[1],temp[2],temp[3]); 226 247 } 227 228 void getEuler(btScalar& yaw, btScalar& pitch, btScalar& roll) const 248 249 /**@brief Get the matrix represented as euler angles around YXZ, roundtrip with setEulerYPR 250 * @param yaw Yaw around Y axis 251 * @param pitch Pitch around X axis 252 * @param roll around Z axis */ 253 void getEulerYPR(btScalar& yaw, btScalar& pitch, btScalar& roll) const 229 254 { 230 255 231 if (btScalar(m_el[1].z()) < btScalar(1)) 232 { 233 if (btScalar(m_el[1].z()) > -btScalar(1)) 234 { 235 yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x())); 236 pitch = btScalar(btAsin(-m_el[1].y())); 237 roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z())); 238 } 239 else 240 { 241 yaw = btScalar(-btAtan2(-m_el[0].y(), m_el[0].z())); 242 pitch = SIMD_HALF_PI; 243 roll = btScalar(0.0); 244 } 245 } 246 else 247 { 248 yaw = btScalar(btAtan2(-m_el[0].y(), m_el[0].z())); 249 pitch = -SIMD_HALF_PI; 250 roll = btScalar(0.0); 251 } 252 } 253 254 255 256 // first use the normal calculus 257 yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x())); 258 pitch = btScalar(btAsin(-m_el[2].x())); 259 roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z())); 260 261 // on pitch = +/-HalfPI 262 if (btFabs(pitch)==SIMD_HALF_PI) 263 { 264 if (yaw>0) 265 yaw-=SIMD_PI; 266 else 267 yaw+=SIMD_PI; 268 269 if (roll>0) 270 roll-=SIMD_PI; 271 else 272 roll+=SIMD_PI; 273 } 274 }; 275 276 277 /**@brief Get the matrix represented as euler angles around ZYX 278 * @param yaw Yaw around X axis 279 * @param pitch Pitch around Y axis 280 * @param roll around X axis 281 * @param solution_number Which solution of two possible solutions ( 1 or 2) are possible values*/ 282 void getEulerZYX(btScalar& yaw, btScalar& pitch, btScalar& roll, unsigned int solution_number = 1) const 283 { 284 struct Euler{btScalar yaw, pitch, roll;}; 285 Euler euler_out; 286 Euler euler_out2; //second solution 287 //get the pointer to the raw data 288 289 // Check that pitch is not at a singularity 290 if (btFabs(m_el[2].x()) >= 1) 291 { 292 euler_out.yaw = 0; 293 euler_out2.yaw = 0; 294 295 // From difference of angles formula 296 btScalar delta = btAtan2(m_el[0].x(),m_el[0].z()); 297 if (m_el[2].x() > 0) //gimbal locked up 298 { 299 euler_out.pitch = SIMD_PI / btScalar(2.0); 300 euler_out2.pitch = SIMD_PI / btScalar(2.0); 301 euler_out.roll = euler_out.pitch + delta; 302 euler_out2.roll = euler_out.pitch + delta; 303 } 304 else // gimbal locked down 305 { 306 euler_out.pitch = -SIMD_PI / btScalar(2.0); 307 euler_out2.pitch = -SIMD_PI / btScalar(2.0); 308 euler_out.roll = -euler_out.pitch + delta; 309 euler_out2.roll = -euler_out.pitch + delta; 310 } 311 } 312 else 313 { 314 euler_out.pitch = - btAsin(m_el[2].x()); 315 euler_out2.pitch = SIMD_PI - euler_out.pitch; 316 317 euler_out.roll = btAtan2(m_el[2].y()/btCos(euler_out.pitch), 318 m_el[2].z()/btCos(euler_out.pitch)); 319 euler_out2.roll = btAtan2(m_el[2].y()/btCos(euler_out2.pitch), 320 m_el[2].z()/btCos(euler_out2.pitch)); 321 322 euler_out.yaw = btAtan2(m_el[1].x()/btCos(euler_out.pitch), 323 m_el[0].x()/btCos(euler_out.pitch)); 324 euler_out2.yaw = btAtan2(m_el[1].x()/btCos(euler_out2.pitch), 325 m_el[0].x()/btCos(euler_out2.pitch)); 326 } 327 328 if (solution_number == 1) 329 { 330 yaw = euler_out.yaw; 331 pitch = euler_out.pitch; 332 roll = euler_out.roll; 333 } 334 else 335 { 336 yaw = euler_out2.yaw; 337 pitch = euler_out2.pitch; 338 roll = euler_out2.roll; 339 } 340 } 341 342 /**@brief Create a scaled copy of the matrix 343 * @param s Scaling vector The elements of the vector will scale each column */ 256 344 257 345 btMatrix3x3 scaled(const btVector3& s) const … … 262 350 } 263 351 352 /**@brief Return the determinant of the matrix */ 264 353 btScalar determinant() const; 354 /**@brief Return the adjoint of the matrix */ 265 355 btMatrix3x3 adjoint() const; 356 /**@brief Return the matrix with all values non negative */ 266 357 btMatrix3x3 absolute() const; 358 /**@brief Return the transpose of the matrix */ 267 359 btMatrix3x3 transpose() const; 360 /**@brief Return the inverse of the matrix */ 268 361 btMatrix3x3 inverse() const; 269 362 … … 285 378 286 379 287 ///diagonalizes this matrix by the Jacobi method. rot stores the rotation 288 ///from the coordinate system in which the matrix is diagonal to the original 289 ///coordinate system, i.e., old_this = rot * new_this * rot^T. The iteration 290 ///stops when all off-diagonal elements are less than the threshold multiplied 291 ///by the sum of the absolute values of the diagonal, or when maxSteps have 292 ///been executed. Note that this matrix is assumed to be symmetric. 380 /**@brief diagonalizes this matrix by the Jacobi method. 381 * @param rot stores the rotation from the coordinate system in which the matrix is diagonal to the original 382 * coordinate system, i.e., old_this = rot * new_this * rot^T. 383 * @param threshold See iteration 384 * @param iteration The iteration stops when all off-diagonal elements are less than the threshold multiplied 385 * by the sum of the absolute values of the diagonal, or when maxSteps have been executed. 386 * 387 * Note that this matrix is assumed to be symmetric. 388 */ 293 389 void diagonalize(btMatrix3x3& rot, btScalar threshold, int maxSteps) 294 390 { … … 372 468 373 469 protected: 470 /**@brief Calculate the matrix cofactor 471 * @param r1 The first row to use for calculating the cofactor 472 * @param c1 The first column to use for calculating the cofactor 473 * @param r1 The second row to use for calculating the cofactor 474 * @param c1 The second column to use for calculating the cofactor 475 * See http://en.wikipedia.org/wiki/Cofactor_(linear_algebra) for more details 476 */ 374 477 btScalar cofac(int r1, int c1, int r2, int c2) const 375 478 { 376 479 return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1]; 377 480 } 378 481 ///Data storage for the matrix, each vector is a row of the matrix 379 482 btVector3 m_el[3]; 380 483 }; … … 495 598 */ 496 599 600 /**@brief Equality operator between two matrices 601 * It will test all elements are equal. */ 497 602 SIMD_FORCE_INLINE bool operator==(const btMatrix3x3& m1, const btMatrix3x3& m2) 498 603 { -
code/branches/physics/src/bullet/LinearMath/btQuadWord.h
r2192 r2430 19 19 #include "btScalar.h" 20 20 #include "btMinMax.h" 21 #include <math.h>22 21 23 22 23 #if defined (__CELLOS_LV2) && defined (__SPU__) 24 #include <altivec.h> 25 #endif 24 26 25 ///The btQuadWordStorage class is base class for btVector3 and btQuaternion. 26 ///Some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword. todo: look into this 27 ///ATTRIBUTE_ALIGNED16(class) btQuadWordStorage 27 /**@brief The btQuadWordStorage class is base class for btVector3 and btQuaternion. 28 * Some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword. 29 */ 30 #ifndef USE_LIBSPE2 31 ATTRIBUTE_ALIGNED16(class) btQuadWordStorage 32 #else 28 33 class btQuadWordStorage 34 #endif 29 35 { 30 36 protected: 31 37 32 btScalar m_x; 33 btScalar m_y;34 btScalar m_z;35 btScalar m_unusedW;36 38 #if defined (__SPU__) && defined (__CELLOS_LV2__) 39 union { 40 vec_float4 mVec128; 41 btScalar m_floats[4]; 42 }; 37 43 public: 44 vec_float4 get128() const 45 { 46 return mVec128; 47 } 48 #else //__CELLOS_LV2__ __SPU__ 49 btScalar m_floats[4]; 50 #endif //__CELLOS_LV2__ __SPU__ 38 51 39 52 }; 40 53 41 42 ///btQuadWord is base-class for vectors, points 54 /** @brief The btQuadWord is base-class for vectors, points */ 43 55 class btQuadWord : public btQuadWordStorage 44 56 { 45 57 public: 46 47 // SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_x)[i]; } 48 // SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_x)[i]; } 58 49 59 50 SIMD_FORCE_INLINE const btScalar& getX() const { return m_x; } 60 /**@brief Return the x value */ 61 SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; } 62 /**@brief Return the y value */ 63 SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; } 64 /**@brief Return the z value */ 65 SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; } 66 /**@brief Set the x value */ 67 SIMD_FORCE_INLINE void setX(btScalar x) { m_floats[0] = x;}; 68 /**@brief Set the y value */ 69 SIMD_FORCE_INLINE void setY(btScalar y) { m_floats[1] = y;}; 70 /**@brief Set the z value */ 71 SIMD_FORCE_INLINE void setZ(btScalar z) { m_floats[2] = z;}; 72 /**@brief Set the w value */ 73 SIMD_FORCE_INLINE void setW(btScalar w) { m_floats[3] = w;}; 74 /**@brief Return the x value */ 75 SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; } 76 /**@brief Return the y value */ 77 SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; } 78 /**@brief Return the z value */ 79 SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; } 80 /**@brief Return the w value */ 81 SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; } 51 82 52 SIMD_FORCE_INLINE const btScalar& getY() const { return m_y; } 83 //SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; } 84 //SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; } 85 ///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons. 86 SIMD_FORCE_INLINE operator btScalar *() { return &m_floats[0]; } 87 SIMD_FORCE_INLINE operator const btScalar *() const { return &m_floats[0]; } 53 88 54 SIMD_FORCE_INLINE const btScalar& getZ() const { return m_z; } 89 SIMD_FORCE_INLINE bool operator==(const btQuadWord& other) const 90 { 91 return ((m_floats[3]==other.m_floats[3]) && (m_floats[2]==other.m_floats[2]) && (m_floats[1]==other.m_floats[1]) && (m_floats[0]==other.m_floats[0])); 92 } 55 93 56 SIMD_FORCE_INLINE void setX(btScalar x) { m_x = x;}; 94 SIMD_FORCE_INLINE bool operator!=(const btQuadWord& other) const 95 { 96 return !(*this == other); 97 } 57 98 58 SIMD_FORCE_INLINE void setY(btScalar y) { m_y = y;}; 59 60 SIMD_FORCE_INLINE void setZ(btScalar z) { m_z = z;}; 61 62 SIMD_FORCE_INLINE void setW(btScalar w) { m_unusedW = w;}; 63 64 SIMD_FORCE_INLINE const btScalar& x() const { return m_x; } 65 66 SIMD_FORCE_INLINE const btScalar& y() const { return m_y; } 67 68 SIMD_FORCE_INLINE const btScalar& z() const { return m_z; } 69 70 SIMD_FORCE_INLINE const btScalar& w() const { return m_unusedW; } 71 72 73 SIMD_FORCE_INLINE operator btScalar *() { return &m_x; } 74 SIMD_FORCE_INLINE operator const btScalar *() const { return &m_x; } 75 76 77 99 /**@brief Set x,y,z and zero w 100 * @param x Value of x 101 * @param y Value of y 102 * @param z Value of z 103 */ 78 104 SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z) 79 105 { 80 m_ x=x;81 m_ y=y;82 m_ z=z;83 m_ unusedW= 0.f;106 m_floats[0]=x; 107 m_floats[1]=y; 108 m_floats[2]=z; 109 m_floats[3] = 0.f; 84 110 } 85 111 86 112 /* void getValue(btScalar *m) const 87 113 { 88 m[0] = m_ x;89 m[1] = m_ y;90 m[2] = m_ z;114 m[0] = m_floats[0]; 115 m[1] = m_floats[1]; 116 m[2] = m_floats[2]; 91 117 } 92 118 */ 119 /**@brief Set the values 120 * @param x Value of x 121 * @param y Value of y 122 * @param z Value of z 123 * @param w Value of w 124 */ 93 125 SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) 94 126 { 95 m_ x=x;96 m_ y=y;97 m_ z=z;98 m_ unusedW=w;127 m_floats[0]=x; 128 m_floats[1]=y; 129 m_floats[2]=z; 130 m_floats[3]=w; 99 131 } 100 132 /**@brief No initialization constructor */ 101 133 SIMD_FORCE_INLINE btQuadWord() 102 // :m_ x(btScalar(0.)),m_y(btScalar(0.)),m_z(btScalar(0.)),m_unusedW(btScalar(0.))134 // :m_floats[0](btScalar(0.)),m_floats[1](btScalar(0.)),m_floats[2](btScalar(0.)),m_floats[3](btScalar(0.)) 103 135 { 104 136 } 105 137 /**@brief Copy constructor */ 106 138 SIMD_FORCE_INLINE btQuadWord(const btQuadWordStorage& q) 107 139 { 108 140 *((btQuadWordStorage*)this) = q; 109 141 } 110 142 /**@brief Three argument constructor (zeros w) 143 * @param x Value of x 144 * @param y Value of y 145 * @param z Value of z 146 */ 111 147 SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z) 112 148 { 113 m_ x = x, m_y = y, m_z = z, m_unusedW= 0.0f;149 m_floats[0] = x, m_floats[1] = y, m_floats[2] = z, m_floats[3] = 0.0f; 114 150 } 115 151 152 /**@brief Initializing constructor 153 * @param x Value of x 154 * @param y Value of y 155 * @param z Value of z 156 * @param w Value of w 157 */ 116 158 SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) 117 159 { 118 m_ x = x, m_y = y, m_z = z, m_unusedW= w;160 m_floats[0] = x, m_floats[1] = y, m_floats[2] = z, m_floats[3] = w; 119 161 } 120 162 121 163 /**@brief Set each element to the max of the current values and the values of another btQuadWord 164 * @param other The other btQuadWord to compare with 165 */ 122 166 SIMD_FORCE_INLINE void setMax(const btQuadWord& other) 123 167 { 124 btSetMax(m_ x, other.m_x);125 btSetMax(m_ y, other.m_y);126 btSetMax(m_ z, other.m_z);127 btSetMax(m_ unusedW, other.m_unusedW);168 btSetMax(m_floats[0], other.m_floats[0]); 169 btSetMax(m_floats[1], other.m_floats[1]); 170 btSetMax(m_floats[2], other.m_floats[2]); 171 btSetMax(m_floats[3], other.m_floats[3]); 128 172 } 129 173 /**@brief Set each element to the min of the current values and the values of another btQuadWord 174 * @param other The other btQuadWord to compare with 175 */ 130 176 SIMD_FORCE_INLINE void setMin(const btQuadWord& other) 131 177 { 132 btSetMin(m_ x, other.m_x);133 btSetMin(m_ y, other.m_y);134 btSetMin(m_ z, other.m_z);135 btSetMin(m_ unusedW, other.m_unusedW);178 btSetMin(m_floats[0], other.m_floats[0]); 179 btSetMin(m_floats[1], other.m_floats[1]); 180 btSetMin(m_floats[2], other.m_floats[2]); 181 btSetMin(m_floats[3], other.m_floats[3]); 136 182 } 137 183 -
code/branches/physics/src/bullet/LinearMath/btQuaternion.h
r2192 r2430 18 18 #define SIMD__QUATERNION_H_ 19 19 20 20 21 #include "btVector3.h" 21 22 22 / //The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatrix3x3, btVector3 and btTransform.23 /**@brief The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatrix3x3, btVector3 and btTransform. */ 23 24 class btQuaternion : public btQuadWord { 24 25 public: 26 /**@brief No initialization constructor */ 25 27 btQuaternion() {} 26 28 27 29 // template <typename btScalar> 28 30 // explicit Quaternion(const btScalar *v) : Tuple4<btScalar>(v) {} 29 31 /**@brief Constructor from scalars */ 30 32 btQuaternion(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w) 31 33 : btQuadWord(x, y, z, w) 32 34 {} 33 35 /**@brief Axis angle Constructor 36 * @param axis The axis which the rotation is around 37 * @param angle The magnitude of the rotation around the angle (Radians) */ 34 38 btQuaternion(const btVector3& axis, const btScalar& angle) 35 39 { 36 40 setRotation(axis, angle); 37 41 } 38 42 /**@brief Constructor from Euler angles 43 * @param yaw Angle around Y unless BT_EULER_DEFAULT_ZYX defined then Z 44 * @param pitch Angle around X unless BT_EULER_DEFAULT_ZYX defined then Y 45 * @param roll Angle around Z unless BT_EULER_DEFAULT_ZYX defined then X */ 39 46 btQuaternion(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) 40 47 { 48 #ifndef BT_EULER_DEFAULT_ZYX 41 49 setEuler(yaw, pitch, roll); 42 } 43 50 #else 51 setEulerZYX(yaw, pitch, roll); 52 #endif 53 } 54 /**@brief Set the rotation using axis angle notation 55 * @param axis The axis around which to rotate 56 * @param angle The magnitude of the rotation in Radians */ 44 57 void setRotation(const btVector3& axis, const btScalar& angle) 45 58 { … … 50 63 btCos(angle * btScalar(0.5))); 51 64 } 52 65 /**@brief Set the quaternion using Euler angles 66 * @param yaw Angle around Y 67 * @param pitch Angle around X 68 * @param roll Angle around Z */ 53 69 void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) 54 70 { … … 67 83 cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); 68 84 } 69 70 btQuaternion& operator+=(const btQuaternion& q) 71 { 72 m_x += q.x(); m_y += q.y(); m_z += q.z(); m_unusedW += q.m_unusedW; 85 /**@brief Set the quaternion using euler angles 86 * @param yaw Angle around Z 87 * @param pitch Angle around Y 88 * @param roll Angle around X */ 89 void setEulerZYX(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) 90 { 91 btScalar halfYaw = btScalar(yaw) * btScalar(0.5); 92 btScalar halfPitch = btScalar(pitch) * btScalar(0.5); 93 btScalar halfRoll = btScalar(roll) * btScalar(0.5); 94 btScalar cosYaw = btCos(halfYaw); 95 btScalar sinYaw = btSin(halfYaw); 96 btScalar cosPitch = btCos(halfPitch); 97 btScalar sinPitch = btSin(halfPitch); 98 btScalar cosRoll = btCos(halfRoll); 99 btScalar sinRoll = btSin(halfRoll); 100 setValue(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, //x 101 cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, //y 102 cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, //z 103 cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); //formerly yzx 104 } 105 /**@brief Add two quaternions 106 * @param q The quaternion to add to this one */ 107 SIMD_FORCE_INLINE btQuaternion& operator+=(const btQuaternion& q) 108 { 109 m_floats[0] += q.x(); m_floats[1] += q.y(); m_floats[2] += q.z(); m_floats[3] += q.m_floats[3]; 73 110 return *this; 74 111 } 75 112 113 /**@brief Subtract out a quaternion 114 * @param q The quaternion to subtract from this one */ 76 115 btQuaternion& operator-=(const btQuaternion& q) 77 116 { 78 m_ x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_unusedW -= q.m_unusedW;117 m_floats[0] -= q.x(); m_floats[1] -= q.y(); m_floats[2] -= q.z(); m_floats[3] -= q.m_floats[3]; 79 118 return *this; 80 119 } 81 120 121 /**@brief Scale this quaternion 122 * @param s The scalar to scale by */ 82 123 btQuaternion& operator*=(const btScalar& s) 83 124 { 84 m_ x *= s; m_y *= s; m_z *= s; m_unusedW*= s;125 m_floats[0] *= s; m_floats[1] *= s; m_floats[2] *= s; m_floats[3] *= s; 85 126 return *this; 86 127 } 87 128 88 129 /**@brief Multiply this quaternion by q on the right 130 * @param q The other quaternion 131 * Equivilant to this = this * q */ 89 132 btQuaternion& operator*=(const btQuaternion& q) 90 133 { 91 setValue(m_ unusedW * q.x() + m_x * q.m_unusedW + m_y * q.z() - m_z* q.y(),92 m_ unusedW * q.y() + m_y * q.m_unusedW + m_z * q.x() - m_x* q.z(),93 m_ unusedW * q.z() + m_z * q.m_unusedW + m_x * q.y() - m_y* q.x(),94 m_ unusedW * q.m_unusedW - m_x * q.x() - m_y * q.y() - m_z* q.z());134 setValue(m_floats[3] * q.x() + m_floats[0] * q.m_floats[3] + m_floats[1] * q.z() - m_floats[2] * q.y(), 135 m_floats[3] * q.y() + m_floats[1] * q.m_floats[3] + m_floats[2] * q.x() - m_floats[0] * q.z(), 136 m_floats[3] * q.z() + m_floats[2] * q.m_floats[3] + m_floats[0] * q.y() - m_floats[1] * q.x(), 137 m_floats[3] * q.m_floats[3] - m_floats[0] * q.x() - m_floats[1] * q.y() - m_floats[2] * q.z()); 95 138 return *this; 96 139 } 97 140 /**@brief Return the dot product between this quaternion and another 141 * @param q The other quaternion */ 98 142 btScalar dot(const btQuaternion& q) const 99 143 { 100 return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_unusedW * q.m_unusedW; 101 } 102 144 return m_floats[0] * q.x() + m_floats[1] * q.y() + m_floats[2] * q.z() + m_floats[3] * q.m_floats[3]; 145 } 146 147 /**@brief Return the length squared of the quaternion */ 103 148 btScalar length2() const 104 149 { … … 106 151 } 107 152 153 /**@brief Return the length of the quaternion */ 108 154 btScalar length() const 109 155 { … … 111 157 } 112 158 159 /**@brief Normalize the quaternion 160 * Such that x^2 + y^2 + z^2 +w^2 = 1 */ 113 161 btQuaternion& normalize() 114 162 { … … 116 164 } 117 165 166 /**@brief Return a scaled version of this quaternion 167 * @param s The scale factor */ 118 168 SIMD_FORCE_INLINE btQuaternion 119 169 operator*(const btScalar& s) const 120 170 { 121 return btQuaternion(x() * s, y() * s, z() * s, m_unusedW * s); 122 } 123 124 125 171 return btQuaternion(x() * s, y() * s, z() * s, m_floats[3] * s); 172 } 173 174 175 /**@brief Return an inversely scaled versionof this quaternion 176 * @param s The inverse scale factor */ 126 177 btQuaternion operator/(const btScalar& s) const 127 178 { … … 130 181 } 131 182 132 183 /**@brief Inversely scale this quaternion 184 * @param s The scale factor */ 133 185 btQuaternion& operator/=(const btScalar& s) 134 186 { … … 137 189 } 138 190 139 191 /**@brief Return a normalized version of this quaternion */ 140 192 btQuaternion normalized() const 141 193 { 142 194 return *this / length(); 143 195 } 144 196 /**@brief Return the angle between this quaternion and the other 197 * @param q The other quaternion */ 145 198 btScalar angle(const btQuaternion& q) const 146 199 { … … 149 202 return btAcos(dot(q) / s); 150 203 } 151 204 /**@brief Return the angle of rotation represented by this quaternion */ 152 205 btScalar getAngle() const 153 206 { 154 btScalar s = btScalar(2.) * btAcos(m_ unusedW);207 btScalar s = btScalar(2.) * btAcos(m_floats[3]); 155 208 return s; 156 209 } 157 210 158 211 159 212 /**@brief Return the inverse of this quaternion */ 160 213 btQuaternion inverse() const 161 214 { 162 return btQuaternion(-m_x, -m_y, -m_z, m_unusedW); 163 } 164 215 return btQuaternion(-m_floats[0], -m_floats[1], -m_floats[2], m_floats[3]); 216 } 217 218 /**@brief Return the sum of this quaternion and the other 219 * @param q2 The other quaternion */ 165 220 SIMD_FORCE_INLINE btQuaternion 166 221 operator+(const btQuaternion& q2) const 167 222 { 168 223 const btQuaternion& q1 = *this; 169 return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_unusedW + q2.m_unusedW); 170 } 171 224 return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_floats[3] + q2.m_floats[3]); 225 } 226 227 /**@brief Return the difference between this quaternion and the other 228 * @param q2 The other quaternion */ 172 229 SIMD_FORCE_INLINE btQuaternion 173 230 operator-(const btQuaternion& q2) const 174 231 { 175 232 const btQuaternion& q1 = *this; 176 return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_unusedW - q2.m_unusedW); 177 } 178 233 return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_floats[3] - q2.m_floats[3]); 234 } 235 236 /**@brief Return the negative of this quaternion 237 * This simply negates each element */ 179 238 SIMD_FORCE_INLINE btQuaternion operator-() const 180 239 { 181 240 const btQuaternion& q2 = *this; 182 return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_ unusedW);183 } 184 241 return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_floats[3]); 242 } 243 /**@todo document this and it's use */ 185 244 SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const 186 245 { … … 193 252 } 194 253 254 /**@brief Return the quaternion which is the result of Spherical Linear Interpolation between this and the other quaternion 255 * @param q The other quaternion to interpolate with 256 * @param t The ratio between this and q to interpolate. If t = 0 the result is this, if t=1 the result is q. 257 * Slerp interpolates assuming constant velocity. */ 195 258 btQuaternion slerp(const btQuaternion& q, const btScalar& t) const 196 259 { … … 201 264 btScalar s0 = btSin((btScalar(1.0) - t) * theta); 202 265 btScalar s1 = btSin(t * theta); 203 return btQuaternion((m_ x* s0 + q.x() * s1) * d,204 (m_ y* s0 + q.y() * s1) * d,205 (m_ z* s0 + q.z() * s1) * d,206 (m_ unusedW * s0 + q.m_unusedW* s1) * d);266 return btQuaternion((m_floats[0] * s0 + q.x() * s1) * d, 267 (m_floats[1] * s0 + q.y() * s1) * d, 268 (m_floats[2] * s0 + q.z() * s1) * d, 269 (m_floats[3] * s0 + q.m_floats[3] * s1) * d); 207 270 } 208 271 else … … 212 275 } 213 276 214 SIMD_FORCE_INLINE const btScalar& getW() const { return m_ unusedW; }277 SIMD_FORCE_INLINE const btScalar& getW() const { return m_floats[3]; } 215 278 216 279 … … 218 281 219 282 220 283 /**@brief Return the negative of a quaternion */ 221 284 SIMD_FORCE_INLINE btQuaternion 222 285 operator-(const btQuaternion& q) … … 227 290 228 291 229 292 /**@brief Return the product of two quaternions */ 230 293 SIMD_FORCE_INLINE btQuaternion 231 294 operator*(const btQuaternion& q1, const btQuaternion& q2) { … … 254 317 } 255 318 319 /**@brief Calculate the dot product between two quaternions */ 256 320 SIMD_FORCE_INLINE btScalar 257 321 dot(const btQuaternion& q1, const btQuaternion& q2) … … 261 325 262 326 327 /**@brief Return the length of a quaternion */ 263 328 SIMD_FORCE_INLINE btScalar 264 329 length(const btQuaternion& q) … … 267 332 } 268 333 334 /**@brief Return the angle between two quaternions*/ 269 335 SIMD_FORCE_INLINE btScalar 270 336 angle(const btQuaternion& q1, const btQuaternion& q2) … … 273 339 } 274 340 275 341 /**@brief Return the inverse of a quaternion*/ 276 342 SIMD_FORCE_INLINE btQuaternion 277 343 inverse(const btQuaternion& q) … … 280 346 } 281 347 348 /**@brief Return the result of spherical linear interpolation betwen two quaternions 349 * @param q1 The first quaternion 350 * @param q2 The second quaternion 351 * @param t The ration between q1 and q2. t = 0 return q1, t=1 returns q2 352 * Slerp assumes constant velocity between positions. */ 282 353 SIMD_FORCE_INLINE btQuaternion 283 354 slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t) -
code/branches/physics/src/bullet/LinearMath/btQuickprof.cpp
r2192 r2430 111 111 TotalCalls = 0; 112 112 TotalTime = 0.0f; 113 gProfileClock.reset();113 114 114 115 115 if ( Child ) { … … 252 252 void CProfileManager::Reset( void ) 253 253 { 254 gProfileClock.reset(); 254 255 Root.Reset(); 255 256 Root.Call(); … … 279 280 } 280 281 282 #include <stdio.h> 283 284 void CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spacing) 285 { 286 profileIterator->First(); 287 if (profileIterator->Is_Done()) 288 return; 289 290 float accumulated_time=0,parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time(); 291 int i; 292 int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset(); 293 for (i=0;i<spacing;i++) printf("."); 294 printf("----------------------------------\n"); 295 for (i=0;i<spacing;i++) printf("."); 296 printf("Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time ); 297 float totalTime = 0.f; 298 299 300 int numChildren = 0; 301 302 for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next()) 303 { 304 numChildren++; 305 float current_total_time = profileIterator->Get_Current_Total_Time(); 306 accumulated_time += current_total_time; 307 float fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f; 308 { 309 int i; for (i=0;i<spacing;i++) printf("."); 310 } 311 printf("%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)\n",i, profileIterator->Get_Current_Name(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls()); 312 totalTime += current_total_time; 313 //recurse into children 314 } 315 316 if (parent_time < accumulated_time) 317 { 318 printf("what's wrong\n"); 319 } 320 for (i=0;i<spacing;i++) printf("."); 321 printf("%s (%.3f %%) :: %.3f ms\n", "Unaccounted:",parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); 322 323 for (i=0;i<numChildren;i++) 324 { 325 profileIterator->Enter_Child(i); 326 dumpRecursive(profileIterator,spacing+3); 327 profileIterator->Enter_Parent(); 328 } 329 } 330 331 332 333 void CProfileManager::dumpAll() 334 { 335 CProfileIterator* profileIterator = 0; 336 profileIterator = CProfileManager::Get_Iterator(); 337 338 dumpRecursive(profileIterator,0); 339 340 CProfileManager::Release_Iterator(profileIterator); 341 } 342 343 344 281 345 #endif //USE_BT_CLOCK 282 346 -
code/branches/physics/src/bullet/LinearMath/btQuickprof.h
r2192 r2430 11 11 // Ogre (www.ogre3d.org). 12 12 13 14 13 15 #ifndef QUICK_PROF_H 14 16 #define QUICK_PROF_H 17 18 //To disable built-in profiling, please comment out next line 19 //#define BT_NO_PROFILE 1 20 #ifndef BT_NO_PROFILE 15 21 16 22 #include "btScalar.h" 17 23 #include "LinearMath/btAlignedAllocator.h" 18 24 #include <new> 19 //To disable built-in profiling, please comment out next line 20 //#define BT_NO_PROFILE 1 25 26 21 27 22 28 … … 322 328 static void Release_Iterator( CProfileIterator * iterator ) { delete ( iterator); } 323 329 330 static void dumpRecursive(CProfileIterator* profileIterator, int spacing); 331 332 static void dumpAll(); 333 324 334 private: 325 335 static CProfileNode Root; … … 345 355 }; 346 356 347 #if !defined(BT_NO_PROFILE) 357 348 358 #define BT_PROFILE( name ) CProfileSample __profile( name ) 349 #else 359 360 #else 361 350 362 #define BT_PROFILE( name ) 351 #endif 352 363 364 #endif //#ifndef BT_NO_PROFILE 353 365 354 366 -
code/branches/physics/src/bullet/LinearMath/btScalar.h
r2192 r2430 19 19 20 20 #include <math.h> 21 21 22 #include <stdlib.h>//size_t for MSVC 6.0 22 23 … … 25 26 #include <float.h> 26 27 27 #define BT_BULLET_VERSION 27 228 #define BT_BULLET_VERSION 273 28 29 29 30 inline int btGetVersion() … … 66 67 67 68 #include <assert.h> 68 #if defined(DEBUG) || defined (_DEBUG)69 #ifdef BT_DEBUG 69 70 #define btAssert assert 70 71 #else … … 86 87 #include <assert.h> 87 88 #endif 89 #ifdef BT_DEBUG 88 90 #define btAssert assert 91 #else 92 #define btAssert(x) 93 #endif 89 94 //btFullAssert is optional, slows down a lot 90 95 #define btFullAssert(x) … … 103 108 #include <assert.h> 104 109 #endif 110 #ifdef BT_DEBUG 105 111 #define btAssert assert 112 #else 113 #define btAssert(x) 114 #endif 106 115 //btFullAssert is optional, slows down a lot 107 116 #define btFullAssert(x) -
code/branches/physics/src/bullet/LinearMath/btStackAlloc.h
r2192 r2430 24 24 #include "btAlignedAllocator.h" 25 25 26 ///The btBlock class is an internal structure for the btStackAlloc memory allocator. 26 27 struct btBlock 27 28 { -
code/branches/physics/src/bullet/LinearMath/btTransform.h
r2192 r2430 22 22 23 23 24 / //The btTransform class supports rigid transforms with only translation and rotation and no scaling/shear.25 ///It can be used in combination with btVector3, btQuaternion and btMatrix3x3 linear algebra classes. 24 /**@brief The btTransform class supports rigid transforms with only translation and rotation and no scaling/shear. 25 *It can be used in combination with btVector3, btQuaternion and btMatrix3x3 linear algebra classes. */ 26 26 class btTransform { 27 27 … … 29 29 public: 30 30 31 31 /**@brief No initialization constructor */ 32 32 btTransform() {} 33 33 /**@brief Constructor from btQuaternion (optional btVector3 ) 34 * @param q Rotation from quaternion 35 * @param c Translation from Vector (default 0,0,0) */ 34 36 explicit SIMD_FORCE_INLINE btTransform(const btQuaternion& q, 35 37 const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0))) … … 38 40 {} 39 41 42 /**@brief Constructor from btMatrix3x3 (optional btVector3) 43 * @param b Rotation from Matrix 44 * @param c Translation from Vector default (0,0,0)*/ 40 45 explicit SIMD_FORCE_INLINE btTransform(const btMatrix3x3& b, 41 46 const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0))) … … 43 48 m_origin(c) 44 49 {} 45 50 /**@brief Copy constructor */ 46 51 SIMD_FORCE_INLINE btTransform (const btTransform& other) 47 52 : m_basis(other.m_basis), … … 49 54 { 50 55 } 51 56 /**@brief Assignment Operator */ 52 57 SIMD_FORCE_INLINE btTransform& operator=(const btTransform& other) 53 58 { … … 58 63 59 64 65 /**@brief Set the current transform as the value of the product of two transforms 66 * @param t1 Transform 1 67 * @param t2 Transform 2 68 * This = Transform1 * Transform2 */ 60 69 SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2) { 61 70 m_basis = t1.m_basis * t2.m_basis; … … 70 79 */ 71 80 72 81 /**@brief Return the transform of the vector */ 73 82 SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const 74 83 { … … 78 87 } 79 88 89 /**@brief Return the transform of the vector */ 80 90 SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const 81 91 { … … 83 93 } 84 94 95 /**@brief Return the transform of the btQuaternion */ 96 SIMD_FORCE_INLINE btQuaternion operator*(const btQuaternion& q) const 97 { 98 return getRotation() * q; 99 } 100 101 /**@brief Return the basis matrix for the rotation */ 85 102 SIMD_FORCE_INLINE btMatrix3x3& getBasis() { return m_basis; } 103 /**@brief Return the basis matrix for the rotation */ 86 104 SIMD_FORCE_INLINE const btMatrix3x3& getBasis() const { return m_basis; } 87 105 106 /**@brief Return the origin vector translation */ 88 107 SIMD_FORCE_INLINE btVector3& getOrigin() { return m_origin; } 108 /**@brief Return the origin vector translation */ 89 109 SIMD_FORCE_INLINE const btVector3& getOrigin() const { return m_origin; } 90 110 111 /**@brief Return a quaternion representing the rotation */ 91 112 btQuaternion getRotation() const { 92 113 btQuaternion q; … … 96 117 97 118 119 /**@brief Set from an array 120 * @param m A pointer to a 15 element array (12 rotation(row major padded on the right by 1), and 3 translation */ 98 121 void setFromOpenGLMatrix(const btScalar *m) 99 122 { … … 102 125 } 103 126 127 /**@brief Fill an array representation 128 * @param m A pointer to a 15 element array (12 rotation(row major padded on the right by 1), and 3 translation */ 104 129 void getOpenGLMatrix(btScalar *m) const 105 130 { … … 111 136 } 112 137 138 /**@brief Set the translational element 139 * @param origin The vector to set the translation to */ 113 140 SIMD_FORCE_INLINE void setOrigin(const btVector3& origin) 114 141 { … … 119 146 120 147 121 148 /**@brief Set the rotational element by btMatrix3x3 */ 122 149 SIMD_FORCE_INLINE void setBasis(const btMatrix3x3& basis) 123 150 { … … 125 152 } 126 153 154 /**@brief Set the rotational element by btQuaternion */ 127 155 SIMD_FORCE_INLINE void setRotation(const btQuaternion& q) 128 156 { … … 131 159 132 160 133 161 /**@brief Set this transformation to the identity */ 134 162 void setIdentity() 135 163 { … … 138 166 } 139 167 140 168 /**@brief Multiply this Transform by another(this = this * another) 169 * @param t The other transform */ 141 170 btTransform& operator*=(const btTransform& t) 142 171 { … … 146 175 } 147 176 177 /**@brief Return the inverse of this transform */ 148 178 btTransform inverse() const 149 179 { … … 152 182 } 153 183 184 /**@brief Return the inverse of this transform times the other transform 185 * @param t The other transform 186 * return this.inverse() * the other */ 154 187 btTransform inverseTimes(const btTransform& t) const; 155 188 189 /**@brief Return the product of this transform and the other */ 156 190 btTransform operator*(const btTransform& t) const; 157 191 192 /**@brief Return an identity transform */ 158 193 static btTransform getIdentity() 159 194 { … … 164 199 165 200 private: 166 201 ///Storage for the rotation 167 202 btMatrix3x3 m_basis; 203 ///Storage for the translation 168 204 btVector3 m_origin; 169 205 }; … … 192 228 } 193 229 230 /**@brief Test if two transforms have all elements equal */ 194 231 SIMD_FORCE_INLINE bool operator==(const btTransform& t1, const btTransform& t2) 195 232 { -
code/branches/physics/src/bullet/LinearMath/btTransformUtil.h
r2192 r2430 101 101 } 102 102 103 static void calculateVelocityQuaternion(const btVector3& pos0,const btVector3& pos1,const btQuaternion& orn0,const btQuaternion& orn1,btScalar timeStep,btVector3& linVel,btVector3& angVel) 104 { 105 linVel = (pos1 - pos0) / timeStep; 106 btVector3 axis; 107 btScalar angle; 108 if (orn0 != orn1) 109 { 110 calculateDiffAxisAngleQuaternion(orn0,orn1,axis,angle); 111 angVel = axis * angle / timeStep; 112 } else 113 { 114 angVel.setValue(0,0,0); 115 } 116 } 117 118 static void calculateDiffAxisAngleQuaternion(const btQuaternion& orn0,const btQuaternion& orn1a,btVector3& axis,btScalar& angle) 119 { 120 btQuaternion orn1 = orn0.farthest(orn1a); 121 btQuaternion dorn = orn1 * orn0.inverse(); 122 ///floating point inaccuracy can lead to w component > 1..., which breaks 123 dorn.normalize(); 124 angle = dorn.getAngle(); 125 axis = btVector3(dorn.x(),dorn.y(),dorn.z()); 126 axis[3] = btScalar(0.); 127 //check for axis length 128 btScalar len = axis.length2(); 129 if (len < SIMD_EPSILON*SIMD_EPSILON) 130 axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.)); 131 else 132 axis /= btSqrt(len); 133 } 134 103 135 static void calculateVelocity(const btTransform& transform0,const btTransform& transform1,btScalar timeStep,btVector3& linVel,btVector3& angVel) 104 136 { … … 112 144 static void calculateDiffAxisAngle(const btTransform& transform0,const btTransform& transform1,btVector3& axis,btScalar& angle) 113 145 { 114 115 #ifdef USE_QUATERNION_DIFF116 btQuaternion orn0 = transform0.getRotation();117 btQuaternion orn1a = transform1.getRotation();118 btQuaternion orn1 = orn0.farthest(orn1a);119 btQuaternion dorn = orn1 * orn0.inverse();120 #else121 146 btMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse(); 122 147 btQuaternion dorn; 123 148 dmat.getRotation(dorn); 124 #endif//USE_QUATERNION_DIFF 125 149 126 150 ///floating point inaccuracy can lead to w component > 1..., which breaks 127 128 151 dorn.normalize(); 129 152 … … 141 164 }; 142 165 166 167 ///The btConvexSeparatingDistanceUtil can help speed up convex collision detection 168 ///by conservatively updating a cached separating distance/vector instead of re-calculating the closest distance 169 class btConvexSeparatingDistanceUtil 170 { 171 btQuaternion m_ornA; 172 btQuaternion m_ornB; 173 btVector3 m_posA; 174 btVector3 m_posB; 175 176 btVector3 m_separatingNormal; 177 178 btScalar m_boundingRadiusA; 179 btScalar m_boundingRadiusB; 180 btScalar m_separatingDistance; 181 182 public: 183 184 btConvexSeparatingDistanceUtil(btScalar boundingRadiusA,btScalar boundingRadiusB) 185 :m_boundingRadiusA(boundingRadiusA), 186 m_boundingRadiusB(boundingRadiusB), 187 m_separatingDistance(0.f) 188 { 189 } 190 191 btScalar getConservativeSeparatingDistance() 192 { 193 return m_separatingDistance; 194 } 195 196 void updateSeparatingDistance(const btTransform& transA,const btTransform& transB) 197 { 198 const btVector3& toPosA = transA.getOrigin(); 199 const btVector3& toPosB = transB.getOrigin(); 200 btQuaternion toOrnA = transA.getRotation(); 201 btQuaternion toOrnB = transB.getRotation(); 202 203 if (m_separatingDistance>0.f) 204 { 205 206 207 btVector3 linVelA,angVelA,linVelB,angVelB; 208 btTransformUtil::calculateVelocityQuaternion(m_posA,toPosA,m_ornA,toOrnA,btScalar(1.),linVelA,angVelA); 209 btTransformUtil::calculateVelocityQuaternion(m_posB,toPosB,m_ornB,toOrnB,btScalar(1.),linVelB,angVelB); 210 btScalar maxAngularProjectedVelocity = angVelA.length() * m_boundingRadiusA + angVelB.length() * m_boundingRadiusB; 211 btVector3 relLinVel = (linVelB-linVelA); 212 btScalar relLinVelocLength = (linVelB-linVelA).dot(m_separatingNormal); 213 if (relLinVelocLength<0.f) 214 { 215 relLinVelocLength = 0.f; 216 } 217 218 btScalar projectedMotion = maxAngularProjectedVelocity +relLinVelocLength; 219 m_separatingDistance -= projectedMotion; 220 } 221 222 m_posA = toPosA; 223 m_posB = toPosB; 224 m_ornA = toOrnA; 225 m_ornB = toOrnB; 226 } 227 228 void initSeparatingDistance(const btVector3& separatingVector,btScalar separatingDistance,const btTransform& transA,const btTransform& transB) 229 { 230 m_separatingNormal = separatingVector; 231 m_separatingDistance = separatingDistance; 232 233 const btVector3& toPosA = transA.getOrigin(); 234 const btVector3& toPosB = transB.getOrigin(); 235 btQuaternion toOrnA = transA.getRotation(); 236 btQuaternion toOrnB = transB.getRotation(); 237 m_posA = toPosA; 238 m_posB = toPosB; 239 m_ornA = toOrnA; 240 m_ornB = toOrnB; 241 } 242 243 }; 244 245 143 246 #endif //SIMD_TRANSFORM_UTIL_H 144 247 -
code/branches/physics/src/bullet/LinearMath/btVector3.h
r2192 r2430 20 20 #include "btQuadWord.h" 21 21 22 ///btVector3 can be used to represent 3D points and vectors. 23 ///It has an un-used w component to suit 16-byte alignment when btVector3 is stored in containers. This extra component can be used by derived classes (Quaternion?) or by user 24 ///Ideally, this class should be replaced by a platform optimized SIMD version that keeps the data in registers 22 /**@brief btVector3 can be used to represent 3D points and vectors. 23 * It has an un-used w component to suit 16-byte alignment when btVector3 is stored in containers. This extra component can be used by derived classes (Quaternion?) or by user 24 * Ideally, this class should be replaced by a platform optimized SIMD version that keeps the data in registers 25 */ 25 26 class btVector3 : public btQuadWord { 26 27 27 28 public: 29 /**@brief No initialization constructor */ 28 30 SIMD_FORCE_INLINE btVector3() {} 29 31 32 /**@brief Constructor from btQuadWordStorage (btVector3 inherits from this so is also valid) 33 * Note: Vector3 derives from btQuadWordStorage*/ 30 34 SIMD_FORCE_INLINE btVector3(const btQuadWordStorage& q) 31 35 : btQuadWord(q) … … 33 37 } 34 38 35 39 /**@brief Constructor from scalars 40 * @param x X value 41 * @param y Y value 42 * @param z Z value 43 */ 36 44 SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z) 37 45 :btQuadWord(x,y,z,btScalar(0.)) … … 45 53 46 54 47 55 /**@brief Add a vector to this one 56 * @param The vector to add to this one */ 48 57 SIMD_FORCE_INLINE btVector3& operator+=(const btVector3& v) 49 58 { 50 59 51 m_ x += v.x(); m_y += v.y(); m_z+= v.z();60 m_floats[0] += v.x(); m_floats[1] += v.y(); m_floats[2] += v.z(); 52 61 return *this; 53 62 } 54 63 55 64 56 65 /**@brief Subtract a vector from this one 66 * @param The vector to subtract */ 57 67 SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v) 58 68 { 59 m_ x -= v.x(); m_y -= v.y(); m_z-= v.z();69 m_floats[0] -= v.x(); m_floats[1] -= v.y(); m_floats[2] -= v.z(); 60 70 return *this; 61 71 } 62 72 /**@brief Scale the vector 73 * @param s Scale factor */ 63 74 SIMD_FORCE_INLINE btVector3& operator*=(const btScalar& s) 64 75 { 65 m_ x *= s; m_y *= s; m_z*= s;76 m_floats[0] *= s; m_floats[1] *= s; m_floats[2] *= s; 66 77 return *this; 67 78 } 68 79 80 /**@brief Inversely scale the vector 81 * @param s Scale factor to divide by */ 69 82 SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s) 70 83 { … … 73 86 } 74 87 88 /**@brief Return the dot product 89 * @param v The other vector in the dot product */ 75 90 SIMD_FORCE_INLINE btScalar dot(const btVector3& v) const 76 91 { 77 return m_x * v.x() + m_y * v.y() + m_z * v.z(); 78 } 79 92 return m_floats[0] * v.x() + m_floats[1] * v.y() + m_floats[2] * v.z(); 93 } 94 95 /**@brief Return the length of the vector squared */ 80 96 SIMD_FORCE_INLINE btScalar length2() const 81 97 { … … 83 99 } 84 100 101 /**@brief Return the length of the vector */ 85 102 SIMD_FORCE_INLINE btScalar length() const 86 103 { … … 88 105 } 89 106 107 /**@brief Return the distance squared between the ends of this and another vector 108 * This is symantically treating the vector like a point */ 90 109 SIMD_FORCE_INLINE btScalar distance2(const btVector3& v) const; 91 110 111 /**@brief Return the distance between the ends of this and another vector 112 * This is symantically treating the vector like a point */ 92 113 SIMD_FORCE_INLINE btScalar distance(const btVector3& v) const; 93 114 115 /**@brief Normalize this vector 116 * x^2 + y^2 + z^2 = 1 */ 94 117 SIMD_FORCE_INLINE btVector3& normalize() 95 118 { … … 97 120 } 98 121 122 /**@brief Return a normalized version of this vector */ 99 123 SIMD_FORCE_INLINE btVector3 normalized() const; 100 124 125 /**@brief Rotate this vector 126 * @param wAxis The axis to rotate about 127 * @param angle The angle to rotate by */ 101 128 SIMD_FORCE_INLINE btVector3 rotate( const btVector3& wAxis, const btScalar angle ); 102 129 130 /**@brief Return the angle between this and another vector 131 * @param v The other vector */ 103 132 SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const 104 133 { … … 107 136 return btAcos(dot(v) / s); 108 137 } 109 138 /**@brief Return a vector will the absolute values of each element */ 110 139 SIMD_FORCE_INLINE btVector3 absolute() const 111 140 { 112 141 return btVector3( 113 btFabs(m_x), 114 btFabs(m_y), 115 btFabs(m_z)); 116 } 117 142 btFabs(m_floats[0]), 143 btFabs(m_floats[1]), 144 btFabs(m_floats[2])); 145 } 146 /**@brief Return the cross product between this and another vector 147 * @param v The other vector */ 118 148 SIMD_FORCE_INLINE btVector3 cross(const btVector3& v) const 119 149 { 120 150 return btVector3( 121 m_ y * v.z() - m_z* v.y(),122 m_ z * v.x() - m_x* v.z(),123 m_ x * v.y() - m_y* v.x());151 m_floats[1] * v.z() - m_floats[2] * v.y(), 152 m_floats[2] * v.x() - m_floats[0] * v.z(), 153 m_floats[0] * v.y() - m_floats[1] * v.x()); 124 154 } 125 155 126 156 SIMD_FORCE_INLINE btScalar triple(const btVector3& v1, const btVector3& v2) const 127 157 { 128 return m_x * (v1.y() * v2.z() - v1.z() * v2.y()) + 129 m_y * (v1.z() * v2.x() - v1.x() * v2.z()) + 130 m_z * (v1.x() * v2.y() - v1.y() * v2.x()); 131 } 132 158 return m_floats[0] * (v1.y() * v2.z() - v1.z() * v2.y()) + 159 m_floats[1] * (v1.z() * v2.x() - v1.x() * v2.z()) + 160 m_floats[2] * (v1.x() * v2.y() - v1.y() * v2.x()); 161 } 162 163 /**@brief Return the axis with the smallest value 164 * Note return values are 0,1,2 for x, y, or z */ 133 165 SIMD_FORCE_INLINE int minAxis() const 134 166 { 135 return m_x < m_y ? (m_x < m_z ? 0 : 2) : (m_y < m_z ? 1 : 2); 136 } 137 167 return m_floats[0] < m_floats[1] ? (m_floats[0] < m_floats[2] ? 0 : 2) : (m_floats[1] < m_floats[2] ? 1 : 2); 168 } 169 170 /**@brief Return the axis with the largest value 171 * Note return values are 0,1,2 for x, y, or z */ 138 172 SIMD_FORCE_INLINE int maxAxis() const 139 173 { 140 return m_ x < m_y ? (m_y < m_z ? 2 : 1) : (m_x < m_z? 2 : 0);174 return m_floats[0] < m_floats[1] ? (m_floats[1] < m_floats[2] ? 2 : 1) : (m_floats[0] < m_floats[2] ? 2 : 0); 141 175 } 142 176 … … 154 188 { 155 189 btScalar s = btScalar(1.0) - rt; 156 m_ x= s * v0.x() + rt * v1.x();157 m_ y= s * v0.y() + rt * v1.y();158 m_ z= s * v0.z() + rt * v1.z();190 m_floats[0] = s * v0.x() + rt * v1.x(); 191 m_floats[1] = s * v0.y() + rt * v1.y(); 192 m_floats[2] = s * v0.z() + rt * v1.z(); 159 193 //don't do the unused w component 160 194 // m_co[3] = s * v0[3] + rt * v1[3]; 161 195 } 162 196 197 /**@brief Return the linear interpolation between this and another vector 198 * @param v The other vector 199 * @param t The ration of this to v (t = 0 => return this, t=1 => return other) */ 163 200 SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const 164 201 { 165 return btVector3(m_x + (v.x() - m_x) * t, 166 m_y + (v.y() - m_y) * t, 167 m_z + (v.z() - m_z) * t); 168 } 169 170 202 return btVector3(m_floats[0] + (v.x() - m_floats[0]) * t, 203 m_floats[1] + (v.y() - m_floats[1]) * t, 204 m_floats[2] + (v.z() - m_floats[2]) * t); 205 } 206 207 /**@brief Elementwise multiply this vector by the other 208 * @param v The other vector */ 171 209 SIMD_FORCE_INLINE btVector3& operator*=(const btVector3& v) 172 210 { 173 m_ x *= v.x(); m_y *= v.y(); m_z*= v.z();211 m_floats[0] *= v.x(); m_floats[1] *= v.y(); m_floats[2] *= v.z(); 174 212 return *this; 175 213 } … … 179 217 }; 180 218 219 /**@brief Return the sum of two vectors (Point symantics)*/ 181 220 SIMD_FORCE_INLINE btVector3 182 221 operator+(const btVector3& v1, const btVector3& v2) … … 185 224 } 186 225 226 /**@brief Return the elementwise product of two vectors */ 187 227 SIMD_FORCE_INLINE btVector3 188 228 operator*(const btVector3& v1, const btVector3& v2) … … 191 231 } 192 232 233 /**@brief Return the difference between two vectors */ 193 234 SIMD_FORCE_INLINE btVector3 194 235 operator-(const btVector3& v1, const btVector3& v2) … … 196 237 return btVector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z()); 197 238 } 198 239 /**@brief Return the negative of the vector */ 199 240 SIMD_FORCE_INLINE btVector3 200 241 operator-(const btVector3& v) … … 203 244 } 204 245 246 /**@brief Return the vector scaled by s */ 205 247 SIMD_FORCE_INLINE btVector3 206 248 operator*(const btVector3& v, const btScalar& s) … … 209 251 } 210 252 253 /**@brief Return the vector scaled by s */ 211 254 SIMD_FORCE_INLINE btVector3 212 255 operator*(const btScalar& s, const btVector3& v) … … 215 258 } 216 259 260 /**@brief Return the vector inversely scaled by s */ 217 261 SIMD_FORCE_INLINE btVector3 218 262 operator/(const btVector3& v, const btScalar& s) … … 222 266 } 223 267 268 /**@brief Return the vector inversely scaled by s */ 224 269 SIMD_FORCE_INLINE btVector3 225 270 operator/(const btVector3& v1, const btVector3& v2) … … 228 273 } 229 274 275 /**@brief Return the dot product between two vectors */ 230 276 SIMD_FORCE_INLINE btScalar 231 277 dot(const btVector3& v1, const btVector3& v2) … … 235 281 236 282 237 283 /**@brief Return the distance squared between two vectors */ 238 284 SIMD_FORCE_INLINE btScalar 239 285 distance2(const btVector3& v1, const btVector3& v2) … … 243 289 244 290 291 /**@brief Return the distance between two vectors */ 245 292 SIMD_FORCE_INLINE btScalar 246 293 distance(const btVector3& v1, const btVector3& v2) … … 249 296 } 250 297 298 /**@brief Return the angle between two vectors */ 251 299 SIMD_FORCE_INLINE btScalar 252 300 angle(const btVector3& v1, const btVector3& v2) … … 255 303 } 256 304 305 /**@brief Return the cross product of two vectors */ 257 306 SIMD_FORCE_INLINE btVector3 258 307 cross(const btVector3& v1, const btVector3& v2) … … 267 316 } 268 317 318 /**@brief Return the linear interpolation between two vectors 319 * @param v1 One vector 320 * @param v2 The other vector 321 * @param t The ration of this to v (t = 0 => return v1, t=1 => return v2) */ 269 322 SIMD_FORCE_INLINE btVector3 270 323 lerp(const btVector3& v1, const btVector3& v2, const btScalar& t) … … 273 326 } 274 327 275 328 /**@brief Test if each element of the vector is equivalent */ 276 329 SIMD_FORCE_INLINE bool operator==(const btVector3& p1, const btVector3& p2) 277 330 { … … 317 370 : btVector3(x,y,z) 318 371 { 319 m_ unusedW= w;372 m_floats[3] = w; 320 373 } 321 374 … … 324 377 { 325 378 return btVector4( 326 btFabs(m_ x),327 btFabs(m_ y),328 btFabs(m_ z),329 btFabs(m_ unusedW));330 } 331 332 333 334 btScalar getW() const { return m_ unusedW;}379 btFabs(m_floats[0]), 380 btFabs(m_floats[1]), 381 btFabs(m_floats[2]), 382 btFabs(m_floats[3])); 383 } 384 385 386 387 btScalar getW() const { return m_floats[3];} 335 388 336 389 … … 339 392 int maxIndex = -1; 340 393 btScalar maxVal = btScalar(-1e30); 341 if (m_ x> maxVal)394 if (m_floats[0] > maxVal) 342 395 { 343 396 maxIndex = 0; 344 maxVal = m_ x;345 } 346 if (m_ y> maxVal)397 maxVal = m_floats[0]; 398 } 399 if (m_floats[1] > maxVal) 347 400 { 348 401 maxIndex = 1; 349 maxVal = m_ y;350 } 351 if (m_ z> maxVal)402 maxVal = m_floats[1]; 403 } 404 if (m_floats[2] > maxVal) 352 405 { 353 406 maxIndex = 2; 354 maxVal = m_ z;355 } 356 if (m_ unusedW> maxVal)407 maxVal = m_floats[2]; 408 } 409 if (m_floats[3] > maxVal) 357 410 { 358 411 maxIndex = 3; 359 maxVal = m_ unusedW;412 maxVal = m_floats[3]; 360 413 } 361 414 … … 372 425 int minIndex = -1; 373 426 btScalar minVal = btScalar(1e30); 374 if (m_ x< minVal)427 if (m_floats[0] < minVal) 375 428 { 376 429 minIndex = 0; 377 minVal = m_ x;378 } 379 if (m_ y< minVal)430 minVal = m_floats[0]; 431 } 432 if (m_floats[1] < minVal) 380 433 { 381 434 minIndex = 1; 382 minVal = m_ y;383 } 384 if (m_ z< minVal)435 minVal = m_floats[1]; 436 } 437 if (m_floats[2] < minVal) 385 438 { 386 439 minIndex = 2; 387 minVal = m_ z;388 } 389 if (m_ unusedW< minVal)440 minVal = m_floats[2]; 441 } 442 if (m_floats[3] < minVal) 390 443 { 391 444 minIndex = 3; 392 minVal = m_ unusedW;445 minVal = m_floats[3]; 393 446 } 394 447 -
code/branches/physics/src/bullet/VERSION
r2192 r2430 1 Bullet Collision Detection and Physics Library version 2.72 2 http://bullet.googlecode.com 1 2.73
Note: See TracChangeset
for help on using the changeset viewer.