Changeset 2908 for code/branches/questsystem5/src/bullet
- Timestamp:
- Apr 8, 2009, 12:58:47 AM (16 years ago)
- Location:
- code/branches/questsystem5
- Files:
-
- 1 deleted
- 112 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/questsystem5
- Property svn:mergeinfo changed
-
code/branches/questsystem5/src/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp
r2907 r2908 20 20 #include "btAxisSweep3.h" 21 21 22 #include <assert.h> 22 23 23 24 btAxisSweep3::btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache, bool disableRaycastAccelerator) -
code/branches/questsystem5/src/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.h
r2907 r2908 43 43 public: 44 44 45 BT_DECLARE_ALIGNED_ALLOCATOR();46 45 47 46 class Edge … … 140 139 SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;} 141 140 142 v irtual void resetPool(btDispatcher* dispatcher);141 void resetPool(); 143 142 144 143 void processAllOverlappingPairs(btOverlapCallback* callback); … … 222 221 223 222 if (checkCardinality) 224 btAssert(numEdges == m_numHandles*2+1);223 assert(numEdges == m_numHandles*2+1); 225 224 } 226 225 #endif //DEBUG_BROADPHASE … … 348 347 } 349 348 350 // btAssert(bounds.HasVolume());349 //assert(bounds.HasVolume()); 351 350 352 351 // init bounds … … 454 453 BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::allocHandle() 455 454 { 456 btAssert(m_firstFreeHandle);455 assert(m_firstFreeHandle); 457 456 458 457 BP_FP_INT_TYPE handle = m_firstFreeHandle; … … 466 465 void btAxisSweep3Internal<BP_FP_INT_TYPE>::freeHandle(BP_FP_INT_TYPE handle) 467 466 { 468 btAssert(handle > 0 && handle < m_maxHandles);467 assert(handle > 0 && handle < m_maxHandles); 469 468 470 469 getHandle(handle)->SetNextFree(m_firstFreeHandle); … … 589 588 590 589 template <typename BP_FP_INT_TYPE> 591 void btAxisSweep3Internal<BP_FP_INT_TYPE>::resetPool( btDispatcher* dispatcher)590 void btAxisSweep3Internal<BP_FP_INT_TYPE>::resetPool() 592 591 { 593 592 if (m_numHandles == 0) … … 643 642 if (!isDuplicate) 644 643 { 645 ///important to use an AABB test that is consistent with the broadphase646 644 bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1); 647 645 … … 689 687 } 690 688 689 690 691 692 691 693 } 692 694 … … 729 731 void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher) 730 732 { 731 // btAssert(bounds.IsFinite());732 // btAssert(bounds.HasVolume());733 // assert(bounds.IsFinite()); 734 //assert(bounds.HasVolume()); 733 735 734 736 Handle* pHandle = getHandle(handle); -
code/branches/questsystem5/src/bullet/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
r2907 r2908 65 65 virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const =0; 66 66 67 ///reset broadphase internal structures, to ensure determinism/reproducability68 virtual void resetPool(btDispatcher* dispatcher) {};69 70 67 virtual void printStats() = 0; 71 68 -
code/branches/questsystem5/src/bullet/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
r2907 r2908 70 70 71 71 SOFTBODY_SHAPE_PROXYTYPE, 72 HFFLUID_SHAPE_PROXYTYPE, 73 HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE, 72 74 73 INVALID_SHAPE_PROXYTYPE, 75 74 … … 189 188 190 189 //keep them sorted, so the std::set operations work 191 if ( proxy0.m_uniqueId < proxy1.m_uniqueId)190 if (&proxy0 < &proxy1) 192 191 { 193 192 m_pProxy0 = &proxy0; … … 230 229 bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b ) 231 230 { 232 const int uidA0 = a.m_pProxy0 ? a.m_pProxy0->m_uniqueId : -1; 233 const int uidB0 = b.m_pProxy0 ? b.m_pProxy0->m_uniqueId : -1; 234 const int uidA1 = a.m_pProxy1 ? a.m_pProxy1->m_uniqueId : -1; 235 const int uidB1 = b.m_pProxy1 ? b.m_pProxy1->m_uniqueId : -1; 236 237 return uidA0 > uidB0 || 238 (a.m_pProxy0 == b.m_pProxy0 && uidA1 > uidB1) || 231 return a.m_pProxy0 > b.m_pProxy0 || 232 (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 > b.m_pProxy1) || 239 233 (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 == b.m_pProxy1 && a.m_algorithm > b.m_algorithm); 240 234 } -
code/branches/questsystem5/src/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp
r2907 r2908 394 394 } 395 395 396 #if 0 396 // 397 397 static DBVT_INLINE btDbvtNode* walkup(btDbvtNode* n,int count) 398 398 { … … 400 400 return(n); 401 401 } 402 #endif403 402 404 403 // … … 425 424 void btDbvt::clear() 426 425 { 427 if(m_root) 428 recursedeletenode(this,m_root); 426 if(m_root) recursedeletenode(this,m_root); 429 427 btAlignedFree(m_free); 430 428 m_free=0; 431 m_lkhd = -1;432 m_stkStack.clear();433 m_opath = 0;434 435 429 } 436 430 -
code/branches/questsystem5/src/bullet/BulletCollision/BroadphaseCollision/btDbvt.h
r2907 r2908 58 58 59 59 //SSE gives errors on a MSVC 7.1 60 #if def BT_USE_SSE60 #if (defined (WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (BT_USE_DOUBLE_PRECISION)) 61 61 #define DBVT_SELECT_IMPL DBVT_IMPL_SSE 62 62 #define DBVT_MERGE_IMPL DBVT_IMPL_SSE … … 83 83 #define DBVT_PREFIX template <typename T> 84 84 #define DBVT_IPOLICY T& policy 85 #define DBVT_CHECKTYPE static const ICollide& typechecker=*(T*) 1;(void)typechecker;85 #define DBVT_CHECKTYPE static const ICollide& typechecker=*(T*)0; 86 86 #else 87 87 #define DBVT_VIRTUAL_DTOR(a) virtual ~a() {} … … 147 147 DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, 148 148 const btDbvtAabbMm& b); 149 149 DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, 150 const btDbvtAabbMm& b, 151 const btTransform& xform); 150 152 DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, 151 153 const btVector3& b); … … 303 305 const btDbvtNode* root1, 304 306 DBVT_IPOLICY); 305 #if 0 307 306 308 DBVT_PREFIX 307 309 void collideTT( const btDbvtNode* root0, … … 315 317 const btTransform& xform1, 316 318 DBVT_IPOLICY); 317 #endif318 319 319 DBVT_PREFIX 320 320 void collideTV( const btDbvtNode* root, … … 531 531 } 532 532 533 533 // 534 DBVT_INLINE bool Intersect( const btDbvtAabbMm& a, 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); 547 } 534 548 535 549 // … … 835 849 } 836 850 837 #if 0 851 838 852 // 839 853 DBVT_PREFIX … … 891 905 } 892 906 } 907 893 908 // 894 909 DBVT_PREFIX … … 902 917 collideTT(root0,root1,xform,policy); 903 918 } 904 #endif905 919 906 920 // -
code/branches/questsystem5/src/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp
r2907 r2908 101 101 btDbvtProxy* pb=(btDbvtProxy*)nb->data; 102 102 #if DBVT_BP_SORTPAIRS 103 if(pa->m_uniqueId>pb->m_uniqueId) 104 btSwap(pa,pb); 103 if(pa>pb) btSwap(pa,pb); 105 104 #endif 106 105 pbp->m_paircache->addOverlappingPair(pa,pb); … … 134 133 m_updates_done = 0; 135 134 m_updates_ratio = 0; 136 m_paircache = paircache? paircache : new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache(); 135 m_paircache = paircache? 136 paircache : 137 new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache(); 137 138 m_gid = 0; 138 139 m_pid = 0; … … 210 211 } 211 212 212 struct BroadphaseRayTester : btDbvt::ICollide213 {214 btBroadphaseRayCallback& m_rayCallback;215 BroadphaseRayTester(btBroadphaseRayCallback& orgCallback)216 :m_rayCallback(orgCallback)217 {218 }219 void Process(const btDbvtNode* leaf)220 {221 btDbvtProxy* proxy=(btDbvtProxy*)leaf->data;222 m_rayCallback.process(proxy);223 }224 };225 226 213 void btDbvtBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax) 227 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 228 230 BroadphaseRayTester callback(rayCallback); 229 231 … … 340 342 } 341 343 #endif 342 343 performDeferredRemoval(dispatcher);344 345 }346 347 void btDbvtBroadphase::performDeferredRemoval(btDispatcher* dispatcher)348 {349 350 if (m_paircache->hasDeferredRemoval())351 {352 353 btBroadphasePairArray& overlappingPairArray = m_paircache->getOverlappingPairArray();354 355 //perform a sort, to find duplicates and to sort 'invalid' pairs to the end356 overlappingPairArray.quickSort(btBroadphasePairSortPredicate());357 358 int invalidPair = 0;359 360 361 int i;362 363 btBroadphasePair previousPair;364 previousPair.m_pProxy0 = 0;365 previousPair.m_pProxy1 = 0;366 previousPair.m_algorithm = 0;367 368 369 for (i=0;i<overlappingPairArray.size();i++)370 {371 372 btBroadphasePair& pair = overlappingPairArray[i];373 374 bool isDuplicate = (pair == previousPair);375 376 previousPair = pair;377 378 bool needsRemoval = false;379 380 if (!isDuplicate)381 {382 //important to perform AABB check that is consistent with the broadphase383 btDbvtProxy* pa=(btDbvtProxy*)pair.m_pProxy0;384 btDbvtProxy* pb=(btDbvtProxy*)pair.m_pProxy1;385 bool hasOverlap = Intersect(pa->leaf->volume,pb->leaf->volume);386 387 if (hasOverlap)388 {389 needsRemoval = false;390 } else391 {392 needsRemoval = true;393 }394 } else395 {396 //remove duplicate397 needsRemoval = true;398 //should have no algorithm399 btAssert(!pair.m_algorithm);400 }401 402 if (needsRemoval)403 {404 m_paircache->cleanOverlappingPair(pair,dispatcher);405 406 pair.m_pProxy0 = 0;407 pair.m_pProxy1 = 0;408 invalidPair++;409 }410 411 }412 413 //perform a sort, to sort 'invalid' pairs to the end414 overlappingPairArray.quickSort(btBroadphasePairSortPredicate());415 overlappingPairArray.resize(overlappingPairArray.size() - invalidPair);416 }417 344 } 418 345 … … 420 347 void btDbvtBroadphase::collide(btDispatcher* dispatcher) 421 348 { 422 /*printf("---------------------------------------------------------\n");423 printf("m_sets[0].m_leaves=%d\n",m_sets[0].m_leaves);424 printf("m_sets[1].m_leaves=%d\n",m_sets[1].m_leaves);425 printf("numPairs = %d\n",getOverlappingPairCache()->getNumOverlappingPairs());426 {427 int i;428 for (i=0;i<getOverlappingPairCache()->getNumOverlappingPairs();i++)429 {430 printf("pair[%d]=(%d,%d),",i,getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy0->getUid(),431 getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy1->getUid());432 }433 printf("\n");434 }435 */436 437 438 439 349 SPC(m_profiling.m_total); 440 350 /* optimize */ … … 492 402 if(pairs.size()>0) 493 403 { 494 495 int ni=btMin( pairs.size(),btMax<int>(m_newpairs,(pairs.size()*m_cupdates)/100));404 const int ci=pairs.size(); 405 int ni=btMin(ci,btMax<int>(m_newpairs,(ci*m_cupdates)/100)); 496 406 for(int i=0;i<ni;++i) 497 407 { 498 btBroadphasePair& p=pairs[(m_cid+i)% pairs.size()];408 btBroadphasePair& p=pairs[(m_cid+i)%ci]; 499 409 btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0; 500 410 btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1; … … 502 412 { 503 413 #if DBVT_BP_SORTPAIRS 504 if(pa->m_uniqueId>pb->m_uniqueId) 505 btSwap(pa,pb); 414 if(pa>pb) btSwap(pa,pb); 506 415 #endif 507 416 m_paircache->removeOverlappingPair(pa,pb,dispatcher); … … 558 467 aabbMin=bounds.Mins(); 559 468 aabbMax=bounds.Maxs(); 560 }561 562 void btDbvtBroadphase::resetPool(btDispatcher* dispatcher)563 {564 565 int totalObjects = m_sets[0].m_leaves + m_sets[1].m_leaves;566 if (!totalObjects)567 {568 //reset internal dynamic tree data structures569 m_sets[0].clear();570 m_sets[1].clear();571 572 m_deferedcollide = false;573 m_needcleanup = true;574 m_prediction = 1/(btScalar)2;575 m_stageCurrent = 0;576 m_fixedleft = 0;577 m_fupdates = 1;578 m_dupdates = 0;579 m_cupdates = 10;580 m_newpairs = 1;581 m_updates_call = 0;582 m_updates_done = 0;583 m_updates_ratio = 0;584 585 m_gid = 0;586 m_pid = 0;587 m_cid = 0;588 for(int i=0;i<=STAGECOUNT;++i)589 {590 m_stageRoots[i]=0;591 }592 }593 469 } 594 470 … … 725 601 #undef SPC 726 602 #endif 727 -
code/branches/questsystem5/src/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h
r2907 r2908 25 25 26 26 #define DBVT_BP_PROFILE 0 27 //#define DBVT_BP_SORTPAIRS 127 #define DBVT_BP_SORTPAIRS 1 28 28 #define DBVT_BP_PREVENTFALSEUPDATE 0 29 29 #define DBVT_BP_ACCURATESLEEPING 0 … … 115 115 void printStats(); 116 116 static void benchmark(btBroadphaseInterface*); 117 118 119 void performDeferredRemoval(btDispatcher* dispatcher);120 121 ///reset broadphase internal structures, to ensure determinism/reproducability122 virtual void resetPool(btDispatcher* dispatcher);123 124 117 }; 125 118 -
code/branches/questsystem5/src/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp
r2907 r2908 483 483 484 484 } 485 486 void btMultiSapBroadphase::resetPool(btDispatcher* dispatcher)487 {488 // not yet489 } -
code/branches/questsystem5/src/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h
r2907 r2908 144 144 void quicksort (btBroadphasePairArray& a, int lo, int hi); 145 145 146 ///reset broadphase internal structures, to ensure determinism/reproducability147 virtual void resetPool(btDispatcher* dispatcher);148 149 146 }; 150 147 -
code/branches/questsystem5/src/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
r2907 r2908 20 20 #include "btDispatcher.h" 21 21 #include "btCollisionAlgorithm.h" 22 #include "LinearMath/btAabbUtil2.h"23 22 24 23 #include <stdio.h> … … 137 136 { 138 137 gFindPairs++; 139 if(proxy0->m_uniqueId>proxy1->m_uniqueId) 140 btSwap(proxy0,proxy1); 138 if(proxy0>proxy1) btSwap(proxy0,proxy1); 141 139 int proxyId1 = proxy0->getUid(); 142 140 int proxyId2 = proxy1->getUid(); … … 214 212 btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) 215 213 { 216 if(proxy0->m_uniqueId>proxy1->m_uniqueId) 217 btSwap(proxy0,proxy1); 214 if(proxy0>proxy1) btSwap(proxy0,proxy1); 218 215 int proxyId1 = proxy0->getUid(); 219 216 int proxyId2 = proxy1->getUid(); … … 274 271 { 275 272 gRemovePairs++; 276 if(proxy0->m_uniqueId>proxy1->m_uniqueId) 277 btSwap(proxy0,proxy1); 273 if(proxy0>proxy1) btSwap(proxy0,proxy1); 278 274 int proxyId1 = proxy0->getUid(); 279 275 int proxyId2 = proxy1->getUid(); … … 397 393 } 398 394 399 void btHashedOverlappingPairCache::sortOverlappingPairs(btDispatcher* dispatcher)400 {401 ///need to keep hashmap in sync with pair address, so rebuild all402 btBroadphasePairArray tmpPairs;403 int i;404 for (i=0;i<m_overlappingPairArray.size();i++)405 {406 tmpPairs.push_back(m_overlappingPairArray[i]);407 }408 409 for (i=0;i<tmpPairs.size();i++)410 {411 removeOverlappingPair(tmpPairs[i].m_pProxy0,tmpPairs[i].m_pProxy1,dispatcher);412 }413 414 for (i = 0; i < m_next.size(); i++)415 {416 m_next[i] = BT_NULL_PAIR;417 }418 419 tmpPairs.quickSort(btBroadphasePairSortPredicate());420 421 for (i=0;i<tmpPairs.size();i++)422 {423 addOverlappingPair(tmpPairs[i].m_pProxy0,tmpPairs[i].m_pProxy1);424 }425 426 427 }428 395 429 396 … … 463 430 { 464 431 //don't add overlap with own 465 btAssert(proxy0 != proxy1);432 assert(proxy0 != proxy1); 466 433 467 434 if (!needsBroadphaseCollision(proxy0,proxy1)) … … 494 461 if (findIndex < m_overlappingPairArray.size()) 495 462 { 496 // btAssert(it != m_overlappingPairSet.end());463 //assert(it != m_overlappingPairSet.end()); 497 464 btBroadphasePair* pair = &m_overlappingPairArray[findIndex]; 498 465 return pair; … … 524 491 { 525 492 cleanOverlappingPair(*pair,dispatcher); 526 pair->m_pProxy0 = 0; 527 pair->m_pProxy1 = 0; 528 m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); 493 494 m_overlappingPairArray.swap(i,m_overlappingPairArray.capacity()-1); 529 495 m_overlappingPairArray.pop_back(); 530 496 gOverlappingPairs--; … … 626 592 processAllOverlappingPairs(&removeCallback,dispatcher); 627 593 } 628 629 void btSortedOverlappingPairCache::sortOverlappingPairs(btDispatcher* dispatcher)630 {631 //should already be sorted632 }633 -
code/branches/questsystem5/src/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
r2907 r2908 84 84 85 85 virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)=0; 86 87 virtual void sortOverlappingPairs(btDispatcher* dispatcher) = 0;88 89 86 90 87 }; … … 263 260 } 264 261 265 virtual void sortOverlappingPairs(btDispatcher* dispatcher); 266 267 268 protected: 262 public: 269 263 270 264 btAlignedObjectArray<int> m_hashTable; … … 376 370 } 377 371 378 virtual void sortOverlappingPairs(btDispatcher* dispatcher);379 380 372 381 373 }; … … 456 448 } 457 449 458 virtual void sortOverlappingPairs(btDispatcher* dispatcher)459 {460 }461 450 462 451 -
code/branches/questsystem5/src/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
r2907 r2908 470 470 471 471 #ifdef RAYAABB2 472 btVector3 rayFrom = raySource; 472 473 btVector3 rayDir = (rayTarget-raySource); 473 474 rayDir.normalize (); … … 558 559 559 560 #ifdef RAYAABB2 561 btVector3 rayFrom = raySource; 560 562 btVector3 rayDirection = (rayTarget-raySource); 561 563 rayDirection.normalize (); … … 816 818 #include <new> 817 819 818 #if 0819 820 //PCK: consts 820 821 static const unsigned BVH_ALIGNMENT = 16; … … 822 823 823 824 static const unsigned BVH_ALIGNMENT_BLOCKS = 2; 824 #endif 825 825 826 826 827 … … 1146 1147 1147 1148 1148 -
code/branches/questsystem5/src/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
r2907 r2908 325 325 } 326 326 327 void btSimpleBroadphase::resetPool(btDispatcher* dispatcher) 328 { 329 //not yet 330 } 327 328 -
code/branches/questsystem5/src/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
r2907 r2908 109 109 } 110 110 111 ///reset broadphase internal structures, to ensure determinism/reproducability112 virtual void resetPool(btDispatcher* dispatcher);113 114 111 115 112 void validate(); -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
r2907 r2908 53 53 { 54 54 m_doubleDispatch[i][j] = m_collisionConfiguration->getCollisionAlgorithmCreateFunc(i,j); 55 btAssert(m_doubleDispatch[i][j]);55 assert(m_doubleDispatch[i][j]); 56 56 } 57 57 } … … 80 80 btCollisionObject* body1 = (btCollisionObject*)b1; 81 81 82 //test for Bullet 2.74: use a relative contact breaking threshold without clamping against 'gContactBreakingThreshold' 83 //btScalar contactBreakingThreshold = btMin(gContactBreakingThreshold,btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold())); 84 btScalar contactBreakingThreshold = btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold()); 85 86 btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(),body1->getContactProcessingThreshold()); 87 82 btScalar contactBreakingThreshold = btMin(gContactBreakingThreshold,btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold())); 83 88 84 void* mem = 0; 89 85 … … 96 92 97 93 } 98 btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0,contactBreakingThreshold ,contactProcessingThreshold);94 btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0,contactBreakingThreshold); 99 95 manifold->m_index1a = m_manifoldsPtr.size(); 100 96 m_manifoldsPtr.push_back(manifold); … … 147 143 return algo; 148 144 } 145 149 146 150 147 … … 164 161 bool btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionObject* body1) 165 162 { 166 btAssert(body0);167 btAssert(body1);163 assert(body0); 164 assert(body1); 168 165 169 166 bool needsCollision = true; -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btCollisionObject.cpp
r2907 r2908 18 18 19 19 btCollisionObject::btCollisionObject() 20 : m_anisotropicFriction(1.f,1.f,1.f), 21 m_hasAnisotropicFriction(false), 22 m_contactProcessingThreshold(1e30f), 23 m_broadphaseHandle(0), 20 : m_broadphaseHandle(0), 24 21 m_collisionShape(0), 25 22 m_rootCollisionShape(0), -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h
r2907 r2908 53 53 btVector3 m_interpolationLinearVelocity; 54 54 btVector3 m_interpolationAngularVelocity; 55 56 btVector3 m_anisotropicFriction;57 bool m_hasAnisotropicFriction;58 btScalar m_contactProcessingThreshold;59 60 55 btBroadphaseProxy* m_broadphaseHandle; 61 56 btCollisionShape* m_collisionShape; … … 120 115 CO_COLLISION_OBJECT =1, 121 116 CO_RIGID_BODY, 117 CO_SOFT_BODY, 122 118 ///CO_GHOST_OBJECT keeps track of all objects overlapping its AABB and that pass its collision filter 123 119 ///It is useful for collision sensors, explosion objects, character controller etc. 124 CO_GHOST_OBJECT, 125 CO_SOFT_BODY, 126 CO_HF_FLUID 120 CO_GHOST_OBJECT 127 121 }; 128 122 … … 133 127 } 134 128 135 const btVector3& getAnisotropicFriction() const136 {137 return m_anisotropicFriction;138 }139 void setAnisotropicFriction(const btVector3& anisotropicFriction)140 {141 m_anisotropicFriction = anisotropicFriction;142 m_hasAnisotropicFriction = (anisotropicFriction[0]!=1.f) || (anisotropicFriction[1]!=1.f) || (anisotropicFriction[2]!=1.f);143 }144 bool hasAnisotropicFriction() const145 {146 return m_hasAnisotropicFriction;147 }148 149 ///the constraint solver can discard solving contacts, if the distance is above this threshold. 0 by default.150 ///Note that using contacts with positive distance can improve stability. It increases, however, the chance of colliding with degerate contacts, such as 'interior' triangle edges151 void setContactProcessingThreshold( btScalar contactProcessingThreshold)152 {153 m_contactProcessingThreshold = contactProcessingThreshold;154 }155 btScalar getContactProcessingThreshold() const156 {157 return m_contactProcessingThreshold;158 }159 129 160 130 SIMD_FORCE_INLINE bool isStaticObject() const { -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
r2907 r2908 70 70 getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1); 71 71 getBroadphase()->destroyProxy(bp,m_dispatcher1); 72 collisionObject->setBroadphaseHandle(0);73 72 } 74 73 } … … 120 119 121 120 122 void btCollisionWorld::updateSingleAabb(btCollisionObject* colObj)123 {124 btVector3 minAabb,maxAabb;125 colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);126 //need to increase the aabb for contact thresholds127 btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);128 minAabb -= contactThreshold;129 maxAabb += contactThreshold;130 131 btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache;132 133 //moving objects should be moderately sized, probably something wrong if not134 if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12)))135 {136 bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);137 } else138 {139 //something went wrong, investigate140 //this assert is unwanted in 3D modelers (danger of loosing work)141 colObj->setActivationState(DISABLE_SIMULATION);142 143 static bool reportMe = true;144 if (reportMe && m_debugDrawer)145 {146 reportMe = false;147 m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation");148 m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n");149 m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n");150 m_debugDrawer->reportErrorWarning("Thanks.\n");151 }152 }153 }154 155 121 void btCollisionWorld::updateAabbs() 156 122 { … … 165 131 if (colObj->isActive()) 166 132 { 167 updateSingleAabb(colObj); 168 } 169 } 133 btVector3 minAabb,maxAabb; 134 colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb); 135 //need to increase the aabb for contact thresholds 136 btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold); 137 minAabb -= contactThreshold; 138 maxAabb += contactThreshold; 139 140 btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache; 141 142 //moving objects should be moderately sized, probably something wrong if not 143 if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12))) 144 { 145 bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1); 146 } else 147 { 148 //something went wrong, investigate 149 //this assert is unwanted in 3D modelers (danger of loosing work) 150 colObj->setActivationState(DISABLE_SIMULATION); 151 152 static bool reportMe = true; 153 if (reportMe && m_debugDrawer) 154 { 155 reportMe = false; 156 m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation"); 157 m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n"); 158 m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n"); 159 m_debugDrawer->reportErrorWarning("Thanks.\n"); 160 } 161 } 162 } 163 } 164 170 165 } 171 166 … … 299 294 BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to, 300 295 btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh): 301 //@BP Mod 302 btTriangleRaycastCallback(from,to, resultCallback->m_flags), 296 btTriangleRaycastCallback(from,to), 303 297 m_resultCallback(resultCallback), 304 298 m_collisionObject(collisionObject), … … 349 343 BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to, 350 344 btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh): 351 //@BP Mod 352 btTriangleRaycastCallback(from,to, resultCallback->m_flags), 345 btTriangleRaycastCallback(from,to), 353 346 m_resultCallback(resultCallback), 354 347 m_collisionObject(collisionObject), … … 671 664 //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); 672 665 //btVector3 collisionObjectAabbMin,collisionObjectAabbMax; 673 #if 0 666 674 667 #ifdef RECALCULATE_AABB 675 668 btVector3 collisionObjectAabbMin,collisionObjectAabbMax; … … 679 672 const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin; 680 673 const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax; 681 #endif682 674 #endif 683 675 //btScalar hitLambda = m_resultCallback.m_closestHitFraction; -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h
r2907 r2908 59 59 * 60 60 */ 61 62 63 61 64 62 … … 82 80 { 83 81 84 85 82 86 83 protected: 87 84 88 85 btAlignedObjectArray<btCollisionObject*> m_collisionObjects; 89 90 86 91 87 btDispatcher* m_dispatcher1; … … 99 95 btIDebugDraw* m_debugDrawer; 100 96 101 102 97 103 98 public: … … 138 133 return m_dispatcher1; 139 134 } 140 141 void updateSingleAabb(btCollisionObject* colObj);142 135 143 136 virtual void updateAabbs(); … … 161 154 int m_shapePart; 162 155 int m_triangleIndex; 163 164 156 165 157 //const btCollisionShape* m_shapeTemp; … … 194 186 short int m_collisionFilterGroup; 195 187 short int m_collisionFilterMask; 196 //@BP Mod - Custom flags, currently used to enable backface culling on tri-meshes, see btRaycastCallback197 unsigned int m_flags;198 188 199 189 virtual ~RayResultCallback() … … 209 199 m_collisionObject(0), 210 200 m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), 211 m_collisionFilterMask(btBroadphaseProxy::AllFilter), 212 //@BP Mod 213 m_flags(0) 201 m_collisionFilterMask(btBroadphaseProxy::AllFilter) 214 202 { 215 203 } … … 239 227 btVector3 m_hitNormalWorld; 240 228 btVector3 m_hitPointWorld; 241 242 229 243 230 virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) … … 245 232 //caller already does the filter on the m_closestHitFraction 246 233 btAssert(rayResult.m_hitFraction <= m_closestHitFraction); 247 248 234 249 235 m_closestHitFraction = rayResult.m_hitFraction; … … 292 278 short int m_collisionFilterGroup; 293 279 short int m_collisionFilterMask; 294 295 280 296 281 ConvexResultCallback() … … 304 289 { 305 290 } 306 307 291 308 292 bool hasHit() const … … 310 294 return (m_closestHitFraction < btScalar(1.)); 311 295 } 312 313 296 314 297 … … 339 322 btVector3 m_hitPointWorld; 340 323 btCollisionObject* m_hitCollisionObject; 341 342 324 343 325 virtual btScalar addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace) … … 345 327 //caller already does the filter on the m_closestHitFraction 346 328 btAssert(convexResult.m_hitFraction <= m_closestHitFraction); 347 348 329 349 330 m_closestHitFraction = convexResult.m_hitFraction; -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
r2907 r2908 20 20 #include "LinearMath/btIDebugDraw.h" 21 21 #include "LinearMath/btAabbUtil2.h" 22 #include "btManifoldResult.h"23 22 24 23 btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped) … … 30 29 31 30 btCollisionObject* colObj = m_isSwapped? body1 : body0; 32 btAssert (colObj->getCollisionShape()->isCompound()); 31 btCollisionObject* otherObj = m_isSwapped? body0 : body1; 32 assert (colObj->getCollisionShape()->isCompound()); 33 33 34 34 btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape()); 35 m_compoundShapeRevision = compoundShape->getUpdateRevision();36 37 preallocateChildAlgorithms(body0,body1);38 }39 40 void btCompoundCollisionAlgorithm::preallocateChildAlgorithms(btCollisionObject* body0,btCollisionObject* body1)41 {42 btCollisionObject* colObj = m_isSwapped? body1 : body0;43 btCollisionObject* otherObj = m_isSwapped? body0 : body1;44 btAssert (colObj->getCollisionShape()->isCompound());45 46 btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());47 48 35 int numChildren = compoundShape->getNumChildShapes(); 49 36 int i; … … 60 47 btCollisionShape* childShape = compoundShape->getChildShape(i); 61 48 colObj->internalSetTemporaryCollisionShape( childShape ); 62 m_childCollisionAlgorithms[i] = m_dispatcher->findAlgorithm(colObj,otherObj,m_sharedManifold);49 m_childCollisionAlgorithms[i] = ci.m_dispatcher1->findAlgorithm(colObj,otherObj,m_sharedManifold); 63 50 colObj->internalSetTemporaryCollisionShape( tmpShape ); 64 51 } … … 66 53 } 67 54 68 void btCompoundCollisionAlgorithm::removeChildAlgorithms() 55 56 btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm() 69 57 { 70 58 int numChildren = m_childCollisionAlgorithms.size(); … … 78 66 } 79 67 } 80 }81 82 btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm()83 {84 removeChildAlgorithms();85 68 } 86 69 … … 185 168 btCollisionObject* otherObj = m_isSwapped? body0 : body1; 186 169 187 188 189 btAssert (colObj->getCollisionShape()->isCompound()); 170 assert (colObj->getCollisionShape()->isCompound()); 190 171 btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape()); 191 192 ///btCompoundShape might have changed:193 ////make sure the internal child collision algorithm caches are still valid194 if (compoundShape->getUpdateRevision() != m_compoundShapeRevision)195 {196 ///clear and update all197 removeChildAlgorithms();198 199 preallocateChildAlgorithms(body0,body1);200 }201 202 172 203 173 btDbvt* tree = compoundShape->getDynamicAabbTree(); … … 205 175 btCompoundLeafCallback callback(colObj,otherObj,m_dispatcher,dispatchInfo,resultOut,&m_childCollisionAlgorithms[0],m_sharedManifold); 206 176 207 ///we need to refresh all contact manifolds208 ///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep209 ///so we should add a 'refreshManifolds' in the btCollisionAlgorithm210 {211 int i;212 btManifoldArray manifoldArray;213 for (i=0;i<m_childCollisionAlgorithms.size();i++)214 {215 if (m_childCollisionAlgorithms[i])216 {217 m_childCollisionAlgorithms[i]->getAllContactManifolds(manifoldArray);218 for (int m=0;m<manifoldArray.size();m++)219 {220 if (manifoldArray[m]->getNumContacts())221 {222 resultOut->setPersistentManifold(manifoldArray[m]);223 resultOut->refreshContactPoints();224 resultOut->setPersistentManifold(0);//??necessary?225 }226 }227 manifoldArray.clear();228 }229 }230 }231 177 232 178 if (tree) … … 297 243 btCollisionObject* otherObj = m_isSwapped? body0 : body1; 298 244 299 btAssert (colObj->getCollisionShape()->isCompound());245 assert (colObj->getCollisionShape()->isCompound()); 300 246 301 247 btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape()); … … 340 286 341 287 342 -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
r2907 r2908 27 27 #include "LinearMath/btAlignedObjectArray.h" 28 28 class btDispatcher; 29 class btCollisionObject;30 29 31 30 /// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes … … 37 36 class btPersistentManifold* m_sharedManifold; 38 37 bool m_ownsManifold; 39 40 int m_compoundShapeRevision;//to keep track of changes, so that childAlgorithm array can be updated41 38 42 void removeChildAlgorithms();43 44 void preallocateChildAlgorithms(btCollisionObject* body0,btCollisionObject* body1);45 46 39 public: 47 40 -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
r2907 r2908 52 52 btConvexConvexAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver) 53 53 { 54 m_numPerturbationIterations = 0;55 m_minimumPointsPerturbationThreshold = 3;56 54 m_simplexSolver = simplexSolver; 57 55 m_pdSolver = pdSolver; … … 62 60 } 63 61 64 btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver ,int numPerturbationIterations, int minimumPointsPerturbationThreshold)62 btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver) 65 63 : btActivatingCollisionAlgorithm(ci,body0,body1), 66 64 m_simplexSolver(simplexSolver), … … 68 66 m_ownManifold (false), 69 67 m_manifoldPtr(mf), 70 m_lowLevelOfDetail(false) ,68 m_lowLevelOfDetail(false) 71 69 #ifdef USE_SEPDISTANCE_UTIL2 72 70 ,m_sepDistance((static_cast<btConvexShape*>(body0->getCollisionShape()))->getAngularMotionDisc(), 73 (static_cast<btConvexShape*>(body1->getCollisionShape()))->getAngularMotionDisc()) ,71 (static_cast<btConvexShape*>(body1->getCollisionShape()))->getAngularMotionDisc()) 74 72 #endif 75 m_numPerturbationIterations(numPerturbationIterations),76 m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)77 73 { 78 74 (void)body0; … … 98 94 99 95 100 struct btPerturbedContactResult : public btManifoldResult 101 { 102 btManifoldResult* m_originalManifoldResult; 103 btTransform m_transformA; 104 btTransform m_transformB; 105 btTransform m_unPerturbedTransform; 106 bool m_perturbA; 107 btIDebugDraw* m_debugDrawer; 108 109 110 btPerturbedContactResult(btManifoldResult* originalResult,const btTransform& transformA,const btTransform& transformB,const btTransform& unPerturbedTransform,bool perturbA,btIDebugDraw* debugDrawer) 111 :m_originalManifoldResult(originalResult), 112 m_transformA(transformA), 113 m_transformB(transformB), 114 m_perturbA(perturbA), 115 m_unPerturbedTransform(unPerturbedTransform), 116 m_debugDrawer(debugDrawer) 117 { 118 } 119 virtual ~ btPerturbedContactResult() 120 { 121 } 122 123 virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar orgDepth) 124 { 125 btVector3 endPt,startPt; 126 btScalar newDepth; 127 btVector3 newNormal; 128 129 if (m_perturbA) 130 { 131 btVector3 endPtOrg = pointInWorld + normalOnBInWorld*orgDepth; 132 endPt = (m_unPerturbedTransform*m_transformA.inverse())(endPtOrg); 133 newDepth = (endPt - pointInWorld).dot(normalOnBInWorld); 134 startPt = endPt+normalOnBInWorld*newDepth; 135 } else 136 { 137 endPt = pointInWorld + normalOnBInWorld*orgDepth; 138 startPt = (m_unPerturbedTransform*m_transformB.inverse())(pointInWorld); 139 newDepth = (endPt - startPt).dot(normalOnBInWorld); 140 141 } 142 143 //#define DEBUG_CONTACTS 1 144 #ifdef DEBUG_CONTACTS 145 m_debugDrawer->drawLine(startPt,endPt,btVector3(1,0,0)); 146 m_debugDrawer->drawSphere(startPt,0.05,btVector3(0,1,0)); 147 m_debugDrawer->drawSphere(endPt,0.05,btVector3(0,0,1)); 148 #endif //DEBUG_CONTACTS 149 150 151 m_originalManifoldResult->addContactPoint(normalOnBInWorld,startPt,newDepth); 152 } 153 154 }; 155 156 extern btScalar gContactBreakingThreshold; 96 97 157 98 158 99 // … … 170 111 resultOut->setPersistentManifold(m_manifoldPtr); 171 112 172 //comment-out next line to test multi-contact generation173 //resultOut->getPersistentManifold()->clearManifold();174 113 175 114 … … 208 147 209 148 gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); 149 210 150 btScalar sepDist = gjkPairDetector.getCachedSeparatingDistance()+dispatchInfo.m_convexConservativeDistanceThreshold; 211 212 //now perturbe directions to get multiple contact points213 btVector3 v0,v1;214 btVector3 sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis().normalized();215 btPlaneSpace1(sepNormalWorldSpace,v0,v1);216 //now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects217 218 //perform perturbation when more then 'm_minimumPointsPerturbationThreshold' points219 if (resultOut->getPersistentManifold()->getNumContacts() < m_minimumPointsPerturbationThreshold)220 {221 222 int i;223 224 bool perturbeA = true;225 const btScalar angleLimit = 0.125f * SIMD_PI;226 btScalar perturbeAngle;227 btScalar radiusA = min0->getAngularMotionDisc();228 btScalar radiusB = min1->getAngularMotionDisc();229 if (radiusA < radiusB)230 {231 perturbeAngle = gContactBreakingThreshold /radiusA;232 perturbeA = true;233 } else234 {235 perturbeAngle = gContactBreakingThreshold / radiusB;236 perturbeA = false;237 }238 if ( perturbeAngle > angleLimit )239 perturbeAngle = angleLimit;240 241 btTransform unPerturbedTransform;242 if (perturbeA)243 {244 unPerturbedTransform = input.m_transformA;245 } else246 {247 unPerturbedTransform = input.m_transformB;248 }249 250 for ( i=0;i<m_numPerturbationIterations;i++)251 {252 btQuaternion perturbeRot(v0,perturbeAngle);253 btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));254 btQuaternion rotq(sepNormalWorldSpace,iterationAngle);255 256 257 if (perturbeA)258 {259 input.m_transformA.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0->getWorldTransform().getBasis());260 input.m_transformB = body1->getWorldTransform();261 #ifdef DEBUG_CONTACTS262 dispatchInfo.m_debugDraw->drawTransform(input.m_transformA,10.0);263 #endif //DEBUG_CONTACTS264 } else265 {266 input.m_transformA = body0->getWorldTransform();267 input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1->getWorldTransform().getBasis());268 #ifdef DEBUG_CONTACTS269 dispatchInfo.m_debugDraw->drawTransform(input.m_transformB,10.0);270 #endif271 }272 273 btPerturbedContactResult perturbedResultOut(resultOut,input.m_transformA,input.m_transformB,unPerturbedTransform,perturbeA,dispatchInfo.m_debugDraw);274 gjkPairDetector.getClosestPoints(input,perturbedResultOut,dispatchInfo.m_debugDraw);275 276 277 }278 }279 280 281 151 282 152 #ifdef USE_SEPDISTANCE_UTIL2 -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
r2907 r2908 34 34 ///#define USE_SEPDISTANCE_UTIL2 1 35 35 36 ///The convexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations between two convex objects. 37 ///Multiple contact points are calculated by perturbing the orientation of the smallest object orthogonal to the separating normal. 38 ///This idea was described by Gino van den Bergen in this forum topic http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=4&t=288&p=888#p888 36 ///ConvexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations. 39 37 class btConvexConvexAlgorithm : public btActivatingCollisionAlgorithm 40 38 { … … 50 48 bool m_lowLevelOfDetail; 51 49 52 int m_numPerturbationIterations;53 int m_minimumPointsPerturbationThreshold;54 55 56 50 ///cache separating vector to speedup collision detection 57 51 … … 59 53 public: 60 54 61 btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold); 62 55 btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver); 63 56 64 57 virtual ~btConvexConvexAlgorithm(); … … 86 79 struct CreateFunc :public btCollisionAlgorithmCreateFunc 87 80 { 88 89 81 btConvexPenetrationDepthSolver* m_pdSolver; 90 82 btSimplexSolverInterface* m_simplexSolver; 91 int m_numPerturbationIterations; 92 int m_minimumPointsPerturbationThreshold; 93 83 94 84 CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver); 95 85 … … 99 89 { 100 90 void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConvexAlgorithm)); 101 return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver ,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);91 return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver); 102 92 } 103 93 }; -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
r2907 r2908 5 5 This software is provided 'as-is', without any express or implied warranty. 6 6 In no event will the authors be held liable for any damages arising from the use of this software. 7 Permission is granted to anyone to use this software for any purpose, 8 including commercial applications, and to alter it and redistribute it freely, 7 Permission is granted to anyone to use this software for any purpose, 8 including commercial applications, and to alter it and redistribute it freely, 9 9 subject to the following restrictions: 10 10 … … 23 23 //#include <stdio.h> 24 24 25 btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped , int numPerturbationIterations,int minimumPointsPerturbationThreshold)25 btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped) 26 26 : btCollisionAlgorithm(ci), 27 27 m_ownManifold(false), 28 28 m_manifoldPtr(mf), 29 m_isSwapped(isSwapped), 30 m_numPerturbationIterations(numPerturbationIterations), 31 m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold) 29 m_isSwapped(isSwapped) 32 30 { 33 31 btCollisionObject* convexObj = m_isSwapped? col1 : col0; 34 32 btCollisionObject* planeObj = m_isSwapped? col0 : col1; 35 33 36 34 if (!m_manifoldPtr && m_dispatcher->needsCollision(convexObj,planeObj)) 37 35 { … … 51 49 } 52 50 53 void btConvexPlaneCollisionAlgorithm::collideSingleContact (const btQuaternion& perturbeRot, btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) 51 52 53 void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) 54 54 { 55 btCollisionObject* convexObj = m_isSwapped? body1 : body0; 55 (void)dispatchInfo; 56 (void)resultOut; 57 if (!m_manifoldPtr) 58 return; 59 60 btCollisionObject* convexObj = m_isSwapped? body1 : body0; 56 61 btCollisionObject* planeObj = m_isSwapped? body0: body1; 57 62 … … 59 64 btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape(); 60 65 61 66 bool hasCollision = false; 62 67 const btVector3& planeNormal = planeShape->getPlaneNormal(); 63 68 const btScalar& planeConstant = planeShape->getPlaneConstant(); 64 65 btTransform convexWorldTransform = convexObj->getWorldTransform();69 btTransform planeInConvex; 70 planeInConvex= convexObj->getWorldTransform().inverse() * planeObj->getWorldTransform(); 66 71 btTransform convexInPlaneTrans; 67 convexInPlaneTrans= planeObj->getWorldTransform().inverse() * convexWorldTransform; 68 //now perturbe the convex-world transform 69 convexWorldTransform.getBasis()*=btMatrix3x3(perturbeRot); 70 btTransform planeInConvex; 71 planeInConvex= convexWorldTransform.inverse() * planeObj->getWorldTransform(); 72 72 convexInPlaneTrans= planeObj->getWorldTransform().inverse() * convexObj->getWorldTransform(); 73 73 74 btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal); 74 75 75 btVector3 vtxInPlane = convexInPlaneTrans(vtx); 76 76 btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant); … … 88 88 resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance); 89 89 } 90 }91 92 93 void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)94 {95 (void)dispatchInfo;96 if (!m_manifoldPtr)97 return;98 99 btCollisionObject* convexObj = m_isSwapped? body1 : body0;100 btCollisionObject* planeObj = m_isSwapped? body0: body1;101 102 btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();103 btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();104 105 bool hasCollision = false;106 const btVector3& planeNormal = planeShape->getPlaneNormal();107 const btScalar& planeConstant = planeShape->getPlaneConstant();108 109 //first perform a collision query with the non-perturbated collision objects110 {111 btQuaternion rotq(0,0,0,1);112 collideSingleContact(rotq,body0,body1,dispatchInfo,resultOut);113 }114 115 if (resultOut->getPersistentManifold()->getNumContacts()<m_minimumPointsPerturbationThreshold)116 {117 btVector3 v0,v1;118 btPlaneSpace1(planeNormal,v0,v1);119 //now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects120 121 const btScalar angleLimit = 0.125f * SIMD_PI;122 btScalar perturbeAngle;123 btScalar radius = convexShape->getAngularMotionDisc();124 perturbeAngle = gContactBreakingThreshold / radius;125 if ( perturbeAngle > angleLimit )126 perturbeAngle = angleLimit;127 128 btQuaternion perturbeRot(v0,perturbeAngle);129 for (int i=0;i<m_numPerturbationIterations;i++)130 {131 btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));132 btQuaternion rotq(planeNormal,iterationAngle);133 collideSingleContact(rotq.inverse()*perturbeRot*rotq,body0,body1,dispatchInfo,resultOut);134 }135 }136 137 90 if (m_ownManifold) 138 91 { -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
r2907 r2908 5 5 This software is provided 'as-is', without any express or implied warranty. 6 6 In no event will the authors be held liable for any damages arising from the use of this software. 7 Permission is granted to anyone to use this software for any purpose, 8 including commercial applications, and to alter it and redistribute it freely, 7 Permission is granted to anyone to use this software for any purpose, 8 including commercial applications, and to alter it and redistribute it freely, 9 9 subject to the following restrictions: 10 10 … … 29 29 class btConvexPlaneCollisionAlgorithm : public btCollisionAlgorithm 30 30 { 31 bool 31 bool m_ownManifold; 32 32 btPersistentManifold* m_manifoldPtr; 33 bool m_isSwapped; 34 int m_numPerturbationIterations; 35 int m_minimumPointsPerturbationThreshold; 36 33 bool m_isSwapped; 34 37 35 public: 38 36 39 btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped , int numPerturbationIterations,int minimumPointsPerturbationThreshold);37 btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped); 40 38 41 39 virtual ~btConvexPlaneCollisionAlgorithm(); 42 40 43 41 virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); 44 45 void collideSingleContact (const btQuaternion& perturbeRot, btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);46 42 47 43 virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); … … 57 53 struct CreateFunc :public btCollisionAlgorithmCreateFunc 58 54 { 59 int m_numPerturbationIterations;60 int m_minimumPointsPerturbationThreshold;61 62 CreateFunc()63 : m_numPerturbationIterations(3),64 m_minimumPointsPerturbationThreshold(3)65 {66 }67 68 55 virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) 69 56 { … … 71 58 if (!m_swapped) 72 59 { 73 return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,false ,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);60 return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,false); 74 61 } else 75 62 { 76 return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,true ,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);63 return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,true); 77 64 } 78 65 } -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp
r2907 r2908 289 289 return m_emptyCreateFunc; 290 290 } 291 292 void btDefaultCollisionConfiguration::setConvexConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold)293 {294 btConvexConvexAlgorithm::CreateFunc* convexConvex = (btConvexConvexAlgorithm::CreateFunc*) m_convexConvexCreateFunc;295 convexConvex->m_numPerturbationIterations = numPerturbationIterations;296 convexConvex->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;297 } -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h
r2907 r2908 112 112 virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1); 113 113 114 ///Use this method to allow to generate multiple contact points between at once, between two objects using the generic convex-convex algorithm.115 ///By default, this feature is disabled for best performance.116 ///@param numPerturbationIterations controls the number of collision queries. Set it to zero to disable the feature.117 ///@param minimumPointsPerturbationThreshold is the minimum number of points in the contact cache, above which the feature is disabled118 ///3 is a good value for both params, if you want to enable the feature. This is because the default contact cache contains a maximum of 4 points, and one collision query at the unperturbed orientation is performed first.119 ///See Bullet/Demos/CollisionDemo for an example how this feature gathers multiple points.120 ///@todo we could add a per-object setting of those parameters, for level-of-detail collision detection.121 void setConvexConvexMultipointIterations(int numPerturbationIterations=3, int minimumPointsPerturbationThreshold = 3);122 114 123 115 }; -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btGhostObject.cpp
r2907 r2908 64 64 btPairCachingGhostObject::~btPairCachingGhostObject() 65 65 { 66 m_hashPairCache->~btHashedOverlappingPairCache();67 66 btAlignedFree( m_hashPairCache ); 68 67 } -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btManifoldResult.cpp
r2907 r2908 56 56 void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) 57 57 { 58 btAssert(m_manifoldPtr);58 assert(m_manifoldPtr); 59 59 //order in manifold needs to match 60 60 … … 93 93 newPt.m_index0 = m_index0; 94 94 newPt.m_index1 = m_index1; 95 //printf("depth=%f\n",depth);95 96 96 ///@todo, check this for any side effects 97 97 if (insertIndex >= 0) -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btManifoldResult.h
r2907 r2908 46 46 int m_index0; 47 47 int m_index1; 48 49 50 48 public: 51 49 … … 80 78 } 81 79 82 83 80 virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth); 84 81 -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
r2907 r2908 25 25 #include "LinearMath/btQuickprof.h" 26 26 27 btSimulationIslandManager::btSimulationIslandManager(): 28 m_splitIslands(true) 27 btSimulationIslandManager::btSimulationIslandManager() 29 28 { 30 29 } … … 45 44 46 45 { 47 46 btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr(); 47 48 48 for (int i=0;i<colWorld->getPairCache()->getNumOverlappingPairs();i++) 49 49 { 50 btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr();51 50 const btBroadphasePair& collisionPair = pairPtr[i]; 52 51 btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject; … … 187 186 } 188 187 189 btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));188 assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); 190 189 if (colObj0->getIslandTag() == islandId) 191 190 { … … 214 213 } 215 214 216 btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));215 assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); 217 216 218 217 if (colObj0->getIslandTag() == islandId) … … 235 234 } 236 235 237 btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));236 assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); 238 237 239 238 if (colObj0->getIslandTag() == islandId) … … 253 252 int maxNumManifolds = dispatcher->getNumManifolds(); 254 253 255 //#define SPLIT_ISLANDS 1256 //#ifdef SPLIT_ISLANDS257 258 259 //#endif //SPLIT_ISLANDS254 #define SPLIT_ISLANDS 1 255 #ifdef SPLIT_ISLANDS 256 257 258 #endif //SPLIT_ISLANDS 260 259 261 260 … … 281 280 colObj0->activate(); 282 281 } 283 if(m_splitIslands) 284 { 285 //filtering for response 286 if (dispatcher->needsResponse(colObj0,colObj1)) 287 m_islandmanifold.push_back(manifold); 288 } 282 #ifdef SPLIT_ISLANDS 283 // //filtering for response 284 if (dispatcher->needsResponse(colObj0,colObj1)) 285 m_islandmanifold.push_back(manifold); 286 #endif //SPLIT_ISLANDS 289 287 } 290 288 } … … 306 304 BT_PROFILE("processIslands"); 307 305 308 if(!m_splitIslands) 309 { 310 btPersistentManifold** manifold = dispatcher->getInternalManifoldPointer(); 311 int maxNumManifolds = dispatcher->getNumManifolds(); 312 callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, -1); 313 } 314 else 315 { 316 // Sort manifolds, based on islands 317 // Sort the vector using predicate and std::sort 318 //std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate); 319 320 int numManifolds = int (m_islandmanifold.size()); 321 322 //we should do radix sort, it it much faster (O(n) instead of O (n log2(n)) 323 m_islandmanifold.quickSort(btPersistentManifoldSortPredicate()); 324 325 //now process all active islands (sets of manifolds for now) 326 327 int startManifoldIndex = 0; 328 int endManifoldIndex = 1; 329 330 //int islandId; 331 332 333 334 // printf("Start Islands\n"); 335 336 //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated 337 for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex) 338 { 339 int islandId = getUnionFind().getElement(startIslandIndex).m_id; 340 341 342 bool islandSleeping = false; 343 344 for (endIslandIndex = startIslandIndex;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++) 345 { 346 int i = getUnionFind().getElement(endIslandIndex).m_sz; 347 btCollisionObject* colObj0 = collisionObjects[i]; 348 m_islandBodies.push_back(colObj0); 349 if (!colObj0->isActive()) 350 islandSleeping = true; 351 } 352 353 354 //find the accompanying contact manifold for this islandId 355 int numIslandManifolds = 0; 356 btPersistentManifold** startManifold = 0; 357 358 if (startManifoldIndex<numManifolds) 359 { 360 int curIslandId = getIslandId(m_islandmanifold[startManifoldIndex]); 361 if (curIslandId == islandId) 362 { 363 startManifold = &m_islandmanifold[startManifoldIndex]; 364 365 for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(m_islandmanifold[endManifoldIndex]));endManifoldIndex++) 366 { 367 368 } 369 /// Process the actual simulation, only if not sleeping/deactivated 370 numIslandManifolds = endManifoldIndex-startManifoldIndex; 371 } 372 373 } 374 375 if (!islandSleeping) 376 { 377 callback->ProcessIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId); 378 // printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds); 379 } 306 #ifndef SPLIT_ISLANDS 307 btPersistentManifold** manifold = dispatcher->getInternalManifoldPointer(); 308 309 callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, -1); 310 #else 311 // Sort manifolds, based on islands 312 // Sort the vector using predicate and std::sort 313 //std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate); 314 315 int numManifolds = int (m_islandmanifold.size()); 316 317 //we should do radix sort, it it much faster (O(n) instead of O (n log2(n)) 318 m_islandmanifold.quickSort(btPersistentManifoldSortPredicate()); 319 320 //now process all active islands (sets of manifolds for now) 321 322 int startManifoldIndex = 0; 323 int endManifoldIndex = 1; 324 325 //int islandId; 326 327 328 329 // printf("Start Islands\n"); 330 331 //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated 332 for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex) 333 { 334 int islandId = getUnionFind().getElement(startIslandIndex).m_id; 335 336 337 bool islandSleeping = false; 338 339 for (endIslandIndex = startIslandIndex;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++) 340 { 341 int i = getUnionFind().getElement(endIslandIndex).m_sz; 342 btCollisionObject* colObj0 = collisionObjects[i]; 343 m_islandBodies.push_back(colObj0); 344 if (!colObj0->isActive()) 345 islandSleeping = true; 346 } 347 348 349 //find the accompanying contact manifold for this islandId 350 int numIslandManifolds = 0; 351 btPersistentManifold** startManifold = 0; 352 353 if (startManifoldIndex<numManifolds) 354 { 355 int curIslandId = getIslandId(m_islandmanifold[startManifoldIndex]); 356 if (curIslandId == islandId) 357 { 358 startManifold = &m_islandmanifold[startManifoldIndex]; 380 359 381 if (numIslandManifolds) 382 { 383 startManifoldIndex = endManifoldIndex; 384 } 385 386 m_islandBodies.resize(0); 387 } 388 } // else if(!splitIslands) 389 390 } 360 for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(m_islandmanifold[endManifoldIndex]));endManifoldIndex++) 361 { 362 363 } 364 /// Process the actual simulation, only if not sleeping/deactivated 365 numIslandManifolds = endManifoldIndex-startManifoldIndex; 366 } 367 368 } 369 370 if (!islandSleeping) 371 { 372 callback->ProcessIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId); 373 // printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds); 374 } 375 376 if (numIslandManifolds) 377 { 378 startManifoldIndex = endManifoldIndex; 379 } 380 381 m_islandBodies.resize(0); 382 } 383 #endif //SPLIT_ISLANDS 384 385 386 } -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.h
r2907 r2908 36 36 btAlignedObjectArray<btCollisionObject* > m_islandBodies; 37 37 38 bool m_splitIslands;39 38 40 39 public: … … 67 66 void buildIslands(btDispatcher* dispatcher,btCollisionWorld* colWorld); 68 67 69 bool getSplitIslands()70 {71 return m_splitIslands;72 }73 void setSplitIslands(bool doSplitIslands)74 {75 m_splitIslands = doSplitIslands;76 }77 78 68 }; 79 69 -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
r2907 r2908 79 79 80 80 ///point on A (worldspace) 81 ///btVector3 pos0 = col0->getWorldTransform().getOrigin() - radius0 * normalOnSurfaceB;81 btVector3 pos0 = col0->getWorldTransform().getOrigin() - radius0 * normalOnSurfaceB; 82 82 ///point on B (worldspace) 83 83 btVector3 pos1 = col1->getWorldTransform().getOrigin() + radius1* normalOnSurfaceB; -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btUnionFind.cpp
r2907 r2908 15 15 16 16 #include "btUnionFind.h" 17 #include <assert.h> 18 17 19 18 20 -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionDispatch/btUnionFind.h
r2907 r2908 99 99 int find(int x) 100 100 { 101 // btAssert(x < m_N);102 // btAssert(x >= 0);101 //assert(x < m_N); 102 //assert(x >= 0); 103 103 104 104 while (x != m_elements[x].m_id) … … 111 111 #endif // 112 112 x = m_elements[x].m_id; 113 // btAssert(x < m_N);114 // btAssert(x >= 0);113 //assert(x < m_N); 114 //assert(x >= 0); 115 115 116 116 } -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btBoxShape.h
r2907 r2908 162 162 { 163 163 case 0: 164 plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x()); 164 plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.)); 165 plane[3] = -halfExtents.x(); 165 166 break; 166 167 case 1: 167 plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x()); 168 plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.)); 169 plane[3] = -halfExtents.x(); 168 170 break; 169 171 case 2: 170 plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y()); 172 plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.)); 173 plane[3] = -halfExtents.y(); 171 174 break; 172 175 case 3: 173 plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y()); 176 plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.)); 177 plane[3] = -halfExtents.y(); 174 178 break; 175 179 case 4: 176 plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z()); 180 plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.)); 181 plane[3] = -halfExtents.z(); 177 182 break; 178 183 case 5: 179 plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z()); 184 plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.)); 185 plane[3] = -halfExtents.z(); 180 186 break; 181 187 default: 182 btAssert(0);188 assert(0); 183 189 } 184 190 } … … 307 313 break; 308 314 default: 309 btAssert(0);315 assert(0); 310 316 } 311 317 } -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btCollisionShape.cpp
r2907 r2908 15 15 16 16 #include "BulletCollision/CollisionShapes/btCollisionShape.h" 17 18 19 btScalar gContactThresholdFactor=btScalar(0.02);20 17 21 18 … … 48 45 btScalar btCollisionShape::getContactBreakingThreshold() const 49 46 { 50 return getAngularMotionDisc() * gContactThresholdFactor; 47 ///@todo make this 0.1 configurable 48 return getAngularMotionDisc() * btScalar(0.1); 51 49 } 52 50 btScalar btCollisionShape::getAngularMotionDisc() const -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btCompoundShape.cpp
r2907 r2908 23 23 m_collisionMargin(btScalar(0.)), 24 24 m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)), 25 m_dynamicAabbTree(0), 26 m_updateRevision(1) 25 m_dynamicAabbTree(0) 27 26 { 28 27 m_shapeType = COMPOUND_SHAPE_PROXYTYPE; … … 48 47 void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape) 49 48 { 50 m_updateRevision++;51 49 //m_childTransforms.push_back(localTransform); 52 50 //m_childShapes.push_back(shape); … … 57 55 child.m_childMargin = shape->getMargin(); 58 56 59 57 m_children.push_back(child); 58 60 59 //extend the local aabbMin/aabbMax 61 60 btVector3 localAabbMin,localAabbMax; … … 76 75 { 77 76 const btDbvtVolume bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax); 78 int index = m_children.size() ;77 int index = m_children.size()-1; 79 78 child.m_node = m_dynamicAabbTree->insert(bounds,(void*)index); 80 79 } 81 82 m_children.push_back(child);83 80 84 81 } … … 103 100 void btCompoundShape::removeChildShapeByIndex(int childShapeIndex) 104 101 { 105 m_updateRevision++;106 102 btAssert(childShapeIndex >=0 && childShapeIndex < m_children.size()); 107 103 if (m_dynamicAabbTree) … … 118 114 void btCompoundShape::removeChildShape(btCollisionShape* shape) 119 115 { 120 m_updateRevision++;121 116 // Find the children containing the shape specified, and remove those children. 122 117 //note: there might be multiple children using the same shape! … … 145 140 // Recalculate the local aabb 146 141 // Brute force, it iterates over all the shapes left. 147 148 142 m_localAabbMin = btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30)); 149 143 m_localAabbMax = btVector3(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); … … 168 162 { 169 163 btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin); 164 localHalfExtents += btVector3(getMargin(),getMargin(),getMargin()); 170 165 btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin); 171 172 //avoid an illegal AABB when there are no children173 if (!m_children.size())174 {175 localHalfExtents.setValue(0,0,0);176 localCenter.setValue(0,0,0);177 }178 localHalfExtents += btVector3(getMargin(),getMargin(),getMargin());179 180 166 181 167 btMatrix3x3 abs_b = trans.getBasis().absolute(); … … 188 174 aabbMin = center-extent; 189 175 aabbMax = center+extent; 190 176 191 177 } 192 178 -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btCompoundShape.h
r2907 r2908 59 59 60 60 btDbvt* m_dynamicAabbTree; 61 62 ///increment m_updateRevision when adding/removing/replacing child shapes, so that some caches can be updated63 int m_updateRevision;64 61 65 62 public: … … 156 153 void calculatePrincipalAxisTransform(btScalar* masses, btTransform& principal, btVector3& inertia) const; 157 154 158 int getUpdateRevision() const159 {160 return m_updateRevision;161 }162 155 163 156 private: -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btConeShape.cpp
r2907 r2908 61 61 break; 62 62 default: 63 btAssert(0);63 assert(0); 64 64 }; 65 65 } -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btConvexHullShape.cpp
r2907 r2908 182 182 bool btConvexHullShape::isInside(const btVector3& ,btScalar ) const 183 183 { 184 btAssert(0);184 assert(0); 185 185 return false; 186 186 } -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
r2907 r2908 151 151 bool btConvexPointCloudShape::isInside(const btVector3& ,btScalar ) const 152 152 { 153 btAssert(0);153 assert(0); 154 154 return false; 155 155 } -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btConvexShape.cpp
r2907 r2908 155 155 156 156 btCapsuleShape* capsuleShape = (btCapsuleShape*)this; 157 btVector3 halfExtents = capsuleShape->getImplicitShapeDimensions(); 157 158 btScalar halfHeight = capsuleShape->getHalfHeight(); 158 159 int capsuleUpAxis = capsuleShape->getUpAxis(); … … 301 302 { 302 303 btSphereShape* sphereShape = (btSphereShape*)this; 303 btScalarradius = sphereShape->getImplicitShapeDimensions().getX();// * convexShape->getLocalScaling().getX();304 btScalarmargin = radius + sphereShape->getMarginNonVirtual();304 float radius = sphereShape->getImplicitShapeDimensions().getX();// * convexShape->getLocalScaling().getX(); 305 float margin = radius + sphereShape->getMarginNonVirtual(); 305 306 const btVector3& center = t.getOrigin(); 306 307 btVector3 extent(margin,margin,margin); … … 314 315 { 315 316 btBoxShape* convexShape = (btBoxShape*)this; 316 btScalarmargin=convexShape->getMarginNonVirtual();317 float margin=convexShape->getMarginNonVirtual(); 317 318 btVector3 halfExtents = convexShape->getImplicitShapeDimensions(); 318 319 halfExtents += btVector3(margin,margin,margin); -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
r2907 r2908 145 145 } 146 146 147 148 /// This returns the "raw" (user's initial) height, not the actual height. 149 /// The actual height needs to be adjusted to be relative to the center 150 /// of the heightfield's AABB. 151 btScalar 152 btHeightfieldTerrainShape::getRawHeightFieldValue(int x,int y) const 147 btScalar btHeightfieldTerrainShape::getHeightFieldValue(int x,int y) const 153 148 { 154 149 btScalar val = 0.f; … … 187 182 188 183 189 /// this returns the vertex in bullet-local coordinates 184 190 185 void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const 191 186 { 187 192 188 btAssert(x>=0); 193 189 btAssert(y>=0); … … 195 191 btAssert(y<m_heightStickLength); 196 192 197 btScalar height = getRawHeightFieldValue(x,y); 193 194 btScalar height = getHeightFieldValue(x,y); 198 195 199 196 switch (m_upAxis) … … 202 199 { 203 200 vertex.setValue( 204 height - m_localOrigin.getX(),201 height, 205 202 (-m_width/btScalar(2.0)) + x, 206 203 (-m_length/btScalar(2.0) ) + y … … 212 209 vertex.setValue( 213 210 (-m_width/btScalar(2.0)) + x, 214 height - m_localOrigin.getY(),211 height, 215 212 (-m_length/btScalar(2.0)) + y 216 213 ); … … 222 219 (-m_width/btScalar(2.0)) + x, 223 220 (-m_length/btScalar(2.0)) + y, 224 height - m_localOrigin.getZ()221 height 225 222 ); 226 223 break; … … 234 231 235 232 vertex*=m_localScaling; 233 236 234 } 237 235 … … 241 239 getQuantized 242 240 ( 243 btScalarx241 float x 244 242 ) 245 243 { -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
r2907 r2908 30 30 center (as determined by width and length and height, with each 31 31 axis multiplied by the localScaling). 32 33 \b NOTE: be careful with coordinates. If you have a heightfield with a local34 min height of -100m, and a max height of +500m, you may be tempted to place it35 at the origin (0,0) and expect the heights in world coordinates to be36 -100 to +500 meters.37 Actually, the heights will be -300 to +300m, because bullet will re-center38 the heightfield based on its AABB (which is determined by the min/max39 heights). So keep in mind that once you create a btHeightfieldTerrainShape40 object, the heights will be adjusted relative to the center of the AABB. This41 is different to the behavior of many rendering engines, but is useful for42 physics engines.43 32 44 33 Most (but not all) rendering and heightfield libraries assume upAxis = 1 … … 100 89 btVector3 m_localScaling; 101 90 102 virtual btScalar get RawHeightFieldValue(int x,int y) const;91 virtual btScalar getHeightFieldValue(int x,int y) const; 103 92 void quantizeWithClamp(int* out, const btVector3& point,int isMax) const; 104 93 void getVertex(int x,int y,btVector3& vertex) const; -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp
r2907 r2908 29 29 btVector3 btMinkowskiSumShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const 30 30 { 31 btVector3 supVertexA = m_transA(m_shapeA->localGetSupportingVertexWithoutMargin( vec*m_transA.getBasis()));32 btVector3 supVertexB = m_transB(m_shapeB->localGetSupportingVertexWithoutMargin( -vec*m_transB.getBasis()));31 btVector3 supVertexA = m_transA(m_shapeA->localGetSupportingVertexWithoutMargin(-vec*m_transA.getBasis())); 32 btVector3 supVertexB = m_transB(m_shapeB->localGetSupportingVertexWithoutMargin(vec*m_transB.getBasis())); 33 33 return supVertexA - supVertexB; 34 34 } -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h
r2907 r2908 32 32 BT_DECLARE_ALIGNED_ALLOCATOR(); 33 33 34 btMultimaterialTriangleMeshShape(): btBvhTriangleMeshShape() { m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;}34 btMultimaterialTriangleMeshShape(): btBvhTriangleMeshShape() {} 35 35 btMultimaterialTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true): 36 36 btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, buildBvh) 37 37 { 38 m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;39 40 38 btVector3 m_triangle[3]; 41 39 const unsigned char *vertexbase; … … 70 68 btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, bvhAabbMin, bvhAabbMax, buildBvh) 71 69 { 72 m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;73 74 70 btVector3 m_triangle[3]; 75 71 const unsigned char *vertexbase; … … 112 108 */ 113 109 } 110 virtual int getShapeType() const 111 { 112 return MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE; 113 } 114 114 115 //debugging 115 116 virtual const char* getName()const {return "MULTIMATERIALTRIANGLEMESH";} -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btSphereShape.h
r2907 r2908 48 48 btScalar getRadius() const { return m_implicitShapeDimensions.getX() * m_localScaling.getX();} 49 49 50 void setUnscaledRadius(btScalar radius)51 {52 m_implicitShapeDimensions.setX(radius);53 btConvexInternalShape::setMargin(radius);54 }55 56 50 //debugging 57 51 virtual const char* getName()const {return "SPHERE";} -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp
r2907 r2908 83 83 } 84 84 85 86 void btTriangleIndexVertexArray::setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const 85 void btTriangleIndexVertexArray::setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) 87 86 { 88 87 m_aabbMin = aabbMin; … … 97 96 } 98 97 99 -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h
r2907 r2908 53 53 IndexedMeshArray m_indexedMeshes; 54 54 int m_pad[2]; 55 mutableint m_hasAabb; // using int instead of bool to maintain alignment56 mutablebtVector3 m_aabbMin;57 mutablebtVector3 m_aabbMax;55 int m_hasAabb; // using int instead of bool to maintain alignment 56 btVector3 m_aabbMin; 57 btVector3 m_aabbMax; 58 58 59 59 public: … … 107 107 108 108 virtual bool hasPremadeAabb() const; 109 virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const;109 virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ); 110 110 virtual void getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const; 111 111 -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
r2907 r2908 1 2 1 /* 3 2 Bullet Continuous Collision Detection and Physics Library -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btTriangleMesh.cpp
r2907 r2908 36 36 { 37 37 m_indexedMeshes[0].m_numTriangles = m_32bitIndices.size()/3; 38 m_indexedMeshes[0].m_triangleIndexBase = 0;38 m_indexedMeshes[0].m_triangleIndexBase = (unsigned char*) &m_32bitIndices[0]; 39 39 m_indexedMeshes[0].m_indexType = PHY_INTEGER; 40 40 m_indexedMeshes[0].m_triangleIndexStride = 3*sizeof(int); … … 42 42 { 43 43 m_indexedMeshes[0].m_numTriangles = m_16bitIndices.size()/3; 44 m_indexedMeshes[0].m_triangleIndexBase = 0;44 m_indexedMeshes[0].m_triangleIndexBase = (unsigned char*) &m_16bitIndices[0]; 45 45 m_indexedMeshes[0].m_indexType = PHY_SHORT; 46 46 m_indexedMeshes[0].m_triangleIndexStride = 3*sizeof(short int); … … 50 50 { 51 51 m_indexedMeshes[0].m_numVertices = m_4componentVertices.size(); 52 m_indexedMeshes[0].m_vertexBase = 0;52 m_indexedMeshes[0].m_vertexBase = (unsigned char*)&m_4componentVertices[0]; 53 53 m_indexedMeshes[0].m_vertexStride = sizeof(btVector3); 54 54 } else 55 55 { 56 56 m_indexedMeshes[0].m_numVertices = m_3componentVertices.size()/3; 57 m_indexedMeshes[0].m_vertexBase = 0;57 m_indexedMeshes[0].m_vertexBase = (unsigned char*)&m_3componentVertices[0]; 58 58 m_indexedMeshes[0].m_vertexStride = 3*sizeof(btScalar); 59 59 } … … 112 112 } 113 113 } 114 m_3componentVertices.push_back( (float)vertex.getX());115 m_3componentVertices.push_back( (float)vertex.getY());116 m_3componentVertices.push_back( (float)vertex.getZ());114 m_3componentVertices.push_back(vertex.getX()); 115 m_3componentVertices.push_back(vertex.getY()); 116 m_3componentVertices.push_back(vertex.getZ()); 117 117 m_indexedMeshes[0].m_numVertices++; 118 118 m_indexedMeshes[0].m_vertexBase = (unsigned char*)&m_3componentVertices[0]; -
code/branches/questsystem5/src/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.h
r2907 r2908 41 41 virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const 42 42 { 43 btAssert(0);43 assert(0); 44 44 return localGetSupportingVertex(vec); 45 45 } -
code/branches/questsystem5/src/bullet/BulletCollision/Gimpact/btGImpactBvh.cpp
r2907 r2908 151 151 } 152 152 153 btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex)))); 153 bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex)); 154 btAssert(!unbal); 154 155 155 156 return splitIndex; -
code/branches/questsystem5/src/bullet/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp
r2907 r2908 172 172 } 173 173 174 btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex)))); 174 bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex)); 175 btAssert(!unbal); 175 176 176 177 return splitIndex; -
code/branches/questsystem5/src/bullet/BulletCollision/Gimpact/btGImpactShape.h
r2907 r2908 882 882 class btGImpactMeshShape : public btGImpactShapeInterface 883 883 { 884 btStridingMeshInterface* m_meshInterface;885 886 884 protected: 887 885 btAlignedObjectArray<btGImpactMeshShapePart*> m_mesh_parts; … … 910 908 btGImpactMeshShape(btStridingMeshInterface * meshInterface) 911 909 { 912 m_meshInterface = meshInterface;913 910 buildMeshParts(meshInterface); 914 911 } … … 926 923 927 924 928 btStridingMeshInterface* getMeshInterface()929 {930 return m_meshInterface;931 }932 933 const btStridingMeshInterface* getMeshInterface() const934 {935 return m_meshInterface;936 }937 925 938 926 int getMeshPartCount() const … … 1046 1034 1047 1035 //! call when reading child shapes 1048 virtual void lockChildShapes() const1049 { 1050 btAssert(0); 1051 } 1052 1053 virtual void unlockChildShapes() const1036 virtual void lockChildShapes() 1037 { 1038 btAssert(0); 1039 } 1040 1041 virtual void unlockChildShapes() 1054 1042 { 1055 1043 btAssert(0); -
code/branches/questsystem5/src/bullet/BulletCollision/Gimpact/gim_box_set.cpp
r2907 r2908 111 111 } 112 112 113 btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex)))); 113 bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex)); 114 btAssert(!unbal); 114 115 115 116 return splitIndex; … … 180 181 } 181 182 182 -
code/branches/questsystem5/src/bullet/BulletCollision/Gimpact/gim_math.h
r2907 r2908 108 108 #define GIM_CLAMP(number,minval,maxval) (number<minval?minval:(number>maxval?maxval:number)) 109 109 110 #define GIM_GREATER(x, y) btFabs(x) > (y)110 #define GIM_GREATER(x, y) fabsf(x) > (y) 111 111 112 112 ///Swap numbers -
code/branches/questsystem5/src/bullet/BulletCollision/Gimpact/gim_tri_collision.h
r2907 r2908 276 276 else 277 277 { 278 btScalarsumuv;278 float sumuv; 279 279 sumuv = u+v; 280 280 if(sumuv<-G_EPSILON) -
code/branches/questsystem5/src/bullet/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
r2907 r2908 136 136 //btScalar clippedDist = dist; 137 137 138 //don't report time of impact for motion away from the contact normal (or causes minor penetration)139 if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=SIMD_EPSILON)140 return false;141 138 142 139 dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity); … … 200 197 201 198 } 202 199 200 //don't report time of impact for motion away from the contact normal (or causes minor penetration) 203 201 if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=result.m_allowedPenetration)//SIMD_EPSILON) 204 202 return false; 205 203 206 204 result.m_fraction = lambda; 207 205 result.m_normal = n; -
code/branches/questsystem5/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
r2907 r2908 151 151 if ((delta > btScalar(0.0)) && (delta * delta > squaredDistance * input.m_maximumDistanceSquared)) 152 152 { 153 checkSimplex=true; 154 //checkPenetration = false; 153 checkPenetration = false; 155 154 break; 156 155 } -
code/branches/questsystem5/src/bullet/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
r2907 r2908 113 113 } 114 114 115 ///this returns the most recent applied impulse, to satisfy contact constraints by the constraint solver116 btScalar getAppliedImpulse() const117 {118 return m_appliedImpulse;119 }120 121 115 122 116 -
code/branches/questsystem5/src/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
r2907 r2908 184 184 185 185 } 186 if (insertIndex<0)187 insertIndex=0;188 189 186 btAssert(m_pointCache[insertIndex].m_userPersistentData==0); 190 187 m_pointCache[insertIndex] = newPoint; -
code/branches/questsystem5/src/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
r2907 r2908 56 56 57 57 btScalar m_contactBreakingThreshold; 58 btScalar m_contactProcessingThreshold;59 58 60 59 … … 72 71 btPersistentManifold(); 73 72 74 btPersistentManifold(void* body0,void* body1,int , btScalar contactBreakingThreshold ,btScalar contactProcessingThreshold)73 btPersistentManifold(void* body0,void* body1,int , btScalar contactBreakingThreshold) 75 74 : m_body0(body0),m_body1(body1),m_cachedPoints(0), 76 m_contactBreakingThreshold(contactBreakingThreshold), 77 m_contactProcessingThreshold(contactProcessingThreshold) 75 m_contactBreakingThreshold(contactBreakingThreshold) 78 76 { 79 77 … … 114 112 ///@todo: get this margin from the current physics / collision environment 115 113 btScalar getContactBreakingThreshold() const; 116 117 btScalar getContactProcessingThreshold() const118 {119 return m_contactProcessingThreshold;120 }121 114 122 115 int getCacheEntry(const btManifoldPoint& newPoint) const; -
code/branches/questsystem5/src/bullet/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
r2907 r2908 24 24 #include "btRaycastCallback.h" 25 25 26 btTriangleRaycastCallback::btTriangleRaycastCallback(const btVector3& from,const btVector3& to , unsigned int flags)26 btTriangleRaycastCallback::btTriangleRaycastCallback(const btVector3& from,const btVector3& to) 27 27 : 28 28 m_from(from), 29 29 m_to(to), 30 //@BP Mod31 m_flags(flags),32 30 m_hitFraction(btScalar(1.)) 33 31 { … … 58 56 return ; // same sign 59 57 } 60 //@BP Mod - Backface filtering61 if (((m_flags & kF_FilterBackfaces) != 0) && (dist_a > btScalar(0.0)))62 {63 // Backface, skip check64 return;65 }66 58 67 59 const btScalar proj_length=dist_a-dist_b; … … 98 90 if ( (btScalar)(cp2.dot(triangleNormal)) >=edge_tolerance) 99 91 { 100 //@BP Mod101 // Triangle normal isn't normalized102 triangleNormal.normalize();103 92 104 //@BP Mod - Allow for unflipped normal when raycasting against backfaces 105 if (((m_flags & kF_KeepUnflippedNormal) != 0) || (dist_a <= btScalar(0.0))) 93 if ( dist_a > 0 ) 106 94 { 107 m_hitFraction = reportHit( -triangleNormal,distance,partId,triangleIndex);95 m_hitFraction = reportHit(triangleNormal,distance,partId,triangleIndex); 108 96 } 109 97 else 110 98 { 111 m_hitFraction = reportHit(triangleNormal,distance,partId,triangleIndex);99 m_hitFraction = reportHit(-triangleNormal,distance,partId,triangleIndex); 112 100 } 113 101 } -
code/branches/questsystem5/src/bullet/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
r2907 r2908 30 30 btVector3 m_to; 31 31 32 //@BP Mod - allow backface filtering and unflipped normals33 enum EFlags34 {35 kF_None = 0,36 kF_FilterBackfaces = 1 << 0,37 kF_KeepUnflippedNormal = 1 << 1, // Prevents returned face normal getting flipped when a ray hits a back-facing triangle38 39 kF_Terminator = 0xFFFFFFFF40 };41 unsigned int m_flags;42 43 32 btScalar m_hitFraction; 44 33 45 btTriangleRaycastCallback(const btVector3& from,const btVector3& to , unsigned int flags=0);34 btTriangleRaycastCallback(const btVector3& from,const btVector3& to); 46 35 47 36 virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); -
code/branches/questsystem5/src/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
r2907 r2908 26 26 27 27 #include "btVoronoiSimplexSolver.h" 28 #include <assert.h> 29 //#include <stdio.h> 28 30 29 31 #define VERTA 0 … … 36 38 { 37 39 38 btAssert(m_numVertices>0);40 assert(m_numVertices>0); 39 41 m_numVertices--; 40 42 m_simplexVectorW[index] = m_simplexVectorW[m_numVertices]; -
code/branches/questsystem5/src/bullet/BulletDynamics/CMakeLists.txt
r2907 r2908 36 36 ConstraintSolver/btTypedConstraint.h 37 37 38 Dynamics/btActionInterface.h39 38 Dynamics/btContinuousDynamicsWorld.h 40 39 Dynamics/btDiscreteDynamicsWorld.h -
code/branches/questsystem5/src/bullet/BulletDynamics/Character/btCharacterControllerInterface.h
r2907 r2908 18 18 19 19 #include "LinearMath/btVector3.h" 20 #include "BulletDynamics/Dynamics/btActionInterface.h"21 20 22 21 class btCollisionShape; … … 24 23 class btCollisionWorld; 25 24 26 class btCharacterControllerInterface : public btActionInterface25 class btCharacterControllerInterface 27 26 { 28 27 public: -
code/branches/questsystem5/src/bullet/BulletDynamics/Character/btKinematicCharacterController.cpp
r2907 r2908 23 23 #include "btKinematicCharacterController.h" 24 24 25 static btVector3 upAxisDirection[3] = { btVector3(1.0f, 0.0f, 0.0f), btVector3(0.0f, 1.0f, 0.0f), btVector3(0.0f, 0.0f, 1.0f) };26 27 25 ///@todo Interact with dynamic objects, 28 26 ///Ride kinematicly animated platforms properly … … 96 94 } 97 95 98 btKinematicCharacterController::btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight, int upAxis) 99 { 100 m_upAxis = upAxis; 96 btKinematicCharacterController::btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight) 97 { 101 98 m_addedMargin = 0.02f; 102 99 m_walkDirection.setValue(0,0,0); … … 105 102 m_stepHeight = stepHeight; 106 103 m_turnAngle = btScalar(0.0); 107 m_convexShape=convexShape; 104 m_convexShape=convexShape; 105 108 106 } 109 107 … … 112 110 } 113 111 112 114 113 btPairCachingGhostObject* btKinematicCharacterController::getGhostObject() 115 114 { … … 117 116 } 118 117 119 bool btKinematicCharacterController::recoverFromPenetration ( 118 bool btKinematicCharacterController::recoverFromPenetration (btCollisionWorld* collisionWorld) 120 119 { 121 120 … … 174 173 // phase 1: up 175 174 btTransform start, end; 176 m_targetPosition = m_currentPosition + upAxisDirection[m_upAxis] * m_stepHeight;175 m_targetPosition = m_currentPosition + btVector3 (btScalar(0.0), m_stepHeight, btScalar(0.0)); 177 176 178 177 start.setIdentity (); … … 180 179 181 180 /* FIXME: Handle penetration properly */ 182 start.setOrigin (m_currentPosition + upAxisDirection[m_upAxis] * btScalar(0.1f));181 start.setOrigin (m_currentPosition + btVector3(btScalar(0.0), btScalar(0.1), btScalar(0.0))); 183 182 end.setOrigin (m_targetPosition); 184 183 … … 345 344 346 345 // phase 3: down 347 btVector3 step_drop = upAxisDirection[m_upAxis] * m_currentStepOffset;348 btVector3 gravity_drop = upAxisDirection[m_upAxis] * m_stepHeight;346 btVector3 step_drop = btVector3(btScalar(0.0), m_currentStepOffset, btScalar(0.0)); 347 btVector3 gravity_drop = btVector3(btScalar(0.0), m_stepHeight, btScalar(0.0)); 349 348 m_targetPosition -= (step_drop + gravity_drop); 350 349 … … 391 390 392 391 393 void btKinematicCharacterController::preStep ( 392 void btKinematicCharacterController::preStep ( btCollisionWorld* collisionWorld) 394 393 { 395 394 … … 414 413 } 415 414 416 void btKinematicCharacterController::playerStep ( 415 void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWorld, btScalar dt) 417 416 { 418 417 btTransform xform; … … 470 469 return true; 471 470 } 472 473 474 void btKinematicCharacterController::debugDraw(btIDebugDraw* debugDrawer)475 {476 } -
code/branches/questsystem5/src/bullet/BulletDynamics/Character/btKinematicCharacterController.h
r2907 r2908 63 63 64 64 bool m_useGhostObjectSweepTest; 65 66 int m_upAxis;67 65 68 66 btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal); … … 70 68 btVector3 perpindicularComponent (const btVector3& direction, const btVector3& normal); 71 69 72 bool recoverFromPenetration ( 70 bool recoverFromPenetration (btCollisionWorld* collisionWorld); 73 71 void stepUp (btCollisionWorld* collisionWorld); 74 72 void updateTargetPositionBasedOnCollision (const btVector3& hit_normal, btScalar tangentMag = btScalar(0.0), btScalar normalMag = btScalar(1.0)); … … 76 74 void stepDown (btCollisionWorld* collisionWorld, btScalar dt); 77 75 public: 78 btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight , int upAxis = 1);76 btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight); 79 77 ~btKinematicCharacterController (); 80 78 81 82 ///btActionInterface interface83 virtual void updateAction( btCollisionWorld* collisionWorld,btScalar deltaTime)84 {85 preStep ( collisionWorld);86 playerStep (collisionWorld, deltaTime);87 }88 89 ///btActionInterface interface90 void debugDraw(btIDebugDraw* debugDrawer);91 92 void setUpAxis (int axis)93 {94 if (axis < 0)95 axis = 0;96 if (axis > 2)97 axis = 2;98 m_upAxis = axis;99 }100 101 79 virtual void setWalkDirection(const btVector3& walkDirection) 102 80 { … … 107 85 void warp (const btVector3& origin); 108 86 109 void preStep ( 110 void playerStep ( 87 void preStep ( btCollisionWorld* collisionWorld); 88 void playerStep (btCollisionWorld* collisionWorld, btScalar dt); 111 89 112 90 void setFallSpeed (btScalar fallSpeed); -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
r2907 r2908 23 23 #include <new> 24 24 25 //-----------------------------------------------------------------------------26 27 #define CONETWIST_USE_OBSOLETE_SOLVER false28 #define CONETWIST_DEF_FIX_THRESH btScalar(.05f)29 30 //-----------------------------------------------------------------------------31 32 25 btConeTwistConstraint::btConeTwistConstraint() 33 :btTypedConstraint(CONETWIST_CONSTRAINT_TYPE), 34 m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER) 26 :btTypedConstraint(CONETWIST_CONSTRAINT_TYPE) 35 27 { 36 28 } … … 40 32 const btTransform& rbAFrame,const btTransform& rbBFrame) 41 33 :btTypedConstraint(CONETWIST_CONSTRAINT_TYPE, rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame), 42 m_angularOnly(false), 43 m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER) 44 { 45 init(); 34 m_angularOnly(false) 35 { 36 m_swingSpan1 = btScalar(1e30); 37 m_swingSpan2 = btScalar(1e30); 38 m_twistSpan = btScalar(1e30); 39 m_biasFactor = 0.3f; 40 m_relaxationFactor = 1.0f; 41 42 m_solveTwistLimit = false; 43 m_solveSwingLimit = false; 44 46 45 } 47 46 48 47 btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame) 49 48 :btTypedConstraint(CONETWIST_CONSTRAINT_TYPE,rbA),m_rbAFrame(rbAFrame), 50 m_angularOnly(false), 51 m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER) 49 m_angularOnly(false) 52 50 { 53 51 m_rbBFrame = m_rbAFrame; 54 init();55 } 56 57 58 void btConeTwistConstraint::init() 59 { 60 m_angularOnly = false; 52 53 m_swingSpan1 = btScalar(1e30); 54 m_swingSpan2 = btScalar(1e30); 55 m_twistSpan = btScalar(1e30); 56 m_biasFactor = 0.3f; 57 m_relaxationFactor = 1.0f; 58 61 59 m_solveTwistLimit = false; 62 60 m_solveSwingLimit = false; 63 m_bMotorEnabled = false; 64 m_maxMotorImpulse = btScalar(-1); 65 66 setLimit(btScalar(1e30), btScalar(1e30), btScalar(1e30)); 67 m_damping = btScalar(0.01); 68 m_fixThresh = CONETWIST_DEF_FIX_THRESH; 69 } 70 71 72 //----------------------------------------------------------------------------- 73 74 void btConeTwistConstraint::getInfo1 (btConstraintInfo1* info) 75 { 76 if (m_useSolveConstraintObsolete) 77 { 78 info->m_numConstraintRows = 0; 79 info->nub = 0; 80 } 81 else 82 { 83 info->m_numConstraintRows = 3; 84 info->nub = 3; 85 calcAngleInfo2(); 86 if(m_solveSwingLimit) 87 { 88 info->m_numConstraintRows++; 89 info->nub--; 90 if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh)) 91 { 92 info->m_numConstraintRows++; 93 info->nub--; 94 } 95 } 96 if(m_solveTwistLimit) 97 { 98 info->m_numConstraintRows++; 99 info->nub--; 100 } 101 } 102 } // btConeTwistConstraint::getInfo1() 103 104 //----------------------------------------------------------------------------- 105 106 void btConeTwistConstraint::getInfo2 (btConstraintInfo2* info) 107 { 108 btAssert(!m_useSolveConstraintObsolete); 109 //retrieve matrices 110 btTransform body0_trans; 111 body0_trans = m_rbA.getCenterOfMassTransform(); 112 btTransform body1_trans; 113 body1_trans = m_rbB.getCenterOfMassTransform(); 114 // set jacobian 115 info->m_J1linearAxis[0] = 1; 116 info->m_J1linearAxis[info->rowskip+1] = 1; 117 info->m_J1linearAxis[2*info->rowskip+2] = 1; 118 btVector3 a1 = body0_trans.getBasis() * m_rbAFrame.getOrigin(); 119 { 120 btVector3* angular0 = (btVector3*)(info->m_J1angularAxis); 121 btVector3* angular1 = (btVector3*)(info->m_J1angularAxis+info->rowskip); 122 btVector3* angular2 = (btVector3*)(info->m_J1angularAxis+2*info->rowskip); 123 btVector3 a1neg = -a1; 124 a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2); 125 } 126 btVector3 a2 = body1_trans.getBasis() * m_rbBFrame.getOrigin(); 127 { 128 btVector3* angular0 = (btVector3*)(info->m_J2angularAxis); 129 btVector3* angular1 = (btVector3*)(info->m_J2angularAxis+info->rowskip); 130 btVector3* angular2 = (btVector3*)(info->m_J2angularAxis+2*info->rowskip); 131 a2.getSkewSymmetricMatrix(angular0,angular1,angular2); 132 } 133 // set right hand side 134 btScalar k = info->fps * info->erp; 135 int j; 136 for (j=0; j<3; j++) 137 { 138 info->m_constraintError[j*info->rowskip] = k * (a2[j] + body1_trans.getOrigin()[j] - a1[j] - body0_trans.getOrigin()[j]); 139 info->m_lowerLimit[j*info->rowskip] = -SIMD_INFINITY; 140 info->m_upperLimit[j*info->rowskip] = SIMD_INFINITY; 141 } 142 int row = 3; 143 int srow = row * info->rowskip; 144 btVector3 ax1; 145 // angular limits 146 if(m_solveSwingLimit) 147 { 148 btScalar *J1 = info->m_J1angularAxis; 149 btScalar *J2 = info->m_J2angularAxis; 150 if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh)) 151 { 152 btTransform trA = m_rbA.getCenterOfMassTransform()*m_rbAFrame; 153 btVector3 p = trA.getBasis().getColumn(1); 154 btVector3 q = trA.getBasis().getColumn(2); 155 int srow1 = srow + info->rowskip; 156 J1[srow+0] = p[0]; 157 J1[srow+1] = p[1]; 158 J1[srow+2] = p[2]; 159 J1[srow1+0] = q[0]; 160 J1[srow1+1] = q[1]; 161 J1[srow1+2] = q[2]; 162 J2[srow+0] = -p[0]; 163 J2[srow+1] = -p[1]; 164 J2[srow+2] = -p[2]; 165 J2[srow1+0] = -q[0]; 166 J2[srow1+1] = -q[1]; 167 J2[srow1+2] = -q[2]; 168 btScalar fact = info->fps * m_relaxationFactor; 169 info->m_constraintError[srow] = fact * m_swingAxis.dot(p); 170 info->m_constraintError[srow1] = fact * m_swingAxis.dot(q); 171 info->m_lowerLimit[srow] = -SIMD_INFINITY; 172 info->m_upperLimit[srow] = SIMD_INFINITY; 173 info->m_lowerLimit[srow1] = -SIMD_INFINITY; 174 info->m_upperLimit[srow1] = SIMD_INFINITY; 175 srow = srow1 + info->rowskip; 61 62 } 63 64 void btConeTwistConstraint::buildJacobian() 65 { 66 m_appliedImpulse = btScalar(0.); 67 68 //set bias, sign, clear accumulator 69 m_swingCorrection = btScalar(0.); 70 m_twistLimitSign = btScalar(0.); 71 m_solveTwistLimit = false; 72 m_solveSwingLimit = false; 73 m_accTwistLimitImpulse = btScalar(0.); 74 m_accSwingLimitImpulse = btScalar(0.); 75 76 if (!m_angularOnly) 77 { 78 btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); 79 btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); 80 btVector3 relPos = pivotBInW - pivotAInW; 81 82 btVector3 normal[3]; 83 if (relPos.length2() > SIMD_EPSILON) 84 { 85 normal[0] = relPos.normalized(); 176 86 } 177 87 else 178 88 { 179 ax1 = m_swingAxis * m_relaxationFactor * m_relaxationFactor; 180 J1[srow+0] = ax1[0]; 181 J1[srow+1] = ax1[1]; 182 J1[srow+2] = ax1[2]; 183 J2[srow+0] = -ax1[0]; 184 J2[srow+1] = -ax1[1]; 185 J2[srow+2] = -ax1[2]; 186 btScalar k = info->fps * m_biasFactor; 187 188 info->m_constraintError[srow] = k * m_swingCorrection; 189 info->cfm[srow] = 0.0f; 190 // m_swingCorrection is always positive or 0 191 info->m_lowerLimit[srow] = 0; 192 info->m_upperLimit[srow] = SIMD_INFINITY; 193 srow += info->rowskip; 194 } 195 } 196 if(m_solveTwistLimit) 197 { 198 ax1 = m_twistAxis * m_relaxationFactor * m_relaxationFactor; 199 btScalar *J1 = info->m_J1angularAxis; 200 btScalar *J2 = info->m_J2angularAxis; 201 J1[srow+0] = ax1[0]; 202 J1[srow+1] = ax1[1]; 203 J1[srow+2] = ax1[2]; 204 J2[srow+0] = -ax1[0]; 205 J2[srow+1] = -ax1[1]; 206 J2[srow+2] = -ax1[2]; 207 btScalar k = info->fps * m_biasFactor; 208 info->m_constraintError[srow] = k * m_twistCorrection; 209 info->cfm[srow] = 0.0f; 210 if(m_twistSpan > 0.0f) 211 { 212 213 if(m_twistCorrection > 0.0f) 214 { 215 info->m_lowerLimit[srow] = 0; 216 info->m_upperLimit[srow] = SIMD_INFINITY; 217 } 218 else 219 { 220 info->m_lowerLimit[srow] = -SIMD_INFINITY; 221 info->m_upperLimit[srow] = 0; 222 } 223 } 224 else 225 { 226 info->m_lowerLimit[srow] = -SIMD_INFINITY; 227 info->m_upperLimit[srow] = SIMD_INFINITY; 228 } 229 srow += info->rowskip; 230 } 231 } 232 233 //----------------------------------------------------------------------------- 234 235 void btConeTwistConstraint::buildJacobian() 236 { 237 if (m_useSolveConstraintObsolete) 238 { 239 m_appliedImpulse = btScalar(0.); 240 m_accTwistLimitImpulse = btScalar(0.); 241 m_accSwingLimitImpulse = btScalar(0.); 242 243 if (!m_angularOnly) 244 { 245 btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); 246 btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); 247 btVector3 relPos = pivotBInW - pivotAInW; 248 249 btVector3 normal[3]; 250 if (relPos.length2() > SIMD_EPSILON) 251 { 252 normal[0] = relPos.normalized(); 253 } 254 else 255 { 256 normal[0].setValue(btScalar(1.0),0,0); 257 } 258 259 btPlaneSpace1(normal[0], normal[1], normal[2]); 260 261 for (int i=0;i<3;i++) 262 { 263 new (&m_jac[i]) btJacobianEntry( 89 normal[0].setValue(btScalar(1.0),0,0); 90 } 91 92 btPlaneSpace1(normal[0], normal[1], normal[2]); 93 94 for (int i=0;i<3;i++) 95 { 96 new (&m_jac[i]) btJacobianEntry( 264 97 m_rbA.getCenterOfMassTransform().getBasis().transpose(), 265 98 m_rbB.getCenterOfMassTransform().getBasis().transpose(), … … 271 104 m_rbB.getInvInertiaDiagLocal(), 272 105 m_rbB.getInvMass()); 273 } 274 } 275 276 calcAngleInfo2(); 277 } 278 } 279 280 //----------------------------------------------------------------------------- 281 282 void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) 283 { 284 if (m_useSolveConstraintObsolete) 285 { 286 btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); 287 btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); 288 289 btScalar tau = btScalar(0.3); 290 291 //linear part 292 if (!m_angularOnly) 293 { 294 btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); 295 btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); 296 297 btVector3 vel1; 298 bodyA.getVelocityInLocalPointObsolete(rel_pos1,vel1); 299 btVector3 vel2; 300 bodyB.getVelocityInLocalPointObsolete(rel_pos2,vel2); 301 btVector3 vel = vel1 - vel2; 302 303 for (int i=0;i<3;i++) 304 { 305 const btVector3& normal = m_jac[i].m_linearJointAxis; 306 btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal(); 307 308 btScalar rel_vel; 309 rel_vel = normal.dot(vel); 310 //positional error (zeroth order error) 311 btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal 312 btScalar impulse = depth*tau/timeStep * jacDiagABInv - rel_vel * jacDiagABInv; 313 m_appliedImpulse += impulse; 314 315 btVector3 ftorqueAxis1 = rel_pos1.cross(normal); 316 btVector3 ftorqueAxis2 = rel_pos2.cross(normal); 317 bodyA.applyImpulse(normal*m_rbA.getInvMass(), m_rbA.getInvInertiaTensorWorld()*ftorqueAxis1,impulse); 318 bodyB.applyImpulse(normal*m_rbB.getInvMass(), m_rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-impulse); 319 320 } 321 } 322 323 // apply motor 324 if (m_bMotorEnabled) 325 { 326 // compute current and predicted transforms 327 btTransform trACur = m_rbA.getCenterOfMassTransform(); 328 btTransform trBCur = m_rbB.getCenterOfMassTransform(); 329 btVector3 omegaA; bodyA.getAngularVelocity(omegaA); 330 btVector3 omegaB; bodyB.getAngularVelocity(omegaB); 331 btTransform trAPred; trAPred.setIdentity(); 332 btVector3 zerovec(0,0,0); 333 btTransformUtil::integrateTransform( 334 trACur, zerovec, omegaA, timeStep, trAPred); 335 btTransform trBPred; trBPred.setIdentity(); 336 btTransformUtil::integrateTransform( 337 trBCur, zerovec, omegaB, timeStep, trBPred); 338 339 // compute desired transforms in world 340 btTransform trPose(m_qTarget); 341 btTransform trABDes = m_rbBFrame * trPose * m_rbAFrame.inverse(); 342 btTransform trADes = trBPred * trABDes; 343 btTransform trBDes = trAPred * trABDes.inverse(); 344 345 // compute desired omegas in world 346 btVector3 omegaADes, omegaBDes; 347 348 btTransformUtil::calculateVelocity(trACur, trADes, timeStep, zerovec, omegaADes); 349 btTransformUtil::calculateVelocity(trBCur, trBDes, timeStep, zerovec, omegaBDes); 350 351 // compute delta omegas 352 btVector3 dOmegaA = omegaADes - omegaA; 353 btVector3 dOmegaB = omegaBDes - omegaB; 354 355 // compute weighted avg axis of dOmega (weighting based on inertias) 356 btVector3 axisA, axisB; 357 btScalar kAxisAInv = 0, kAxisBInv = 0; 358 359 if (dOmegaA.length2() > SIMD_EPSILON) 360 { 361 axisA = dOmegaA.normalized(); 362 kAxisAInv = getRigidBodyA().computeAngularImpulseDenominator(axisA); 363 } 364 365 if (dOmegaB.length2() > SIMD_EPSILON) 366 { 367 axisB = dOmegaB.normalized(); 368 kAxisBInv = getRigidBodyB().computeAngularImpulseDenominator(axisB); 369 } 370 371 btVector3 avgAxis = kAxisAInv * axisA + kAxisBInv * axisB; 372 373 static bool bDoTorque = true; 374 if (bDoTorque && avgAxis.length2() > SIMD_EPSILON) 375 { 376 avgAxis.normalize(); 377 kAxisAInv = getRigidBodyA().computeAngularImpulseDenominator(avgAxis); 378 kAxisBInv = getRigidBodyB().computeAngularImpulseDenominator(avgAxis); 379 btScalar kInvCombined = kAxisAInv + kAxisBInv; 380 381 btVector3 impulse = (kAxisAInv * dOmegaA - kAxisBInv * dOmegaB) / 382 (kInvCombined * kInvCombined); 383 384 if (m_maxMotorImpulse >= 0) 385 { 386 btScalar fMaxImpulse = m_maxMotorImpulse; 387 if (m_bNormalizedMotorStrength) 388 fMaxImpulse = fMaxImpulse/kAxisAInv; 389 390 btVector3 newUnclampedAccImpulse = m_accMotorImpulse + impulse; 391 btScalar newUnclampedMag = newUnclampedAccImpulse.length(); 392 if (newUnclampedMag > fMaxImpulse) 393 { 394 newUnclampedAccImpulse.normalize(); 395 newUnclampedAccImpulse *= fMaxImpulse; 396 impulse = newUnclampedAccImpulse - m_accMotorImpulse; 397 } 398 m_accMotorImpulse += impulse; 399 } 400 401 btScalar impulseMag = impulse.length(); 402 btVector3 impulseAxis = impulse / impulseMag; 403 404 bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*impulseAxis, impulseMag); 405 bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*impulseAxis, -impulseMag); 406 407 } 408 } 409 else // no motor: do a little damping 410 { 411 const btVector3& angVelA = getRigidBodyA().getAngularVelocity(); 412 const btVector3& angVelB = getRigidBodyB().getAngularVelocity(); 413 btVector3 relVel = angVelB - angVelA; 414 if (relVel.length2() > SIMD_EPSILON) 415 { 416 btVector3 relVelAxis = relVel.normalized(); 417 btScalar m_kDamping = btScalar(1.) / 418 (getRigidBodyA().computeAngularImpulseDenominator(relVelAxis) + 419 getRigidBodyB().computeAngularImpulseDenominator(relVelAxis)); 420 btVector3 impulse = m_damping * m_kDamping * relVel; 421 422 btScalar impulseMag = impulse.length(); 423 btVector3 impulseAxis = impulse / impulseMag; 424 bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*impulseAxis, impulseMag); 425 bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*impulseAxis, -impulseMag); 426 } 427 } 428 429 // joint limits 430 { 431 ///solve angular part 432 btVector3 angVelA; 433 bodyA.getAngularVelocity(angVelA); 434 btVector3 angVelB; 435 bodyB.getAngularVelocity(angVelB); 436 437 // solve swing limit 438 if (m_solveSwingLimit) 439 { 440 btScalar amplitude = m_swingLimitRatio * m_swingCorrection*m_biasFactor/timeStep; 441 btScalar relSwingVel = (angVelB - angVelA).dot(m_swingAxis); 442 if (relSwingVel > 0) 443 amplitude += m_swingLimitRatio * relSwingVel * m_relaxationFactor; 444 btScalar impulseMag = amplitude * m_kSwing; 445 446 // Clamp the accumulated impulse 447 btScalar temp = m_accSwingLimitImpulse; 448 m_accSwingLimitImpulse = btMax(m_accSwingLimitImpulse + impulseMag, btScalar(0.0) ); 449 impulseMag = m_accSwingLimitImpulse - temp; 450 451 btVector3 impulse = m_swingAxis * impulseMag; 452 453 // don't let cone response affect twist 454 // (this can happen since body A's twist doesn't match body B's AND we use an elliptical cone limit) 455 { 456 btVector3 impulseTwistCouple = impulse.dot(m_twistAxisA) * m_twistAxisA; 457 btVector3 impulseNoTwistCouple = impulse - impulseTwistCouple; 458 impulse = impulseNoTwistCouple; 459 } 460 461 impulseMag = impulse.length(); 462 btVector3 noTwistSwingAxis = impulse / impulseMag; 463 464 bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*noTwistSwingAxis, impulseMag); 465 bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*noTwistSwingAxis, -impulseMag); 466 } 467 468 469 // solve twist limit 470 if (m_solveTwistLimit) 471 { 472 btScalar amplitude = m_twistLimitRatio * m_twistCorrection*m_biasFactor/timeStep; 473 btScalar relTwistVel = (angVelB - angVelA).dot( m_twistAxis ); 474 if (relTwistVel > 0) // only damp when moving towards limit (m_twistAxis flipping is important) 475 amplitude += m_twistLimitRatio * relTwistVel * m_relaxationFactor; 476 btScalar impulseMag = amplitude * m_kTwist; 477 478 // Clamp the accumulated impulse 479 btScalar temp = m_accTwistLimitImpulse; 480 m_accTwistLimitImpulse = btMax(m_accTwistLimitImpulse + impulseMag, btScalar(0.0) ); 481 impulseMag = m_accTwistLimitImpulse - temp; 482 483 btVector3 impulse = m_twistAxis * impulseMag; 484 485 bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*m_twistAxis,impulseMag); 486 bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*m_twistAxis,-impulseMag); 487 } 488 } 489 } 490 491 } 492 493 //----------------------------------------------------------------------------- 494 495 void btConeTwistConstraint::updateRHS(btScalar timeStep) 496 { 497 (void)timeStep; 498 499 } 500 501 //----------------------------------------------------------------------------- 502 503 void btConeTwistConstraint::calcAngleInfo() 504 { 505 m_swingCorrection = btScalar(0.); 506 m_twistLimitSign = btScalar(0.); 507 m_solveTwistLimit = false; 508 m_solveSwingLimit = false; 106 } 107 } 509 108 510 109 btVector3 b1Axis1,b1Axis2,b1Axis3; … … 524 123 { 525 124 b1Axis2 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(1); 125 // swing1 = btAtan2Fast( b2Axis1.dot(b1Axis2),b2Axis1.dot(b1Axis1) ); 526 126 swx = b2Axis1.dot(b1Axis1); 527 127 swy = b2Axis1.dot(b1Axis2); … … 530 130 fact = fact / (fact + btScalar(1.0)); 531 131 swing1 *= fact; 132 532 133 } 533 134 … … 535 136 { 536 137 b1Axis3 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(2); 138 // swing2 = btAtan2Fast( b2Axis1.dot(b1Axis3),b2Axis1.dot(b1Axis1) ); 537 139 swx = b2Axis1.dot(b1Axis1); 538 140 swy = b2Axis1.dot(b1Axis3); … … 551 153 m_swingCorrection = EllipseAngle-1.0f; 552 154 m_solveSwingLimit = true; 155 553 156 // Calculate necessary axis & factors 554 157 m_swingAxis = b2Axis1.cross(b1Axis2* b2Axis1.dot(b1Axis2) + b1Axis3* b2Axis1.dot(b1Axis3)); 555 158 m_swingAxis.normalize(); 159 556 160 btScalar swingAxisSign = (b2Axis1.dot(b1Axis1) >= 0.0f) ? 1.0f : -1.0f; 557 161 m_swingAxis *= swingAxisSign; 162 163 m_kSwing = btScalar(1.) / (getRigidBodyA().computeAngularImpulseDenominator(m_swingAxis) + 164 getRigidBodyB().computeAngularImpulseDenominator(m_swingAxis)); 165 558 166 } 559 167 … … 565 173 btVector3 TwistRef = quatRotate(rotationArc,b2Axis2); 566 174 btScalar twist = btAtan2Fast( TwistRef.dot(b1Axis3), TwistRef.dot(b1Axis2) ); 567 m_twistAngle = twist; 568 569 // btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? m_limitSoftness : btScalar(0.); 570 btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? btScalar(1.0f) : btScalar(0.); 175 176 btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? m_limitSoftness : btScalar(0.); 571 177 if (twist <= -m_twistSpan*lockedFreeFactor) 572 178 { 573 179 m_twistCorrection = -(twist + m_twistSpan); 574 180 m_solveTwistLimit = true; 181 575 182 m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f; 576 183 m_twistAxis.normalize(); 577 184 m_twistAxis *= -1.0f; 578 } 579 else if (twist > m_twistSpan*lockedFreeFactor) 580 { 581 m_twistCorrection = (twist - m_twistSpan); 582 m_solveTwistLimit = true; 583 m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f; 584 m_twistAxis.normalize(); 585 } 586 } 587 } // btConeTwistConstraint::calcAngleInfo() 588 589 590 static btVector3 vTwist(1,0,0); // twist axis in constraint's space 591 592 //----------------------------------------------------------------------------- 593 594 void btConeTwistConstraint::calcAngleInfo2() 595 { 596 m_swingCorrection = btScalar(0.); 597 m_twistLimitSign = btScalar(0.); 598 m_solveTwistLimit = false; 599 m_solveSwingLimit = false; 600 601 { 602 // compute rotation of A wrt B (in constraint space) 603 btQuaternion qA = getRigidBodyA().getCenterOfMassTransform().getRotation() * m_rbAFrame.getRotation(); 604 btQuaternion qB = getRigidBodyB().getCenterOfMassTransform().getRotation() * m_rbBFrame.getRotation(); 605 btQuaternion qAB = qB.inverse() * qA; 606 607 // split rotation into cone and twist 608 // (all this is done from B's perspective. Maybe I should be averaging axes...) 609 btVector3 vConeNoTwist = quatRotate(qAB, vTwist); vConeNoTwist.normalize(); 610 btQuaternion qABCone = shortestArcQuat(vTwist, vConeNoTwist); qABCone.normalize(); 611 btQuaternion qABTwist = qABCone.inverse() * qAB; qABTwist.normalize(); 612 613 if (m_swingSpan1 >= m_fixThresh && m_swingSpan2 >= m_fixThresh) 614 { 615 btScalar swingAngle, swingLimit = 0; btVector3 swingAxis; 616 computeConeLimitInfo(qABCone, swingAngle, swingAxis, swingLimit); 617 618 if (swingAngle > swingLimit * m_limitSoftness) 185 186 m_kTwist = btScalar(1.) / (getRigidBodyA().computeAngularImpulseDenominator(m_twistAxis) + 187 getRigidBodyB().computeAngularImpulseDenominator(m_twistAxis)); 188 189 } else 190 if (twist > m_twistSpan*lockedFreeFactor) 619 191 { 620 m_solveSwingLimit = true; 621 622 // compute limit ratio: 0->1, where 623 // 0 == beginning of soft limit 624 // 1 == hard/real limit 625 m_swingLimitRatio = 1.f; 626 if (swingAngle < swingLimit && m_limitSoftness < 1.f - SIMD_EPSILON) 627 { 628 m_swingLimitRatio = (swingAngle - swingLimit * m_limitSoftness)/ 629 (swingLimit - swingLimit * m_limitSoftness); 630 } 631 632 // swing correction tries to get back to soft limit 633 m_swingCorrection = swingAngle - (swingLimit * m_limitSoftness); 634 635 // adjustment of swing axis (based on ellipse normal) 636 adjustSwingAxisToUseEllipseNormal(swingAxis); 637 638 // Calculate necessary axis & factors 639 m_swingAxis = quatRotate(qB, -swingAxis); 640 641 m_twistAxisA.setValue(0,0,0); 642 643 m_kSwing = btScalar(1.) / 644 (getRigidBodyA().computeAngularImpulseDenominator(m_swingAxis) + 645 getRigidBodyB().computeAngularImpulseDenominator(m_swingAxis)); 192 m_twistCorrection = (twist - m_twistSpan); 193 m_solveTwistLimit = true; 194 195 m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f; 196 m_twistAxis.normalize(); 197 198 m_kTwist = btScalar(1.) / (getRigidBodyA().computeAngularImpulseDenominator(m_twistAxis) + 199 getRigidBodyB().computeAngularImpulseDenominator(m_twistAxis)); 200 646 201 } 647 } 648 else 649 { 650 // you haven't set any limits; 651 // or you're trying to set at least one of the swing limits too small. (if so, do you really want a conetwist constraint?) 652 // anyway, we have either hinge or fixed joint 653 btVector3 ivA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(0); 654 btVector3 jvA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(1); 655 btVector3 kvA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); 656 btVector3 ivB = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_rbBFrame.getBasis().getColumn(0); 657 btVector3 target; 658 btScalar x = ivB.dot(ivA); 659 btScalar y = ivB.dot(jvA); 660 btScalar z = ivB.dot(kvA); 661 if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh)) 662 { // fixed. We'll need to add one more row to constraint 663 if((!btFuzzyZero(y)) || (!(btFuzzyZero(z)))) 664 { 665 m_solveSwingLimit = true; 666 m_swingAxis = -ivB.cross(ivA); 667 } 668 } 669 else 670 { 671 if(m_swingSpan1 < m_fixThresh) 672 { // hinge around Y axis 673 if(!(btFuzzyZero(y))) 674 { 675 m_solveSwingLimit = true; 676 if(m_swingSpan2 >= m_fixThresh) 677 { 678 y = btScalar(0.f); 679 btScalar span2 = btAtan2(z, x); 680 if(span2 > m_swingSpan2) 681 { 682 x = btCos(m_swingSpan2); 683 z = btSin(m_swingSpan2); 684 } 685 else if(span2 < -m_swingSpan2) 686 { 687 x = btCos(m_swingSpan2); 688 z = -btSin(m_swingSpan2); 689 } 690 } 691 } 692 } 693 else 694 { // hinge around Z axis 695 if(!btFuzzyZero(z)) 696 { 697 m_solveSwingLimit = true; 698 if(m_swingSpan1 >= m_fixThresh) 699 { 700 z = btScalar(0.f); 701 btScalar span1 = btAtan2(y, x); 702 if(span1 > m_swingSpan1) 703 { 704 x = btCos(m_swingSpan1); 705 y = btSin(m_swingSpan1); 706 } 707 else if(span1 < -m_swingSpan1) 708 { 709 x = btCos(m_swingSpan1); 710 y = -btSin(m_swingSpan1); 711 } 712 } 713 } 714 } 715 target[0] = x * ivA[0] + y * jvA[0] + z * kvA[0]; 716 target[1] = x * ivA[1] + y * jvA[1] + z * kvA[1]; 717 target[2] = x * ivA[2] + y * jvA[2] + z * kvA[2]; 718 target.normalize(); 719 m_swingAxis = -ivB.cross(target); 720 m_swingCorrection = m_swingAxis.length(); 721 m_swingAxis.normalize(); 722 } 723 } 724 725 if (m_twistSpan >= btScalar(0.f)) 726 { 727 btVector3 twistAxis; 728 computeTwistLimitInfo(qABTwist, m_twistAngle, twistAxis); 729 730 if (m_twistAngle > m_twistSpan*m_limitSoftness) 731 { 732 m_solveTwistLimit = true; 733 734 m_twistLimitRatio = 1.f; 735 if (m_twistAngle < m_twistSpan && m_limitSoftness < 1.f - SIMD_EPSILON) 736 { 737 m_twistLimitRatio = (m_twistAngle - m_twistSpan * m_limitSoftness)/ 738 (m_twistSpan - m_twistSpan * m_limitSoftness); 739 } 740 741 // twist correction tries to get back to soft limit 742 m_twistCorrection = m_twistAngle - (m_twistSpan * m_limitSoftness); 743 744 m_twistAxis = quatRotate(qB, -twistAxis); 745 746 m_kTwist = btScalar(1.) / 747 (getRigidBodyA().computeAngularImpulseDenominator(m_twistAxis) + 748 getRigidBodyB().computeAngularImpulseDenominator(m_twistAxis)); 749 } 750 751 if (m_solveSwingLimit) 752 m_twistAxisA = quatRotate(qA, -twistAxis); 753 } 754 else 755 { 756 m_twistAngle = btScalar(0.f); 757 } 758 } 759 } // btConeTwistConstraint::calcAngleInfo2() 760 761 762 763 // given a cone rotation in constraint space, (pre: twist must already be removed) 764 // this method computes its corresponding swing angle and axis. 765 // more interestingly, it computes the cone/swing limit (angle) for this cone "pose". 766 void btConeTwistConstraint::computeConeLimitInfo(const btQuaternion& qCone, 767 btScalar& swingAngle, // out 768 btVector3& vSwingAxis, // out 769 btScalar& swingLimit) // out 770 { 771 swingAngle = qCone.getAngle(); 772 if (swingAngle > SIMD_EPSILON) 773 { 774 vSwingAxis = btVector3(qCone.x(), qCone.y(), qCone.z()); 775 vSwingAxis.normalize(); 776 if (fabs(vSwingAxis.x()) > SIMD_EPSILON) 777 { 778 // non-zero twist?! this should never happen. 779 int wtf = 0; wtf = wtf; 780 } 781 782 // Compute limit for given swing. tricky: 783 // Given a swing axis, we're looking for the intersection with the bounding cone ellipse. 784 // (Since we're dealing with angles, this ellipse is embedded on the surface of a sphere.) 785 786 // For starters, compute the direction from center to surface of ellipse. 787 // This is just the perpendicular (ie. rotate 2D vector by PI/2) of the swing axis. 788 // (vSwingAxis is the cone rotation (in z,y); change vars and rotate to (x,y) coords.) 789 btScalar xEllipse = vSwingAxis.y(); 790 btScalar yEllipse = -vSwingAxis.z(); 791 792 // Now, we use the slope of the vector (using x/yEllipse) and find the length 793 // of the line that intersects the ellipse: 794 // x^2 y^2 795 // --- + --- = 1, where a and b are semi-major axes 2 and 1 respectively (ie. the limits) 796 // a^2 b^2 797 // Do the math and it should be clear. 798 799 swingLimit = m_swingSpan1; // if xEllipse == 0, we have a pure vSwingAxis.z rotation: just use swingspan1 800 if (fabs(xEllipse) > SIMD_EPSILON) 801 { 802 btScalar surfaceSlope2 = (yEllipse*yEllipse)/(xEllipse*xEllipse); 803 btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2); 804 norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1); 805 btScalar swingLimit2 = (1 + surfaceSlope2) / norm; 806 swingLimit = sqrt(swingLimit2); 807 } 808 809 // test! 810 /*swingLimit = m_swingSpan2; 811 if (fabs(vSwingAxis.z()) > SIMD_EPSILON) 812 { 813 btScalar mag_2 = m_swingSpan1*m_swingSpan1 + m_swingSpan2*m_swingSpan2; 814 btScalar sinphi = m_swingSpan2 / sqrt(mag_2); 815 btScalar phi = asin(sinphi); 816 btScalar theta = atan2(fabs(vSwingAxis.y()),fabs(vSwingAxis.z())); 817 btScalar alpha = 3.14159f - theta - phi; 818 btScalar sinalpha = sin(alpha); 819 swingLimit = m_swingSpan1 * sinphi/sinalpha; 820 }*/ 821 } 822 else if (swingAngle < 0) 823 { 824 // this should never happen! 825 int wtf = 0; wtf = wtf; 826 } 827 } 828 829 btVector3 btConeTwistConstraint::GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const 830 { 831 // compute x/y in ellipse using cone angle (0 -> 2*PI along surface of cone) 832 btScalar xEllipse = btCos(fAngleInRadians); 833 btScalar yEllipse = btSin(fAngleInRadians); 834 835 // Use the slope of the vector (using x/yEllipse) and find the length 836 // of the line that intersects the ellipse: 837 // x^2 y^2 838 // --- + --- = 1, where a and b are semi-major axes 2 and 1 respectively (ie. the limits) 839 // a^2 b^2 840 // Do the math and it should be clear. 841 842 float swingLimit = m_swingSpan1; // if xEllipse == 0, just use axis b (1) 843 if (fabs(xEllipse) > SIMD_EPSILON) 844 { 845 btScalar surfaceSlope2 = (yEllipse*yEllipse)/(xEllipse*xEllipse); 846 btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2); 847 norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1); 848 btScalar swingLimit2 = (1 + surfaceSlope2) / norm; 849 swingLimit = sqrt(swingLimit2); 850 } 851 852 // convert into point in constraint space: 853 // note: twist is x-axis, swing 1 and 2 are along the z and y axes respectively 854 btVector3 vSwingAxis(0, xEllipse, -yEllipse); 855 btQuaternion qSwing(vSwingAxis, swingLimit); 856 btVector3 vPointInConstraintSpace(fLength,0,0); 857 return quatRotate(qSwing, vPointInConstraintSpace); 858 } 859 860 // given a twist rotation in constraint space, (pre: cone must already be removed) 861 // this method computes its corresponding angle and axis. 862 void btConeTwistConstraint::computeTwistLimitInfo(const btQuaternion& qTwist, 863 btScalar& twistAngle, // out 864 btVector3& vTwistAxis) // out 865 { 866 btQuaternion qMinTwist = qTwist; 867 twistAngle = qTwist.getAngle(); 868 869 if (twistAngle > SIMD_PI) // long way around. flip quat and recalculate. 870 { 871 qMinTwist = operator-(qTwist); 872 twistAngle = qMinTwist.getAngle(); 873 } 874 if (twistAngle < 0) 875 { 876 // this should never happen 877 int wtf = 0; wtf = wtf; 878 } 879 880 vTwistAxis = btVector3(qMinTwist.x(), qMinTwist.y(), qMinTwist.z()); 881 if (twistAngle > SIMD_EPSILON) 882 vTwistAxis.normalize(); 883 } 884 885 886 void btConeTwistConstraint::adjustSwingAxisToUseEllipseNormal(btVector3& vSwingAxis) const 887 { 888 // the swing axis is computed as the "twist-free" cone rotation, 889 // but the cone limit is not circular, but elliptical (if swingspan1 != swingspan2). 890 // so, if we're outside the limits, the closest way back inside the cone isn't 891 // along the vector back to the center. better (and more stable) to use the ellipse normal. 892 893 // convert swing axis to direction from center to surface of ellipse 894 // (ie. rotate 2D vector by PI/2) 895 btScalar y = -vSwingAxis.z(); 896 btScalar z = vSwingAxis.y(); 897 898 // do the math... 899 if (fabs(z) > SIMD_EPSILON) // avoid division by 0. and we don't need an update if z == 0. 900 { 901 // compute gradient/normal of ellipse surface at current "point" 902 btScalar grad = y/z; 903 grad *= m_swingSpan2 / m_swingSpan1; 904 905 // adjust y/z to represent normal at point (instead of vector to point) 906 if (y > 0) 907 y = fabs(grad * z); 908 else 909 y = -fabs(grad * z); 910 911 // convert ellipse direction back to swing axis 912 vSwingAxis.setZ(-y); 913 vSwingAxis.setY( z); 914 vSwingAxis.normalize(); 915 } 916 } 917 918 919 920 void btConeTwistConstraint::setMotorTarget(const btQuaternion &q) 921 { 922 btTransform trACur = m_rbA.getCenterOfMassTransform(); 923 btTransform trBCur = m_rbB.getCenterOfMassTransform(); 924 btTransform trABCur = trBCur.inverse() * trACur; 925 btQuaternion qABCur = trABCur.getRotation(); 926 btTransform trConstraintCur = (trBCur * m_rbBFrame).inverse() * (trACur * m_rbAFrame); 927 btQuaternion qConstraintCur = trConstraintCur.getRotation(); 928 929 btQuaternion qConstraint = m_rbBFrame.getRotation().inverse() * q * m_rbAFrame.getRotation(); 930 setMotorTargetInConstraintSpace(qConstraint); 931 } 932 933 934 void btConeTwistConstraint::setMotorTargetInConstraintSpace(const btQuaternion &q) 935 { 936 m_qTarget = q; 937 938 // clamp motor target to within limits 939 { 940 btScalar softness = 1.f;//m_limitSoftness; 941 942 // split into twist and cone 943 btVector3 vTwisted = quatRotate(m_qTarget, vTwist); 944 btQuaternion qTargetCone = shortestArcQuat(vTwist, vTwisted); qTargetCone.normalize(); 945 btQuaternion qTargetTwist = qTargetCone.inverse() * m_qTarget; qTargetTwist.normalize(); 946 947 // clamp cone 948 if (m_swingSpan1 >= btScalar(0.05f) && m_swingSpan2 >= btScalar(0.05f)) 949 { 950 btScalar swingAngle, swingLimit; btVector3 swingAxis; 951 computeConeLimitInfo(qTargetCone, swingAngle, swingAxis, swingLimit); 952 953 if (fabs(swingAngle) > SIMD_EPSILON) 954 { 955 if (swingAngle > swingLimit*softness) 956 swingAngle = swingLimit*softness; 957 else if (swingAngle < -swingLimit*softness) 958 swingAngle = -swingLimit*softness; 959 qTargetCone = btQuaternion(swingAxis, swingAngle); 960 } 961 } 962 963 // clamp twist 964 if (m_twistSpan >= btScalar(0.05f)) 965 { 966 btScalar twistAngle; btVector3 twistAxis; 967 computeTwistLimitInfo(qTargetTwist, twistAngle, twistAxis); 968 969 if (fabs(twistAngle) > SIMD_EPSILON) 970 { 971 // eddy todo: limitSoftness used here??? 972 if (twistAngle > m_twistSpan*softness) 973 twistAngle = m_twistSpan*softness; 974 else if (twistAngle < -m_twistSpan*softness) 975 twistAngle = -m_twistSpan*softness; 976 qTargetTwist = btQuaternion(twistAxis, twistAngle); 977 } 978 } 979 980 m_qTarget = qTargetCone * qTargetTwist; 981 } 982 } 983 984 985 //----------------------------------------------------------------------------- 986 //----------------------------------------------------------------------------- 987 //----------------------------------------------------------------------------- 988 989 202 } 203 } 204 205 void btConeTwistConstraint::solveConstraint(btScalar timeStep) 206 { 207 208 btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); 209 btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); 210 211 btScalar tau = btScalar(0.3); 212 213 //linear part 214 if (!m_angularOnly) 215 { 216 btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); 217 btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); 218 219 btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1); 220 btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2); 221 btVector3 vel = vel1 - vel2; 222 223 for (int i=0;i<3;i++) 224 { 225 const btVector3& normal = m_jac[i].m_linearJointAxis; 226 btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal(); 227 228 btScalar rel_vel; 229 rel_vel = normal.dot(vel); 230 //positional error (zeroth order error) 231 btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal 232 btScalar impulse = depth*tau/timeStep * jacDiagABInv - rel_vel * jacDiagABInv; 233 m_appliedImpulse += impulse; 234 btVector3 impulse_vector = normal * impulse; 235 m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition()); 236 m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition()); 237 } 238 } 239 240 { 241 ///solve angular part 242 const btVector3& angVelA = getRigidBodyA().getAngularVelocity(); 243 const btVector3& angVelB = getRigidBodyB().getAngularVelocity(); 244 245 // solve swing limit 246 if (m_solveSwingLimit) 247 { 248 btScalar amplitude = ((angVelB - angVelA).dot( m_swingAxis )*m_relaxationFactor*m_relaxationFactor + m_swingCorrection*(btScalar(1.)/timeStep)*m_biasFactor); 249 btScalar impulseMag = amplitude * m_kSwing; 250 251 // Clamp the accumulated impulse 252 btScalar temp = m_accSwingLimitImpulse; 253 m_accSwingLimitImpulse = btMax(m_accSwingLimitImpulse + impulseMag, btScalar(0.0) ); 254 impulseMag = m_accSwingLimitImpulse - temp; 255 256 btVector3 impulse = m_swingAxis * impulseMag; 257 258 m_rbA.applyTorqueImpulse(impulse); 259 m_rbB.applyTorqueImpulse(-impulse); 260 261 } 262 263 // solve twist limit 264 if (m_solveTwistLimit) 265 { 266 btScalar amplitude = ((angVelB - angVelA).dot( m_twistAxis )*m_relaxationFactor*m_relaxationFactor + m_twistCorrection*(btScalar(1.)/timeStep)*m_biasFactor ); 267 btScalar impulseMag = amplitude * m_kTwist; 268 269 // Clamp the accumulated impulse 270 btScalar temp = m_accTwistLimitImpulse; 271 m_accTwistLimitImpulse = btMax(m_accTwistLimitImpulse + impulseMag, btScalar(0.0) ); 272 impulseMag = m_accTwistLimitImpulse - temp; 273 274 btVector3 impulse = m_twistAxis * impulseMag; 275 276 m_rbA.applyTorqueImpulse(impulse); 277 m_rbB.applyTorqueImpulse(-impulse); 278 279 } 280 281 } 282 283 } 284 285 void btConeTwistConstraint::updateRHS(btScalar timeStep) 286 { 287 (void)timeStep; 288 289 } -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
r2907 r2908 43 43 btScalar m_relaxationFactor; 44 44 45 btScalar m_damping;46 47 45 btScalar m_swingSpan1; 48 46 btScalar m_swingSpan2; 49 47 btScalar m_twistSpan; 50 51 btScalar m_fixThresh;52 48 53 49 btVector3 m_swingAxis; … … 61 57 btScalar m_twistCorrection; 62 58 63 btScalar m_twistAngle;64 65 59 btScalar m_accSwingLimitImpulse; 66 60 btScalar m_accTwistLimitImpulse; … … 70 64 bool m_solveSwingLimit; 71 65 72 bool m_useSolveConstraintObsolete;73 74 // not yet used...75 btScalar m_swingLimitRatio;76 btScalar m_twistLimitRatio;77 btVector3 m_twistAxisA;78 79 // motor80 bool m_bMotorEnabled;81 bool m_bNormalizedMotorStrength;82 btQuaternion m_qTarget;83 btScalar m_maxMotorImpulse;84 btVector3 m_accMotorImpulse;85 66 86 67 public: … … 94 75 virtual void buildJacobian(); 95 76 96 virtual void getInfo1 (btConstraintInfo1* info); 97 98 virtual void getInfo2 (btConstraintInfo2* info); 99 100 101 virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep); 77 virtual void solveConstraint(btScalar timeStep); 102 78 103 79 void updateRHS(btScalar timeStep); … … 117 93 } 118 94 119 void setLimit(int limitIndex,btScalar limitValue) 120 { 121 switch (limitIndex) 122 { 123 case 3: 124 { 125 m_twistSpan = limitValue; 126 break; 127 } 128 case 4: 129 { 130 m_swingSpan2 = limitValue; 131 break; 132 } 133 case 5: 134 { 135 m_swingSpan1 = limitValue; 136 break; 137 } 138 default: 139 { 140 } 141 }; 142 } 143 144 void setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) 95 void setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 0.8f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) 145 96 { 146 97 m_swingSpan1 = _swingSpan1; … … 171 122 } 172 123 173 void calcAngleInfo();174 void calcAngleInfo2();175 176 inline btScalar getSwingSpan1()177 {178 return m_swingSpan1;179 }180 inline btScalar getSwingSpan2()181 {182 return m_swingSpan2;183 }184 inline btScalar getTwistSpan()185 {186 return m_twistSpan;187 }188 inline btScalar getTwistAngle()189 {190 return m_twistAngle;191 }192 bool isPastSwingLimit() { return m_solveSwingLimit; }193 194 195 void setDamping(btScalar damping) { m_damping = damping; }196 197 void enableMotor(bool b) { m_bMotorEnabled = b; }198 void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = false; }199 void setMaxMotorImpulseNormalized(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = true; }200 201 btScalar getFixThresh() { return m_fixThresh; }202 void setFixThresh(btScalar fixThresh) { m_fixThresh = fixThresh; }203 204 // setMotorTarget:205 // q: the desired rotation of bodyA wrt bodyB.206 // note: if q violates the joint limits, the internal target is clamped to avoid conflicting impulses (very bad for stability)207 // note: don't forget to enableMotor()208 void setMotorTarget(const btQuaternion &q);209 210 // same as above, but q is the desired rotation of frameA wrt frameB in constraint space211 void setMotorTargetInConstraintSpace(const btQuaternion &q);212 213 btVector3 GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const;214 215 216 217 protected:218 void init();219 220 void computeConeLimitInfo(const btQuaternion& qCone, // in221 btScalar& swingAngle, btVector3& vSwingAxis, btScalar& swingLimit); // all outs222 223 void computeTwistLimitInfo(const btQuaternion& qTwist, // in224 btScalar& twistAngle, btVector3& vTwistAxis); // all outs225 226 void adjustSwingAxisToUseEllipseNormal(btVector3& vSwingAxis) const;227 124 }; 228 125 -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
r2907 r2908 23 23 #include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h" 24 24 25 #define ASSERT2 btAssert25 #define ASSERT2 assert 26 26 27 27 #define USE_INTERNAL_APPLY_IMPULSE 1 … … 53 53 54 54 55 55 btJacobianEntry jac(body1.getCenterOfMassTransform().getBasis().transpose(), 56 56 body2.getCenterOfMassTransform().getBasis().transpose(), 57 57 rel_pos1,rel_pos2,normal,body1.getInvInertiaDiagLocal(),body1.getInvMass(), … … 115 115 116 116 btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData; 117 btAssert(cpd);117 assert(cpd); 118 118 btScalar distance = cpd->m_penetration; 119 119 btScalar positionalError = Kcor *-distance; … … 167 167 168 168 btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData; 169 btAssert(cpd);169 assert(cpd); 170 170 171 171 btScalar combinedFriction = cpd->m_friction; … … 256 256 257 257 btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData; 258 btAssert(cpd);258 assert(cpd); 259 259 260 260 btScalar combinedFriction = cpd->m_friction; … … 338 338 339 339 btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData; 340 btAssert(cpd);340 assert(cpd); 341 341 btScalar distance = cpd->m_penetration; 342 342 btScalar positionalError = Kcor *-distance; -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
r2907 r2908 23 23 SOLVER_USE_WARMSTARTING = 4, 24 24 SOLVER_USE_FRICTION_WARMSTARTING = 8, 25 SOLVER_USE_2_FRICTION_DIRECTIONS = 16, 26 SOLVER_ENABLE_FRICTION_DIRECTION_CACHING = 32, 27 SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION = 64, 28 SOLVER_CACHE_FRIENDLY = 128, 29 SOLVER_SIMD = 256, //enabled for Windows, the solver innerloop is branchless SIMD, 40% faster than FPU/scalar version 30 SOLVER_CUDA = 512 //will be open sourced during Game Developers Conference 2009. Much faster. 25 SOLVER_CACHE_FRIENDLY = 16 31 26 }; 32 27 … … 45 40 btScalar m_erp;//used as Baumgarte factor 46 41 btScalar m_erp2;//used in Split Impulse 47 btScalar m_globalCfm;//constraint force mixing48 42 int m_splitImpulse; 49 43 btScalar m_splitImpulsePenetrationThreshold; … … 72 66 m_erp = btScalar(0.2); 73 67 m_erp2 = btScalar(0.1); 74 m_globalCfm = btScalar(0.); 75 m_sor = btScalar(1.); 68 m_sor = btScalar(1.3); 76 69 m_splitImpulse = false; 77 70 m_splitImpulsePenetrationThreshold = -0.02f; 78 71 m_linearSlop = btScalar(0.0); 79 72 m_warmstartingFactor=btScalar(0.85); 80 m_solverMode = SOLVER_ USE_WARMSTARTING | SOLVER_SIMD ;//SOLVER_RANDMIZE_ORDER73 m_solverMode = SOLVER_CACHE_FRIENDLY | SOLVER_RANDMIZE_ORDER | SOLVER_USE_WARMSTARTING; 81 74 m_restingContactRestitutionThreshold = 2;//resting contact lifetime threshold to disable restitution 82 75 } -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
r2907 r2908 20 20 */ 21 21 22 22 23 #include "btGeneric6DofConstraint.h" 23 24 #include "BulletDynamics/Dynamics/btRigidBody.h" … … 26 27 27 28 28 #define D6_USE_OBSOLETE_METHOD false29 //-----------------------------------------------------------------------------30 31 btGeneric6DofConstraint::btGeneric6DofConstraint()32 :btTypedConstraint(D6_CONSTRAINT_TYPE),33 m_useLinearReferenceFrameA(true),34 m_useSolveConstraintObsolete(D6_USE_OBSOLETE_METHOD)35 {36 }37 38 //-----------------------------------------------------------------------------39 40 btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA)41 : btTypedConstraint(D6_CONSTRAINT_TYPE, rbA, rbB)42 , m_frameInA(frameInA)43 , m_frameInB(frameInB),44 m_useLinearReferenceFrameA(useLinearReferenceFrameA),45 m_useSolveConstraintObsolete(D6_USE_OBSOLETE_METHOD)46 {47 48 }49 //-----------------------------------------------------------------------------50 51 52 29 #define GENERIC_D6_DISABLE_WARMSTARTING 1 53 54 //-----------------------------------------------------------------------------55 30 56 31 btScalar btGetMatrixElem(const btMatrix3x3& mat, int index); … … 62 37 } 63 38 64 //-----------------------------------------------------------------------------65 66 39 ///MatrixToEulerXYZ from http://www.geometrictools.com/LibFoundation/Mathematics/Wm4Matrix3.inl.html 67 40 bool matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz); 68 41 bool matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz) 69 42 { 70 // // rot = cy*cz -cy*sz sy 71 // // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx 72 // // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy 73 // 74 75 btScalar fi = btGetMatrixElem(mat,2); 76 if (fi < btScalar(1.0f)) 77 { 78 if (fi > btScalar(-1.0f)) 43 // // rot = cy*cz -cy*sz sy 44 // // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx 45 // // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy 46 // 47 48 if (btGetMatrixElem(mat,2) < btScalar(1.0)) 79 49 { 80 xyz[0] = btAtan2(-btGetMatrixElem(mat,5),btGetMatrixElem(mat,8)); 81 xyz[1] = btAsin(btGetMatrixElem(mat,2)); 82 xyz[2] = btAtan2(-btGetMatrixElem(mat,1),btGetMatrixElem(mat,0)); 83 return true; 50 if (btGetMatrixElem(mat,2) > btScalar(-1.0)) 51 { 52 xyz[0] = btAtan2(-btGetMatrixElem(mat,5),btGetMatrixElem(mat,8)); 53 xyz[1] = btAsin(btGetMatrixElem(mat,2)); 54 xyz[2] = btAtan2(-btGetMatrixElem(mat,1),btGetMatrixElem(mat,0)); 55 return true; 56 } 57 else 58 { 59 // WARNING. Not unique. XA - ZA = -atan2(r10,r11) 60 xyz[0] = -btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); 61 xyz[1] = -SIMD_HALF_PI; 62 xyz[2] = btScalar(0.0); 63 return false; 64 } 84 65 } 85 66 else 86 67 { 87 // WARNING. Not unique. XA - ZA = -atan2(r10,r11)88 xyz[0] = -btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4));89 xyz[1] = -SIMD_HALF_PI;90 xyz[2] = btScalar(0.0);91 return false; 68 // WARNING. Not unique. XAngle + ZAngle = atan2(r10,r11) 69 xyz[0] = btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); 70 xyz[1] = SIMD_HALF_PI; 71 xyz[2] = 0.0; 72 92 73 } 93 } 94 else 95 { 96 // WARNING. Not unique. XAngle + ZAngle = atan2(r10,r11) 97 xyz[0] = btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); 98 xyz[1] = SIMD_HALF_PI; 99 xyz[2] = 0.0; 100 } 74 75 101 76 return false; 102 77 } 103 78 79 80 104 81 //////////////////////////// btRotationalLimitMotor //////////////////////////////////// 82 105 83 106 84 int btRotationalLimitMotor::testLimitValue(btScalar test_value) … … 127 105 m_currentLimit = 0;//Free from violation 128 106 return 0; 129 130 } 131 132 //----------------------------------------------------------------------------- 107 108 } 109 133 110 134 111 btScalar btRotationalLimitMotor::solveAngularLimits( 135 btScalar timeStep,btVector3& axis,btScalar jacDiagABInv,136 btRigidBody * body0, btSolverBody& bodyA, btRigidBody * body1, btSolverBody& bodyB)137 { 138 139 140 141 112 btScalar timeStep,btVector3& axis,btScalar jacDiagABInv, 113 btRigidBody * body0, btRigidBody * body1) 114 { 115 if (needApplyTorques()==false) return 0.0f; 116 117 btScalar target_velocity = m_targetVelocity; 118 btScalar maxMotorForce = m_maxMotorForce; 142 119 143 120 //current error correction 144 if (m_currentLimit!=0) 145 { 146 target_velocity = -m_ERP*m_currentLimitError/(timeStep); 147 maxMotorForce = m_maxLimitForce; 148 } 149 150 maxMotorForce *= timeStep; 151 152 // current velocity difference 153 154 btVector3 angVelA; 155 bodyA.getAngularVelocity(angVelA); 156 btVector3 angVelB; 157 bodyB.getAngularVelocity(angVelB); 158 159 btVector3 vel_diff; 160 vel_diff = angVelA-angVelB; 161 162 163 164 btScalar rel_vel = axis.dot(vel_diff); 121 if (m_currentLimit!=0) 122 { 123 target_velocity = -m_ERP*m_currentLimitError/(timeStep); 124 maxMotorForce = m_maxLimitForce; 125 } 126 127 maxMotorForce *= timeStep; 128 129 // current velocity difference 130 btVector3 vel_diff = body0->getAngularVelocity(); 131 if (body1) 132 { 133 vel_diff -= body1->getAngularVelocity(); 134 } 135 136 137 138 btScalar rel_vel = axis.dot(vel_diff); 165 139 166 140 // correction velocity 167 168 169 170 171 172 173 141 btScalar motor_relvel = m_limitSoftness*(target_velocity - m_damping*rel_vel); 142 143 144 if ( motor_relvel < SIMD_EPSILON && motor_relvel > -SIMD_EPSILON ) 145 { 146 return 0.0f;//no need for applying force 147 } 174 148 175 149 176 150 // correction impulse 177 151 btScalar unclippedMotorImpulse = (1+m_bounce)*motor_relvel*jacDiagABInv; 178 152 179 153 // clip correction impulse 180 181 182 183 184 185 186 187 188 189 190 154 btScalar clippedMotorImpulse; 155 156 ///@todo: should clip against accumulated impulse 157 if (unclippedMotorImpulse>0.0f) 158 { 159 clippedMotorImpulse = unclippedMotorImpulse > maxMotorForce? maxMotorForce: unclippedMotorImpulse; 160 } 161 else 162 { 163 clippedMotorImpulse = unclippedMotorImpulse < -maxMotorForce ? -maxMotorForce: unclippedMotorImpulse; 164 } 191 165 192 166 193 167 // sort with accumulated impulses 194 btScalar lo = btScalar(-1e30); 195 btScalar hi = btScalar(1e30); 196 197 btScalar oldaccumImpulse = m_accumulatedImpulse; 198 btScalar sum = oldaccumImpulse + clippedMotorImpulse; 199 m_accumulatedImpulse = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum; 200 201 clippedMotorImpulse = m_accumulatedImpulse - oldaccumImpulse; 202 203 btVector3 motorImp = clippedMotorImpulse * axis; 204 205 //body0->applyTorqueImpulse(motorImp); 206 //body1->applyTorqueImpulse(-motorImp); 207 208 bodyA.applyImpulse(btVector3(0,0,0), body0->getInvInertiaTensorWorld()*axis,clippedMotorImpulse); 209 bodyB.applyImpulse(btVector3(0,0,0), body1->getInvInertiaTensorWorld()*axis,-clippedMotorImpulse); 210 211 212 return clippedMotorImpulse; 168 btScalar lo = btScalar(-1e30); 169 btScalar hi = btScalar(1e30); 170 171 btScalar oldaccumImpulse = m_accumulatedImpulse; 172 btScalar sum = oldaccumImpulse + clippedMotorImpulse; 173 m_accumulatedImpulse = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum; 174 175 clippedMotorImpulse = m_accumulatedImpulse - oldaccumImpulse; 176 177 178 179 btVector3 motorImp = clippedMotorImpulse * axis; 180 181 182 body0->applyTorqueImpulse(motorImp); 183 if (body1) body1->applyTorqueImpulse(-motorImp); 184 185 return clippedMotorImpulse; 213 186 214 187 … … 217 190 //////////////////////////// End btRotationalLimitMotor //////////////////////////////////// 218 191 219 220 221 222 192 //////////////////////////// btTranslationalLimitMotor //////////////////////////////////// 223 224 225 int btTranslationalLimitMotor::testLimitValue(int limitIndex, btScalar test_value)226 {227 btScalar loLimit = m_lowerLimit[limitIndex];228 btScalar hiLimit = m_upperLimit[limitIndex];229 if(loLimit > hiLimit)230 {231 m_currentLimit[limitIndex] = 0;//Free from violation232 m_currentLimitError[limitIndex] = btScalar(0.f);233 return 0;234 }235 236 if (test_value < loLimit)237 {238 m_currentLimit[limitIndex] = 2;//low limit violation239 m_currentLimitError[limitIndex] = test_value - loLimit;240 return 2;241 }242 else if (test_value> hiLimit)243 {244 m_currentLimit[limitIndex] = 1;//High limit violation245 m_currentLimitError[limitIndex] = test_value - hiLimit;246 return 1;247 };248 249 m_currentLimit[limitIndex] = 0;//Free from violation250 m_currentLimitError[limitIndex] = btScalar(0.f);251 return 0;252 } // btTranslationalLimitMotor::testLimitValue()253 254 //-----------------------------------------------------------------------------255 256 193 btScalar btTranslationalLimitMotor::solveLinearAxis( 257 btScalar timeStep, 258 btScalar jacDiagABInv, 259 btRigidBody& body1,btSolverBody& bodyA,const btVector3 &pointInA, 260 btRigidBody& body2,btSolverBody& bodyB,const btVector3 &pointInB, 261 int limit_index, 262 const btVector3 & axis_normal_on_a, 263 const btVector3 & anchorPos) 264 { 265 266 ///find relative velocity 267 // btVector3 rel_pos1 = pointInA - body1.getCenterOfMassPosition(); 268 // btVector3 rel_pos2 = pointInB - body2.getCenterOfMassPosition(); 269 btVector3 rel_pos1 = anchorPos - body1.getCenterOfMassPosition(); 270 btVector3 rel_pos2 = anchorPos - body2.getCenterOfMassPosition(); 271 272 btVector3 vel1; 273 bodyA.getVelocityInLocalPointObsolete(rel_pos1,vel1); 274 btVector3 vel2; 275 bodyB.getVelocityInLocalPointObsolete(rel_pos2,vel2); 276 btVector3 vel = vel1 - vel2; 277 278 btScalar rel_vel = axis_normal_on_a.dot(vel); 279 280 281 282 /// apply displacement correction 283 284 //positional error (zeroth order error) 285 btScalar depth = -(pointInA - pointInB).dot(axis_normal_on_a); 286 btScalar lo = btScalar(-1e30); 287 btScalar hi = btScalar(1e30); 288 289 btScalar minLimit = m_lowerLimit[limit_index]; 290 btScalar maxLimit = m_upperLimit[limit_index]; 291 292 //handle the limits 293 if (minLimit < maxLimit) 294 { 295 { 296 if (depth > maxLimit) 297 { 298 depth -= maxLimit; 299 lo = btScalar(0.); 300 301 } 302 else 303 { 304 if (depth < minLimit) 305 { 306 depth -= minLimit; 307 hi = btScalar(0.); 308 } 309 else 310 { 311 return 0.0f; 312 } 313 } 314 } 315 } 316 317 btScalar normalImpulse= m_limitSoftness*(m_restitution*depth/timeStep - m_damping*rel_vel) * jacDiagABInv; 318 319 320 321 322 btScalar oldNormalImpulse = m_accumulatedImpulse[limit_index]; 323 btScalar sum = oldNormalImpulse + normalImpulse; 324 m_accumulatedImpulse[limit_index] = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum; 325 normalImpulse = m_accumulatedImpulse[limit_index] - oldNormalImpulse; 326 327 btVector3 impulse_vector = axis_normal_on_a * normalImpulse; 328 //body1.applyImpulse( impulse_vector, rel_pos1); 329 //body2.applyImpulse(-impulse_vector, rel_pos2); 330 331 btVector3 ftorqueAxis1 = rel_pos1.cross(axis_normal_on_a); 332 btVector3 ftorqueAxis2 = rel_pos2.cross(axis_normal_on_a); 333 bodyA.applyImpulse(axis_normal_on_a*body1.getInvMass(), body1.getInvInertiaTensorWorld()*ftorqueAxis1,normalImpulse); 334 bodyB.applyImpulse(axis_normal_on_a*body2.getInvMass(), body2.getInvInertiaTensorWorld()*ftorqueAxis2,-normalImpulse); 335 336 337 338 339 return normalImpulse; 194 btScalar timeStep, 195 btScalar jacDiagABInv, 196 btRigidBody& body1,const btVector3 &pointInA, 197 btRigidBody& body2,const btVector3 &pointInB, 198 int limit_index, 199 const btVector3 & axis_normal_on_a, 200 const btVector3 & anchorPos) 201 { 202 203 ///find relative velocity 204 // btVector3 rel_pos1 = pointInA - body1.getCenterOfMassPosition(); 205 // btVector3 rel_pos2 = pointInB - body2.getCenterOfMassPosition(); 206 btVector3 rel_pos1 = anchorPos - body1.getCenterOfMassPosition(); 207 btVector3 rel_pos2 = anchorPos - body2.getCenterOfMassPosition(); 208 209 btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); 210 btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); 211 btVector3 vel = vel1 - vel2; 212 213 btScalar rel_vel = axis_normal_on_a.dot(vel); 214 215 216 217 /// apply displacement correction 218 219 //positional error (zeroth order error) 220 btScalar depth = -(pointInA - pointInB).dot(axis_normal_on_a); 221 btScalar lo = btScalar(-1e30); 222 btScalar hi = btScalar(1e30); 223 224 btScalar minLimit = m_lowerLimit[limit_index]; 225 btScalar maxLimit = m_upperLimit[limit_index]; 226 227 //handle the limits 228 if (minLimit < maxLimit) 229 { 230 { 231 if (depth > maxLimit) 232 { 233 depth -= maxLimit; 234 lo = btScalar(0.); 235 236 } 237 else 238 { 239 if (depth < minLimit) 240 { 241 depth -= minLimit; 242 hi = btScalar(0.); 243 } 244 else 245 { 246 return 0.0f; 247 } 248 } 249 } 250 } 251 252 btScalar normalImpulse= m_limitSoftness*(m_restitution*depth/timeStep - m_damping*rel_vel) * jacDiagABInv; 253 254 255 256 257 btScalar oldNormalImpulse = m_accumulatedImpulse[limit_index]; 258 btScalar sum = oldNormalImpulse + normalImpulse; 259 m_accumulatedImpulse[limit_index] = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum; 260 normalImpulse = m_accumulatedImpulse[limit_index] - oldNormalImpulse; 261 262 btVector3 impulse_vector = axis_normal_on_a * normalImpulse; 263 body1.applyImpulse( impulse_vector, rel_pos1); 264 body2.applyImpulse(-impulse_vector, rel_pos2); 265 return normalImpulse; 340 266 } 341 267 342 268 //////////////////////////// btTranslationalLimitMotor //////////////////////////////////// 343 269 270 271 btGeneric6DofConstraint::btGeneric6DofConstraint() 272 :btTypedConstraint(D6_CONSTRAINT_TYPE), 273 m_useLinearReferenceFrameA(true) 274 { 275 } 276 277 btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) 278 : btTypedConstraint(D6_CONSTRAINT_TYPE, rbA, rbB) 279 , m_frameInA(frameInA) 280 , m_frameInB(frameInB), 281 m_useLinearReferenceFrameA(useLinearReferenceFrameA) 282 { 283 284 } 285 286 287 288 289 344 290 void btGeneric6DofConstraint::calculateAngleInfo() 345 291 { 346 292 btMatrix3x3 relative_frame = m_calculatedTransformA.getBasis().inverse()*m_calculatedTransformB.getBasis(); 293 347 294 matrixToEulerXYZ(relative_frame,m_calculatedAxisAngleDiff); 295 296 297 348 298 // in euler angle mode we do not actually constrain the angular velocity 349 // along the axes axis[0] and axis[2] (although we do use axis[1]) : 350 // 351 // to get constrain w2-w1 along ...not 352 // ------ --------------------- ------ 353 // d(angle[0])/dt = 0 ax[1] x ax[2] ax[0] 354 // d(angle[1])/dt = 0 ax[1] 355 // d(angle[2])/dt = 0 ax[0] x ax[1] ax[2] 356 // 357 // constraining w2-w1 along an axis 'a' means that a'*(w2-w1)=0. 358 // to prove the result for angle[0], write the expression for angle[0] from 359 // GetInfo1 then take the derivative. to prove this for angle[2] it is 360 // easier to take the euler rate expression for d(angle[2])/dt with respect 361 // to the components of w and set that to 0. 299 // along the axes axis[0] and axis[2] (although we do use axis[1]) : 300 // 301 // to get constrain w2-w1 along ...not 302 // ------ --------------------- ------ 303 // d(angle[0])/dt = 0 ax[1] x ax[2] ax[0] 304 // d(angle[1])/dt = 0 ax[1] 305 // d(angle[2])/dt = 0 ax[0] x ax[1] ax[2] 306 // 307 // constraining w2-w1 along an axis 'a' means that a'*(w2-w1)=0. 308 // to prove the result for angle[0], write the expression for angle[0] from 309 // GetInfo1 then take the derivative. to prove this for angle[2] it is 310 // easier to take the euler rate expression for d(angle[2])/dt with respect 311 // to the components of w and set that to 0. 312 362 313 btVector3 axis0 = m_calculatedTransformB.getBasis().getColumn(0); 363 314 btVector3 axis2 = m_calculatedTransformA.getBasis().getColumn(2); … … 367 318 m_calculatedAxis[2] = axis0.cross(m_calculatedAxis[1]); 368 319 369 m_calculatedAxis[0].normalize(); 370 m_calculatedAxis[1].normalize(); 371 m_calculatedAxis[2].normalize(); 372 373 } 374 375 //----------------------------------------------------------------------------- 320 321 // if(m_debugDrawer) 322 // { 323 // 324 // char buff[300]; 325 // sprintf(buff,"\n X: %.2f ; Y: %.2f ; Z: %.2f ", 326 // m_calculatedAxisAngleDiff[0], 327 // m_calculatedAxisAngleDiff[1], 328 // m_calculatedAxisAngleDiff[2]); 329 // m_debugDrawer->reportErrorWarning(buff); 330 // } 331 332 } 376 333 377 334 void btGeneric6DofConstraint::calculateTransforms() 378 335 { 379 m_calculatedTransformA = m_rbA.getCenterOfMassTransform() * m_frameInA; 380 m_calculatedTransformB = m_rbB.getCenterOfMassTransform() * m_frameInB; 381 calculateLinearInfo(); 382 calculateAngleInfo(); 383 } 384 385 //----------------------------------------------------------------------------- 336 m_calculatedTransformA = m_rbA.getCenterOfMassTransform() * m_frameInA; 337 m_calculatedTransformB = m_rbB.getCenterOfMassTransform() * m_frameInB; 338 339 calculateAngleInfo(); 340 } 341 386 342 387 343 void btGeneric6DofConstraint::buildLinearJacobian( 388 389 390 { 391 344 btJacobianEntry & jacLinear,const btVector3 & normalWorld, 345 const btVector3 & pivotAInW,const btVector3 & pivotBInW) 346 { 347 new (&jacLinear) btJacobianEntry( 392 348 m_rbA.getCenterOfMassTransform().getBasis().transpose(), 393 349 m_rbB.getCenterOfMassTransform().getBasis().transpose(), … … 399 355 m_rbB.getInvInertiaDiagLocal(), 400 356 m_rbB.getInvMass()); 401 } 402 403 //----------------------------------------------------------------------------- 357 358 } 404 359 405 360 void btGeneric6DofConstraint::buildAngularJacobian( 406 407 { 408 361 btJacobianEntry & jacAngular,const btVector3 & jointAxisW) 362 { 363 new (&jacAngular) btJacobianEntry(jointAxisW, 409 364 m_rbA.getCenterOfMassTransform().getBasis().transpose(), 410 365 m_rbB.getCenterOfMassTransform().getBasis().transpose(), … … 414 369 } 415 370 416 //-----------------------------------------------------------------------------417 418 371 bool btGeneric6DofConstraint::testAngularLimitMotor(int axis_index) 419 372 { 420 btScalar angle = m_calculatedAxisAngleDiff[axis_index]; 421 //test limits 422 m_angularLimits[axis_index].testLimitValue(angle); 423 return m_angularLimits[axis_index].needApplyTorques(); 424 } 425 426 //----------------------------------------------------------------------------- 373 btScalar angle = m_calculatedAxisAngleDiff[axis_index]; 374 375 //test limits 376 m_angularLimits[axis_index].testLimitValue(angle); 377 return m_angularLimits[axis_index].needApplyTorques(); 378 } 427 379 428 380 void btGeneric6DofConstraint::buildJacobian() 429 381 { 430 if (m_useSolveConstraintObsolete) 431 { 432 433 // Clear accumulated impulses for the next simulation step 434 m_linearLimits.m_accumulatedImpulse.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); 435 int i; 436 for(i = 0; i < 3; i++) 437 { 438 m_angularLimits[i].m_accumulatedImpulse = btScalar(0.); 439 } 440 //calculates transform 441 calculateTransforms(); 442 443 // const btVector3& pivotAInW = m_calculatedTransformA.getOrigin(); 444 // const btVector3& pivotBInW = m_calculatedTransformB.getOrigin(); 445 calcAnchorPos(); 446 btVector3 pivotAInW = m_AnchorPos; 447 btVector3 pivotBInW = m_AnchorPos; 448 449 // not used here 450 // btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); 451 // btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); 452 453 btVector3 normalWorld; 454 //linear part 455 for (i=0;i<3;i++) 456 { 457 if (m_linearLimits.isLimited(i)) 458 { 459 if (m_useLinearReferenceFrameA) 460 normalWorld = m_calculatedTransformA.getBasis().getColumn(i); 461 else 462 normalWorld = m_calculatedTransformB.getBasis().getColumn(i); 463 464 buildLinearJacobian( 465 m_jacLinear[i],normalWorld , 466 pivotAInW,pivotBInW); 467 468 } 469 } 470 471 // angular part 472 for (i=0;i<3;i++) 473 { 474 //calculates error angle 475 if (testAngularLimitMotor(i)) 476 { 477 normalWorld = this->getAxis(i); 478 // Create angular atom 479 buildAngularJacobian(m_jacAng[i],normalWorld); 480 } 481 } 482 483 } 484 } 485 486 //----------------------------------------------------------------------------- 487 488 void btGeneric6DofConstraint::getInfo1 (btConstraintInfo1* info) 489 { 490 if (m_useSolveConstraintObsolete) 491 { 492 info->m_numConstraintRows = 0; 493 info->nub = 0; 494 } else 495 { 496 //prepare constraint 497 calculateTransforms(); 498 info->m_numConstraintRows = 0; 499 info->nub = 6; 500 int i; 501 //test linear limits 502 for(i = 0; i < 3; i++) 503 { 504 if(m_linearLimits.needApplyForce(i)) 505 { 506 info->m_numConstraintRows++; 507 info->nub--; 508 } 509 } 510 //test angular limits 511 for (i=0;i<3 ;i++ ) 512 { 513 if(testAngularLimitMotor(i)) 514 { 515 info->m_numConstraintRows++; 516 info->nub--; 517 } 518 } 519 } 520 } 521 522 //----------------------------------------------------------------------------- 523 524 void btGeneric6DofConstraint::getInfo2 (btConstraintInfo2* info) 525 { 526 btAssert(!m_useSolveConstraintObsolete); 527 int row = setLinearLimits(info); 528 setAngularLimits(info, row); 529 } 530 531 //----------------------------------------------------------------------------- 532 533 int btGeneric6DofConstraint::setLinearLimits(btConstraintInfo2* info) 534 { 535 btGeneric6DofConstraint * d6constraint = this; 536 int row = 0; 537 //solve linear limits 538 btRotationalLimitMotor limot; 539 for (int i=0;i<3 ;i++ ) 540 { 541 if(m_linearLimits.needApplyForce(i)) 542 { // re-use rotational motor code 543 limot.m_bounce = btScalar(0.f); 544 limot.m_currentLimit = m_linearLimits.m_currentLimit[i]; 545 limot.m_currentLimitError = m_linearLimits.m_currentLimitError[i]; 546 limot.m_damping = m_linearLimits.m_damping; 547 limot.m_enableMotor = m_linearLimits.m_enableMotor[i]; 548 limot.m_ERP = m_linearLimits.m_restitution; 549 limot.m_hiLimit = m_linearLimits.m_upperLimit[i]; 550 limot.m_limitSoftness = m_linearLimits.m_limitSoftness; 551 limot.m_loLimit = m_linearLimits.m_lowerLimit[i]; 552 limot.m_maxLimitForce = btScalar(0.f); 553 limot.m_maxMotorForce = m_linearLimits.m_maxMotorForce[i]; 554 limot.m_targetVelocity = m_linearLimits.m_targetVelocity[i]; 555 btVector3 axis = m_calculatedTransformA.getBasis().getColumn(i); 556 row += get_limit_motor_info2(&limot, &m_rbA, &m_rbB, info, row, axis, 0); 557 } 558 } 559 return row; 560 } 561 562 //----------------------------------------------------------------------------- 563 564 int btGeneric6DofConstraint::setAngularLimits(btConstraintInfo2 *info, int row_offset) 565 { 566 btGeneric6DofConstraint * d6constraint = this; 567 int row = row_offset; 568 //solve angular limits 569 for (int i=0;i<3 ;i++ ) 570 { 571 if(d6constraint->getRotationalLimitMotor(i)->needApplyTorques()) 572 { 573 btVector3 axis = d6constraint->getAxis(i); 574 row += get_limit_motor_info2( 575 d6constraint->getRotationalLimitMotor(i), 576 &m_rbA, 577 &m_rbB, 578 info,row,axis,1); 579 } 580 } 581 582 return row; 583 } 584 585 //----------------------------------------------------------------------------- 586 587 void btGeneric6DofConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) 588 { 589 if (m_useSolveConstraintObsolete) 590 { 591 592 593 m_timeStep = timeStep; 594 595 //calculateTransforms(); 596 597 int i; 598 599 // linear 600 601 btVector3 pointInA = m_calculatedTransformA.getOrigin(); 602 btVector3 pointInB = m_calculatedTransformB.getOrigin(); 603 604 btScalar jacDiagABInv; 605 btVector3 linear_axis; 606 for (i=0;i<3;i++) 607 { 608 if (m_linearLimits.isLimited(i)) 609 { 610 jacDiagABInv = btScalar(1.) / m_jacLinear[i].getDiagonal(); 611 612 if (m_useLinearReferenceFrameA) 613 linear_axis = m_calculatedTransformA.getBasis().getColumn(i); 614 else 615 linear_axis = m_calculatedTransformB.getBasis().getColumn(i); 616 617 m_linearLimits.solveLinearAxis( 618 m_timeStep, 619 jacDiagABInv, 620 m_rbA,bodyA,pointInA, 621 m_rbB,bodyB,pointInB, 622 i,linear_axis, m_AnchorPos); 623 624 } 625 } 626 627 // angular 628 btVector3 angular_axis; 629 btScalar angularJacDiagABInv; 630 for (i=0;i<3;i++) 631 { 632 if (m_angularLimits[i].needApplyTorques()) 633 { 634 635 // get axis 636 angular_axis = getAxis(i); 637 638 angularJacDiagABInv = btScalar(1.) / m_jacAng[i].getDiagonal(); 639 640 m_angularLimits[i].solveAngularLimits(m_timeStep,angular_axis,angularJacDiagABInv, &m_rbA,bodyA,&m_rbB,bodyB); 641 } 642 } 643 } 644 } 645 646 //----------------------------------------------------------------------------- 382 383 // Clear accumulated impulses for the next simulation step 384 m_linearLimits.m_accumulatedImpulse.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); 385 int i; 386 for(i = 0; i < 3; i++) 387 { 388 m_angularLimits[i].m_accumulatedImpulse = btScalar(0.); 389 } 390 //calculates transform 391 calculateTransforms(); 392 393 // const btVector3& pivotAInW = m_calculatedTransformA.getOrigin(); 394 // const btVector3& pivotBInW = m_calculatedTransformB.getOrigin(); 395 calcAnchorPos(); 396 btVector3 pivotAInW = m_AnchorPos; 397 btVector3 pivotBInW = m_AnchorPos; 398 399 // not used here 400 // btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); 401 // btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); 402 403 btVector3 normalWorld; 404 //linear part 405 for (i=0;i<3;i++) 406 { 407 if (m_linearLimits.isLimited(i)) 408 { 409 if (m_useLinearReferenceFrameA) 410 normalWorld = m_calculatedTransformA.getBasis().getColumn(i); 411 else 412 normalWorld = m_calculatedTransformB.getBasis().getColumn(i); 413 414 buildLinearJacobian( 415 m_jacLinear[i],normalWorld , 416 pivotAInW,pivotBInW); 417 418 } 419 } 420 421 // angular part 422 for (i=0;i<3;i++) 423 { 424 //calculates error angle 425 if (testAngularLimitMotor(i)) 426 { 427 normalWorld = this->getAxis(i); 428 // Create angular atom 429 buildAngularJacobian(m_jacAng[i],normalWorld); 430 } 431 } 432 433 434 } 435 436 437 void btGeneric6DofConstraint::solveConstraint(btScalar timeStep) 438 { 439 m_timeStep = timeStep; 440 441 //calculateTransforms(); 442 443 int i; 444 445 // linear 446 447 btVector3 pointInA = m_calculatedTransformA.getOrigin(); 448 btVector3 pointInB = m_calculatedTransformB.getOrigin(); 449 450 btScalar jacDiagABInv; 451 btVector3 linear_axis; 452 for (i=0;i<3;i++) 453 { 454 if (m_linearLimits.isLimited(i)) 455 { 456 jacDiagABInv = btScalar(1.) / m_jacLinear[i].getDiagonal(); 457 458 if (m_useLinearReferenceFrameA) 459 linear_axis = m_calculatedTransformA.getBasis().getColumn(i); 460 else 461 linear_axis = m_calculatedTransformB.getBasis().getColumn(i); 462 463 m_linearLimits.solveLinearAxis( 464 m_timeStep, 465 jacDiagABInv, 466 m_rbA,pointInA, 467 m_rbB,pointInB, 468 i,linear_axis, m_AnchorPos); 469 470 } 471 } 472 473 // angular 474 btVector3 angular_axis; 475 btScalar angularJacDiagABInv; 476 for (i=0;i<3;i++) 477 { 478 if (m_angularLimits[i].needApplyTorques()) 479 { 480 481 // get axis 482 angular_axis = getAxis(i); 483 484 angularJacDiagABInv = btScalar(1.) / m_jacAng[i].getDiagonal(); 485 486 m_angularLimits[i].solveAngularLimits(m_timeStep,angular_axis,angularJacDiagABInv, &m_rbA,&m_rbB); 487 } 488 } 489 } 647 490 648 491 void btGeneric6DofConstraint::updateRHS(btScalar timeStep) 649 492 { 650 (void)timeStep; 651 652 } 653 654 //----------------------------------------------------------------------------- 493 (void)timeStep; 494 495 } 655 496 656 497 btVector3 btGeneric6DofConstraint::getAxis(int axis_index) const 657 498 { 658 return m_calculatedAxis[axis_index]; 659 } 660 661 //----------------------------------------------------------------------------- 499 return m_calculatedAxis[axis_index]; 500 } 662 501 663 502 btScalar btGeneric6DofConstraint::getAngle(int axis_index) const 664 503 { 665 return m_calculatedAxisAngleDiff[axis_index]; 666 } 667 668 //----------------------------------------------------------------------------- 504 return m_calculatedAxisAngleDiff[axis_index]; 505 } 669 506 670 507 void btGeneric6DofConstraint::calcAnchorPos(void) … … 687 524 } // btGeneric6DofConstraint::calcAnchorPos() 688 525 689 //-----------------------------------------------------------------------------690 691 void btGeneric6DofConstraint::calculateLinearInfo()692 {693 m_calculatedLinearDiff = m_calculatedTransformB.getOrigin() - m_calculatedTransformA.getOrigin();694 m_calculatedLinearDiff = m_calculatedTransformA.getBasis().inverse() * m_calculatedLinearDiff;695 for(int i = 0; i < 3; i++)696 {697 m_linearLimits.testLimitValue(i, m_calculatedLinearDiff[i]);698 }699 } // btGeneric6DofConstraint::calculateLinearInfo()700 701 //-----------------------------------------------------------------------------702 703 int btGeneric6DofConstraint::get_limit_motor_info2(704 btRotationalLimitMotor * limot,705 btRigidBody * body0, btRigidBody * body1,706 btConstraintInfo2 *info, int row, btVector3& ax1, int rotational)707 {708 int srow = row * info->rowskip;709 int powered = limot->m_enableMotor;710 int limit = limot->m_currentLimit;711 if (powered || limit)712 { // if the joint is powered, or has joint limits, add in the extra row713 btScalar *J1 = rotational ? info->m_J1angularAxis : info->m_J1linearAxis;714 btScalar *J2 = rotational ? info->m_J2angularAxis : 0;715 J1[srow+0] = ax1[0];716 J1[srow+1] = ax1[1];717 J1[srow+2] = ax1[2];718 if(rotational)719 {720 J2[srow+0] = -ax1[0];721 J2[srow+1] = -ax1[1];722 J2[srow+2] = -ax1[2];723 }724 if((!rotational) && limit)725 {726 btVector3 ltd; // Linear Torque Decoupling vector727 btVector3 c = m_calculatedTransformB.getOrigin() - body0->getCenterOfMassPosition();728 ltd = c.cross(ax1);729 info->m_J1angularAxis[srow+0] = ltd[0];730 info->m_J1angularAxis[srow+1] = ltd[1];731 info->m_J1angularAxis[srow+2] = ltd[2];732 733 c = m_calculatedTransformB.getOrigin() - body1->getCenterOfMassPosition();734 ltd = -c.cross(ax1);735 info->m_J2angularAxis[srow+0] = ltd[0];736 info->m_J2angularAxis[srow+1] = ltd[1];737 info->m_J2angularAxis[srow+2] = ltd[2];738 }739 // if we're limited low and high simultaneously, the joint motor is740 // ineffective741 if (limit && (limot->m_loLimit == limot->m_hiLimit)) powered = 0;742 info->m_constraintError[srow] = btScalar(0.f);743 if (powered)744 {745 info->cfm[srow] = 0.0f;746 if(!limit)747 {748 info->m_constraintError[srow] += limot->m_targetVelocity;749 info->m_lowerLimit[srow] = -limot->m_maxMotorForce;750 info->m_upperLimit[srow] = limot->m_maxMotorForce;751 }752 }753 if(limit)754 {755 btScalar k = info->fps * limot->m_ERP;756 if(!rotational)757 {758 info->m_constraintError[srow] += k * limot->m_currentLimitError;759 }760 else761 {762 info->m_constraintError[srow] += -k * limot->m_currentLimitError;763 }764 info->cfm[srow] = 0.0f;765 if (limot->m_loLimit == limot->m_hiLimit)766 { // limited low and high simultaneously767 info->m_lowerLimit[srow] = -SIMD_INFINITY;768 info->m_upperLimit[srow] = SIMD_INFINITY;769 }770 else771 {772 if (limit == 1)773 {774 info->m_lowerLimit[srow] = 0;775 info->m_upperLimit[srow] = SIMD_INFINITY;776 }777 else778 {779 info->m_lowerLimit[srow] = -SIMD_INFINITY;780 info->m_upperLimit[srow] = 0;781 }782 // deal with bounce783 if (limot->m_bounce > 0)784 {785 // calculate joint velocity786 btScalar vel;787 if (rotational)788 {789 vel = body0->getAngularVelocity().dot(ax1);790 if (body1)791 vel -= body1->getAngularVelocity().dot(ax1);792 }793 else794 {795 vel = body0->getLinearVelocity().dot(ax1);796 if (body1)797 vel -= body1->getLinearVelocity().dot(ax1);798 }799 // only apply bounce if the velocity is incoming, and if the800 // resulting c[] exceeds what we already have.801 if (limit == 1)802 {803 if (vel < 0)804 {805 btScalar newc = -limot->m_bounce* vel;806 if (newc > info->m_constraintError[srow])807 info->m_constraintError[srow] = newc;808 }809 }810 else811 {812 if (vel > 0)813 {814 btScalar newc = -limot->m_bounce * vel;815 if (newc < info->m_constraintError[srow])816 info->m_constraintError[srow] = newc;817 }818 }819 }820 }821 }822 return 1;823 }824 else return 0;825 }826 827 //-----------------------------------------------------------------------------828 //-----------------------------------------------------------------------------829 //----------------------------------------------------------------------------- -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
r2907 r2908 29 29 30 30 class btRigidBody; 31 32 33 31 34 32 … … 95 93 bool isLimited() 96 94 { 97 if(m_loLimit >m_hiLimit) return false;95 if(m_loLimit>=m_hiLimit) return false; 98 96 return true; 99 97 } … … 113 111 114 112 //! apply the correction impulses for two bodies 115 btScalar solveAngularLimits(btScalar timeStep,btVector3& axis, btScalar jacDiagABInv,btRigidBody * body0, btSolverBody& bodyA,btRigidBody * body1,btSolverBody& bodyB); 113 btScalar solveAngularLimits(btScalar timeStep,btVector3& axis, btScalar jacDiagABInv,btRigidBody * body0, btRigidBody * body1); 114 116 115 117 116 }; … … 131 130 btScalar m_restitution;//! Bounce parameter for linear limit 132 131 //!@} 133 bool m_enableMotor[3];134 btVector3 m_targetVelocity;//!< target motor velocity135 btVector3 m_maxMotorForce;//!< max force on motor136 btVector3 m_currentLimitError;//! How much is violated this limit137 int m_currentLimit[3];//!< 0=free, 1=at lower limit, 2=at upper limit138 132 139 133 btTranslationalLimitMotor() … … 146 140 m_damping = btScalar(1.0f); 147 141 m_restitution = btScalar(0.5f); 148 for(int i=0; i < 3; i++)149 {150 m_enableMotor[i] = false;151 m_targetVelocity[i] = btScalar(0.f);152 m_maxMotorForce[i] = btScalar(0.f);153 }154 142 } 155 143 … … 163 151 m_damping = other.m_damping; 164 152 m_restitution = other.m_restitution; 165 for(int i=0; i < 3; i++)166 {167 m_enableMotor[i] = other.m_enableMotor[i];168 m_targetVelocity[i] = other.m_targetVelocity[i];169 m_maxMotorForce[i] = other.m_maxMotorForce[i];170 }171 153 } 172 154 … … 182 164 return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]); 183 165 } 184 inline bool needApplyForce(int limitIndex)185 {186 if(m_currentLimit[limitIndex] == 0 && m_enableMotor[limitIndex] == false) return false;187 return true;188 }189 int testLimitValue(int limitIndex, btScalar test_value);190 166 191 167 … … 193 169 btScalar timeStep, 194 170 btScalar jacDiagABInv, 195 btRigidBody& body1, btSolverBody& bodyA,const btVector3 &pointInA,196 btRigidBody& body2, btSolverBody& bodyB,const btVector3 &pointInB,171 btRigidBody& body1,const btVector3 &pointInA, 172 btRigidBody& body2,const btVector3 &pointInB, 197 173 int limit_index, 198 174 const btVector3 & axis_normal_on_a, … … 272 248 btVector3 m_calculatedAxisAngleDiff; 273 249 btVector3 m_calculatedAxis[3]; 274 btVector3 m_calculatedLinearDiff;275 250 276 251 btVector3 m_AnchorPos; // point betwen pivots of bodies A and B to solve linear axes … … 288 263 289 264 290 int setAngularLimits(btConstraintInfo2 *info, int row_offset);291 292 int setLinearLimits(btConstraintInfo2 *info);293 265 294 266 void buildLinearJacobian( … … 298 270 void buildAngularJacobian(btJacobianEntry & jacAngular,const btVector3 & jointAxisW); 299 271 300 // tests linear limits301 void calculateLinearInfo();302 272 303 273 //! calcs the euler angles between the two bodies. … … 307 277 308 278 public: 309 310 ///for backwards compatibility during the transition to 'getInfo/getInfo2'311 bool m_useSolveConstraintObsolete;312 313 279 btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); 314 280 … … 365 331 virtual void buildJacobian(); 366 332 367 virtual void getInfo1 (btConstraintInfo1* info); 368 369 virtual void getInfo2 (btConstraintInfo2* info); 370 371 virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep); 333 virtual void solveConstraint(btScalar timeStep); 372 334 373 335 void updateRHS(btScalar timeStep); … … 471 433 virtual void calcAnchorPos(void); // overridable 472 434 473 int get_limit_motor_info2( btRotationalLimitMotor * limot,474 btRigidBody * body0, btRigidBody * body1,475 btConstraintInfo2 *info, int row, btVector3& ax1, int rotational);476 477 478 435 }; 479 436 -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
r2907 r2908 20 20 #include "LinearMath/btMinMax.h" 21 21 #include <new> 22 #include "btSolverBody.h"23 24 //-----------------------------------------------------------------------------25 26 #define HINGE_USE_OBSOLETE_SOLVER false27 28 //-----------------------------------------------------------------------------29 22 30 23 31 24 btHingeConstraint::btHingeConstraint() 32 25 : btTypedConstraint (HINGE_CONSTRAINT_TYPE), 33 m_enableAngularMotor(false), 34 m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), 35 m_useReferenceFrameA(false) 36 { 37 m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f); 38 } 39 40 //----------------------------------------------------------------------------- 26 m_enableAngularMotor(false) 27 { 28 } 41 29 42 30 btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, 43 btVector3& axisInA,btVector3& axisInB , bool useReferenceFrameA)31 btVector3& axisInA,btVector3& axisInB) 44 32 :btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA,rbB), 45 33 m_angularOnly(false), 46 m_enableAngularMotor(false), 47 m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), 48 m_useReferenceFrameA(useReferenceFrameA) 34 m_enableAngularMotor(false) 49 35 { 50 36 m_rbAFrame.getOrigin() = pivotInA; … … 75 61 76 62 m_rbBFrame.getOrigin() = pivotInB; 77 m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(), axisInB.getX(),78 rbAxisB1.getY(),rbAxisB2.getY(), axisInB.getY(),79 rbAxisB1.getZ(),rbAxisB2.getZ(), axisInB.getZ() );63 m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),-axisInB.getX(), 64 rbAxisB1.getY(),rbAxisB2.getY(),-axisInB.getY(), 65 rbAxisB1.getZ(),rbAxisB2.getZ(),-axisInB.getZ() ); 80 66 81 67 //start with free … … 86 72 m_limitSoftness = 0.9f; 87 73 m_solveLimit = false; 88 m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f); 89 } 90 91 //----------------------------------------------------------------------------- 92 93 btHingeConstraint::btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA, bool useReferenceFrameA) 94 :btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA), m_angularOnly(false), m_enableAngularMotor(false), 95 m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), 96 m_useReferenceFrameA(useReferenceFrameA) 74 75 } 76 77 78 79 btHingeConstraint::btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA) 80 :btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA), m_angularOnly(false), m_enableAngularMotor(false) 97 81 { 98 82 … … 107 91 rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() ); 108 92 109 btVector3 axisInB = rbA.getCenterOfMassTransform().getBasis() * axisInA;93 btVector3 axisInB = rbA.getCenterOfMassTransform().getBasis() * -axisInA; 110 94 111 95 btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB); … … 126 110 m_limitSoftness = 0.9f; 127 111 m_solveLimit = false; 128 m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f); 129 } 130 131 //----------------------------------------------------------------------------- 112 } 132 113 133 114 btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, 134 const btTransform& rbAFrame, const btTransform& rbBFrame , bool useReferenceFrameA)115 const btTransform& rbAFrame, const btTransform& rbBFrame) 135 116 :btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame), 136 117 m_angularOnly(false), 137 m_enableAngularMotor(false), 138 m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), 139 m_useReferenceFrameA(useReferenceFrameA) 140 { 118 m_enableAngularMotor(false) 119 { 120 // flip axis 121 m_rbBFrame.getBasis()[0][2] *= btScalar(-1.); 122 m_rbBFrame.getBasis()[1][2] *= btScalar(-1.); 123 m_rbBFrame.getBasis()[2][2] *= btScalar(-1.); 124 141 125 //start with free 142 126 m_lowerLimit = btScalar(1e30); … … 146 130 m_limitSoftness = 0.9f; 147 131 m_solveLimit = false; 148 m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f);149 132 } 150 133 151 //----------------------------------------------------------------------------- 152 153 btHingeConstraint::btHingeConstraint(btRigidBody& rbA, const btTransform& rbAFrame , bool useReferenceFrameA)134 135 136 btHingeConstraint::btHingeConstraint(btRigidBody& rbA, const btTransform& rbAFrame) 154 137 :btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA),m_rbAFrame(rbAFrame),m_rbBFrame(rbAFrame), 155 138 m_angularOnly(false), 156 m_enableAngularMotor(false), 157 m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), 158 m_useReferenceFrameA(useReferenceFrameA) 139 m_enableAngularMotor(false) 159 140 { 160 141 ///not providing rigidbody B means implicitly using worldspace for body B 142 143 // flip axis 144 m_rbBFrame.getBasis()[0][2] *= btScalar(-1.); 145 m_rbBFrame.getBasis()[1][2] *= btScalar(-1.); 146 m_rbBFrame.getBasis()[2][2] *= btScalar(-1.); 161 147 162 148 m_rbBFrame.getOrigin() = m_rbA.getCenterOfMassTransform()(m_rbAFrame.getOrigin()); … … 169 155 m_limitSoftness = 0.9f; 170 156 m_solveLimit = false; 171 m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f); 172 } 173 174 //----------------------------------------------------------------------------- 157 } 175 158 176 159 void btHingeConstraint::buildJacobian() 177 160 { 178 if (m_useSolveConstraintObsolete) 161 m_appliedImpulse = btScalar(0.); 162 163 if (!m_angularOnly) 179 164 { 180 m_appliedImpulse = btScalar(0.); 181 182 if (!m_angularOnly) 183 { 184 btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); 185 btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); 186 btVector3 relPos = pivotBInW - pivotAInW; 187 188 btVector3 normal[3]; 189 if (relPos.length2() > SIMD_EPSILON) 190 { 191 normal[0] = relPos.normalized(); 192 } 193 else 194 { 195 normal[0].setValue(btScalar(1.0),0,0); 196 } 197 198 btPlaneSpace1(normal[0], normal[1], normal[2]); 199 200 for (int i=0;i<3;i++) 201 { 202 new (&m_jac[i]) btJacobianEntry( 165 btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); 166 btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); 167 btVector3 relPos = pivotBInW - pivotAInW; 168 169 btVector3 normal[3]; 170 if (relPos.length2() > SIMD_EPSILON) 171 { 172 normal[0] = relPos.normalized(); 173 } 174 else 175 { 176 normal[0].setValue(btScalar(1.0),0,0); 177 } 178 179 btPlaneSpace1(normal[0], normal[1], normal[2]); 180 181 for (int i=0;i<3;i++) 182 { 183 new (&m_jac[i]) btJacobianEntry( 203 184 m_rbA.getCenterOfMassTransform().getBasis().transpose(), 204 185 m_rbB.getCenterOfMassTransform().getBasis().transpose(), … … 210 191 m_rbB.getInvInertiaDiagLocal(), 211 192 m_rbB.getInvMass()); 193 } 194 } 195 196 //calculate two perpendicular jointAxis, orthogonal to hingeAxis 197 //these two jointAxis require equal angular velocities for both bodies 198 199 //this is unused for now, it's a todo 200 btVector3 jointAxis0local; 201 btVector3 jointAxis1local; 202 203 btPlaneSpace1(m_rbAFrame.getBasis().getColumn(2),jointAxis0local,jointAxis1local); 204 205 getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); 206 btVector3 jointAxis0 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis0local; 207 btVector3 jointAxis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis1local; 208 btVector3 hingeAxisWorld = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); 209 210 new (&m_jacAng[0]) btJacobianEntry(jointAxis0, 211 m_rbA.getCenterOfMassTransform().getBasis().transpose(), 212 m_rbB.getCenterOfMassTransform().getBasis().transpose(), 213 m_rbA.getInvInertiaDiagLocal(), 214 m_rbB.getInvInertiaDiagLocal()); 215 216 new (&m_jacAng[1]) btJacobianEntry(jointAxis1, 217 m_rbA.getCenterOfMassTransform().getBasis().transpose(), 218 m_rbB.getCenterOfMassTransform().getBasis().transpose(), 219 m_rbA.getInvInertiaDiagLocal(), 220 m_rbB.getInvInertiaDiagLocal()); 221 222 new (&m_jacAng[2]) btJacobianEntry(hingeAxisWorld, 223 m_rbA.getCenterOfMassTransform().getBasis().transpose(), 224 m_rbB.getCenterOfMassTransform().getBasis().transpose(), 225 m_rbA.getInvInertiaDiagLocal(), 226 m_rbB.getInvInertiaDiagLocal()); 227 228 229 // Compute limit information 230 btScalar hingeAngle = getHingeAngle(); 231 232 //set bias, sign, clear accumulator 233 m_correction = btScalar(0.); 234 m_limitSign = btScalar(0.); 235 m_solveLimit = false; 236 m_accLimitImpulse = btScalar(0.); 237 238 // if (m_lowerLimit < m_upperLimit) 239 if (m_lowerLimit <= m_upperLimit) 240 { 241 // if (hingeAngle <= m_lowerLimit*m_limitSoftness) 242 if (hingeAngle <= m_lowerLimit) 243 { 244 m_correction = (m_lowerLimit - hingeAngle); 245 m_limitSign = 1.0f; 246 m_solveLimit = true; 247 } 248 // else if (hingeAngle >= m_upperLimit*m_limitSoftness) 249 else if (hingeAngle >= m_upperLimit) 250 { 251 m_correction = m_upperLimit - hingeAngle; 252 m_limitSign = -1.0f; 253 m_solveLimit = true; 254 } 255 } 256 257 //Compute K = J*W*J' for hinge axis 258 btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); 259 m_kHinge = 1.0f / (getRigidBodyA().computeAngularImpulseDenominator(axisA) + 260 getRigidBodyB().computeAngularImpulseDenominator(axisA)); 261 262 } 263 264 void btHingeConstraint::solveConstraint(btScalar timeStep) 265 { 266 267 btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); 268 btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); 269 270 btScalar tau = btScalar(0.3); 271 272 //linear part 273 if (!m_angularOnly) 274 { 275 btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); 276 btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); 277 278 btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1); 279 btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2); 280 btVector3 vel = vel1 - vel2; 281 282 for (int i=0;i<3;i++) 283 { 284 const btVector3& normal = m_jac[i].m_linearJointAxis; 285 btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal(); 286 287 btScalar rel_vel; 288 rel_vel = normal.dot(vel); 289 //positional error (zeroth order error) 290 btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal 291 btScalar impulse = depth*tau/timeStep * jacDiagABInv - rel_vel * jacDiagABInv; 292 m_appliedImpulse += impulse; 293 btVector3 impulse_vector = normal * impulse; 294 m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition()); 295 m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition()); 296 } 297 } 298 299 300 { 301 ///solve angular part 302 303 // get axes in world space 304 btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); 305 btVector3 axisB = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_rbBFrame.getBasis().getColumn(2); 306 307 const btVector3& angVelA = getRigidBodyA().getAngularVelocity(); 308 const btVector3& angVelB = getRigidBodyB().getAngularVelocity(); 309 310 btVector3 angVelAroundHingeAxisA = axisA * axisA.dot(angVelA); 311 btVector3 angVelAroundHingeAxisB = axisB * axisB.dot(angVelB); 312 313 btVector3 angAorthog = angVelA - angVelAroundHingeAxisA; 314 btVector3 angBorthog = angVelB - angVelAroundHingeAxisB; 315 btVector3 velrelOrthog = angAorthog-angBorthog; 316 { 317 //solve orthogonal angular velocity correction 318 btScalar relaxation = btScalar(1.); 319 btScalar len = velrelOrthog.length(); 320 if (len > btScalar(0.00001)) 321 { 322 btVector3 normal = velrelOrthog.normalized(); 323 btScalar denom = getRigidBodyA().computeAngularImpulseDenominator(normal) + 324 getRigidBodyB().computeAngularImpulseDenominator(normal); 325 // scale for mass and relaxation 326 velrelOrthog *= (btScalar(1.)/denom) * m_relaxationFactor; 212 327 } 213 } 214 215 //calculate two perpendicular jointAxis, orthogonal to hingeAxis 216 //these two jointAxis require equal angular velocities for both bodies 217 218 //this is unused for now, it's a todo 219 btVector3 jointAxis0local; 220 btVector3 jointAxis1local; 221 222 btPlaneSpace1(m_rbAFrame.getBasis().getColumn(2),jointAxis0local,jointAxis1local); 223 224 getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); 225 btVector3 jointAxis0 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis0local; 226 btVector3 jointAxis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis1local; 227 btVector3 hingeAxisWorld = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); 328 329 //solve angular positional correction 330 btVector3 angularError = -axisA.cross(axisB) *(btScalar(1.)/timeStep); 331 btScalar len2 = angularError.length(); 332 if (len2>btScalar(0.00001)) 333 { 334 btVector3 normal2 = angularError.normalized(); 335 btScalar denom2 = getRigidBodyA().computeAngularImpulseDenominator(normal2) + 336 getRigidBodyB().computeAngularImpulseDenominator(normal2); 337 angularError *= (btScalar(1.)/denom2) * relaxation; 338 } 339 340 m_rbA.applyTorqueImpulse(-velrelOrthog+angularError); 341 m_rbB.applyTorqueImpulse(velrelOrthog-angularError); 342 343 // solve limit 344 if (m_solveLimit) 345 { 346 btScalar amplitude = ( (angVelB - angVelA).dot( axisA )*m_relaxationFactor + m_correction* (btScalar(1.)/timeStep)*m_biasFactor ) * m_limitSign; 347 348 btScalar impulseMag = amplitude * m_kHinge; 349 350 // Clamp the accumulated impulse 351 btScalar temp = m_accLimitImpulse; 352 m_accLimitImpulse = btMax(m_accLimitImpulse + impulseMag, btScalar(0) ); 353 impulseMag = m_accLimitImpulse - temp; 354 355 356 btVector3 impulse = axisA * impulseMag * m_limitSign; 357 m_rbA.applyTorqueImpulse(impulse); 358 m_rbB.applyTorqueImpulse(-impulse); 359 } 360 } 361 362 //apply motor 363 if (m_enableAngularMotor) 364 { 365 //todo: add limits too 366 btVector3 angularLimit(0,0,0); 367 368 btVector3 velrel = angVelAroundHingeAxisA - angVelAroundHingeAxisB; 369 btScalar projRelVel = velrel.dot(axisA); 370 371 btScalar desiredMotorVel = m_motorTargetVelocity; 372 btScalar motor_relvel = desiredMotorVel - projRelVel; 373 374 btScalar unclippedMotorImpulse = m_kHinge * motor_relvel;; 375 //todo: should clip against accumulated impulse 376 btScalar clippedMotorImpulse = unclippedMotorImpulse > m_maxMotorImpulse ? m_maxMotorImpulse : unclippedMotorImpulse; 377 clippedMotorImpulse = clippedMotorImpulse < -m_maxMotorImpulse ? -m_maxMotorImpulse : clippedMotorImpulse; 378 btVector3 motorImp = clippedMotorImpulse * axisA; 379 380 m_rbA.applyTorqueImpulse(motorImp+angularLimit); 381 m_rbB.applyTorqueImpulse(-motorImp-angularLimit); 228 382 229 new (&m_jacAng[0]) btJacobianEntry(jointAxis0, 230 m_rbA.getCenterOfMassTransform().getBasis().transpose(), 231 m_rbB.getCenterOfMassTransform().getBasis().transpose(), 232 m_rbA.getInvInertiaDiagLocal(), 233 m_rbB.getInvInertiaDiagLocal()); 234 235 new (&m_jacAng[1]) btJacobianEntry(jointAxis1, 236 m_rbA.getCenterOfMassTransform().getBasis().transpose(), 237 m_rbB.getCenterOfMassTransform().getBasis().transpose(), 238 m_rbA.getInvInertiaDiagLocal(), 239 m_rbB.getInvInertiaDiagLocal()); 240 241 new (&m_jacAng[2]) btJacobianEntry(hingeAxisWorld, 242 m_rbA.getCenterOfMassTransform().getBasis().transpose(), 243 m_rbB.getCenterOfMassTransform().getBasis().transpose(), 244 m_rbA.getInvInertiaDiagLocal(), 245 m_rbB.getInvInertiaDiagLocal()); 246 247 // clear accumulator 248 m_accLimitImpulse = btScalar(0.); 249 250 // test angular limit 251 testLimit(); 252 253 //Compute K = J*W*J' for hinge axis 254 btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); 255 m_kHinge = 1.0f / (getRigidBodyA().computeAngularImpulseDenominator(axisA) + 256 getRigidBodyB().computeAngularImpulseDenominator(axisA)); 257 383 } 258 384 } 259 } 260 261 //----------------------------------------------------------------------------- 262 263 void btHingeConstraint::getInfo1(btConstraintInfo1* info) 264 { 265 if (m_useSolveConstraintObsolete) 266 { 267 info->m_numConstraintRows = 0; 268 info->nub = 0; 269 } 270 else 271 { 272 info->m_numConstraintRows = 5; // Fixed 3 linear + 2 angular 273 info->nub = 1; 274 //prepare constraint 275 testLimit(); 276 if(getSolveLimit() || getEnableAngularMotor()) 277 { 278 info->m_numConstraintRows++; // limit 3rd anguar as well 279 info->nub--; 280 } 281 } 282 } // btHingeConstraint::getInfo1 () 283 284 //----------------------------------------------------------------------------- 285 286 void btHingeConstraint::getInfo2 (btConstraintInfo2* info) 287 { 288 btAssert(!m_useSolveConstraintObsolete); 289 int i, s = info->rowskip; 290 // transforms in world space 291 btTransform trA = m_rbA.getCenterOfMassTransform()*m_rbAFrame; 292 btTransform trB = m_rbB.getCenterOfMassTransform()*m_rbBFrame; 293 // pivot point 294 btVector3 pivotAInW = trA.getOrigin(); 295 btVector3 pivotBInW = trB.getOrigin(); 296 // linear (all fixed) 297 info->m_J1linearAxis[0] = 1; 298 info->m_J1linearAxis[s + 1] = 1; 299 info->m_J1linearAxis[2 * s + 2] = 1; 300 btVector3 a1 = pivotAInW - m_rbA.getCenterOfMassTransform().getOrigin(); 301 { 302 btVector3* angular0 = (btVector3*)(info->m_J1angularAxis); 303 btVector3* angular1 = (btVector3*)(info->m_J1angularAxis + s); 304 btVector3* angular2 = (btVector3*)(info->m_J1angularAxis + 2 * s); 305 btVector3 a1neg = -a1; 306 a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2); 307 } 308 btVector3 a2 = pivotBInW - m_rbB.getCenterOfMassTransform().getOrigin(); 309 { 310 btVector3* angular0 = (btVector3*)(info->m_J2angularAxis); 311 btVector3* angular1 = (btVector3*)(info->m_J2angularAxis + s); 312 btVector3* angular2 = (btVector3*)(info->m_J2angularAxis + 2 * s); 313 a2.getSkewSymmetricMatrix(angular0,angular1,angular2); 314 } 315 // linear RHS 316 btScalar k = info->fps * info->erp; 317 for(i = 0; i < 3; i++) 318 { 319 info->m_constraintError[i * s] = k * (pivotBInW[i] - pivotAInW[i]); 320 } 321 // make rotations around X and Y equal 322 // the hinge axis should be the only unconstrained 323 // rotational axis, the angular velocity of the two bodies perpendicular to 324 // the hinge axis should be equal. thus the constraint equations are 325 // p*w1 - p*w2 = 0 326 // q*w1 - q*w2 = 0 327 // where p and q are unit vectors normal to the hinge axis, and w1 and w2 328 // are the angular velocity vectors of the two bodies. 329 // get hinge axis (Z) 330 btVector3 ax1 = trA.getBasis().getColumn(2); 331 // get 2 orthos to hinge axis (X, Y) 332 btVector3 p = trA.getBasis().getColumn(0); 333 btVector3 q = trA.getBasis().getColumn(1); 334 // set the two hinge angular rows 335 int s3 = 3 * info->rowskip; 336 int s4 = 4 * info->rowskip; 337 338 info->m_J1angularAxis[s3 + 0] = p[0]; 339 info->m_J1angularAxis[s3 + 1] = p[1]; 340 info->m_J1angularAxis[s3 + 2] = p[2]; 341 info->m_J1angularAxis[s4 + 0] = q[0]; 342 info->m_J1angularAxis[s4 + 1] = q[1]; 343 info->m_J1angularAxis[s4 + 2] = q[2]; 344 345 info->m_J2angularAxis[s3 + 0] = -p[0]; 346 info->m_J2angularAxis[s3 + 1] = -p[1]; 347 info->m_J2angularAxis[s3 + 2] = -p[2]; 348 info->m_J2angularAxis[s4 + 0] = -q[0]; 349 info->m_J2angularAxis[s4 + 1] = -q[1]; 350 info->m_J2angularAxis[s4 + 2] = -q[2]; 351 // compute the right hand side of the constraint equation. set relative 352 // body velocities along p and q to bring the hinge back into alignment. 353 // if ax1,ax2 are the unit length hinge axes as computed from body1 and 354 // body2, we need to rotate both bodies along the axis u = (ax1 x ax2). 355 // if `theta' is the angle between ax1 and ax2, we need an angular velocity 356 // along u to cover angle erp*theta in one step : 357 // |angular_velocity| = angle/time = erp*theta / stepsize 358 // = (erp*fps) * theta 359 // angular_velocity = |angular_velocity| * (ax1 x ax2) / |ax1 x ax2| 360 // = (erp*fps) * theta * (ax1 x ax2) / sin(theta) 361 // ...as ax1 and ax2 are unit length. if theta is smallish, 362 // theta ~= sin(theta), so 363 // angular_velocity = (erp*fps) * (ax1 x ax2) 364 // ax1 x ax2 is in the plane space of ax1, so we project the angular 365 // velocity to p and q to find the right hand side. 366 btVector3 ax2 = trB.getBasis().getColumn(2); 367 btVector3 u = ax1.cross(ax2); 368 info->m_constraintError[s3] = k * u.dot(p); 369 info->m_constraintError[s4] = k * u.dot(q); 370 // check angular limits 371 int nrow = 4; // last filled row 372 int srow; 373 btScalar limit_err = btScalar(0.0); 374 int limit = 0; 375 if(getSolveLimit()) 376 { 377 limit_err = m_correction * m_referenceSign; 378 limit = (limit_err > btScalar(0.0)) ? 1 : 2; 379 } 380 // if the hinge has joint limits or motor, add in the extra row 381 int powered = 0; 382 if(getEnableAngularMotor()) 383 { 384 powered = 1; 385 } 386 if(limit || powered) 387 { 388 nrow++; 389 srow = nrow * info->rowskip; 390 info->m_J1angularAxis[srow+0] = ax1[0]; 391 info->m_J1angularAxis[srow+1] = ax1[1]; 392 info->m_J1angularAxis[srow+2] = ax1[2]; 393 394 info->m_J2angularAxis[srow+0] = -ax1[0]; 395 info->m_J2angularAxis[srow+1] = -ax1[1]; 396 info->m_J2angularAxis[srow+2] = -ax1[2]; 397 398 btScalar lostop = getLowerLimit(); 399 btScalar histop = getUpperLimit(); 400 if(limit && (lostop == histop)) 401 { // the joint motor is ineffective 402 powered = 0; 403 } 404 info->m_constraintError[srow] = btScalar(0.0f); 405 if(powered) 406 { 407 info->cfm[srow] = btScalar(0.0); 408 btScalar mot_fact = getMotorFactor(m_hingeAngle, lostop, histop, m_motorTargetVelocity, info->fps * info->erp); 409 info->m_constraintError[srow] += mot_fact * m_motorTargetVelocity * m_referenceSign; 410 info->m_lowerLimit[srow] = - m_maxMotorImpulse; 411 info->m_upperLimit[srow] = m_maxMotorImpulse; 412 } 413 if(limit) 414 { 415 k = info->fps * info->erp; 416 info->m_constraintError[srow] += k * limit_err; 417 info->cfm[srow] = btScalar(0.0); 418 if(lostop == histop) 419 { 420 // limited low and high simultaneously 421 info->m_lowerLimit[srow] = -SIMD_INFINITY; 422 info->m_upperLimit[srow] = SIMD_INFINITY; 423 } 424 else if(limit == 1) 425 { // low limit 426 info->m_lowerLimit[srow] = 0; 427 info->m_upperLimit[srow] = SIMD_INFINITY; 428 } 429 else 430 { // high limit 431 info->m_lowerLimit[srow] = -SIMD_INFINITY; 432 info->m_upperLimit[srow] = 0; 433 } 434 // bounce (we'll use slider parameter abs(1.0 - m_dampingLimAng) for that) 435 btScalar bounce = m_relaxationFactor; 436 if(bounce > btScalar(0.0)) 437 { 438 btScalar vel = m_rbA.getAngularVelocity().dot(ax1); 439 vel -= m_rbB.getAngularVelocity().dot(ax1); 440 // only apply bounce if the velocity is incoming, and if the 441 // resulting c[] exceeds what we already have. 442 if(limit == 1) 443 { // low limit 444 if(vel < 0) 445 { 446 btScalar newc = -bounce * vel; 447 if(newc > info->m_constraintError[srow]) 448 { 449 info->m_constraintError[srow] = newc; 450 } 451 } 452 } 453 else 454 { // high limit - all those computations are reversed 455 if(vel > 0) 456 { 457 btScalar newc = -bounce * vel; 458 if(newc < info->m_constraintError[srow]) 459 { 460 info->m_constraintError[srow] = newc; 461 } 462 } 463 } 464 } 465 info->m_constraintError[srow] *= m_biasFactor; 466 } // if(limit) 467 } // if angular limit or powered 468 } 469 470 //----------------------------------------------------------------------------- 471 472 void btHingeConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) 473 { 474 475 ///for backwards compatibility during the transition to 'getInfo/getInfo2' 476 if (m_useSolveConstraintObsolete) 477 { 478 479 btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); 480 btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); 481 482 btScalar tau = btScalar(0.3); 483 484 //linear part 485 if (!m_angularOnly) 486 { 487 btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); 488 btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); 489 490 btVector3 vel1,vel2; 491 bodyA.getVelocityInLocalPointObsolete(rel_pos1,vel1); 492 bodyB.getVelocityInLocalPointObsolete(rel_pos2,vel2); 493 btVector3 vel = vel1 - vel2; 494 495 for (int i=0;i<3;i++) 496 { 497 const btVector3& normal = m_jac[i].m_linearJointAxis; 498 btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal(); 499 500 btScalar rel_vel; 501 rel_vel = normal.dot(vel); 502 //positional error (zeroth order error) 503 btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal 504 btScalar impulse = depth*tau/timeStep * jacDiagABInv - rel_vel * jacDiagABInv; 505 m_appliedImpulse += impulse; 506 btVector3 impulse_vector = normal * impulse; 507 btVector3 ftorqueAxis1 = rel_pos1.cross(normal); 508 btVector3 ftorqueAxis2 = rel_pos2.cross(normal); 509 bodyA.applyImpulse(normal*m_rbA.getInvMass(), m_rbA.getInvInertiaTensorWorld()*ftorqueAxis1,impulse); 510 bodyB.applyImpulse(normal*m_rbB.getInvMass(), m_rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-impulse); 511 } 512 } 513 514 515 { 516 ///solve angular part 517 518 // get axes in world space 519 btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); 520 btVector3 axisB = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_rbBFrame.getBasis().getColumn(2); 521 522 btVector3 angVelA; 523 bodyA.getAngularVelocity(angVelA); 524 btVector3 angVelB; 525 bodyB.getAngularVelocity(angVelB); 526 527 btVector3 angVelAroundHingeAxisA = axisA * axisA.dot(angVelA); 528 btVector3 angVelAroundHingeAxisB = axisB * axisB.dot(angVelB); 529 530 btVector3 angAorthog = angVelA - angVelAroundHingeAxisA; 531 btVector3 angBorthog = angVelB - angVelAroundHingeAxisB; 532 btVector3 velrelOrthog = angAorthog-angBorthog; 533 { 534 535 536 //solve orthogonal angular velocity correction 537 btScalar relaxation = btScalar(1.); 538 btScalar len = velrelOrthog.length(); 539 if (len > btScalar(0.00001)) 540 { 541 btVector3 normal = velrelOrthog.normalized(); 542 btScalar denom = getRigidBodyA().computeAngularImpulseDenominator(normal) + 543 getRigidBodyB().computeAngularImpulseDenominator(normal); 544 // scale for mass and relaxation 545 //velrelOrthog *= (btScalar(1.)/denom) * m_relaxationFactor; 546 547 bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*velrelOrthog,-(btScalar(1.)/denom)); 548 bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*velrelOrthog,(btScalar(1.)/denom)); 549 550 } 551 552 //solve angular positional correction 553 btVector3 angularError = axisA.cross(axisB) *(btScalar(1.)/timeStep); 554 btScalar len2 = angularError.length(); 555 if (len2>btScalar(0.00001)) 556 { 557 btVector3 normal2 = angularError.normalized(); 558 btScalar denom2 = getRigidBodyA().computeAngularImpulseDenominator(normal2) + 559 getRigidBodyB().computeAngularImpulseDenominator(normal2); 560 //angularError *= (btScalar(1.)/denom2) * relaxation; 561 562 bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*angularError,(btScalar(1.)/denom2)); 563 bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*angularError,-(btScalar(1.)/denom2)); 564 565 } 566 567 568 569 570 571 // solve limit 572 if (m_solveLimit) 573 { 574 btScalar amplitude = ( (angVelB - angVelA).dot( axisA )*m_relaxationFactor + m_correction* (btScalar(1.)/timeStep)*m_biasFactor ) * m_limitSign; 575 576 btScalar impulseMag = amplitude * m_kHinge; 577 578 // Clamp the accumulated impulse 579 btScalar temp = m_accLimitImpulse; 580 m_accLimitImpulse = btMax(m_accLimitImpulse + impulseMag, btScalar(0) ); 581 impulseMag = m_accLimitImpulse - temp; 582 583 584 585 bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*axisA,impulseMag * m_limitSign); 586 bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*axisA,-(impulseMag * m_limitSign)); 587 588 } 589 } 590 591 //apply motor 592 if (m_enableAngularMotor) 593 { 594 //todo: add limits too 595 btVector3 angularLimit(0,0,0); 596 597 btVector3 velrel = angVelAroundHingeAxisA - angVelAroundHingeAxisB; 598 btScalar projRelVel = velrel.dot(axisA); 599 600 btScalar desiredMotorVel = m_motorTargetVelocity; 601 btScalar motor_relvel = desiredMotorVel - projRelVel; 602 603 btScalar unclippedMotorImpulse = m_kHinge * motor_relvel;; 604 //todo: should clip against accumulated impulse 605 btScalar clippedMotorImpulse = unclippedMotorImpulse > m_maxMotorImpulse ? m_maxMotorImpulse : unclippedMotorImpulse; 606 clippedMotorImpulse = clippedMotorImpulse < -m_maxMotorImpulse ? -m_maxMotorImpulse : clippedMotorImpulse; 607 btVector3 motorImp = clippedMotorImpulse * axisA; 608 609 bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*axisA,clippedMotorImpulse); 610 bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*axisA,-clippedMotorImpulse); 611 612 } 613 } 614 } 615 616 } 617 618 //----------------------------------------------------------------------------- 385 386 } 619 387 620 388 void btHingeConstraint::updateRHS(btScalar timeStep) … … 623 391 624 392 } 625 626 //-----------------------------------------------------------------------------627 393 628 394 btScalar btHingeConstraint::getHingeAngle() … … 631 397 const btVector3 refAxis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(1); 632 398 const btVector3 swingAxis = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_rbBFrame.getBasis().getColumn(1); 633 btScalar angle = btAtan2Fast(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1)); 634 return m_referenceSign * angle; 635 } 636 637 //----------------------------------------------------------------------------- 638 639 void btHingeConstraint::testLimit() 640 { 641 // Compute limit information 642 m_hingeAngle = getHingeAngle(); 643 m_correction = btScalar(0.); 644 m_limitSign = btScalar(0.); 645 m_solveLimit = false; 646 if (m_lowerLimit <= m_upperLimit) 647 { 648 if (m_hingeAngle <= m_lowerLimit) 649 { 650 m_correction = (m_lowerLimit - m_hingeAngle); 651 m_limitSign = 1.0f; 652 m_solveLimit = true; 653 } 654 else if (m_hingeAngle >= m_upperLimit) 655 { 656 m_correction = m_upperLimit - m_hingeAngle; 657 m_limitSign = -1.0f; 658 m_solveLimit = true; 659 } 660 } 661 return; 662 } // btHingeConstraint::testLimit() 663 664 //----------------------------------------------------------------------------- 665 //----------------------------------------------------------------------------- 666 //----------------------------------------------------------------------------- 399 400 return btAtan2Fast( swingAxis.dot(refAxis0), swingAxis.dot(refAxis1) ); 401 } 402 -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.h
r2907 r2908 54 54 55 55 btScalar m_accLimitImpulse; 56 btScalar m_hingeAngle;57 btScalar m_referenceSign;58 56 59 57 bool m_angularOnly; 60 58 bool m_enableAngularMotor; 61 59 bool m_solveLimit; 62 bool m_useSolveConstraintObsolete;63 bool m_useReferenceFrameA;64 60 65 61 66 62 public: 67 63 68 btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, btVector3& axisInA,btVector3& axisInB , bool useReferenceFrameA = false);64 btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, btVector3& axisInA,btVector3& axisInB); 69 65 70 btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA , bool useReferenceFrameA = false);66 btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA); 71 67 72 btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame , bool useReferenceFrameA = false);68 btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame); 73 69 74 btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame , bool useReferenceFrameA = false);70 btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame); 75 71 76 72 btHingeConstraint(); … … 78 74 virtual void buildJacobian(); 79 75 80 virtual void getInfo1 (btConstraintInfo1* info); 81 82 virtual void getInfo2 (btConstraintInfo2* info); 83 84 virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep); 76 virtual void solveConstraint(btScalar timeStep); 85 77 86 78 void updateRHS(btScalar timeStep); … … 95 87 } 96 88 97 btRigidBody& getRigidBodyA()98 {99 return m_rbA;100 }101 102 btRigidBody& getRigidBodyB()103 {104 return m_rbB;105 }106 107 89 void setAngularOnly(bool angularOnly) 108 90 { … … 141 123 btScalar getHingeAngle(); 142 124 143 void testLimit();144 145 125 146 126 const btTransform& getAFrame() { return m_rbAFrame; }; -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
r2907 r2908 22 22 23 23 btPoint2PointConstraint::btPoint2PointConstraint() 24 :btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE), 25 m_useSolveConstraintObsolete(false) 24 :btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE) 26 25 { 27 26 } 28 27 29 28 btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB) 30 :btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA,rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB), 31 m_useSolveConstraintObsolete(false) 29 :btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA,rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB) 32 30 { 33 31 … … 36 34 37 35 btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA) 38 :btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA)), 39 m_useSolveConstraintObsolete(false) 36 :btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA)) 40 37 { 41 38 … … 44 41 void btPoint2PointConstraint::buildJacobian() 45 42 { 46 ///we need it for both methods 43 m_appliedImpulse = btScalar(0.); 44 45 btVector3 normal(0,0,0); 46 47 for (int i=0;i<3;i++) 47 48 { 48 m_appliedImpulse = btScalar(0.); 49 50 btVector3 normal(0,0,0); 51 52 for (int i=0;i<3;i++) 53 { 54 normal[i] = 1; 55 new (&m_jac[i]) btJacobianEntry( 49 normal[i] = 1; 50 new (&m_jac[i]) btJacobianEntry( 56 51 m_rbA.getCenterOfMassTransform().getBasis().transpose(), 57 52 m_rbB.getCenterOfMassTransform().getBasis().transpose(), … … 64 59 m_rbB.getInvMass()); 65 60 normal[i] = 0; 66 }67 61 } 68 62 69 63 } 70 64 65 void btPoint2PointConstraint::solveConstraint(btScalar timeStep) 66 { 67 btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_pivotInA; 68 btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_pivotInB; 71 69 72 void btPoint2PointConstraint::getInfo1 (btConstraintInfo1* info)73 {74 if (m_useSolveConstraintObsolete)75 {76 info->m_numConstraintRows = 0;77 info->nub = 0;78 } else79 {80 info->m_numConstraintRows = 3;81 info->nub = 3;82 }83 }84 70 85 void btPoint2PointConstraint::getInfo2 (btConstraintInfo2* info) 86 { 87 btAssert(!m_useSolveConstraintObsolete); 71 btVector3 normal(0,0,0); 72 88 73 89 //retrieve matrices 90 btTransform body0_trans; 91 body0_trans = m_rbA.getCenterOfMassTransform(); 92 btTransform body1_trans; 93 body1_trans = m_rbB.getCenterOfMassTransform(); 74 // btVector3 angvelA = m_rbA.getCenterOfMassTransform().getBasis().transpose() * m_rbA.getAngularVelocity(); 75 // btVector3 angvelB = m_rbB.getCenterOfMassTransform().getBasis().transpose() * m_rbB.getAngularVelocity(); 94 76 95 // anchor points in global coordinates with respect to body PORs. 96 97 // set jacobian 98 info->m_J1linearAxis[0] = 1; 99 info->m_J1linearAxis[info->rowskip+1] = 1; 100 info->m_J1linearAxis[2*info->rowskip+2] = 1; 77 for (int i=0;i<3;i++) 78 { 79 normal[i] = 1; 80 btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal(); 101 81 102 btVector3 a1 = body0_trans.getBasis()*getPivotInA(); 103 { 104 btVector3* angular0 = (btVector3*)(info->m_J1angularAxis); 105 btVector3* angular1 = (btVector3*)(info->m_J1angularAxis+info->rowskip); 106 btVector3* angular2 = (btVector3*)(info->m_J1angularAxis+2*info->rowskip); 107 btVector3 a1neg = -a1; 108 a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2); 109 } 110 111 /*info->m_J2linearAxis[0] = -1; 112 info->m_J2linearAxis[s+1] = -1; 113 info->m_J2linearAxis[2*s+2] = -1; 82 btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); 83 btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); 84 //this jacobian entry could be re-used for all iterations 85 86 btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1); 87 btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2); 88 btVector3 vel = vel1 - vel2; 89 90 btScalar rel_vel; 91 rel_vel = normal.dot(vel); 92 93 /* 94 //velocity error (first order error) 95 btScalar rel_vel = m_jac[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA, 96 m_rbB.getLinearVelocity(),angvelB); 114 97 */ 115 98 116 btVector3 a2 = body1_trans.getBasis()*getPivotInB(); 117 118 { 119 btVector3 a2n = -a2; 120 btVector3* angular0 = (btVector3*)(info->m_J2angularAxis); 121 btVector3* angular1 = (btVector3*)(info->m_J2angularAxis+info->rowskip); 122 btVector3* angular2 = (btVector3*)(info->m_J2angularAxis+2*info->rowskip); 123 a2.getSkewSymmetricMatrix(angular0,angular1,angular2); 124 } 125 99 //positional error (zeroth order error) 100 btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal 101 102 btScalar impulse = depth*m_setting.m_tau/timeStep * jacDiagABInv - m_setting.m_damping * rel_vel * jacDiagABInv; 126 103 104 btScalar impulseClamp = m_setting.m_impulseClamp; 105 if (impulseClamp > 0) 106 { 107 if (impulse < -impulseClamp) 108 impulse = -impulseClamp; 109 if (impulse > impulseClamp) 110 impulse = impulseClamp; 111 } 127 112 128 // set right hand side 129 btScalar k = info->fps * info->erp; 130 int j; 131 132 for (j=0; j<3; j++) 133 { 134 info->m_constraintError[j*info->rowskip] = k * (a2[j] + body1_trans.getOrigin()[j] - a1[j] - body0_trans.getOrigin()[j]); 135 //printf("info->m_constraintError[%d]=%f\n",j,info->m_constraintError[j]); 136 } 137 138 btScalar impulseClamp = m_setting.m_impulseClamp;// 139 for (j=0; j<3; j++) 140 { 141 if (m_setting.m_impulseClamp > 0) 142 { 143 info->m_lowerLimit[j*info->rowskip] = -impulseClamp; 144 info->m_upperLimit[j*info->rowskip] = impulseClamp; 145 } 146 } 147 148 } 149 150 151 void btPoint2PointConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) 152 { 153 if (m_useSolveConstraintObsolete) 154 { 155 btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_pivotInA; 156 btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_pivotInB; 157 158 159 btVector3 normal(0,0,0); 113 m_appliedImpulse+=impulse; 114 btVector3 impulse_vector = normal * impulse; 115 m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition()); 116 m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition()); 160 117 161 162 // btVector3 angvelA = m_rbA.getCenterOfMassTransform().getBasis().transpose() * m_rbA.getAngularVelocity(); 163 // btVector3 angvelB = m_rbB.getCenterOfMassTransform().getBasis().transpose() * m_rbB.getAngularVelocity(); 164 165 for (int i=0;i<3;i++) 166 { 167 normal[i] = 1; 168 btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal(); 169 170 btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); 171 btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); 172 //this jacobian entry could be re-used for all iterations 173 174 btVector3 vel1,vel2; 175 bodyA.getVelocityInLocalPointObsolete(rel_pos1,vel1); 176 bodyB.getVelocityInLocalPointObsolete(rel_pos2,vel2); 177 btVector3 vel = vel1 - vel2; 178 179 btScalar rel_vel; 180 rel_vel = normal.dot(vel); 181 182 /* 183 //velocity error (first order error) 184 btScalar rel_vel = m_jac[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA, 185 m_rbB.getLinearVelocity(),angvelB); 186 */ 187 188 //positional error (zeroth order error) 189 btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal 190 191 btScalar deltaImpulse = depth*m_setting.m_tau/timeStep * jacDiagABInv - m_setting.m_damping * rel_vel * jacDiagABInv; 192 193 btScalar impulseClamp = m_setting.m_impulseClamp; 194 195 const btScalar sum = btScalar(m_appliedImpulse) + deltaImpulse; 196 if (sum < -impulseClamp) 197 { 198 deltaImpulse = -impulseClamp-m_appliedImpulse; 199 m_appliedImpulse = -impulseClamp; 200 } 201 else if (sum > impulseClamp) 202 { 203 deltaImpulse = impulseClamp-m_appliedImpulse; 204 m_appliedImpulse = impulseClamp; 205 } 206 else 207 { 208 m_appliedImpulse = sum; 209 } 210 211 212 btVector3 impulse_vector = normal * deltaImpulse; 213 214 btVector3 ftorqueAxis1 = rel_pos1.cross(normal); 215 btVector3 ftorqueAxis2 = rel_pos2.cross(normal); 216 bodyA.applyImpulse(normal*m_rbA.getInvMass(), m_rbA.getInvInertiaTensorWorld()*ftorqueAxis1,deltaImpulse); 217 bodyB.applyImpulse(normal*m_rbB.getInvMass(), m_rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-deltaImpulse); 218 219 220 normal[i] = 0; 221 } 118 normal[i] = 0; 222 119 } 223 120 } -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
r2907 r2908 51 51 public: 52 52 53 ///for backwards compatibility during the transition to 'getInfo/getInfo2'54 bool m_useSolveConstraintObsolete;55 56 53 btConstraintSetting m_setting; 57 54 … … 64 61 virtual void buildJacobian(); 65 62 66 virtual void getInfo1 (btConstraintInfo1* info);67 63 68 virtual void getInfo2 (btConstraintInfo2* info); 69 70 71 virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep); 64 virtual void solveConstraint(btScalar timeStep); 72 65 73 66 void updateRHS(btScalar timeStep); -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
r2907 r2908 16 16 //#define COMPUTE_IMPULSE_DENOM 1 17 17 //It is not necessary (redundant) to refresh contact manifolds, this refresh has been moved to the collision algorithms. 18 //#define FORCE_REFESH_CONTACT_MANIFOLDS 1 18 19 19 20 #include "btSequentialImpulseConstraintSolver.h" … … 32 33 #include "btSolverBody.h" 33 34 #include "btSolverConstraint.h" 35 36 34 37 #include "LinearMath/btAlignedObjectArray.h" 35 #include <string.h> //for memset 38 39 40 int totalCpd = 0; 41 42 int gTotalContactPoints = 0; 43 44 struct btOrderIndex 45 { 46 int m_manifoldIndex; 47 int m_pointIndex; 48 }; 49 50 51 52 #define SEQUENTIAL_IMPULSE_MAX_SOLVER_POINTS 16384 53 static btOrderIndex gOrder[SEQUENTIAL_IMPULSE_MAX_SOLVER_POINTS]; 54 55 56 unsigned long btSequentialImpulseConstraintSolver::btRand2() 57 { 58 m_btSeed2 = (1664525L*m_btSeed2 + 1013904223L) & 0xffffffff; 59 return m_btSeed2; 60 } 61 62 63 64 //See ODE: adam's all-int straightforward(?) dRandInt (0..n-1) 65 int btSequentialImpulseConstraintSolver::btRandInt2 (int n) 66 { 67 // seems good; xor-fold and modulus 68 const unsigned long un = static_cast<unsigned long>(n); 69 unsigned long r = btRand2(); 70 71 // note: probably more aggressive than it needs to be -- might be 72 // able to get away without one or two of the innermost branches. 73 if (un <= 0x00010000UL) { 74 r ^= (r >> 16); 75 if (un <= 0x00000100UL) { 76 r ^= (r >> 8); 77 if (un <= 0x00000010UL) { 78 r ^= (r >> 4); 79 if (un <= 0x00000004UL) { 80 r ^= (r >> 2); 81 if (un <= 0x00000002UL) { 82 r ^= (r >> 1); 83 } 84 } 85 } 86 } 87 } 88 89 return (int) (r % un); 90 } 91 92 93 94 95 bool MyContactDestroyedCallback(void* userPersistentData); 96 bool MyContactDestroyedCallback(void* userPersistentData) 97 { 98 assert (userPersistentData); 99 btConstraintPersistentData* cpd = (btConstraintPersistentData*)userPersistentData; 100 btAlignedFree(cpd); 101 totalCpd--; 102 //printf("totalCpd = %i. DELETED Ptr %x\n",totalCpd,userPersistentData); 103 return true; 104 } 105 106 36 107 37 108 btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver() 38 109 :m_btSeed2(0) 39 110 { 40 111 gContactDestroyedCallback = &MyContactDestroyedCallback; 112 113 //initialize default friction/contact funcs 114 int i,j; 115 for (i=0;i<MAX_CONTACT_SOLVER_TYPES;i++) 116 for (j=0;j<MAX_CONTACT_SOLVER_TYPES;j++) 117 { 118 119 m_contactDispatch[i][j] = resolveSingleCollision; 120 m_frictionDispatch[i][j] = resolveSingleFriction; 121 } 41 122 } 42 123 43 124 btSequentialImpulseConstraintSolver::~btSequentialImpulseConstraintSolver() 44 125 { 45 } 46 47 #ifdef USE_SIMD 48 #include <emmintrin.h> 49 #define vec_splat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e,e,e,e)) 50 static inline __m128 _vmathVfDot3( __m128 vec0, __m128 vec1 ) 51 { 52 __m128 result = _mm_mul_ps( vec0, vec1); 53 return _mm_add_ps( vec_splat( result, 0 ), _mm_add_ps( vec_splat( result, 1 ), vec_splat( result, 2 ) ) ); 54 } 55 #endif//USE_SIMD 56 57 // Project Gauss Seidel or the equivalent Sequential Impulse 58 void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c) 59 { 60 #ifdef USE_SIMD 61 __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse); 62 __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); 63 __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); 64 __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse),_mm_set1_ps(c.m_cfm))); 65 __m128 deltaVel1Dotn = _mm_add_ps(_vmathVfDot3(c.m_contactNormal.mVec128,body1.m_deltaLinearVelocity.mVec128), _vmathVfDot3(c.m_relpos1CrossNormal.mVec128,body1.m_deltaAngularVelocity.mVec128)); 66 __m128 deltaVel2Dotn = _mm_sub_ps(_vmathVfDot3(c.m_relpos2CrossNormal.mVec128,body2.m_deltaAngularVelocity.mVec128),_vmathVfDot3((c.m_contactNormal).mVec128,body2.m_deltaLinearVelocity.mVec128)); 67 deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv))); 68 deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv))); 69 btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse); 70 btSimdScalar resultLowerLess,resultUpperLess; 71 resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1); 72 resultUpperLess = _mm_cmplt_ps(sum,upperLimit1); 73 __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp); 74 deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) ); 75 c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) ); 76 __m128 upperMinApplied = _mm_sub_ps(upperLimit1,cpAppliedImp); 77 deltaImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, deltaImpulse), _mm_andnot_ps(resultUpperLess, upperMinApplied) ); 78 c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, c.m_appliedImpulse), _mm_andnot_ps(resultUpperLess, upperLimit1) ); 79 __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,_mm_set1_ps(body1.m_invMass)); 80 __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,_mm_set1_ps(body2.m_invMass)); 81 __m128 impulseMagnitude = deltaImpulse; 82 body1.m_deltaLinearVelocity.mVec128 = _mm_add_ps(body1.m_deltaLinearVelocity.mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude)); 83 body1.m_deltaAngularVelocity.mVec128 = _mm_add_ps(body1.m_deltaAngularVelocity.mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude)); 84 body2.m_deltaLinearVelocity.mVec128 = _mm_sub_ps(body2.m_deltaLinearVelocity.mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude)); 85 body2.m_deltaAngularVelocity.mVec128 = _mm_add_ps(body2.m_deltaAngularVelocity.mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude)); 86 #else 87 resolveSingleConstraintRowGeneric(body1,body2,c); 88 #endif 89 } 90 91 // Project Gauss Seidel or the equivalent Sequential Impulse 92 void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGeneric(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c) 93 { 94 btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm; 95 const btScalar deltaVel1Dotn = c.m_contactNormal.dot(body1.m_deltaLinearVelocity) + c.m_relpos1CrossNormal.dot(body1.m_deltaAngularVelocity); 96 const btScalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.m_deltaLinearVelocity) + c.m_relpos2CrossNormal.dot(body2.m_deltaAngularVelocity); 97 98 const btScalar delta_rel_vel = deltaVel1Dotn-deltaVel2Dotn; 99 deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv; 100 deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv; 101 102 const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse; 103 if (sum < c.m_lowerLimit) 104 { 105 deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse; 106 c.m_appliedImpulse = c.m_lowerLimit; 107 } 108 else if (sum > c.m_upperLimit) 109 { 110 deltaImpulse = c.m_upperLimit-c.m_appliedImpulse; 111 c.m_appliedImpulse = c.m_upperLimit; 112 } 113 else 114 { 115 c.m_appliedImpulse = sum; 116 } 117 if (body1.m_invMass) 118 body1.applyImpulse(c.m_contactNormal*body1.m_invMass,c.m_angularComponentA,deltaImpulse); 119 if (body2.m_invMass) 120 body2.applyImpulse(-c.m_contactNormal*body2.m_invMass,c.m_angularComponentB,deltaImpulse); 121 } 122 123 void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c) 124 { 125 #ifdef USE_SIMD 126 __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse); 127 __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); 128 __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); 129 __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse),_mm_set1_ps(c.m_cfm))); 130 __m128 deltaVel1Dotn = _mm_add_ps(_vmathVfDot3(c.m_contactNormal.mVec128,body1.m_deltaLinearVelocity.mVec128), _vmathVfDot3(c.m_relpos1CrossNormal.mVec128,body1.m_deltaAngularVelocity.mVec128)); 131 __m128 deltaVel2Dotn = _mm_sub_ps(_vmathVfDot3(c.m_relpos2CrossNormal.mVec128,body2.m_deltaAngularVelocity.mVec128),_vmathVfDot3((c.m_contactNormal).mVec128,body2.m_deltaLinearVelocity.mVec128)); 132 deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv))); 133 deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv))); 134 btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse); 135 btSimdScalar resultLowerLess,resultUpperLess; 136 resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1); 137 resultUpperLess = _mm_cmplt_ps(sum,upperLimit1); 138 __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp); 139 deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) ); 140 c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) ); 141 __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,_mm_set1_ps(body1.m_invMass)); 142 __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,_mm_set1_ps(body2.m_invMass)); 143 __m128 impulseMagnitude = deltaImpulse; 144 body1.m_deltaLinearVelocity.mVec128 = _mm_add_ps(body1.m_deltaLinearVelocity.mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude)); 145 body1.m_deltaAngularVelocity.mVec128 = _mm_add_ps(body1.m_deltaAngularVelocity.mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude)); 146 body2.m_deltaLinearVelocity.mVec128 = _mm_sub_ps(body2.m_deltaLinearVelocity.mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude)); 147 body2.m_deltaAngularVelocity.mVec128 = _mm_add_ps(body2.m_deltaAngularVelocity.mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude)); 148 #else 149 resolveSingleConstraintRowLowerLimit(body1,body2,c); 150 #endif 151 } 152 153 // Project Gauss Seidel or the equivalent Sequential Impulse 154 void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimit(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c) 155 { 156 btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm; 157 const btScalar deltaVel1Dotn = c.m_contactNormal.dot(body1.m_deltaLinearVelocity) + c.m_relpos1CrossNormal.dot(body1.m_deltaAngularVelocity); 158 const btScalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.m_deltaLinearVelocity) + c.m_relpos2CrossNormal.dot(body2.m_deltaAngularVelocity); 159 160 deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv; 161 deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv; 162 const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse; 163 if (sum < c.m_lowerLimit) 164 { 165 deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse; 166 c.m_appliedImpulse = c.m_lowerLimit; 167 } 168 else 169 { 170 c.m_appliedImpulse = sum; 171 } 172 if (body1.m_invMass) 173 body1.applyImpulse(c.m_contactNormal*body1.m_invMass,c.m_angularComponentA,deltaImpulse); 174 if (body2.m_invMass) 175 body2.applyImpulse(-c.m_contactNormal*body2.m_invMass,c.m_angularComponentB,deltaImpulse); 176 } 177 178 179 180 unsigned long btSequentialImpulseConstraintSolver::btRand2() 181 { 182 m_btSeed2 = (1664525L*m_btSeed2 + 1013904223L) & 0xffffffff; 183 return m_btSeed2; 184 } 185 186 187 188 //See ODE: adam's all-int straightforward(?) dRandInt (0..n-1) 189 int btSequentialImpulseConstraintSolver::btRandInt2 (int n) 190 { 191 // seems good; xor-fold and modulus 192 const unsigned long un = static_cast<unsigned long>(n); 193 unsigned long r = btRand2(); 194 195 // note: probably more aggressive than it needs to be -- might be 196 // able to get away without one or two of the innermost branches. 197 if (un <= 0x00010000UL) { 198 r ^= (r >> 16); 199 if (un <= 0x00000100UL) { 200 r ^= (r >> 8); 201 if (un <= 0x00000010UL) { 202 r ^= (r >> 4); 203 if (un <= 0x00000004UL) { 204 r ^= (r >> 2); 205 if (un <= 0x00000002UL) { 206 r ^= (r >> 1); 207 } 208 } 209 } 210 } 211 } 212 213 return (int) (r % un); 214 } 215 216 217 218 void btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject) 219 { 220 btRigidBody* rb = collisionObject? btRigidBody::upcast(collisionObject) : 0; 221 222 solverBody->m_deltaLinearVelocity.setValue(0.f,0.f,0.f); 223 solverBody->m_deltaAngularVelocity.setValue(0.f,0.f,0.f); 224 126 127 } 128 129 void initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject); 130 void initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject) 131 { 132 btRigidBody* rb = btRigidBody::upcast(collisionObject); 225 133 if (rb) 226 134 { 135 solverBody->m_angularVelocity = rb->getAngularVelocity() ; 136 solverBody->m_centerOfMassPosition = collisionObject->getWorldTransform().getOrigin(); 137 solverBody->m_friction = collisionObject->getFriction(); 227 138 solverBody->m_invMass = rb->getInvMass(); 139 solverBody->m_linearVelocity = rb->getLinearVelocity(); 228 140 solverBody->m_originalBody = rb; 229 141 solverBody->m_angularFactor = rb->getAngularFactor(); 230 142 } else 231 143 { 144 solverBody->m_angularVelocity.setValue(0,0,0); 145 solverBody->m_centerOfMassPosition = collisionObject->getWorldTransform().getOrigin(); 146 solverBody->m_friction = collisionObject->getFriction(); 232 147 solverBody->m_invMass = 0.f; 148 solverBody->m_linearVelocity.setValue(0,0,0); 233 149 solverBody->m_originalBody = 0; 234 150 solverBody->m_angularFactor = 1.f; 235 151 } 152 solverBody->m_pushVelocity.setValue(0.f,0.f,0.f); 153 solverBody->m_turnVelocity.setValue(0.f,0.f,0.f); 236 154 } 237 155 … … 239 157 int gNumSplitImpulseRecoveries = 0; 240 158 241 btScalar btSequentialImpulseConstraintSolver::restitutionCurve(btScalar rel_vel, btScalar restitution) 159 btScalar restitutionCurve(btScalar rel_vel, btScalar restitution); 160 btScalar restitutionCurve(btScalar rel_vel, btScalar restitution) 242 161 { 243 162 btScalar rest = restitution * -rel_vel; … … 246 165 247 166 248 249 void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection); 250 void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection) 251 { 252 if (colObj && colObj->hasAnisotropicFriction()) 253 { 254 // transform to local coordinates 255 btVector3 loc_lateral = frictionDirection * colObj->getWorldTransform().getBasis(); 256 const btVector3& friction_scaling = colObj->getAnisotropicFriction(); 257 //apply anisotropic friction 258 loc_lateral *= friction_scaling; 259 // ... and transform it back to global coordinates 260 frictionDirection = colObj->getWorldTransform().getBasis() * loc_lateral; 261 } 262 } 167 void resolveSplitPenetrationImpulseCacheFriendly( 168 btSolverBody& body1, 169 btSolverBody& body2, 170 const btSolverConstraint& contactConstraint, 171 const btContactSolverInfo& solverInfo); 172 173 //SIMD_FORCE_INLINE 174 void resolveSplitPenetrationImpulseCacheFriendly( 175 btSolverBody& body1, 176 btSolverBody& body2, 177 const btSolverConstraint& contactConstraint, 178 const btContactSolverInfo& solverInfo) 179 { 180 (void)solverInfo; 181 182 if (contactConstraint.m_penetration < solverInfo.m_splitImpulsePenetrationThreshold) 183 { 184 185 gNumSplitImpulseRecoveries++; 186 btScalar normalImpulse; 187 188 // Optimized version of projected relative velocity, use precomputed cross products with normal 189 // body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1); 190 // body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2); 191 // btVector3 vel = vel1 - vel2; 192 // btScalar rel_vel = contactConstraint.m_contactNormal.dot(vel); 193 194 btScalar rel_vel; 195 btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_pushVelocity) 196 + contactConstraint.m_relpos1CrossNormal.dot(body1.m_turnVelocity); 197 btScalar vel2Dotn = contactConstraint.m_contactNormal.dot(body2.m_pushVelocity) 198 + contactConstraint.m_relpos2CrossNormal.dot(body2.m_turnVelocity); 199 200 rel_vel = vel1Dotn-vel2Dotn; 201 202 203 btScalar positionalError = -contactConstraint.m_penetration * solverInfo.m_erp2/solverInfo.m_timeStep; 204 // btScalar positionalError = contactConstraint.m_penetration; 205 206 btScalar velocityError = contactConstraint.m_restitution - rel_vel;// * damping; 207 208 btScalar penetrationImpulse = positionalError * contactConstraint.m_jacDiagABInv; 209 btScalar velocityImpulse = velocityError * contactConstraint.m_jacDiagABInv; 210 normalImpulse = penetrationImpulse+velocityImpulse; 211 212 // See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse 213 btScalar oldNormalImpulse = contactConstraint.m_appliedPushImpulse; 214 btScalar sum = oldNormalImpulse + normalImpulse; 215 contactConstraint.m_appliedPushImpulse = btScalar(0.) > sum ? btScalar(0.): sum; 216 217 normalImpulse = contactConstraint.m_appliedPushImpulse - oldNormalImpulse; 218 219 body1.internalApplyPushImpulse(contactConstraint.m_contactNormal*body1.m_invMass, contactConstraint.m_angularComponentA,normalImpulse); 220 221 body2.internalApplyPushImpulse(contactConstraint.m_contactNormal*body2.m_invMass, contactConstraint.m_angularComponentB,-normalImpulse); 222 223 } 224 225 } 226 227 228 //velocity + friction 229 //response between two dynamic objects with friction 230 231 btScalar resolveSingleCollisionCombinedCacheFriendly( 232 btSolverBody& body1, 233 btSolverBody& body2, 234 const btSolverConstraint& contactConstraint, 235 const btContactSolverInfo& solverInfo); 236 237 //SIMD_FORCE_INLINE 238 btScalar resolveSingleCollisionCombinedCacheFriendly( 239 btSolverBody& body1, 240 btSolverBody& body2, 241 const btSolverConstraint& contactConstraint, 242 const btContactSolverInfo& solverInfo) 243 { 244 (void)solverInfo; 245 246 btScalar normalImpulse; 247 248 { 249 250 251 // Optimized version of projected relative velocity, use precomputed cross products with normal 252 // body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1); 253 // body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2); 254 // btVector3 vel = vel1 - vel2; 255 // btScalar rel_vel = contactConstraint.m_contactNormal.dot(vel); 256 257 btScalar rel_vel; 258 btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_linearVelocity) 259 + contactConstraint.m_relpos1CrossNormal.dot(body1.m_angularVelocity); 260 btScalar vel2Dotn = contactConstraint.m_contactNormal.dot(body2.m_linearVelocity) 261 + contactConstraint.m_relpos2CrossNormal.dot(body2.m_angularVelocity); 262 263 rel_vel = vel1Dotn-vel2Dotn; 264 265 btScalar positionalError = 0.f; 266 if (!solverInfo.m_splitImpulse || (contactConstraint.m_penetration > solverInfo.m_splitImpulsePenetrationThreshold)) 267 { 268 positionalError = -contactConstraint.m_penetration * solverInfo.m_erp/solverInfo.m_timeStep; 269 } 270 271 btScalar velocityError = contactConstraint.m_restitution - rel_vel;// * damping; 272 273 btScalar penetrationImpulse = positionalError * contactConstraint.m_jacDiagABInv; 274 btScalar velocityImpulse = velocityError * contactConstraint.m_jacDiagABInv; 275 normalImpulse = penetrationImpulse+velocityImpulse; 276 277 278 // See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse 279 btScalar oldNormalImpulse = contactConstraint.m_appliedImpulse; 280 btScalar sum = oldNormalImpulse + normalImpulse; 281 contactConstraint.m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum; 282 283 normalImpulse = contactConstraint.m_appliedImpulse - oldNormalImpulse; 284 285 body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass, 286 contactConstraint.m_angularComponentA,normalImpulse); 287 288 body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass, 289 contactConstraint.m_angularComponentB,-normalImpulse); 290 } 291 292 return normalImpulse; 293 } 294 295 296 #ifndef NO_FRICTION_TANGENTIALS 297 298 btScalar resolveSingleFrictionCacheFriendly( 299 btSolverBody& body1, 300 btSolverBody& body2, 301 const btSolverConstraint& contactConstraint, 302 const btContactSolverInfo& solverInfo, 303 btScalar appliedNormalImpulse); 304 305 //SIMD_FORCE_INLINE 306 btScalar resolveSingleFrictionCacheFriendly( 307 btSolverBody& body1, 308 btSolverBody& body2, 309 const btSolverConstraint& contactConstraint, 310 const btContactSolverInfo& solverInfo, 311 btScalar appliedNormalImpulse) 312 { 313 (void)solverInfo; 314 315 316 const btScalar combinedFriction = contactConstraint.m_friction; 317 318 const btScalar limit = appliedNormalImpulse * combinedFriction; 319 320 if (appliedNormalImpulse>btScalar(0.)) 321 //friction 322 { 323 324 btScalar j1; 325 { 326 327 btScalar rel_vel; 328 const btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_linearVelocity) 329 + contactConstraint.m_relpos1CrossNormal.dot(body1.m_angularVelocity); 330 const btScalar vel2Dotn = contactConstraint.m_contactNormal.dot(body2.m_linearVelocity) 331 + contactConstraint.m_relpos2CrossNormal.dot(body2.m_angularVelocity); 332 rel_vel = vel1Dotn-vel2Dotn; 333 334 // calculate j that moves us to zero relative velocity 335 j1 = -rel_vel * contactConstraint.m_jacDiagABInv; 336 #define CLAMP_ACCUMULATED_FRICTION_IMPULSE 1 337 #ifdef CLAMP_ACCUMULATED_FRICTION_IMPULSE 338 btScalar oldTangentImpulse = contactConstraint.m_appliedImpulse; 339 contactConstraint.m_appliedImpulse = oldTangentImpulse + j1; 340 341 if (limit < contactConstraint.m_appliedImpulse) 342 { 343 contactConstraint.m_appliedImpulse = limit; 344 } else 345 { 346 if (contactConstraint.m_appliedImpulse < -limit) 347 contactConstraint.m_appliedImpulse = -limit; 348 } 349 j1 = contactConstraint.m_appliedImpulse - oldTangentImpulse; 350 #else 351 if (limit < j1) 352 { 353 j1 = limit; 354 } else 355 { 356 if (j1 < -limit) 357 j1 = -limit; 358 } 359 360 #endif //CLAMP_ACCUMULATED_FRICTION_IMPULSE 361 362 //GEN_set_min(contactConstraint.m_appliedImpulse, limit); 363 //GEN_set_max(contactConstraint.m_appliedImpulse, -limit); 364 365 366 367 } 368 369 body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass,contactConstraint.m_angularComponentA,j1); 370 371 body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass,contactConstraint.m_angularComponentB,-j1); 372 373 } 374 return 0.f; 375 } 376 377 378 #else 379 380 //velocity + friction 381 //response between two dynamic objects with friction 382 btScalar resolveSingleFrictionCacheFriendly( 383 btSolverBody& body1, 384 btSolverBody& body2, 385 btSolverConstraint& contactConstraint, 386 const btContactSolverInfo& solverInfo) 387 { 388 389 btVector3 vel1; 390 btVector3 vel2; 391 btScalar normalImpulse(0.f); 392 393 { 394 const btVector3& normal = contactConstraint.m_contactNormal; 395 if (contactConstraint.m_penetration < 0.f) 396 return 0.f; 397 398 399 body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1); 400 body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2); 401 btVector3 vel = vel1 - vel2; 402 btScalar rel_vel; 403 rel_vel = normal.dot(vel); 404 405 btVector3 lat_vel = vel - normal * rel_vel; 406 btScalar lat_rel_vel = lat_vel.length2(); 407 408 btScalar combinedFriction = contactConstraint.m_friction; 409 const btVector3& rel_pos1 = contactConstraint.m_rel_posA; 410 const btVector3& rel_pos2 = contactConstraint.m_rel_posB; 411 412 413 if (lat_rel_vel > SIMD_EPSILON*SIMD_EPSILON) 414 { 415 lat_rel_vel = btSqrt(lat_rel_vel); 416 417 lat_vel /= lat_rel_vel; 418 btVector3 temp1 = body1.m_invInertiaWorld * rel_pos1.cross(lat_vel); 419 btVector3 temp2 = body2.m_invInertiaWorld * rel_pos2.cross(lat_vel); 420 btScalar friction_impulse = lat_rel_vel / 421 (body1.m_invMass + body2.m_invMass + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2))); 422 btScalar normal_impulse = contactConstraint.m_appliedImpulse * combinedFriction; 423 424 GEN_set_min(friction_impulse, normal_impulse); 425 GEN_set_max(friction_impulse, -normal_impulse); 426 body1.applyImpulse(lat_vel * -friction_impulse, rel_pos1); 427 body2.applyImpulse(lat_vel * friction_impulse, rel_pos2); 428 } 429 } 430 431 return normalImpulse; 432 } 433 434 #endif //NO_FRICTION_TANGENTIALS 435 436 263 437 264 438 … … 266 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) 267 441 { 268 269 442 270 443 btRigidBody* body0=btRigidBody::upcast(colObj0); 271 444 btRigidBody* body1=btRigidBody::upcast(colObj1); 272 445 273 btSolverConstraint& solverConstraint = m_tmpSolverContactFrictionConstraintPool.expand(); 274 memset(&solverConstraint,0xff,sizeof(btSolverConstraint)); 446 btSolverConstraint& solverConstraint = m_tmpSolverFrictionConstraintPool.expand(); 275 447 solverConstraint.m_contactNormal = normalAxis; 276 448 277 449 solverConstraint.m_solverBodyIdA = solverBodyIdA; 278 450 solverConstraint.m_solverBodyIdB = solverBodyIdB; 451 solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_FRICTION_1D; 279 452 solverConstraint.m_frictionIndex = frictionIndex; 280 453 … … 282 455 solverConstraint.m_originalContactPoint = 0; 283 456 284 solverConstraint.m_appliedImpulse = 0.f;285 //solverConstraint.m_appliedPushImpulse = 0.f;286 457 solverConstraint.m_appliedImpulse = btScalar(0.); 458 solverConstraint.m_appliedPushImpulse = 0.f; 459 solverConstraint.m_penetration = 0.f; 287 460 { 288 461 btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal); 289 462 solverConstraint.m_relpos1CrossNormal = ftorqueAxis1; 290 solverConstraint.m_angularComponentA = body0 ? body0->getInvInertiaTensorWorld()*ftorqueAxis1 *body0->getAngularFactor(): btVector3(0,0,0);291 } 292 { 293 btVector3 ftorqueAxis1 = rel_pos2.cross( -solverConstraint.m_contactNormal);463 solverConstraint.m_angularComponentA = body0 ? body0->getInvInertiaTensorWorld()*ftorqueAxis1 : btVector3(0,0,0); 464 } 465 { 466 btVector3 ftorqueAxis1 = rel_pos2.cross(solverConstraint.m_contactNormal); 294 467 solverConstraint.m_relpos2CrossNormal = ftorqueAxis1; 295 solverConstraint.m_angularComponentB = body1 ? body1->getInvInertiaTensorWorld()*ftorqueAxis1 *body1->getAngularFactor(): btVector3(0,0,0);468 solverConstraint.m_angularComponentB = body1 ? body1->getInvInertiaTensorWorld()*ftorqueAxis1 : btVector3(0,0,0); 296 469 } 297 470 … … 310 483 if (body1) 311 484 { 312 vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2);485 vec = ( solverConstraint.m_angularComponentB).cross(rel_pos2); 313 486 denom1 = body1->getInvMass() + normalAxis.dot(vec); 314 487 } … … 319 492 solverConstraint.m_jacDiagABInv = denom; 320 493 321 #ifdef _USE_JACOBIAN322 solverConstraint.m_jac = btJacobianEntry (323 rel_pos1,rel_pos2,solverConstraint.m_contactNormal,324 body0->getInvInertiaDiagLocal(),325 body0->getInvMass(),326 body1->getInvInertiaDiagLocal(),327 body1->getInvMass());328 #endif //_USE_JACOBIAN329 330 331 {332 btScalar rel_vel;333 btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(body0?body0->getLinearVelocity():btVector3(0,0,0))334 + solverConstraint.m_relpos1CrossNormal.dot(body0?body0->getAngularVelocity():btVector3(0,0,0));335 btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(body1?body1->getLinearVelocity():btVector3(0,0,0))336 + solverConstraint.m_relpos2CrossNormal.dot(body1?body1->getAngularVelocity():btVector3(0,0,0));337 338 rel_vel = vel1Dotn+vel2Dotn;339 340 btScalar positionalError = 0.f;341 342 btSimdScalar velocityError = - rel_vel;343 btSimdScalar velocityImpulse = velocityError * btSimdScalar(solverConstraint.m_jacDiagABInv);344 solverConstraint.m_rhs = velocityImpulse;345 solverConstraint.m_cfm = 0.f;346 solverConstraint.m_lowerLimit = 0;347 solverConstraint.m_upperLimit = 1e10f;348 }349 350 494 return solverConstraint; 351 495 } 352 496 353 int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& body) 354 { 355 int solverBodyIdA = -1; 356 357 if (body.getCompanionId() >= 0) 358 { 359 //body has already been converted 360 solverBodyIdA = body.getCompanionId(); 361 } else 362 { 363 btRigidBody* rb = btRigidBody::upcast(&body); 364 if (rb && rb->getInvMass()) 365 { 366 solverBodyIdA = m_tmpSolverBodyPool.size(); 367 btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); 368 initSolverBody(&solverBody,&body); 369 body.setCompanionId(solverBodyIdA); 370 } else 371 { 372 return 0;//assume first one is a fixed solver body 373 } 374 } 375 return solverBodyIdA; 376 } 377 #include <stdio.h> 378 379 380 381 void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal) 382 { 497 498 499 btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** /*bodies */,int /*numBodies */,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc) 500 { 501 BT_PROFILE("solveGroupCacheFriendlySetup"); 502 (void)stackAlloc; 503 (void)debugDrawer; 504 505 506 if (!(numConstraints + numManifolds)) 507 { 508 // printf("empty\n"); 509 return 0.f; 510 } 511 btPersistentManifold* manifold = 0; 383 512 btCollisionObject* colObj0=0,*colObj1=0; 384 513 385 colObj0 = (btCollisionObject*)manifold->getBody0(); 386 colObj1 = (btCollisionObject*)manifold->getBody1(); 387 388 int solverBodyIdA=-1; 389 int solverBodyIdB=-1; 390 391 if (manifold->getNumContacts()) 392 { 393 solverBodyIdA = getOrInitSolverBody(*colObj0); 394 solverBodyIdB = getOrInitSolverBody(*colObj1); 395 } 396 397 ///avoid collision response between two static objects 398 if (!solverBodyIdA && !solverBodyIdB) 399 return; 400 401 btVector3 rel_pos1; 402 btVector3 rel_pos2; 403 btScalar relaxation; 404 405 for (int j=0;j<manifold->getNumContacts();j++) 406 { 407 408 btManifoldPoint& cp = manifold->getContactPoint(j); 409 410 if (cp.getDistance() <= manifold->getContactProcessingThreshold()) 411 { 412 413 const btVector3& pos1 = cp.getPositionWorldOnA(); 414 const btVector3& pos2 = cp.getPositionWorldOnB(); 415 416 rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin(); 417 rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin(); 418 419 420 relaxation = 1.f; 421 btScalar rel_vel; 422 btVector3 vel; 423 424 int frictionIndex = m_tmpSolverContactConstraintPool.size(); 425 426 { 427 btSolverConstraint& solverConstraint = m_tmpSolverContactConstraintPool.expand(); 428 btRigidBody* rb0 = btRigidBody::upcast(colObj0); 429 btRigidBody* rb1 = btRigidBody::upcast(colObj1); 430 431 solverConstraint.m_solverBodyIdA = solverBodyIdA; 432 solverConstraint.m_solverBodyIdB = solverBodyIdB; 433 434 solverConstraint.m_originalContactPoint = &cp; 435 436 btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB); 437 solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0*rb0->getAngularFactor() : btVector3(0,0,0); 438 btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB); 439 solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*-torqueAxis1*rb1->getAngularFactor() : btVector3(0,0,0); 440 { 441 #ifdef COMPUTE_IMPULSE_DENOM 442 btScalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB); 443 btScalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB); 444 #else 445 btVector3 vec; 446 btScalar denom0 = 0.f; 447 btScalar denom1 = 0.f; 448 if (rb0) 514 //btRigidBody* rb0=0,*rb1=0; 515 516 517 #ifdef FORCE_REFESH_CONTACT_MANIFOLDS 518 519 BEGIN_PROFILE("refreshManifolds"); 520 521 int i; 522 523 524 525 for (i=0;i<numManifolds;i++) 526 { 527 manifold = manifoldPtr[i]; 528 rb1 = (btRigidBody*)manifold->getBody1(); 529 rb0 = (btRigidBody*)manifold->getBody0(); 530 531 manifold->refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform()); 532 533 } 534 535 END_PROFILE("refreshManifolds"); 536 #endif //FORCE_REFESH_CONTACT_MANIFOLDS 537 538 539 540 541 542 //int sizeofSB = sizeof(btSolverBody); 543 //int sizeofSC = sizeof(btSolverConstraint); 544 545 546 //if (1) 547 { 548 //if m_stackAlloc, try to pack bodies/constraints to speed up solving 549 // btBlock* sablock; 550 // sablock = stackAlloc->beginBlock(); 551 552 // int memsize = 16; 553 // unsigned char* stackMemory = stackAlloc->allocate(memsize); 554 555 556 //todo: use stack allocator for this temp memory 557 // int minReservation = numManifolds*2; 558 559 //m_tmpSolverBodyPool.reserve(minReservation); 560 561 //don't convert all bodies, only the one we need so solver the constraints 562 /* 563 { 564 for (int i=0;i<numBodies;i++) 565 { 566 btRigidBody* rb = btRigidBody::upcast(bodies[i]); 567 if (rb && (rb->getIslandTag() >= 0)) 568 { 569 btAssert(rb->getCompanionId() < 0); 570 int solverBodyId = m_tmpSolverBodyPool.size(); 571 btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); 572 initSolverBody(&solverBody,rb); 573 rb->setCompanionId(solverBodyId); 574 } 575 } 576 } 577 */ 578 579 //m_tmpSolverConstraintPool.reserve(minReservation); 580 //m_tmpSolverFrictionConstraintPool.reserve(minReservation); 581 582 { 583 int i; 584 585 for (i=0;i<numManifolds;i++) 586 { 587 manifold = manifoldPtr[i]; 588 colObj0 = (btCollisionObject*)manifold->getBody0(); 589 colObj1 = (btCollisionObject*)manifold->getBody1(); 590 591 int solverBodyIdA=-1; 592 int solverBodyIdB=-1; 593 594 if (manifold->getNumContacts()) 595 { 596 597 598 599 if (colObj0->getIslandTag() >= 0) 449 600 { 450 vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1); 451 denom0 = rb0->getInvMass() + cp.m_normalWorldOnB.dot(vec); 452 } 453 if (rb1) 454 { 455 vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2); 456 denom1 = rb1->getInvMass() + cp.m_normalWorldOnB.dot(vec); 457 } 458 #endif //COMPUTE_IMPULSE_DENOM 459 460 btScalar denom = relaxation/(denom0+denom1); 461 solverConstraint.m_jacDiagABInv = denom; 462 } 463 464 solverConstraint.m_contactNormal = cp.m_normalWorldOnB; 465 solverConstraint.m_relpos1CrossNormal = rel_pos1.cross(cp.m_normalWorldOnB); 466 solverConstraint.m_relpos2CrossNormal = rel_pos2.cross(-cp.m_normalWorldOnB); 467 468 469 btVector3 vel1 = rb0 ? rb0->getVelocityInLocalPoint(rel_pos1) : btVector3(0,0,0); 470 btVector3 vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0); 471 472 vel = vel1 - vel2; 473 474 rel_vel = cp.m_normalWorldOnB.dot(vel); 475 476 btScalar penetration = cp.getDistance()+infoGlobal.m_linearSlop; 477 478 479 solverConstraint.m_friction = cp.m_combinedFriction; 480 481 btScalar restitution = 0.f; 482 483 if (cp.m_lifeTime>infoGlobal.m_restingContactRestitutionThreshold) 484 { 485 restitution = 0.f; 486 } else 487 { 488 restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution); 489 if (restitution <= btScalar(0.)) 490 { 491 restitution = 0.f; 492 }; 493 } 494 495 496 ///warm starting (or zero if disabled) 497 if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) 498 { 499 solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor; 500 if (rb0) 501 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].applyImpulse(solverConstraint.m_contactNormal*rb0->getInvMass(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse); 502 if (rb1) 503 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].applyImpulse(solverConstraint.m_contactNormal*rb1->getInvMass(),-solverConstraint.m_angularComponentB,-solverConstraint.m_appliedImpulse); 504 } else 505 { 506 solverConstraint.m_appliedImpulse = 0.f; 507 } 508 509 // solverConstraint.m_appliedPushImpulse = 0.f; 510 511 { 512 btScalar rel_vel; 513 btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rb0?rb0->getLinearVelocity():btVector3(0,0,0)) 514 + solverConstraint.m_relpos1CrossNormal.dot(rb0?rb0->getAngularVelocity():btVector3(0,0,0)); 515 btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rb1?rb1->getLinearVelocity():btVector3(0,0,0)) 516 + solverConstraint.m_relpos2CrossNormal.dot(rb1?rb1->getAngularVelocity():btVector3(0,0,0)); 517 518 rel_vel = vel1Dotn+vel2Dotn; 519 520 btScalar positionalError = 0.f; 521 positionalError = -penetration * infoGlobal.m_erp/infoGlobal.m_timeStep; 522 btScalar velocityError = restitution - rel_vel;// * damping; 523 btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv; 524 btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv; 525 solverConstraint.m_rhs = penetrationImpulse+velocityImpulse; 526 solverConstraint.m_cfm = 0.f; 527 solverConstraint.m_lowerLimit = 0; 528 solverConstraint.m_upperLimit = 1e10f; 529 } 530 531 532 /////setup the friction constraints 533 534 535 536 if (1) 537 { 538 solverConstraint.m_frictionIndex = m_tmpSolverContactFrictionConstraintPool.size(); 539 if (!(infoGlobal.m_solverMode & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING) || !cp.m_lateralFrictionInitialized) 540 { 541 cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel; 542 btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2(); 543 if (!(infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > SIMD_EPSILON) 601 if (colObj0->getCompanionId() >= 0) 544 602 { 545 cp.m_lateralFrictionDir1 /= btSqrt(lat_rel_vel); 546 applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1); 547 applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1); 548 addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); 549 if((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) 550 { 551 cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB); 552 cp.m_lateralFrictionDir2.normalize();//?? 553 applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2); 554 applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2); 555 addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); 556 } 557 cp.m_lateralFrictionInitialized = true; 603 //body has already been converted 604 solverBodyIdA = colObj0->getCompanionId(); 558 605 } else 559 606 { 560 //re-calculate friction direction every frame, todo: check if this is really needed 561 btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2); 562 applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1); 563 applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1); 564 565 addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); 566 if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) 567 { 568 applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2); 569 applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2); 570 addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); 571 } 572 cp.m_lateralFrictionInitialized = true; 573 } 574 575 } else 576 { 577 addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); 578 if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) 579 addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); 580 } 581 582 if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING) 583 { 584 { 585 btSolverConstraint& frictionConstraint1 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex]; 586 if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) 587 { 588 frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor; 589 if (rb0) 590 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].applyImpulse(frictionConstraint1.m_contactNormal*rb0->getInvMass(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse); 591 if (rb1) 592 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].applyImpulse(frictionConstraint1.m_contactNormal*rb1->getInvMass(),-frictionConstraint1.m_angularComponentB,-frictionConstraint1.m_appliedImpulse); 593 } else 594 { 595 frictionConstraint1.m_appliedImpulse = 0.f; 596 } 597 } 598 599 if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) 600 { 601 btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex+1]; 602 if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) 603 { 604 frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor; 605 if (rb0) 606 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].applyImpulse(frictionConstraint2.m_contactNormal*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse); 607 if (rb1) 608 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].applyImpulse(frictionConstraint2.m_contactNormal*rb1->getInvMass(),-frictionConstraint2.m_angularComponentB,-frictionConstraint2.m_appliedImpulse); 609 } else 610 { 611 frictionConstraint2.m_appliedImpulse = 0.f; 612 } 607 solverBodyIdA = m_tmpSolverBodyPool.size(); 608 btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); 609 initSolverBody(&solverBody,colObj0); 610 colObj0->setCompanionId(solverBodyIdA); 613 611 } 614 612 } else 615 613 { 616 btSolverConstraint& frictionConstraint1 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex]; 617 frictionConstraint1.m_appliedImpulse = 0.f; 618 if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) 614 //create a static body 615 solverBodyIdA = m_tmpSolverBodyPool.size(); 616 btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); 617 initSolverBody(&solverBody,colObj0); 618 } 619 620 if (colObj1->getIslandTag() >= 0) 621 { 622 if (colObj1->getCompanionId() >= 0) 619 623 { 620 btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex+1]; 621 frictionConstraint2.m_appliedImpulse = 0.f; 624 solverBodyIdB = colObj1->getCompanionId(); 625 } else 626 { 627 solverBodyIdB = m_tmpSolverBodyPool.size(); 628 btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); 629 initSolverBody(&solverBody,colObj1); 630 colObj1->setCompanionId(solverBodyIdB); 622 631 } 632 } else 633 { 634 //create a static body 635 solverBodyIdB = m_tmpSolverBodyPool.size(); 636 btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); 637 initSolverBody(&solverBody,colObj1); 623 638 } 624 639 } 625 } 626 627 628 } 629 } 630 } 631 632 633 btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** /*bodies */,int /*numBodies */,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc) 634 { 635 BT_PROFILE("solveGroupCacheFriendlySetup"); 636 (void)stackAlloc; 637 (void)debugDrawer; 638 639 640 if (!(numConstraints + numManifolds)) 641 { 642 // printf("empty\n"); 643 return 0.f; 644 } 645 646 if (1) 640 641 btVector3 rel_pos1; 642 btVector3 rel_pos2; 643 btScalar relaxation; 644 645 for (int j=0;j<manifold->getNumContacts();j++) 646 { 647 648 btManifoldPoint& cp = manifold->getContactPoint(j); 649 650 if (cp.getDistance() <= btScalar(0.)) 651 { 652 653 const btVector3& pos1 = cp.getPositionWorldOnA(); 654 const btVector3& pos2 = cp.getPositionWorldOnB(); 655 656 rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin(); 657 rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin(); 658 659 660 relaxation = 1.f; 661 btScalar rel_vel; 662 btVector3 vel; 663 664 int frictionIndex = m_tmpSolverConstraintPool.size(); 665 666 { 667 btSolverConstraint& solverConstraint = m_tmpSolverConstraintPool.expand(); 668 btRigidBody* rb0 = btRigidBody::upcast(colObj0); 669 btRigidBody* rb1 = btRigidBody::upcast(colObj1); 670 671 solverConstraint.m_solverBodyIdA = solverBodyIdA; 672 solverConstraint.m_solverBodyIdB = solverBodyIdB; 673 solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_CONTACT_1D; 674 675 solverConstraint.m_originalContactPoint = &cp; 676 677 btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB); 678 solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0 : btVector3(0,0,0); 679 btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB); 680 solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*torqueAxis1 : btVector3(0,0,0); 681 { 682 #ifdef COMPUTE_IMPULSE_DENOM 683 btScalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB); 684 btScalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB); 685 #else 686 btVector3 vec; 687 btScalar denom0 = 0.f; 688 btScalar denom1 = 0.f; 689 if (rb0) 690 { 691 vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1); 692 denom0 = rb0->getInvMass() + cp.m_normalWorldOnB.dot(vec); 693 } 694 if (rb1) 695 { 696 vec = ( solverConstraint.m_angularComponentB).cross(rel_pos2); 697 denom1 = rb1->getInvMass() + cp.m_normalWorldOnB.dot(vec); 698 } 699 #endif //COMPUTE_IMPULSE_DENOM 700 701 btScalar denom = relaxation/(denom0+denom1); 702 solverConstraint.m_jacDiagABInv = denom; 703 } 704 705 solverConstraint.m_contactNormal = cp.m_normalWorldOnB; 706 solverConstraint.m_relpos1CrossNormal = rel_pos1.cross(cp.m_normalWorldOnB); 707 solverConstraint.m_relpos2CrossNormal = rel_pos2.cross(cp.m_normalWorldOnB); 708 709 710 btVector3 vel1 = rb0 ? rb0->getVelocityInLocalPoint(rel_pos1) : btVector3(0,0,0); 711 btVector3 vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0); 712 713 vel = vel1 - vel2; 714 715 rel_vel = cp.m_normalWorldOnB.dot(vel); 716 717 solverConstraint.m_penetration = btMin(cp.getDistance()+infoGlobal.m_linearSlop,btScalar(0.)); 718 //solverConstraint.m_penetration = cp.getDistance(); 719 720 solverConstraint.m_friction = cp.m_combinedFriction; 721 722 723 if (cp.m_lifeTime>infoGlobal.m_restingContactRestitutionThreshold) 724 { 725 solverConstraint.m_restitution = 0.f; 726 } else 727 { 728 solverConstraint.m_restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution); 729 if (solverConstraint.m_restitution <= btScalar(0.)) 730 { 731 solverConstraint.m_restitution = 0.f; 732 }; 733 } 734 735 736 btScalar penVel = -solverConstraint.m_penetration/infoGlobal.m_timeStep; 737 738 739 740 if (solverConstraint.m_restitution > penVel) 741 { 742 solverConstraint.m_penetration = btScalar(0.); 743 } 744 745 746 747 ///warm starting (or zero if disabled) 748 if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) 749 { 750 solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor; 751 if (rb0) 752 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(solverConstraint.m_contactNormal*rb0->getInvMass(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse); 753 if (rb1) 754 m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(solverConstraint.m_contactNormal*rb1->getInvMass(),solverConstraint.m_angularComponentB,-solverConstraint.m_appliedImpulse); 755 } else 756 { 757 solverConstraint.m_appliedImpulse = 0.f; 758 } 759 760 solverConstraint.m_appliedPushImpulse = 0.f; 761 762 solverConstraint.m_frictionIndex = m_tmpSolverFrictionConstraintPool.size(); 763 if (!cp.m_lateralFrictionInitialized) 764 { 765 cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel; 766 btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2(); 767 if (lat_rel_vel > SIMD_EPSILON)//0.0f) 768 { 769 cp.m_lateralFrictionDir1 /= btSqrt(lat_rel_vel); 770 addFrictionConstraint(cp.m_lateralFrictionDir1,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 } 778 } else 779 { 780 //re-calculate friction direction every frame, todo: check if this is really needed 781 btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2); 782 addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); 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 } 788 } 789 790 } else 791 { 792 addFrictionConstraint(cp.m_lateralFrictionDir1,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); 795 } 796 797 if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING) 798 { 799 { 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 } 813 { 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 } 826 } 827 } 828 } 829 830 831 } 832 } 833 } 834 } 835 } 836 837 btContactSolverInfo info = infoGlobal; 838 647 839 { 648 840 int j; … … 653 845 } 654 846 } 655 656 btSolverBody& fixedBody = m_tmpSolverBodyPool.expand(); 657 initSolverBody(&fixedBody,0); 658 659 //btRigidBody* rb0=0,*rb1=0; 660 661 //if (1) 662 { 663 { 664 665 int totalNumRows = 0; 666 int i; 667 //calculate the total number of contraint rows 668 for (i=0;i<numConstraints;i++) 669 { 670 671 btTypedConstraint::btConstraintInfo1 info1; 672 constraints[i]->getInfo1(&info1); 673 totalNumRows += info1.m_numConstraintRows; 674 } 675 m_tmpSolverNonContactConstraintPool.resize(totalNumRows); 676 677 btTypedConstraint::btConstraintInfo1 info1; 678 info1.m_numConstraintRows = 0; 679 680 681 ///setup the btSolverConstraints 682 int currentRow = 0; 683 684 for (i=0;i<numConstraints;i++,currentRow+=info1.m_numConstraintRows) 685 { 686 constraints[i]->getInfo1(&info1); 687 if (info1.m_numConstraintRows) 688 { 689 btAssert(currentRow<totalNumRows); 690 691 btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow]; 692 btTypedConstraint* constraint = constraints[i]; 693 694 695 696 btRigidBody& rbA = constraint->getRigidBodyA(); 697 btRigidBody& rbB = constraint->getRigidBodyB(); 698 699 int solverBodyIdA = getOrInitSolverBody(rbA); 700 int solverBodyIdB = getOrInitSolverBody(rbB); 701 702 btSolverBody* bodyAPtr = &m_tmpSolverBodyPool[solverBodyIdA]; 703 btSolverBody* bodyBPtr = &m_tmpSolverBodyPool[solverBodyIdB]; 704 705 int j; 706 for ( j=0;j<info1.m_numConstraintRows;j++) 707 { 708 memset(¤tConstraintRow[j],0,sizeof(btSolverConstraint)); 709 currentConstraintRow[j].m_lowerLimit = -FLT_MAX; 710 currentConstraintRow[j].m_upperLimit = FLT_MAX; 711 currentConstraintRow[j].m_appliedImpulse = 0.f; 712 currentConstraintRow[j].m_appliedPushImpulse = 0.f; 713 currentConstraintRow[j].m_solverBodyIdA = solverBodyIdA; 714 currentConstraintRow[j].m_solverBodyIdB = solverBodyIdB; 715 } 716 717 bodyAPtr->m_deltaLinearVelocity.setValue(0.f,0.f,0.f); 718 bodyAPtr->m_deltaAngularVelocity.setValue(0.f,0.f,0.f); 719 bodyBPtr->m_deltaLinearVelocity.setValue(0.f,0.f,0.f); 720 bodyBPtr->m_deltaAngularVelocity.setValue(0.f,0.f,0.f); 721 722 723 724 btTypedConstraint::btConstraintInfo2 info2; 725 info2.fps = 1.f/infoGlobal.m_timeStep; 726 info2.erp = infoGlobal.m_erp; 727 info2.m_J1linearAxis = currentConstraintRow->m_contactNormal; 728 info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal; 729 info2.m_J2linearAxis = 0; 730 info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal; 731 info2.rowskip = sizeof(btSolverConstraint)/sizeof(btScalar);//check this 732 ///the size of btSolverConstraint needs be a multiple of btScalar 733 btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint)); 734 info2.m_constraintError = ¤tConstraintRow->m_rhs; 735 info2.cfm = ¤tConstraintRow->m_cfm; 736 info2.m_lowerLimit = ¤tConstraintRow->m_lowerLimit; 737 info2.m_upperLimit = ¤tConstraintRow->m_upperLimit; 738 constraints[i]->getInfo2(&info2); 739 740 ///finalize the constraint setup 741 for ( j=0;j<info1.m_numConstraintRows;j++) 742 { 743 btSolverConstraint& solverConstraint = currentConstraintRow[j]; 744 745 { 746 const btVector3& ftorqueAxis1 = solverConstraint.m_relpos1CrossNormal; 747 solverConstraint.m_angularComponentA = constraint->getRigidBodyA().getInvInertiaTensorWorld()*ftorqueAxis1*constraint->getRigidBodyA().getAngularFactor(); 748 } 749 { 750 const btVector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal; 751 solverConstraint.m_angularComponentB = constraint->getRigidBodyB().getInvInertiaTensorWorld()*ftorqueAxis2*constraint->getRigidBodyB().getAngularFactor(); 752 } 753 754 { 755 btVector3 iMJlA = solverConstraint.m_contactNormal*rbA.getInvMass(); 756 btVector3 iMJaA = rbA.getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal; 757 btVector3 iMJlB = solverConstraint.m_contactNormal*rbB.getInvMass();//sign of normal? 758 btVector3 iMJaB = rbB.getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal; 759 760 btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal); 761 sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal); 762 sum += iMJlB.dot(solverConstraint.m_contactNormal); 763 sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal); 764 765 solverConstraint.m_jacDiagABInv = btScalar(1.)/sum; 766 } 767 768 769 ///fix rhs 770 ///todo: add force/torque accelerators 771 { 772 btScalar rel_vel; 773 btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rbA.getLinearVelocity()) + solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity()); 774 btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rbB.getLinearVelocity()) + solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity()); 775 776 rel_vel = vel1Dotn+vel2Dotn; 777 778 btScalar restitution = 0.f; 779 btScalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2 780 btScalar velocityError = restitution - rel_vel;// * damping; 781 btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv; 782 btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv; 783 solverConstraint.m_rhs = penetrationImpulse+velocityImpulse; 784 solverConstraint.m_appliedImpulse = 0.f; 785 786 } 787 } 788 } 789 } 790 } 791 792 { 793 int i; 794 btPersistentManifold* manifold = 0; 795 btCollisionObject* colObj0=0,*colObj1=0; 796 797 798 for (i=0;i<numManifolds;i++) 799 { 800 manifold = manifoldPtr[i]; 801 convertContact(manifold,infoGlobal); 802 } 803 } 804 } 805 806 btContactSolverInfo info = infoGlobal; 807 808 809 810 int numConstraintPool = m_tmpSolverContactConstraintPool.size(); 811 int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size(); 847 848 849 850 int numConstraintPool = m_tmpSolverConstraintPool.size(); 851 int numFrictionPool = m_tmpSolverFrictionConstraintPool.size(); 812 852 813 853 ///@todo: use stack allocator for such temporarily memory, same for solver bodies/constraints … … 826 866 } 827 867 868 869 828 870 return 0.f; 829 871 … … 833 875 { 834 876 BT_PROFILE("solveGroupCacheFriendlyIterations"); 835 836 int numConstraintPool = m_tmpSolverContactConstraintPool.size(); 837 int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size(); 877 int numConstraintPool = m_tmpSolverConstraintPool.size(); 878 int numFrictionPool = m_tmpSolverFrictionConstraintPool.size(); 838 879 839 880 //should traverse the contacts random order... … … 863 904 } 864 905 865 if (infoGlobal.m_solverMode & SOLVER_SIMD) 866 { 867 ///solve all joint constraints, using SIMD, if available 868 for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++) 869 { 870 btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[j]; 871 resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[constraint.m_solverBodyIdA],m_tmpSolverBodyPool[constraint.m_solverBodyIdB],constraint); 872 } 873 874 for (j=0;j<numConstraints;j++) 875 { 876 int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA()); 877 int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB()); 878 btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid]; 879 btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid]; 880 constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep); 881 } 882 883 ///solve all contact constraints using SIMD, if available 884 int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); 906 for (j=0;j<numConstraints;j++) 907 { 908 btTypedConstraint* constraint = constraints[j]; 909 ///todo: use solver bodies, so we don't need to copy from/to btRigidBody 910 911 if ((constraint->getRigidBodyA().getIslandTag() >= 0) && (constraint->getRigidBodyA().getCompanionId() >= 0)) 912 { 913 m_tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].writebackVelocity(); 914 } 915 if ((constraint->getRigidBodyB().getIslandTag() >= 0) && (constraint->getRigidBodyB().getCompanionId() >= 0)) 916 { 917 m_tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].writebackVelocity(); 918 } 919 920 constraint->solveConstraint(infoGlobal.m_timeStep); 921 922 if ((constraint->getRigidBodyA().getIslandTag() >= 0) && (constraint->getRigidBodyA().getCompanionId() >= 0)) 923 { 924 m_tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].readVelocity(); 925 } 926 if ((constraint->getRigidBodyB().getIslandTag() >= 0) && (constraint->getRigidBodyB().getCompanionId() >= 0)) 927 { 928 m_tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].readVelocity(); 929 } 930 931 } 932 933 { 934 int numPoolConstraints = m_tmpSolverConstraintPool.size(); 885 935 for (j=0;j<numPoolConstraints;j++) 886 936 { 887 const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]]; 888 resolveSingleConstraintRowLowerLimitSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); 889 890 } 891 ///solve all friction constraints, using SIMD, if available 892 int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size(); 893 for (j=0;j<numFrictionPoolConstraints;j++) 894 { 895 btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]]; 896 btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse; 897 898 if (totalImpulse>btScalar(0)) 937 938 const btSolverConstraint& solveManifold = m_tmpSolverConstraintPool[m_orderTmpConstraintPool[j]]; 939 resolveSingleCollisionCombinedCacheFriendly(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], 940 m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold,infoGlobal); 941 } 942 } 943 944 { 945 int numFrictionPoolConstraints = m_tmpSolverFrictionConstraintPool.size(); 946 947 for (j=0;j<numFrictionPoolConstraints;j++) 948 { 949 const btSolverConstraint& solveManifold = m_tmpSolverFrictionConstraintPool[m_orderFrictionConstraintPool[j]]; 950 btScalar totalImpulse = m_tmpSolverConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse+ 951 m_tmpSolverConstraintPool[solveManifold.m_frictionIndex].m_appliedPushImpulse; 952 953 resolveSingleFrictionCacheFriendly(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], 954 m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold,infoGlobal, 955 totalImpulse); 956 } 957 } 958 959 960 961 } 962 963 if (infoGlobal.m_splitImpulse) 964 { 965 966 for ( iteration = 0;iteration<infoGlobal.m_numIterations;iteration++) 967 { 968 { 969 int numPoolConstraints = m_tmpSolverConstraintPool.size(); 970 int j; 971 for (j=0;j<numPoolConstraints;j++) 899 972 { 900 solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);901 solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; 902 903 resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);973 const btSolverConstraint& solveManifold = m_tmpSolverConstraintPool[m_orderTmpConstraintPool[j]]; 974 975 resolveSplitPenetrationImpulseCacheFriendly(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], 976 m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold,infoGlobal); 904 977 } 905 978 } 906 } else 907 { 908 909 ///solve all joint constraints 910 for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++) 911 { 912 btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[j]; 913 resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[constraint.m_solverBodyIdA],m_tmpSolverBodyPool[constraint.m_solverBodyIdB],constraint); 914 } 915 916 for (j=0;j<numConstraints;j++) 917 { 918 int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA()); 919 int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB()); 920 btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid]; 921 btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid]; 922 923 constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep); 924 } 925 926 ///solve all contact constraints 927 int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); 928 for (j=0;j<numPoolConstraints;j++) 929 { 930 const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]]; 931 resolveSingleConstraintRowLowerLimit(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); 932 } 933 ///solve all friction constraints 934 int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size(); 935 for (j=0;j<numFrictionPoolConstraints;j++) 936 { 937 btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]]; 938 btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse; 939 940 if (totalImpulse>btScalar(0)) 941 { 942 solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse); 943 solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; 944 945 resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); 946 } 947 } 948 } 949 950 951 952 } 953 } 979 } 980 981 } 982 983 } 984 954 985 return 0.f; 955 986 } 956 987 957 988 958 959 /// btSequentialImpulseConstraintSolver Sequentially applies impulses 960 btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc,btDispatcher* /*dispatcher*/) 961 { 962 963 964 965 BT_PROFILE("solveGroup"); 966 //we only implement SOLVER_CACHE_FRIENDLY now 967 //you need to provide at least some bodies 968 btAssert(bodies); 969 btAssert(numBodies); 970 989 btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc) 990 { 971 991 int i; 972 992 … … 974 994 solveGroupCacheFriendlyIterations(bodies, numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc); 975 995 976 int numPoolConstraints = m_tmpSolverCon tactConstraintPool.size();996 int numPoolConstraints = m_tmpSolverConstraintPool.size(); 977 997 int j; 978 979 998 for (j=0;j<numPoolConstraints;j++) 980 999 { 981 982 const btSolverConstraint& solveManifold = m_tmpSolverCon tactConstraintPool[j];1000 1001 const btSolverConstraint& solveManifold = m_tmpSolverConstraintPool[j]; 983 1002 btManifoldPoint* pt = (btManifoldPoint*) solveManifold.m_originalContactPoint; 984 1003 btAssert(pt); … … 986 1005 if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING) 987 1006 { 988 pt->m_appliedImpulseLateral1 = m_tmpSolver ContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;989 pt->m_appliedImpulseLateral2 = m_tmpSolver ContactFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse;1007 pt->m_appliedImpulseLateral1 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse; 1008 pt->m_appliedImpulseLateral2 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse; 990 1009 } 991 1010 992 1011 //do a callback here? 1012 993 1013 } 994 1014 … … 1002 1022 { 1003 1023 for ( i=0;i<m_tmpSolverBodyPool.size();i++) 1004 { 1005 m_tmpSolverBodyPool[i].writebackVelocity(); 1006 } 1007 } 1008 1024 { 1025 m_tmpSolverBodyPool[i].writebackVelocity(); 1026 } 1027 } 1028 1029 // printf("m_tmpSolverConstraintPool.size() = %i\n",m_tmpSolverConstraintPool.size()); 1030 1031 /* 1032 printf("m_tmpSolverBodyPool.size() = %i\n",m_tmpSolverBodyPool.size()); 1033 printf("m_tmpSolverConstraintPool.size() = %i\n",m_tmpSolverConstraintPool.size()); 1034 printf("m_tmpSolverFrictionConstraintPool.size() = %i\n",m_tmpSolverFrictionConstraintPool.size()); 1035 1036 1037 printf("m_tmpSolverBodyPool.capacity() = %i\n",m_tmpSolverBodyPool.capacity()); 1038 printf("m_tmpSolverConstraintPool.capacity() = %i\n",m_tmpSolverConstraintPool.capacity()); 1039 printf("m_tmpSolverFrictionConstraintPool.capacity() = %i\n",m_tmpSolverFrictionConstraintPool.capacity()); 1040 */ 1009 1041 1010 1042 m_tmpSolverBodyPool.resize(0); 1011 m_tmpSolverCon tactConstraintPool.resize(0);1012 m_tmpSolver NonContactConstraintPool.resize(0);1013 m_tmpSolverContactFrictionConstraintPool.resize(0); 1043 m_tmpSolverConstraintPool.resize(0); 1044 m_tmpSolverFrictionConstraintPool.resize(0); 1045 1014 1046 1015 1047 return 0.f; 1016 1048 } 1017 1049 1018 1019 1020 1021 1022 1023 1050 /// btSequentialImpulseConstraintSolver Sequentially applies impulses 1051 btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc,btDispatcher* /*dispatcher*/) 1052 { 1053 BT_PROFILE("solveGroup"); 1054 if (infoGlobal.m_solverMode & SOLVER_CACHE_FRIENDLY) 1055 { 1056 //you need to provide at least some bodies 1057 //btSimpleDynamicsWorld needs to switch off SOLVER_CACHE_FRIENDLY 1058 btAssert(bodies); 1059 btAssert(numBodies); 1060 return solveGroupCacheFriendly(bodies,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc); 1061 } 1062 1063 1064 1065 btContactSolverInfo info = infoGlobal; 1066 1067 int numiter = infoGlobal.m_numIterations; 1068 1069 int totalPoints = 0; 1070 1071 1072 { 1073 short j; 1074 for (j=0;j<numManifolds;j++) 1075 { 1076 btPersistentManifold* manifold = manifoldPtr[j]; 1077 prepareConstraints(manifold,info,debugDrawer); 1078 1079 for (short p=0;p<manifoldPtr[j]->getNumContacts();p++) 1080 { 1081 gOrder[totalPoints].m_manifoldIndex = j; 1082 gOrder[totalPoints].m_pointIndex = p; 1083 totalPoints++; 1084 } 1085 } 1086 } 1087 1088 { 1089 int j; 1090 for (j=0;j<numConstraints;j++) 1091 { 1092 btTypedConstraint* constraint = constraints[j]; 1093 constraint->buildJacobian(); 1094 } 1095 } 1096 1097 1098 //should traverse the contacts random order... 1099 int iteration; 1100 1101 { 1102 for ( iteration = 0;iteration<numiter;iteration++) 1103 { 1104 int j; 1105 if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER) 1106 { 1107 if ((iteration & 7) == 0) { 1108 for (j=0; j<totalPoints; ++j) { 1109 btOrderIndex tmp = gOrder[j]; 1110 int swapi = btRandInt2(j+1); 1111 gOrder[j] = gOrder[swapi]; 1112 gOrder[swapi] = tmp; 1113 } 1114 } 1115 } 1116 1117 for (j=0;j<numConstraints;j++) 1118 { 1119 btTypedConstraint* constraint = constraints[j]; 1120 constraint->solveConstraint(info.m_timeStep); 1121 } 1122 1123 for (j=0;j<totalPoints;j++) 1124 { 1125 btPersistentManifold* manifold = manifoldPtr[gOrder[j].m_manifoldIndex]; 1126 solve( (btRigidBody*)manifold->getBody0(), 1127 (btRigidBody*)manifold->getBody1() 1128 ,manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer); 1129 } 1130 1131 for (j=0;j<totalPoints;j++) 1132 { 1133 btPersistentManifold* manifold = manifoldPtr[gOrder[j].m_manifoldIndex]; 1134 solveFriction((btRigidBody*)manifold->getBody0(), 1135 (btRigidBody*)manifold->getBody1(),manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer); 1136 } 1137 1138 } 1139 } 1140 1141 1142 1143 1144 return btScalar(0.); 1145 } 1146 1147 1148 1149 1150 1151 1152 1153 void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifold* manifoldPtr, const btContactSolverInfo& info,btIDebugDraw* debugDrawer) 1154 { 1155 1156 (void)debugDrawer; 1157 1158 btRigidBody* body0 = (btRigidBody*)manifoldPtr->getBody0(); 1159 btRigidBody* body1 = (btRigidBody*)manifoldPtr->getBody1(); 1160 1161 1162 //only necessary to refresh the manifold once (first iteration). The integration is done outside the loop 1163 { 1164 #ifdef FORCE_REFESH_CONTACT_MANIFOLDS 1165 manifoldPtr->refreshContactPoints(body0->getCenterOfMassTransform(),body1->getCenterOfMassTransform()); 1166 #endif //FORCE_REFESH_CONTACT_MANIFOLDS 1167 int numpoints = manifoldPtr->getNumContacts(); 1168 1169 gTotalContactPoints += numpoints; 1170 1171 1172 for (int i=0;i<numpoints ;i++) 1173 { 1174 btManifoldPoint& cp = manifoldPtr->getContactPoint(i); 1175 if (cp.getDistance() <= btScalar(0.)) 1176 { 1177 const btVector3& pos1 = cp.getPositionWorldOnA(); 1178 const btVector3& pos2 = cp.getPositionWorldOnB(); 1179 1180 btVector3 rel_pos1 = pos1 - body0->getCenterOfMassPosition(); 1181 btVector3 rel_pos2 = pos2 - body1->getCenterOfMassPosition(); 1182 1183 1184 //this jacobian entry is re-used for all iterations 1185 btJacobianEntry jac(body0->getCenterOfMassTransform().getBasis().transpose(), 1186 body1->getCenterOfMassTransform().getBasis().transpose(), 1187 rel_pos1,rel_pos2,cp.m_normalWorldOnB,body0->getInvInertiaDiagLocal(),body0->getInvMass(), 1188 body1->getInvInertiaDiagLocal(),body1->getInvMass()); 1189 1190 1191 btScalar jacDiagAB = jac.getDiagonal(); 1192 1193 btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData; 1194 if (cpd) 1195 { 1196 //might be invalid 1197 cpd->m_persistentLifeTime++; 1198 if (cpd->m_persistentLifeTime != cp.getLifeTime()) 1199 { 1200 //printf("Invalid: cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd->m_persistentLifeTime,cp.getLifeTime()); 1201 new (cpd) btConstraintPersistentData; 1202 cpd->m_persistentLifeTime = cp.getLifeTime(); 1203 1204 } else 1205 { 1206 //printf("Persistent: cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd->m_persistentLifeTime,cp.getLifeTime()); 1207 1208 } 1209 } else 1210 { 1211 1212 //todo: should this be in a pool? 1213 void* mem = btAlignedAlloc(sizeof(btConstraintPersistentData),16); 1214 cpd = new (mem)btConstraintPersistentData; 1215 assert(cpd); 1216 1217 totalCpd ++; 1218 //printf("totalCpd = %i Created Ptr %x\n",totalCpd,cpd); 1219 cp.m_userPersistentData = cpd; 1220 cpd->m_persistentLifeTime = cp.getLifeTime(); 1221 //printf("CREATED: %x . cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd,cpd->m_persistentLifeTime,cp.getLifeTime()); 1222 1223 } 1224 assert(cpd); 1225 1226 cpd->m_jacDiagABInv = btScalar(1.) / jacDiagAB; 1227 1228 //Dependent on Rigidbody A and B types, fetch the contact/friction response func 1229 //perhaps do a similar thing for friction/restutution combiner funcs... 1230 1231 cpd->m_frictionSolverFunc = m_frictionDispatch[body0->m_frictionSolverType][body1->m_frictionSolverType]; 1232 cpd->m_contactSolverFunc = m_contactDispatch[body0->m_contactSolverType][body1->m_contactSolverType]; 1233 1234 btVector3 vel1 = body0->getVelocityInLocalPoint(rel_pos1); 1235 btVector3 vel2 = body1->getVelocityInLocalPoint(rel_pos2); 1236 btVector3 vel = vel1 - vel2; 1237 btScalar rel_vel; 1238 rel_vel = cp.m_normalWorldOnB.dot(vel); 1239 1240 btScalar combinedRestitution = cp.m_combinedRestitution; 1241 1242 cpd->m_penetration = cp.getDistance();///btScalar(info.m_numIterations); 1243 cpd->m_friction = cp.m_combinedFriction; 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 } 1255 1256 //restitution and penetration work in same direction so 1257 //rel_vel 1258 1259 btScalar penVel = -cpd->m_penetration/info.m_timeStep; 1260 1261 if (cpd->m_restitution > penVel) 1262 { 1263 cpd->m_penetration = btScalar(0.); 1264 } 1265 1266 1267 btScalar relaxation = info.m_damping; 1268 if (info.m_solverMode & SOLVER_USE_WARMSTARTING) 1269 { 1270 cpd->m_appliedImpulse *= relaxation; 1271 } else 1272 { 1273 cpd->m_appliedImpulse =btScalar(0.); 1274 } 1275 1276 //for friction 1277 cpd->m_prevAppliedImpulse = cpd->m_appliedImpulse; 1278 1279 //re-calculate friction direction every frame, todo: check if this is really needed 1280 btPlaneSpace1(cp.m_normalWorldOnB,cpd->m_frictionWorldTangential0,cpd->m_frictionWorldTangential1); 1281 1282 1283 #define NO_FRICTION_WARMSTART 1 1284 1285 #ifdef NO_FRICTION_WARMSTART 1286 cpd->m_accumulatedTangentImpulse0 = btScalar(0.); 1287 cpd->m_accumulatedTangentImpulse1 = btScalar(0.); 1288 #endif //NO_FRICTION_WARMSTART 1289 btScalar denom0 = body0->computeImpulseDenominator(pos1,cpd->m_frictionWorldTangential0); 1290 btScalar denom1 = body1->computeImpulseDenominator(pos2,cpd->m_frictionWorldTangential0); 1291 btScalar denom = relaxation/(denom0+denom1); 1292 cpd->m_jacDiagABInvTangent0 = denom; 1293 1294 1295 denom0 = body0->computeImpulseDenominator(pos1,cpd->m_frictionWorldTangential1); 1296 denom1 = body1->computeImpulseDenominator(pos2,cpd->m_frictionWorldTangential1); 1297 denom = relaxation/(denom0+denom1); 1298 cpd->m_jacDiagABInvTangent1 = denom; 1299 1300 btVector3 totalImpulse = 1301 #ifndef NO_FRICTION_WARMSTART 1302 cpd->m_frictionWorldTangential0*cpd->m_accumulatedTangentImpulse0+ 1303 cpd->m_frictionWorldTangential1*cpd->m_accumulatedTangentImpulse1+ 1304 #endif //NO_FRICTION_WARMSTART 1305 cp.m_normalWorldOnB*cpd->m_appliedImpulse; 1306 1307 1308 1309 /// 1310 { 1311 btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB); 1312 cpd->m_angularComponentA = body0->getInvInertiaTensorWorld()*torqueAxis0; 1313 btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB); 1314 cpd->m_angularComponentB = body1->getInvInertiaTensorWorld()*torqueAxis1; 1315 } 1316 { 1317 btVector3 ftorqueAxis0 = rel_pos1.cross(cpd->m_frictionWorldTangential0); 1318 cpd->m_frictionAngularComponent0A = body0->getInvInertiaTensorWorld()*ftorqueAxis0; 1319 } 1320 { 1321 btVector3 ftorqueAxis1 = rel_pos1.cross(cpd->m_frictionWorldTangential1); 1322 cpd->m_frictionAngularComponent1A = body0->getInvInertiaTensorWorld()*ftorqueAxis1; 1323 } 1324 { 1325 btVector3 ftorqueAxis0 = rel_pos2.cross(cpd->m_frictionWorldTangential0); 1326 cpd->m_frictionAngularComponent0B = body1->getInvInertiaTensorWorld()*ftorqueAxis0; 1327 } 1328 { 1329 btVector3 ftorqueAxis1 = rel_pos2.cross(cpd->m_frictionWorldTangential1); 1330 cpd->m_frictionAngularComponent1B = body1->getInvInertiaTensorWorld()*ftorqueAxis1; 1331 } 1332 1333 /// 1334 1335 1336 1337 //apply previous frames impulse on both bodies 1338 body0->applyImpulse(totalImpulse, rel_pos1); 1339 body1->applyImpulse(-totalImpulse, rel_pos2); 1340 } 1341 1342 } 1343 } 1344 } 1345 1346 1347 btScalar btSequentialImpulseConstraintSolver::solveCombinedContactFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer) 1348 { 1349 btScalar maxImpulse = btScalar(0.); 1350 1351 { 1352 1353 1354 { 1355 if (cp.getDistance() <= btScalar(0.)) 1356 { 1357 1358 1359 1360 { 1361 1362 //btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData; 1363 btScalar impulse = resolveSingleCollisionCombined( 1364 *body0,*body1, 1365 cp, 1366 info); 1367 1368 if (maxImpulse < impulse) 1369 maxImpulse = impulse; 1370 1371 } 1372 } 1373 } 1374 } 1375 return maxImpulse; 1376 } 1377 1378 1379 1380 btScalar btSequentialImpulseConstraintSolver::solve(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer) 1381 { 1382 1383 btScalar maxImpulse = btScalar(0.); 1384 1385 { 1386 1387 1388 { 1389 if (cp.getDistance() <= btScalar(0.)) 1390 { 1391 1392 1393 1394 { 1395 1396 btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData; 1397 btScalar impulse = cpd->m_contactSolverFunc( 1398 *body0,*body1, 1399 cp, 1400 info); 1401 1402 if (maxImpulse < impulse) 1403 maxImpulse = impulse; 1404 1405 } 1406 } 1407 } 1408 } 1409 return maxImpulse; 1410 } 1411 1412 btScalar btSequentialImpulseConstraintSolver::solveFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer) 1413 { 1414 1415 (void)debugDrawer; 1416 (void)iter; 1417 1418 1419 { 1420 1421 1422 { 1423 1424 if (cp.getDistance() <= btScalar(0.)) 1425 { 1426 1427 btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData; 1428 cpd->m_frictionSolverFunc( 1429 *body0,*body1, 1430 cp, 1431 info); 1432 1433 1434 } 1435 } 1436 1437 1438 } 1439 return btScalar(0.); 1440 } 1024 1441 1025 1442 -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
r2907 r2908 24 24 25 25 26 27 ///The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (iterative LCP) method. 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 28 30 class btSequentialImpulseConstraintSolver : public btConstraintSolver 29 31 { 30 protected:31 32 32 33 btAlignedObjectArray<btSolverBody> m_tmpSolverBodyPool; 33 btConstraintArray m_tmpSolverContactConstraintPool; 34 btConstraintArray m_tmpSolverNonContactConstraintPool; 35 btConstraintArray m_tmpSolverContactFrictionConstraintPool; 34 btAlignedObjectArray<btSolverConstraint> m_tmpSolverConstraintPool; 35 btAlignedObjectArray<btSolverConstraint> m_tmpSolverFrictionConstraintPool; 36 36 btAlignedObjectArray<int> m_orderTmpConstraintPool; 37 37 btAlignedObjectArray<int> m_orderFrictionConstraintPool; 38 38 39 40 protected: 41 btScalar solve(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer); 42 btScalar solveFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer); 43 void prepareConstraints(btPersistentManifold* manifoldPtr, const btContactSolverInfo& info,btIDebugDraw* debugDrawer); 39 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 46 ContactSolverFunc m_contactDispatch[MAX_CONTACT_SOLVER_TYPES][MAX_CONTACT_SOLVER_TYPES]; 47 ContactSolverFunc m_frictionDispatch[MAX_CONTACT_SOLVER_TYPES][MAX_CONTACT_SOLVER_TYPES]; 48 40 49 41 50 ///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction 42 51 unsigned long m_btSeed2; 43 52 44 void initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject);45 btScalar restitutionCurve(btScalar rel_vel, btScalar restitution);46 47 void convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal);48 49 void resolveSplitPenetrationImpulseCacheFriendly(50 btSolverBody& body1,51 btSolverBody& body2,52 const btSolverConstraint& contactConstraint,53 const btContactSolverInfo& solverInfo);54 55 //internal method56 int getOrInitSolverBody(btCollisionObject& body);57 58 void resolveSingleConstraintRowGeneric(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);59 60 void resolveSingleConstraintRowGenericSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);61 62 void resolveSingleConstraintRowLowerLimit(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);63 64 void resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);65 66 53 public: 67 54 68 55 69 56 btSequentialImpulseConstraintSolver(); 57 58 ///Advanced: Override the default contact solving function for contacts, for certain types of rigidbody 59 ///See btRigidBody::m_contactSolverType and btRigidBody::m_frictionSolverType 60 void setContactSolverFunc(ContactSolverFunc func,int type0,int type1) 61 { 62 m_contactDispatch[type0][type1] = func; 63 } 64 65 ///Advanced: Override the default friction solving function for contacts, for certain types of rigidbody 66 ///See btRigidBody::m_contactSolverType and btRigidBody::m_frictionSolverType 67 void SetFrictionSolverFunc(ContactSolverFunc func,int type0,int type1) 68 { 69 m_frictionDispatch[type0][type1] = func; 70 } 71 70 72 virtual ~btSequentialImpulseConstraintSolver(); 73 74 virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher); 71 75 72 virtual btScalar solveGroup (btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher);73 76 virtual btScalar solveGroupCacheFriendly(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc); 77 btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc); 74 78 btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc); 75 btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc); 79 76 80 77 81 ///clear internal cached data and reset random seed 78 82 virtual void reset(); 83 84 btScalar solveCombinedContactFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer); 85 86 79 87 80 88 unsigned long btRand2(); -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
r2907 r2908 69 69 btSliderConstraint::btSliderConstraint() 70 70 :btTypedConstraint(SLIDER_CONSTRAINT_TYPE), 71 m_useLinearReferenceFrameA(true), 72 m_useSolveConstraintObsolete(false) 73 // m_useSolveConstraintObsolete(true) 71 m_useLinearReferenceFrameA(true) 74 72 { 75 73 initParams(); … … 82 80 , m_frameInA(frameInA) 83 81 , m_frameInB(frameInB), 84 m_useLinearReferenceFrameA(useLinearReferenceFrameA), 85 m_useSolveConstraintObsolete(false) 86 // m_useSolveConstraintObsolete(true) 82 m_useLinearReferenceFrameA(useLinearReferenceFrameA) 87 83 { 88 84 initParams(); … … 93 89 void btSliderConstraint::buildJacobian() 94 90 { 95 if (!m_useSolveConstraintObsolete)96 {97 return;98 }99 91 if(m_useLinearReferenceFrameA) 100 92 { … … 164 156 //----------------------------------------------------------------------------- 165 157 166 void btSliderConstraint:: getInfo1(btConstraintInfo1* info)167 { 168 if (m_useSolveConstraintObsolete) 169 {170 info->m_numConstraintRows = 0;171 info->nub = 0;158 void btSliderConstraint::solveConstraint(btScalar timeStep) 159 { 160 m_timeStep = timeStep; 161 if(m_useLinearReferenceFrameA) 162 { 163 solveConstraintInt(m_rbA, m_rbB); 172 164 } 173 165 else 174 166 { 175 info->m_numConstraintRows = 4; // Fixed 2 linear + 2 angular 176 info->nub = 2; 177 //prepare constraint 178 calculateTransforms(); 179 testLinLimits(); 180 if(getSolveLinLimit() || getPoweredLinMotor()) 181 { 182 info->m_numConstraintRows++; // limit 3rd linear as well 183 info->nub--; 184 } 185 testAngLimits(); 186 if(getSolveAngLimit() || getPoweredAngMotor()) 187 { 188 info->m_numConstraintRows++; // limit 3rd angular as well 189 info->nub--; 190 } 191 } 192 } // btSliderConstraint::getInfo1() 193 194 //----------------------------------------------------------------------------- 195 196 void btSliderConstraint::getInfo2(btConstraintInfo2* info) 197 { 198 btAssert(!m_useSolveConstraintObsolete); 199 int i, s = info->rowskip; 200 const btTransform& trA = getCalculatedTransformA(); 201 const btTransform& trB = getCalculatedTransformB(); 202 btScalar signFact = m_useLinearReferenceFrameA ? btScalar(1.0f) : btScalar(-1.0f); 203 // make rotations around Y and Z equal 204 // the slider axis should be the only unconstrained 205 // rotational axis, the angular velocity of the two bodies perpendicular to 206 // the slider axis should be equal. thus the constraint equations are 207 // p*w1 - p*w2 = 0 208 // q*w1 - q*w2 = 0 209 // where p and q are unit vectors normal to the slider axis, and w1 and w2 210 // are the angular velocity vectors of the two bodies. 211 // get slider axis (X) 212 btVector3 ax1 = trA.getBasis().getColumn(0); 213 // get 2 orthos to slider axis (Y, Z) 214 btVector3 p = trA.getBasis().getColumn(1); 215 btVector3 q = trA.getBasis().getColumn(2); 216 // set the two slider rows 217 info->m_J1angularAxis[0] = p[0]; 218 info->m_J1angularAxis[1] = p[1]; 219 info->m_J1angularAxis[2] = p[2]; 220 info->m_J1angularAxis[s+0] = q[0]; 221 info->m_J1angularAxis[s+1] = q[1]; 222 info->m_J1angularAxis[s+2] = q[2]; 223 224 info->m_J2angularAxis[0] = -p[0]; 225 info->m_J2angularAxis[1] = -p[1]; 226 info->m_J2angularAxis[2] = -p[2]; 227 info->m_J2angularAxis[s+0] = -q[0]; 228 info->m_J2angularAxis[s+1] = -q[1]; 229 info->m_J2angularAxis[s+2] = -q[2]; 230 // compute the right hand side of the constraint equation. set relative 231 // body velocities along p and q to bring the slider back into alignment. 232 // if ax1,ax2 are the unit length slider axes as computed from body1 and 233 // body2, we need to rotate both bodies along the axis u = (ax1 x ax2). 234 // if "theta" is the angle between ax1 and ax2, we need an angular velocity 235 // along u to cover angle erp*theta in one step : 236 // |angular_velocity| = angle/time = erp*theta / stepsize 237 // = (erp*fps) * theta 238 // angular_velocity = |angular_velocity| * (ax1 x ax2) / |ax1 x ax2| 239 // = (erp*fps) * theta * (ax1 x ax2) / sin(theta) 240 // ...as ax1 and ax2 are unit length. if theta is smallish, 241 // theta ~= sin(theta), so 242 // angular_velocity = (erp*fps) * (ax1 x ax2) 243 // ax1 x ax2 is in the plane space of ax1, so we project the angular 244 // velocity to p and q to find the right hand side. 245 btScalar k = info->fps * info->erp * getSoftnessOrthoAng(); 246 btVector3 ax2 = trB.getBasis().getColumn(0); 247 btVector3 u = ax1.cross(ax2); 248 info->m_constraintError[0] = k * u.dot(p); 249 info->m_constraintError[s] = k * u.dot(q); 250 // pull out pos and R for both bodies. also get the connection 251 // vector c = pos2-pos1. 252 // next two rows. we want: vel2 = vel1 + w1 x c ... but this would 253 // result in three equations, so we project along the planespace vectors 254 // so that sliding along the slider axis is disregarded. for symmetry we 255 // also consider rotation around center of mass of two bodies (factA and factB). 256 btTransform bodyA_trans = m_rbA.getCenterOfMassTransform(); 257 btTransform bodyB_trans = m_rbB.getCenterOfMassTransform(); 258 int s2 = 2 * s, s3 = 3 * s; 259 btVector3 c; 260 btScalar miA = m_rbA.getInvMass(); 261 btScalar miB = m_rbB.getInvMass(); 262 btScalar miS = miA + miB; 263 btScalar factA, factB; 264 if(miS > btScalar(0.f)) 265 { 266 factA = miB / miS; 267 } 268 else 269 { 270 factA = btScalar(0.5f); 271 } 272 if(factA > 0.99f) factA = 0.99f; 273 if(factA < 0.01f) factA = 0.01f; 274 factB = btScalar(1.0f) - factA; 275 c = bodyB_trans.getOrigin() - bodyA_trans.getOrigin(); 276 btVector3 tmp = c.cross(p); 277 for (i=0; i<3; i++) info->m_J1angularAxis[s2+i] = factA*tmp[i]; 278 for (i=0; i<3; i++) info->m_J2angularAxis[s2+i] = factB*tmp[i]; 279 tmp = c.cross(q); 280 for (i=0; i<3; i++) info->m_J1angularAxis[s3+i] = factA*tmp[i]; 281 for (i=0; i<3; i++) info->m_J2angularAxis[s3+i] = factB*tmp[i]; 282 283 for (i=0; i<3; i++) info->m_J1linearAxis[s2+i] = p[i]; 284 for (i=0; i<3; i++) info->m_J1linearAxis[s3+i] = q[i]; 285 // compute two elements of right hand side. we want to align the offset 286 // point (in body 2's frame) with the center of body 1. 287 btVector3 ofs; // offset point in global coordinates 288 ofs = trB.getOrigin() - trA.getOrigin(); 289 k = info->fps * info->erp * getSoftnessOrthoLin(); 290 info->m_constraintError[s2] = k * p.dot(ofs); 291 info->m_constraintError[s3] = k * q.dot(ofs); 292 int nrow = 3; // last filled row 293 int srow; 294 // check linear limits linear 295 btScalar limit_err = btScalar(0.0); 296 int limit = 0; 297 if(getSolveLinLimit()) 298 { 299 limit_err = getLinDepth() * signFact; 300 limit = (limit_err > btScalar(0.0)) ? 2 : 1; 301 } 302 int powered = 0; 303 if(getPoweredLinMotor()) 304 { 305 powered = 1; 306 } 307 // if the slider has joint limits or motor, add in the extra row 308 if (limit || powered) 309 { 310 nrow++; 311 srow = nrow * info->rowskip; 312 info->m_J1linearAxis[srow+0] = ax1[0]; 313 info->m_J1linearAxis[srow+1] = ax1[1]; 314 info->m_J1linearAxis[srow+2] = ax1[2]; 315 // linear torque decoupling step: 316 // 317 // we have to be careful that the linear constraint forces (+/- ax1) applied to the two bodies 318 // do not create a torque couple. in other words, the points that the 319 // constraint force is applied at must lie along the same ax1 axis. 320 // a torque couple will result in limited slider-jointed free 321 // bodies from gaining angular momentum. 322 // the solution used here is to apply the constraint forces at the center of mass of the two bodies 323 btVector3 ltd; // Linear Torque Decoupling vector (a torque) 324 // c = btScalar(0.5) * c; 325 ltd = c.cross(ax1); 326 info->m_J1angularAxis[srow+0] = factA*ltd[0]; 327 info->m_J1angularAxis[srow+1] = factA*ltd[1]; 328 info->m_J1angularAxis[srow+2] = factA*ltd[2]; 329 info->m_J2angularAxis[srow+0] = factB*ltd[0]; 330 info->m_J2angularAxis[srow+1] = factB*ltd[1]; 331 info->m_J2angularAxis[srow+2] = factB*ltd[2]; 332 // right-hand part 333 btScalar lostop = getLowerLinLimit(); 334 btScalar histop = getUpperLinLimit(); 335 if(limit && (lostop == histop)) 336 { // the joint motor is ineffective 337 powered = 0; 338 } 339 info->m_constraintError[srow] = 0.; 340 info->m_lowerLimit[srow] = 0.; 341 info->m_upperLimit[srow] = 0.; 342 if(powered) 343 { 344 info->cfm[nrow] = btScalar(0.0); 345 btScalar tag_vel = getTargetLinMotorVelocity(); 346 btScalar mot_fact = getMotorFactor(m_linPos, m_lowerLinLimit, m_upperLinLimit, tag_vel, info->fps * info->erp); 347 // info->m_constraintError[srow] += mot_fact * getTargetLinMotorVelocity(); 348 info->m_constraintError[srow] -= signFact * mot_fact * getTargetLinMotorVelocity(); 349 info->m_lowerLimit[srow] += -getMaxLinMotorForce() * info->fps; 350 info->m_upperLimit[srow] += getMaxLinMotorForce() * info->fps; 351 } 352 if(limit) 353 { 354 k = info->fps * info->erp; 355 info->m_constraintError[srow] += k * limit_err; 356 info->cfm[srow] = btScalar(0.0); // stop_cfm; 357 if(lostop == histop) 358 { // limited low and high simultaneously 359 info->m_lowerLimit[srow] = -SIMD_INFINITY; 360 info->m_upperLimit[srow] = SIMD_INFINITY; 361 } 362 else if(limit == 1) 363 { // low limit 364 info->m_lowerLimit[srow] = -SIMD_INFINITY; 365 info->m_upperLimit[srow] = 0; 366 } 367 else 368 { // high limit 369 info->m_lowerLimit[srow] = 0; 370 info->m_upperLimit[srow] = SIMD_INFINITY; 371 } 372 // bounce (we'll use slider parameter abs(1.0 - m_dampingLimLin) for that) 373 btScalar bounce = btFabs(btScalar(1.0) - getDampingLimLin()); 374 if(bounce > btScalar(0.0)) 375 { 376 btScalar vel = m_rbA.getLinearVelocity().dot(ax1); 377 vel -= m_rbB.getLinearVelocity().dot(ax1); 378 vel *= signFact; 379 // only apply bounce if the velocity is incoming, and if the 380 // resulting c[] exceeds what we already have. 381 if(limit == 1) 382 { // low limit 383 if(vel < 0) 384 { 385 btScalar newc = -bounce * vel; 386 if (newc > info->m_constraintError[srow]) 387 { 388 info->m_constraintError[srow] = newc; 389 } 390 } 391 } 392 else 393 { // high limit - all those computations are reversed 394 if(vel > 0) 395 { 396 btScalar newc = -bounce * vel; 397 if(newc < info->m_constraintError[srow]) 398 { 399 info->m_constraintError[srow] = newc; 400 } 401 } 402 } 403 } 404 info->m_constraintError[srow] *= getSoftnessLimLin(); 405 } // if(limit) 406 } // if linear limit 407 // check angular limits 408 limit_err = btScalar(0.0); 409 limit = 0; 410 if(getSolveAngLimit()) 411 { 412 limit_err = getAngDepth(); 413 limit = (limit_err > btScalar(0.0)) ? 1 : 2; 414 } 415 // if the slider has joint limits, add in the extra row 416 powered = 0; 417 if(getPoweredAngMotor()) 418 { 419 powered = 1; 420 } 421 if(limit || powered) 422 { 423 nrow++; 424 srow = nrow * info->rowskip; 425 info->m_J1angularAxis[srow+0] = ax1[0]; 426 info->m_J1angularAxis[srow+1] = ax1[1]; 427 info->m_J1angularAxis[srow+2] = ax1[2]; 428 429 info->m_J2angularAxis[srow+0] = -ax1[0]; 430 info->m_J2angularAxis[srow+1] = -ax1[1]; 431 info->m_J2angularAxis[srow+2] = -ax1[2]; 432 433 btScalar lostop = getLowerAngLimit(); 434 btScalar histop = getUpperAngLimit(); 435 if(limit && (lostop == histop)) 436 { // the joint motor is ineffective 437 powered = 0; 438 } 439 if(powered) 440 { 441 info->cfm[srow] = btScalar(0.0); 442 btScalar mot_fact = getMotorFactor(m_angPos, m_lowerAngLimit, m_upperAngLimit, getTargetAngMotorVelocity(), info->fps * info->erp); 443 info->m_constraintError[srow] = mot_fact * getTargetAngMotorVelocity(); 444 info->m_lowerLimit[srow] = -getMaxAngMotorForce() * info->fps; 445 info->m_upperLimit[srow] = getMaxAngMotorForce() * info->fps; 446 } 447 if(limit) 448 { 449 k = info->fps * info->erp; 450 info->m_constraintError[srow] += k * limit_err; 451 info->cfm[srow] = btScalar(0.0); // stop_cfm; 452 if(lostop == histop) 453 { 454 // limited low and high simultaneously 455 info->m_lowerLimit[srow] = -SIMD_INFINITY; 456 info->m_upperLimit[srow] = SIMD_INFINITY; 457 } 458 else if(limit == 1) 459 { // low limit 460 info->m_lowerLimit[srow] = 0; 461 info->m_upperLimit[srow] = SIMD_INFINITY; 462 } 463 else 464 { // high limit 465 info->m_lowerLimit[srow] = -SIMD_INFINITY; 466 info->m_upperLimit[srow] = 0; 467 } 468 // bounce (we'll use slider parameter abs(1.0 - m_dampingLimAng) for that) 469 btScalar bounce = btFabs(btScalar(1.0) - getDampingLimAng()); 470 if(bounce > btScalar(0.0)) 471 { 472 btScalar vel = m_rbA.getAngularVelocity().dot(ax1); 473 vel -= m_rbB.getAngularVelocity().dot(ax1); 474 // only apply bounce if the velocity is incoming, and if the 475 // resulting c[] exceeds what we already have. 476 if(limit == 1) 477 { // low limit 478 if(vel < 0) 479 { 480 btScalar newc = -bounce * vel; 481 if(newc > info->m_constraintError[srow]) 482 { 483 info->m_constraintError[srow] = newc; 484 } 485 } 486 } 487 else 488 { // high limit - all those computations are reversed 489 if(vel > 0) 490 { 491 btScalar newc = -bounce * vel; 492 if(newc < info->m_constraintError[srow]) 493 { 494 info->m_constraintError[srow] = newc; 495 } 496 } 497 } 498 } 499 info->m_constraintError[srow] *= getSoftnessLimAng(); 500 } // if(limit) 501 } // if angular limit or powered 502 } // btSliderConstraint::getInfo2() 503 504 //----------------------------------------------------------------------------- 505 506 void btSliderConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) 507 { 508 if (m_useSolveConstraintObsolete) 509 { 510 m_timeStep = timeStep; 511 if(m_useLinearReferenceFrameA) 512 { 513 solveConstraintInt(m_rbA,bodyA, m_rbB,bodyB); 514 } 515 else 516 { 517 solveConstraintInt(m_rbB,bodyB, m_rbA,bodyA); 518 } 167 solveConstraintInt(m_rbB, m_rbA); 519 168 } 520 169 } // btSliderConstraint::solveConstraint() … … 522 171 //----------------------------------------------------------------------------- 523 172 524 void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, bt SolverBody& bodyA,btRigidBody& rbB, btSolverBody& bodyB)173 void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, btRigidBody& rbB) 525 174 { 526 175 int i; 527 176 // linear 528 btVector3 velA; 529 bodyA.getVelocityInLocalPointObsolete(m_relPosA,velA); 530 btVector3 velB; 531 bodyB.getVelocityInLocalPointObsolete(m_relPosB,velB); 177 btVector3 velA = rbA.getVelocityInLocalPoint(m_relPosA); 178 btVector3 velB = rbB.getVelocityInLocalPoint(m_relPosB); 532 179 btVector3 vel = velA - velB; 533 180 for(i = 0; i < 3; i++) … … 544 191 btScalar normalImpulse = softness * (restitution * depth / m_timeStep - damping * rel_vel) * m_jacLinDiagABInv[i]; 545 192 btVector3 impulse_vector = normal * normalImpulse; 546 547 //rbA.applyImpulse( impulse_vector, m_relPosA); 548 //rbB.applyImpulse(-impulse_vector, m_relPosB); 549 { 550 btVector3 ftorqueAxis1 = m_relPosA.cross(normal); 551 btVector3 ftorqueAxis2 = m_relPosB.cross(normal); 552 bodyA.applyImpulse(normal*rbA.getInvMass(), rbA.getInvInertiaTensorWorld()*ftorqueAxis1,normalImpulse); 553 bodyB.applyImpulse(normal*rbB.getInvMass(), rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-normalImpulse); 554 } 555 556 557 193 rbA.applyImpulse( impulse_vector, m_relPosA); 194 rbB.applyImpulse(-impulse_vector, m_relPosB); 558 195 if(m_poweredLinMotor && (!i)) 559 196 { // apply linear motor … … 581 218 // apply clamped impulse 582 219 impulse_vector = normal * normalImpulse; 583 //rbA.applyImpulse( impulse_vector, m_relPosA); 584 //rbB.applyImpulse(-impulse_vector, m_relPosB); 585 586 { 587 btVector3 ftorqueAxis1 = m_relPosA.cross(normal); 588 btVector3 ftorqueAxis2 = m_relPosB.cross(normal); 589 bodyA.applyImpulse(normal*rbA.getInvMass(), rbA.getInvInertiaTensorWorld()*ftorqueAxis1,normalImpulse); 590 bodyB.applyImpulse(normal*rbB.getInvMass(), rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-normalImpulse); 591 } 592 593 594 220 rbA.applyImpulse( impulse_vector, m_relPosA); 221 rbB.applyImpulse(-impulse_vector, m_relPosB); 595 222 } 596 223 } … … 601 228 btVector3 axisB = m_calculatedTransformB.getBasis().getColumn(0); 602 229 603 btVector3 angVelA; 604 bodyA.getAngularVelocity(angVelA); 605 btVector3 angVelB; 606 bodyB.getAngularVelocity(angVelB); 230 const btVector3& angVelA = rbA.getAngularVelocity(); 231 const btVector3& angVelB = rbB.getAngularVelocity(); 607 232 608 233 btVector3 angVelAroundAxisA = axisA * axisA.dot(angVelA); … … 614 239 //solve orthogonal angular velocity correction 615 240 btScalar len = velrelOrthog.length(); 616 btScalar orthorImpulseMag = 0.f;617 618 241 if (len > btScalar(0.00001)) 619 242 { 620 243 btVector3 normal = velrelOrthog.normalized(); 621 244 btScalar denom = rbA.computeAngularImpulseDenominator(normal) + rbB.computeAngularImpulseDenominator(normal); 622 //velrelOrthog *= (btScalar(1.)/denom) * m_dampingOrthoAng * m_softnessOrthoAng; 623 orthorImpulseMag = (btScalar(1.)/denom) * m_dampingOrthoAng * m_softnessOrthoAng; 245 velrelOrthog *= (btScalar(1.)/denom) * m_dampingOrthoAng * m_softnessOrthoAng; 624 246 } 625 247 //solve angular positional correction 626 248 btVector3 angularError = axisA.cross(axisB) *(btScalar(1.)/m_timeStep); 627 btVector3 angularAxis = angularError;628 btScalar angularImpulseMag = 0;629 630 249 btScalar len2 = angularError.length(); 631 250 if (len2>btScalar(0.00001)) … … 633 252 btVector3 normal2 = angularError.normalized(); 634 253 btScalar denom2 = rbA.computeAngularImpulseDenominator(normal2) + rbB.computeAngularImpulseDenominator(normal2); 635 angularImpulseMag = (btScalar(1.)/denom2) * m_restitutionOrthoAng * m_softnessOrthoAng; 636 angularError *= angularImpulseMag; 254 angularError *= (btScalar(1.)/denom2) * m_restitutionOrthoAng * m_softnessOrthoAng; 637 255 } 638 256 // apply impulse 639 //rbA.applyTorqueImpulse(-velrelOrthog+angularError); 640 //rbB.applyTorqueImpulse(velrelOrthog-angularError); 641 642 bodyA.applyImpulse(btVector3(0,0,0), rbA.getInvInertiaTensorWorld()*velrelOrthog,-orthorImpulseMag); 643 bodyB.applyImpulse(btVector3(0,0,0), rbB.getInvInertiaTensorWorld()*velrelOrthog,orthorImpulseMag); 644 bodyA.applyImpulse(btVector3(0,0,0), rbA.getInvInertiaTensorWorld()*angularAxis,angularImpulseMag); 645 bodyB.applyImpulse(btVector3(0,0,0), rbB.getInvInertiaTensorWorld()*angularAxis,-angularImpulseMag); 646 647 257 rbA.applyTorqueImpulse(-velrelOrthog+angularError); 258 rbB.applyTorqueImpulse(velrelOrthog-angularError); 648 259 btScalar impulseMag; 649 260 //solve angular limits … … 659 270 } 660 271 btVector3 impulse = axisA * impulseMag; 661 //rbA.applyTorqueImpulse(impulse); 662 //rbB.applyTorqueImpulse(-impulse); 663 664 bodyA.applyImpulse(btVector3(0,0,0), rbA.getInvInertiaTensorWorld()*axisA,impulseMag); 665 bodyB.applyImpulse(btVector3(0,0,0), rbB.getInvInertiaTensorWorld()*axisA,-impulseMag); 666 667 668 272 rbA.applyTorqueImpulse(impulse); 273 rbB.applyTorqueImpulse(-impulse); 669 274 //apply angular motor 670 275 if(m_poweredAngMotor) … … 697 302 // apply clamped impulse 698 303 btVector3 motorImp = angImpulse * axisA; 699 //rbA.applyTorqueImpulse(motorImp); 700 //rbB.applyTorqueImpulse(-motorImp); 701 702 bodyA.applyImpulse(btVector3(0,0,0), rbA.getInvInertiaTensorWorld()*axisA,angImpulse); 703 bodyB.applyImpulse(btVector3(0,0,0), rbB.getInvInertiaTensorWorld()*axisA,-angImpulse); 304 m_rbA.applyTorqueImpulse(motorImp); 305 m_rbB.applyTorqueImpulse(-motorImp); 704 306 } 705 307 } … … 711 313 712 314 void btSliderConstraint::calculateTransforms(void){ 713 if(m_useLinearReferenceFrameA || (!m_useSolveConstraintObsolete))315 if(m_useLinearReferenceFrameA) 714 316 { 715 317 m_calculatedTransformA = m_rbA.getCenterOfMassTransform() * m_frameInA; … … 724 326 m_realPivotBInW = m_calculatedTransformB.getOrigin(); 725 327 m_sliderAxis = m_calculatedTransformA.getBasis().getColumn(0); // along X 726 if(m_useLinearReferenceFrameA || m_useSolveConstraintObsolete) 727 { 728 m_delta = m_realPivotBInW - m_realPivotAInW; 729 } 730 else 731 { 732 m_delta = m_realPivotAInW - m_realPivotBInW; 733 } 328 m_delta = m_realPivotBInW - m_realPivotAInW; 734 329 m_projPivotInW = m_realPivotAInW + m_sliderAxis.dot(m_delta) * m_sliderAxis; 735 330 btVector3 normalWorld; … … 773 368 774 369 //----------------------------------------------------------------------------- 370 775 371 776 372 void btSliderConstraint::testAngLimits(void) … … 784 380 const btVector3 axisB0 = m_calculatedTransformB.getBasis().getColumn(1); 785 381 btScalar rot = btAtan2Fast(axisB0.dot(axisA1), axisB0.dot(axisA0)); 786 m_angPos = rot;787 382 if(rot < m_lowerAngLimit) 788 383 { … … 797 392 } 798 393 } // btSliderConstraint::testAngLimits() 394 799 395 800 396 //----------------------------------------------------------------------------- 397 398 801 399 802 400 btVector3 btSliderConstraint::getAncorInA(void) -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h
r2907 r2908 47 47 { 48 48 protected: 49 ///for backwards compatibility during the transition to 'getInfo/getInfo2'50 bool m_useSolveConstraintObsolete;51 49 btTransform m_frameInA; 52 50 btTransform m_frameInB; … … 107 105 108 106 btScalar m_linPos; 109 btScalar m_angPos;110 107 111 108 btScalar m_angDepth; … … 130 127 // overrides 131 128 virtual void buildJacobian(); 132 virtual void getInfo1 (btConstraintInfo1* info); 133 134 virtual void getInfo2 (btConstraintInfo2* info); 135 136 virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep); 137 138 129 virtual void solveConstraint(btScalar timeStep); 139 130 // access 140 131 const btRigidBody& getRigidBodyA() const { return m_rbA; } … … 204 195 btScalar getMaxAngMotorForce() { return m_maxAngMotorForce; } 205 196 btScalar getLinearPos() { return m_linPos; } 206 207 197 208 198 // access for ODE solver … … 213 203 // internal 214 204 void buildJacobianInt(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB); 215 void solveConstraintInt(btRigidBody& rbA, bt SolverBody& bodyA,btRigidBody& rbB, btSolverBody& bodyB);205 void solveConstraintInt(btRigidBody& rbA, btRigidBody& rbB); 216 206 // shared code used by ODE solver 217 207 void calculateTransforms(void); 218 208 void testLinLimits(void); 219 void testLinLimits2(btConstraintInfo2* info);220 209 void testAngLimits(void); 221 210 // access for PE Solver -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btSolverBody.h
r2907 r2908 24 24 #include "LinearMath/btTransformUtil.h" 25 25 26 ///Until we get other contributions, only use SIMD on Windows, when using Visual Studio 2008 or later, and not double precision27 #ifdef BT_USE_SSE28 #define USE_SIMD 129 #endif //30 31 32 #ifdef USE_SIMD33 34 struct btSimdScalar35 {36 SIMD_FORCE_INLINE btSimdScalar()37 {38 39 }40 41 SIMD_FORCE_INLINE btSimdScalar(float fl)42 :m_vec128 (_mm_set1_ps(fl))43 {44 }45 46 SIMD_FORCE_INLINE btSimdScalar(__m128 v128)47 :m_vec128(v128)48 {49 }50 union51 {52 __m128 m_vec128;53 float m_floats[4];54 int m_ints[4];55 btScalar m_unusedPadding;56 };57 SIMD_FORCE_INLINE __m128 get128()58 {59 return m_vec128;60 }61 62 SIMD_FORCE_INLINE const __m128 get128() const63 {64 return m_vec128;65 }66 67 SIMD_FORCE_INLINE void set128(__m128 v128)68 {69 m_vec128 = v128;70 }71 72 SIMD_FORCE_INLINE operator __m128()73 {74 return m_vec128;75 }76 SIMD_FORCE_INLINE operator const __m128() const77 {78 return m_vec128;79 }80 81 SIMD_FORCE_INLINE operator float() const82 {83 return m_floats[0];84 }85 86 };87 88 ///@brief Return the elementwise product of two btSimdScalar89 SIMD_FORCE_INLINE btSimdScalar90 operator*(const btSimdScalar& v1, const btSimdScalar& v2)91 {92 return btSimdScalar(_mm_mul_ps(v1.get128(),v2.get128()));93 }94 95 ///@brief Return the elementwise product of two btSimdScalar96 SIMD_FORCE_INLINE btSimdScalar97 operator+(const btSimdScalar& v1, const btSimdScalar& v2)98 {99 return btSimdScalar(_mm_add_ps(v1.get128(),v2.get128()));100 }101 102 103 #else104 #define btSimdScalar btScalar105 #endif106 26 107 27 ///The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance. … … 109 29 { 110 30 BT_DECLARE_ALIGNED_ALLOCATOR(); 111 btVector3 m_deltaLinearVelocity; 112 btVector3 m_deltaAngularVelocity; 113 btScalar m_angularFactor; 114 btScalar m_invMass; 115 btScalar m_friction; 31 32 btMatrix3x3 m_worldInvInertiaTensor; 33 34 btVector3 m_angularVelocity; 35 btVector3 m_linearVelocity; 36 btVector3 m_centerOfMassPosition; 37 btVector3 m_pushVelocity; 38 btVector3 m_turnVelocity; 39 40 float m_angularFactor; 41 float m_invMass; 42 float m_friction; 116 43 btRigidBody* m_originalBody; 117 btVector3 m_pushVelocity;118 //btVector3 m_turnVelocity;119 120 44 121 SIMD_FORCE_INLINE void getVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity ) const 45 46 SIMD_FORCE_INLINE void getVelocityInLocalPoint(const btVector3& rel_pos, btVector3& velocity ) const 122 47 { 123 if (m_originalBody) 124 velocity = m_originalBody->getLinearVelocity()+m_deltaLinearVelocity + (m_originalBody->getAngularVelocity()+m_deltaAngularVelocity).cross(rel_pos); 125 else 126 velocity.setValue(0,0,0); 48 velocity = m_linearVelocity + m_angularVelocity.cross(rel_pos); 127 49 } 128 50 129 SIMD_FORCE_INLINE void getAngularVelocity(btVector3& angVel) const 51 //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position 52 SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude) 130 53 { 131 if (m_originalBody) 132 angVel = m_originalBody->getAngularVelocity()+m_deltaAngularVelocity; 133 else 134 angVel.setValue(0,0,0); 54 if (m_invMass) 55 { 56 m_linearVelocity += linearComponent*impulseMagnitude; 57 m_angularVelocity += angularComponent*(impulseMagnitude*m_angularFactor); 58 } 135 59 } 136 137 138 //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position 139 SIMD_FORCE_INLINE void applyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,const btScalar impulseMagnitude) 60 61 SIMD_FORCE_INLINE void internalApplyPushImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude) 140 62 { 141 //if (m_invMass)63 if (m_invMass) 142 64 { 143 m_ deltaLinearVelocity += linearComponent*impulseMagnitude;144 m_ deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor);65 m_pushVelocity += linearComponent*impulseMagnitude; 66 m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor); 145 67 } 146 68 } 147 69 148 149 /*150 70 151 71 void writebackVelocity() … … 153 73 if (m_invMass) 154 74 { 155 m_originalBody->setLinearVelocity(m_ originalBody->getLinearVelocity()+ m_deltaLinearVelocity);156 m_originalBody->setAngularVelocity(m_ originalBody->getAngularVelocity()+m_deltaAngularVelocity);75 m_originalBody->setLinearVelocity(m_linearVelocity); 76 m_originalBody->setAngularVelocity(m_angularVelocity); 157 77 158 78 //m_originalBody->setCompanionId(-1); 159 79 } 160 80 } 161 */81 162 82 163 void writebackVelocity(btScalar timeStep =0)83 void writebackVelocity(btScalar timeStep) 164 84 { 165 85 if (m_invMass) 166 86 { 167 m_originalBody->setLinearVelocity(m_originalBody->getLinearVelocity()+m_deltaLinearVelocity); 168 m_originalBody->setAngularVelocity(m_originalBody->getAngularVelocity()+m_deltaAngularVelocity); 87 m_originalBody->setLinearVelocity(m_linearVelocity); 88 m_originalBody->setAngularVelocity(m_angularVelocity); 89 90 //correct the position/orientation based on push/turn recovery 91 btTransform newTransform; 92 btTransformUtil::integrateTransform(m_originalBody->getWorldTransform(),m_pushVelocity,m_turnVelocity,timeStep,newTransform); 93 m_originalBody->setWorldTransform(newTransform); 94 169 95 //m_originalBody->setCompanionId(-1); 170 96 } 171 97 } 98 99 void readVelocity() 100 { 101 if (m_invMass) 102 { 103 m_linearVelocity = m_originalBody->getLinearVelocity(); 104 m_angularVelocity = m_originalBody->getAngularVelocity(); 105 } 106 } 107 172 108 173 109 -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btSolverConstraint.h
r2907 r2908 20 20 #include "LinearMath/btVector3.h" 21 21 #include "LinearMath/btMatrix3x3.h" 22 #include "btJacobianEntry.h"23 22 24 23 //#define NO_FRICTION_TANGENTIALS 1 25 #include "btSolverBody.h"26 27 24 28 25 ///1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and friction constraints. … … 31 28 BT_DECLARE_ALIGNED_ALLOCATOR(); 32 29 33 btVector3 34 btVector3 30 btVector3 m_relpos1CrossNormal; 31 btVector3 m_contactNormal; 35 32 36 btVector3 37 //btVector3 m_contactNormal2;//usually m_contactNormal2 == -m_contactNormal33 btVector3 m_relpos2CrossNormal; 34 btVector3 m_angularComponentA; 38 35 39 btVector3 m_angularComponentA; 40 btVector3 m_angularComponentB; 36 btVector3 m_angularComponentB; 37 38 mutable btScalar m_appliedPushImpulse; 41 39 42 mutable btS imdScalar m_appliedPushImpulse;43 mutable btSimdScalar m_appliedImpulse;44 40 mutable btScalar m_appliedImpulse; 41 int m_solverBodyIdA; 42 int m_solverBodyIdB; 45 43 46 44 btScalar m_friction; 45 btScalar m_restitution; 47 46 btScalar m_jacDiagABInv; 48 union 49 { 50 int m_numConsecutiveRowsPerKernel; 51 btScalar m_unusedPadding0; 52 }; 47 btScalar m_penetration; 48 53 49 54 union55 {56 int m_frictionIndex;57 btScalar m_unusedPadding1;58 };59 union60 {61 int m_solverBodyIdA;62 btScalar m_unusedPadding2;63 };64 union65 {66 int m_solverBodyIdB;67 btScalar m_unusedPadding3;68 };69 50 70 union 71 { 72 void* m_originalContactPoint; 73 btScalar m_unusedPadding4; 74 }; 51 int m_constraintType; 52 int m_frictionIndex; 53 void* m_originalContactPoint; 54 int m_unusedPadding[1]; 75 55 76 btScalar m_rhs;77 btScalar m_cfm;78 btScalar m_lowerLimit;79 btScalar m_upperLimit;80 56 81 57 enum btSolverConstraintType … … 86 62 }; 87 63 88 typedef btAlignedObjectArray<btSolverConstraint> btConstraintArray; 64 65 66 89 67 90 68 -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
r2907 r2908 20 20 static btRigidBody s_fixed(0, 0,0); 21 21 22 #define DEFAULT_DEBUGDRAW_SIZE btScalar(0.3f)23 24 22 btTypedConstraint::btTypedConstraint(btTypedConstraintType type) 25 23 :m_userConstraintType(-1), … … 28 26 m_rbA(s_fixed), 29 27 m_rbB(s_fixed), 30 m_appliedImpulse(btScalar(0.)), 31 m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE) 28 m_appliedImpulse(btScalar(0.)) 32 29 { 33 30 s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); … … 39 36 m_rbA(rbA), 40 37 m_rbB(s_fixed), 41 m_appliedImpulse(btScalar(0.)), 42 m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE) 38 m_appliedImpulse(btScalar(0.)) 43 39 { 44 40 s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); … … 53 49 m_rbA(rbA), 54 50 m_rbB(rbB), 55 m_appliedImpulse(btScalar(0.)), 56 m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE) 51 m_appliedImpulse(btScalar(0.)) 57 52 { 58 53 s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); … … 60 55 } 61 56 62 63 //-----------------------------------------------------------------------------64 65 btScalar btTypedConstraint::getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact)66 {67 if(lowLim > uppLim)68 {69 return btScalar(1.0f);70 }71 else if(lowLim == uppLim)72 {73 return btScalar(0.0f);74 }75 btScalar lim_fact = btScalar(1.0f);76 btScalar delta_max = vel / timeFact;77 if(delta_max < btScalar(0.0f))78 {79 if((pos >= lowLim) && (pos < (lowLim - delta_max)))80 {81 lim_fact = (lowLim - pos) / delta_max;82 }83 else if(pos < lowLim)84 {85 lim_fact = btScalar(0.0f);86 }87 else88 {89 lim_fact = btScalar(1.0f);90 }91 }92 else if(delta_max > btScalar(0.0f))93 {94 if((pos <= uppLim) && (pos > (uppLim - delta_max)))95 {96 lim_fact = (uppLim - pos) / delta_max;97 }98 else if(pos > uppLim)99 {100 lim_fact = btScalar(0.0f);101 }102 else103 {104 lim_fact = btScalar(1.0f);105 }106 }107 else108 {109 lim_fact = btScalar(0.0f);110 }111 return lim_fact;112 } // btTypedConstraint::getMotorFactor()113 114 -
code/branches/questsystem5/src/bullet/BulletDynamics/ConstraintSolver/btTypedConstraint.h
r2907 r2908 19 19 class btRigidBody; 20 20 #include "LinearMath/btScalar.h" 21 #include "btSolverConstraint.h"22 struct btSolverBody;23 24 25 26 21 27 22 enum btTypedConstraintType … … 31 26 CONETWIST_CONSTRAINT_TYPE, 32 27 D6_CONSTRAINT_TYPE, 28 VEHICLE_CONSTRAINT_TYPE, 33 29 SLIDER_CONSTRAINT_TYPE 34 30 }; … … 53 49 btRigidBody& m_rbB; 54 50 btScalar m_appliedImpulse; 55 btScalar m_dbgDrawSize;56 51 57 52 … … 61 56 virtual ~btTypedConstraint() {}; 62 57 btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA); 58 63 59 btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB); 64 65 struct btConstraintInfo1 {66 int m_numConstraintRows,nub;67 };68 69 struct btConstraintInfo2 {70 // integrator parameters: frames per second (1/stepsize), default error71 // reduction parameter (0..1).72 btScalar fps,erp;73 74 // for the first and second body, pointers to two (linear and angular)75 // n*3 jacobian sub matrices, stored by rows. these matrices will have76 // been initialized to 0 on entry. if the second body is zero then the77 // J2xx pointers may be 0.78 btScalar *m_J1linearAxis,*m_J1angularAxis,*m_J2linearAxis,*m_J2angularAxis;79 80 // elements to jump from one row to the next in J's81 int rowskip;82 83 // right hand sides of the equation J*v = c + cfm * lambda. cfm is the84 // "constraint force mixing" vector. c is set to zero on entry, cfm is85 // set to a constant value (typically very small or zero) value on entry.86 btScalar *m_constraintError,*cfm;87 88 // lo and hi limits for variables (set to -/+ infinity on entry).89 btScalar *m_lowerLimit,*m_upperLimit;90 91 // findex vector for variables. see the LCP solver interface for a92 // description of what this does. this is set to -1 on entry.93 // note that the returned indexes are relative to the first index of94 // the constraint.95 int *findex;96 };97 98 60 99 61 virtual void buildJacobian() = 0; 100 62 101 virtual void setupSolverConstraint(btConstraintArray& ca, int solverBodyA,int solverBodyB, btScalar timeStep) 102 { 103 } 104 virtual void getInfo1 (btConstraintInfo1* info)=0; 63 virtual void solveConstraint(btScalar timeStep) = 0; 105 64 106 virtual void getInfo2 (btConstraintInfo2* info)=0;107 108 virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) = 0;109 110 btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact);111 112 65 const btRigidBody& getRigidBodyA() const 113 66 { … … 142 95 m_userConstraintId = uid; 143 96 } 144 97 145 98 int getUserConstraintId() const 146 99 { … … 162 115 return m_constraintType; 163 116 } 164 165 void setDbgDrawSize(btScalar dbgDrawSize) 166 { 167 m_dbgDrawSize = dbgDrawSize; 168 } 169 btScalar getDbgDrawSize() 170 { 171 return m_dbgDrawSize; 172 } 173 117 174 118 }; 175 119 -
code/branches/questsystem5/src/bullet/BulletDynamics/Dynamics/Bullet-C-API.cpp
r2907 r2908 111 111 { 112 112 btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); 113 btAssert(dynamicsWorld);113 assert(dynamicsWorld); 114 114 dynamicsWorld->stepSimulation(timeStep); 115 115 } … … 118 118 { 119 119 btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); 120 btAssert(dynamicsWorld);121 btRigidBody* body = reinterpret_cast< btRigidBody* >(object); 122 btAssert(body);120 assert(dynamicsWorld); 121 btRigidBody* body = reinterpret_cast< btRigidBody* >(object); 122 assert(body); 123 123 124 124 dynamicsWorld->addRigidBody(body); … … 128 128 { 129 129 btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world); 130 btAssert(dynamicsWorld);131 btRigidBody* body = reinterpret_cast< btRigidBody* >(object); 132 btAssert(body);130 assert(dynamicsWorld); 131 btRigidBody* body = reinterpret_cast< btRigidBody* >(object); 132 assert(body); 133 133 134 134 dynamicsWorld->removeRigidBody(body); … … 143 143 btVector3 localInertia(0,0,0); 144 144 btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape); 145 btAssert(shape);145 assert(shape); 146 146 if (mass) 147 147 { … … 159 159 { 160 160 btRigidBody* body = reinterpret_cast< btRigidBody* >(cbody); 161 btAssert(body);161 assert(body); 162 162 btAlignedFree( body); 163 163 } … … 263 263 { 264 264 btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape); 265 btAssert(shape);265 assert(shape); 266 266 btAlignedFree(shape); 267 267 } … … 269 269 { 270 270 btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape); 271 btAssert(shape);271 assert(shape); 272 272 btVector3 scaling(cscaling[0],cscaling[1],cscaling[2]); 273 273 shape->setLocalScaling(scaling); -
code/branches/questsystem5/src/bullet/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp
r2907 r2908 91 91 92 92 ///update vehicle simulation 93 updateActions(timeStep); 93 updateVehicles(timeStep); 94 94 95 95 96 updateActivationState( timeStep ); -
code/branches/questsystem5/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
r2907 r2908 30 30 #include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" 31 31 #include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" 32 #include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"33 #include "BulletDynamics/ConstraintSolver/btHingeConstraint.h"34 #include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h"35 #include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h"36 #include "BulletDynamics/ConstraintSolver/btSliderConstraint.h"37 32 38 33 //for debug rendering … … 52 47 53 48 54 #include "BulletDynamics/Dynamics/btActionInterface.h" 49 50 //vehicle 51 #include "BulletDynamics/Vehicle/btRaycastVehicle.h" 52 #include "BulletDynamics/Vehicle/btVehicleRaycaster.h" 53 #include "BulletDynamics/Vehicle/btWheelInfo.h" 54 //character 55 #include "BulletDynamics/Character/btCharacterControllerInterface.h" 56 57 #include "LinearMath/btIDebugDraw.h" 55 58 #include "LinearMath/btQuickprof.h" 56 59 #include "LinearMath/btMotionState.h" … … 111 114 if (body) 112 115 { 116 btTransform predictedTrans; 113 117 if (body->getActivationState() != ISLAND_SLEEPING) 114 118 { … … 145 149 } 146 150 } 147 bool drawConstraints = false;148 if (getDebugDrawer())149 {150 int mode = getDebugDrawer()->getDebugMode();151 if(mode & (btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits))152 {153 drawConstraints = true;154 }155 }156 if(drawConstraints)157 {158 for(int i = getNumConstraints()-1; i>=0 ;i--)159 {160 btTypedConstraint* constraint = getConstraint(i);161 debugDrawConstraint(constraint);162 }163 }164 165 151 166 152 … … 205 191 } 206 192 207 if (getDebugDrawer() && getDebugDrawer()->getDebugMode()) 208 { 209 for (i=0;i<m_actions.size();i++) 210 { 211 m_actions[i]->debugDraw(m_debugDrawer); 193 for ( i=0;i<this->m_vehicles.size();i++) 194 { 195 for (int v=0;v<m_vehicles[i]->getNumWheels();v++) 196 { 197 btVector3 wheelColor(0,255,255); 198 if (m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_isInContact) 199 { 200 wheelColor.setValue(0,0,255); 201 } else 202 { 203 wheelColor.setValue(255,0,255); 204 } 205 206 btVector3 wheelPosWS = m_vehicles[i]->getWheelInfo(v).m_worldTransform.getOrigin(); 207 208 btVector3 axle = btVector3( 209 m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[0][m_vehicles[i]->getRightAxis()], 210 m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[1][m_vehicles[i]->getRightAxis()], 211 m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[2][m_vehicles[i]->getRightAxis()]); 212 213 214 //m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_wheelAxleWS 215 //debug wheels (cylinders) 216 m_debugDrawer->drawLine(wheelPosWS,wheelPosWS+axle,wheelColor); 217 m_debugDrawer->drawLine(wheelPosWS,m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_contactPointWS,wheelColor); 218 212 219 } 213 220 } … … 281 288 } 282 289 } 283 /* 290 284 291 if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe) 285 292 { … … 293 300 } 294 301 } 295 */296 297 302 298 303 } … … 335 340 if (getDebugDrawer()) 336 341 { 337 btIDebugDraw* debugDrawer = getDebugDrawer (); 338 gDisableDeactivation = (debugDrawer->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0; 342 gDisableDeactivation = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0; 339 343 } 340 344 if (numSimulationSubSteps) … … 400 404 401 405 ///update vehicle simulation 402 updateActions(timeStep); 403 406 updateVehicles(timeStep); 407 408 updateCharacters(timeStep); 409 404 410 updateActivationState( timeStep ); 405 411 … … 465 471 466 472 467 void btDiscreteDynamicsWorld::updateActions(btScalar timeStep) 468 { 469 BT_PROFILE("updateActions"); 470 471 for ( int i=0;i<m_actions.size();i++) 472 { 473 m_actions[i]->updateAction( this, timeStep); 474 } 475 } 473 void btDiscreteDynamicsWorld::updateVehicles(btScalar timeStep) 474 { 475 BT_PROFILE("updateVehicles"); 476 477 for ( int i=0;i<m_vehicles.size();i++) 478 { 479 btRaycastVehicle* vehicle = m_vehicles[i]; 480 vehicle->updateVehicle( timeStep); 481 } 482 } 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 476 496 477 497 … … 530 550 } 531 551 532 void btDiscreteDynamicsWorld::addAction(btActionInterface* action) 533 { 534 m_actions.push_back(action); 535 } 536 537 void btDiscreteDynamicsWorld::removeAction(btActionInterface* action) 538 { 539 m_actions.remove(action); 540 } 541 542 543 void btDiscreteDynamicsWorld::addVehicle(btActionInterface* vehicle) 544 { 545 addAction(vehicle); 546 } 547 548 void btDiscreteDynamicsWorld::removeVehicle(btActionInterface* vehicle) 549 { 550 removeAction(vehicle); 551 } 552 553 void btDiscreteDynamicsWorld::addCharacter(btActionInterface* character) 554 { 555 addAction(character); 556 } 557 558 void btDiscreteDynamicsWorld::removeCharacter(btActionInterface* character) 559 { 560 removeAction(character); 552 void btDiscreteDynamicsWorld::addVehicle(btRaycastVehicle* vehicle) 553 { 554 m_vehicles.push_back(vehicle); 555 } 556 557 void btDiscreteDynamicsWorld::removeVehicle(btRaycastVehicle* vehicle) 558 { 559 m_vehicles.remove(vehicle); 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); 561 570 } 562 571 … … 634 643 if (islandId<0) 635 644 { 636 if (numManifolds + m_numConstraints) 637 { 638 ///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id 639 m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher); 640 } 645 ///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id 646 m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher); 641 647 } else 642 648 { … … 684 690 } 685 691 686 // btAssert(0);692 // assert(0); 687 693 688 694 … … 748 754 btScalar m_allowedPenetration; 749 755 btOverlappingPairCache* m_pairCache; 750 btDispatcher* m_dispatcher;751 756 752 757 753 758 public: 754 btClosestNotMeConvexResultCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache ,btDispatcher* dispatcher) :759 btClosestNotMeConvexResultCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache) : 755 760 btCollisionWorld::ClosestConvexResultCallback(fromA,toA), 756 761 m_allowedPenetration(0.0f), 757 762 m_me(me), 758 m_pairCache(pairCache), 759 m_dispatcher(dispatcher) 763 m_pairCache(pairCache) 760 764 { 761 765 } … … 792 796 return false; 793 797 794 btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject; 795 796 //call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179 797 if (m_dispatcher->needsResponse(m_me,otherObj)) 798 { 799 ///don't do CCD when there are already contact points (touching contact/penetration) 800 btAlignedObjectArray<btPersistentManifold*> manifoldArray; 801 btBroadphasePair* collisionPair = m_pairCache->findPair(m_me->getBroadphaseHandle(),proxy0); 802 if (collisionPair) 803 { 804 if (collisionPair->m_algorithm) 805 { 806 manifoldArray.resize(0); 807 collisionPair->m_algorithm->getAllContactManifolds(manifoldArray); 808 for (int j=0;j<manifoldArray.size();j++) 809 { 810 btPersistentManifold* manifold = manifoldArray[j]; 811 if (manifold->getNumContacts()>0) 812 return false; 813 } 798 ///don't do CCD when there are already contact points (touching contact/penetration) 799 btAlignedObjectArray<btPersistentManifold*> manifoldArray; 800 btBroadphasePair* collisionPair = m_pairCache->findPair(m_me->getBroadphaseHandle(),proxy0); 801 if (collisionPair) 802 { 803 if (collisionPair->m_algorithm) 804 { 805 manifoldArray.resize(0); 806 collisionPair->m_algorithm->getAllContactManifolds(manifoldArray); 807 for (int j=0;j<manifoldArray.size();j++) 808 { 809 btPersistentManifold* manifold = manifoldArray[j]; 810 if (manifold->getNumContacts()>0) 811 return false; 814 812 } 815 813 } … … 849 847 gNumClampedCcdMotions++; 850 848 851 btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache() ,getDispatcher());849 btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache()); 852 850 btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape()); 853 851 btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape()); … … 1190 1188 1191 1189 1192 void btDiscreteDynamicsWorld::debugDrawConstraint(btTypedConstraint* constraint)1193 {1194 bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0;1195 bool drawLimits = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraintLimits) != 0;1196 btScalar dbgDrawSize = constraint->getDbgDrawSize();1197 if(dbgDrawSize <= btScalar(0.f))1198 {1199 return;1200 }1201 1202 switch(constraint->getConstraintType())1203 {1204 case POINT2POINT_CONSTRAINT_TYPE:1205 {1206 btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint;1207 btTransform tr;1208 tr.setIdentity();1209 btVector3 pivot = p2pC->getPivotInA();1210 pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot;1211 tr.setOrigin(pivot);1212 getDebugDrawer()->drawTransform(tr, dbgDrawSize);1213 // that ideally should draw the same frame1214 pivot = p2pC->getPivotInB();1215 pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot;1216 tr.setOrigin(pivot);1217 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);1218 }1219 break;1220 case HINGE_CONSTRAINT_TYPE:1221 {1222 btHingeConstraint* pHinge = (btHingeConstraint*)constraint;1223 btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame();1224 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);1225 tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame();1226 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);1227 btScalar minAng = pHinge->getLowerLimit();1228 btScalar maxAng = pHinge->getUpperLimit();1229 if(minAng == maxAng)1230 {1231 break;1232 }1233 bool drawSect = true;1234 if(minAng > maxAng)1235 {1236 minAng = btScalar(0.f);1237 maxAng = SIMD_2_PI;1238 drawSect = false;1239 }1240 if(drawLimits)1241 {1242 btVector3& center = tr.getOrigin();1243 btVector3 normal = tr.getBasis().getColumn(2);1244 btVector3 axis = tr.getBasis().getColumn(0);1245 getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0,0,0), drawSect);1246 }1247 }1248 break;1249 case CONETWIST_CONSTRAINT_TYPE:1250 {1251 btConeTwistConstraint* pCT = (btConeTwistConstraint*)constraint;1252 btTransform tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();1253 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);1254 tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();1255 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);1256 if(drawLimits)1257 {1258 //const btScalar length = btScalar(5);1259 const btScalar length = dbgDrawSize;1260 static int nSegments = 8*4;1261 btScalar fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)(nSegments-1)/btScalar(nSegments);1262 btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length);1263 pPrev = tr * pPrev;1264 for (int i=0; i<nSegments; i++)1265 {1266 fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)i/btScalar(nSegments);1267 btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length);1268 pCur = tr * pCur;1269 getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0,0,0));1270 1271 if (i%(nSegments/8) == 0)1272 getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0,0,0));1273 1274 pPrev = pCur;1275 }1276 btScalar tws = pCT->getTwistSpan();1277 btScalar twa = pCT->getTwistAngle();1278 bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f));1279 if(useFrameB)1280 {1281 tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();1282 }1283 else1284 {1285 tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();1286 }1287 btVector3 pivot = tr.getOrigin();1288 btVector3 normal = tr.getBasis().getColumn(0);1289 btVector3 axis1 = tr.getBasis().getColumn(1);1290 getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa-tws, -twa+tws, btVector3(0,0,0), true);1291 1292 }1293 }1294 break;1295 case D6_CONSTRAINT_TYPE:1296 {1297 btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)constraint;1298 btTransform tr = p6DOF->getCalculatedTransformA();1299 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);1300 tr = p6DOF->getCalculatedTransformB();1301 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);1302 if(drawLimits)1303 {1304 tr = p6DOF->getCalculatedTransformA();1305 const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();1306 btVector3 up = tr.getBasis().getColumn(2);1307 btVector3 axis = tr.getBasis().getColumn(0);1308 btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;1309 btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;1310 btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;1311 btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;1312 getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0,0,0));1313 axis = tr.getBasis().getColumn(1);1314 btScalar ay = p6DOF->getAngle(1);1315 btScalar az = p6DOF->getAngle(2);1316 btScalar cy = btCos(ay);1317 btScalar sy = btSin(ay);1318 btScalar cz = btCos(az);1319 btScalar sz = btSin(az);1320 btVector3 ref;1321 ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2];1322 ref[1] = -sz*axis[0] + cz*axis[1];1323 ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2];1324 tr = p6DOF->getCalculatedTransformB();1325 btVector3 normal = -tr.getBasis().getColumn(0);1326 btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;1327 btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;1328 if(minFi > maxFi)1329 {1330 getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0,0,0), false);1331 }1332 else if(minFi < maxFi)1333 {1334 getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0,0,0), true);1335 }1336 tr = p6DOF->getCalculatedTransformA();1337 btVector3 bbMin = p6DOF->getTranslationalLimitMotor()->m_lowerLimit;1338 btVector3 bbMax = p6DOF->getTranslationalLimitMotor()->m_upperLimit;1339 getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0,0,0));1340 }1341 }1342 break;1343 case SLIDER_CONSTRAINT_TYPE:1344 {1345 btSliderConstraint* pSlider = (btSliderConstraint*)constraint;1346 btTransform tr = pSlider->getCalculatedTransformA();1347 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);1348 tr = pSlider->getCalculatedTransformB();1349 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);1350 if(drawLimits)1351 {1352 btTransform tr = pSlider->getCalculatedTransformA();1353 btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f);1354 btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f);1355 getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0));1356 btVector3 normal = tr.getBasis().getColumn(0);1357 btVector3 axis = tr.getBasis().getColumn(1);1358 btScalar a_min = pSlider->getLowerAngLimit();1359 btScalar a_max = pSlider->getUpperAngLimit();1360 const btVector3& center = pSlider->getCalculatedTransformB().getOrigin();1361 getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0,0,0), true);1362 }1363 }1364 break;1365 default :1366 break;1367 }1368 return;1369 } // btDiscreteDynamicsWorld::debugDrawConstraint()1370 1371 1372 1373 1374 1375 1190 void btDiscreteDynamicsWorld::setConstraintSolver(btConstraintSolver* solver) 1376 1191 { … … 1401 1216 return m_constraints[index]; 1402 1217 } 1403 1404 -
code/branches/questsystem5/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
r2907 r2908 24 24 class btSimulationIslandManager; 25 25 class btTypedConstraint; 26 class btActionInterface;27 26 27 28 class btRaycastVehicle; 29 class btCharacterControllerInterface; 28 30 class btIDebugDraw; 29 31 #include "LinearMath/btAlignedObjectArray.h" … … 51 53 bool m_ownsConstraintSolver; 52 54 53 btAlignedObjectArray<btActionInterface*> m_actions;54 55 56 btAlignedObjectArray<btRaycastVehicle*> m_vehicles; 57 58 btAlignedObjectArray<btCharacterControllerInterface*> m_characters; 59 60 55 61 int m_profileTimings; 56 62 … … 65 71 void updateActivationState(btScalar timeStep); 66 72 67 void updateActions(btScalar timeStep); 73 void updateVehicles(btScalar timeStep); 74 75 void updateCharacters(btScalar timeStep); 68 76 69 77 void startProfiling(btScalar timeStep); … … 98 106 virtual void removeConstraint(btTypedConstraint* constraint); 99 107 100 virtual void add Action(btActionInterface*);108 virtual void addVehicle(btRaycastVehicle* vehicle); 101 109 102 virtual void remove Action(btActionInterface*);110 virtual void removeVehicle(btRaycastVehicle* vehicle); 103 111 112 virtual void addCharacter(btCharacterControllerInterface* character); 113 114 virtual void removeCharacter(btCharacterControllerInterface* character); 115 116 104 117 btSimulationIslandManager* getSimulationIslandManager() 105 118 { … … 118 131 119 132 virtual void setGravity(const btVector3& gravity); 120 121 133 virtual btVector3 getGravity () const; 122 134 … … 128 140 129 141 void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color); 130 131 void debugDrawConstraint(btTypedConstraint* constraint);132 142 133 143 virtual void debugDrawWorld(); … … 160 170 } 161 171 162 ///obsolete, use updateActions instead163 virtual void updateVehicles(btScalar timeStep)164 {165 updateActions(timeStep);166 }167 168 ///obsolete, use addAction instead169 virtual void addVehicle(btActionInterface* vehicle);170 ///obsolete, use removeAction instead171 virtual void removeVehicle(btActionInterface* vehicle);172 ///obsolete, use addAction instead173 virtual void addCharacter(btActionInterface* character);174 ///obsolete, use removeAction instead175 virtual void removeCharacter(btActionInterface* character);176 177 172 }; 178 173 -
code/branches/questsystem5/src/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h
r2907 r2908 21 21 22 22 class btTypedConstraint; 23 class bt ActionInterface;23 class btRaycastVehicle; 24 24 class btConstraintSolver; 25 25 class btDynamicsWorld; 26 26 class btCharacterControllerInterface; 27 27 28 28 /// Type for the callback for each tick … … 73 73 virtual void removeConstraint(btTypedConstraint* constraint) {(void)constraint;} 74 74 75 virtual void add Action(btActionInterface* action) = 0;75 virtual void addVehicle(btRaycastVehicle* vehicle) {(void)vehicle;} 76 76 77 virtual void removeAction(btActionInterface* action) = 0; 77 virtual void removeVehicle(btRaycastVehicle* vehicle) {(void)vehicle;} 78 79 virtual void addCharacter(btCharacterControllerInterface* character) {(void)character;} 80 81 virtual void removeCharacter(btCharacterControllerInterface* character) {(void)character;} 82 78 83 79 84 //once a rigidbody is added to the dynamics world, it will get this gravity assigned … … 125 130 126 131 127 ///obsolete, use addAction instead.128 virtual void addVehicle(btActionInterface* vehicle) {(void)vehicle;}129 ///obsolete, use removeAction instead130 virtual void removeVehicle(btActionInterface* vehicle) {(void)vehicle;}131 ///obsolete, use addAction instead.132 virtual void addCharacter(btActionInterface* character) {(void)character;}133 ///obsolete, use removeAction instead134 virtual void removeCharacter(btActionInterface* character) {(void)character;}135 136 137 132 }; 138 133 -
code/branches/questsystem5/src/bullet/BulletDynamics/Dynamics/btRigidBody.cpp
r2907 r2908 47 47 m_angularFactor = btScalar(1.); 48 48 m_gravity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); 49 m_gravity_acceleration.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));50 49 m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); 51 50 m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)), … … 126 125 m_gravity = acceleration * (btScalar(1.0) / m_inverseMass); 127 126 } 128 m_gravity_acceleration = acceleration;129 127 } 130 128 -
code/branches/questsystem5/src/bullet/BulletDynamics/Dynamics/btRigidBody.h
r2907 r2908 49 49 50 50 btVector3 m_gravity; 51 btVector3 m_gravity_acceleration;52 51 btVector3 m_invInertiaLocal; 53 52 btVector3 m_totalForce; … … 183 182 const btVector3& getGravity() const 184 183 { 185 return m_gravity _acceleration;184 return m_gravity; 186 185 } 187 186 … … 233 232 m_totalForce += force; 234 233 } 235 236 const btVector3& getTotalForce()237 {238 return m_totalForce;239 };240 241 const btVector3& getTotalTorque()242 {243 return m_totalTorque;244 };245 234 246 const btVector3& getInvInertiaDiagLocal() const235 const btVector3& getInvInertiaDiagLocal() 247 236 { 248 237 return m_invInertiaLocal; -
code/branches/questsystem5/src/bullet/BulletDynamics/Vehicle/btRaycastVehicle.cpp
r2907 r2908 20 20 #include "btWheelInfo.h" 21 21 #include "LinearMath/btMinMax.h" 22 #include "LinearMath/btIDebugDraw.h" 22 23 23 24 #include "BulletDynamics/ConstraintSolver/btContactConstraint.h" 24 25 … … 26 27 27 28 btRaycastVehicle::btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis, btVehicleRaycaster* raycaster ) 28 :m_vehicleRaycaster(raycaster), 29 : btTypedConstraint(VEHICLE_CONSTRAINT_TYPE), 30 m_vehicleRaycaster(raycaster), 29 31 m_pitchControl(btScalar(0.)) 30 32 { … … 86 88 const btTransform& btRaycastVehicle::getWheelTransformWS( int wheelIndex ) const 87 89 { 88 btAssert(wheelIndex < getNumWheels());90 assert(wheelIndex < getNumWheels()); 89 91 const btWheelInfo& wheel = m_wheelInfo[wheelIndex]; 90 92 return wheel.m_worldTransform; … … 174 176 btVehicleRaycaster::btVehicleRaycasterResult rayResults; 175 177 176 btAssert(m_vehicleRaycaster);178 assert(m_vehicleRaycaster); 177 179 178 180 void* object = m_vehicleRaycaster->castRay(source,target,rayResults); … … 358 360 void btRaycastVehicle::setSteeringValue(btScalar steering,int wheel) 359 361 { 360 btAssert(wheel>=0 && wheel < getNumWheels());362 assert(wheel>=0 && wheel < getNumWheels()); 361 363 362 364 btWheelInfo& wheelInfo = getWheelInfo(wheel); … … 374 376 void btRaycastVehicle::applyEngineForce(btScalar force, int wheel) 375 377 { 376 btAssert(wheel>=0 && wheel < getNumWheels());378 assert(wheel>=0 && wheel < getNumWheels()); 377 379 btWheelInfo& wheelInfo = getWheelInfo(wheel); 378 380 wheelInfo.m_engineForce = force; … … 703 705 704 706 705 706 void btRaycastVehicle::debugDraw(btIDebugDraw* debugDrawer)707 {708 709 for (int v=0;v<this->getNumWheels();v++)710 {711 btVector3 wheelColor(0,255,255);712 if (getWheelInfo(v).m_raycastInfo.m_isInContact)713 {714 wheelColor.setValue(0,0,255);715 } else716 {717 wheelColor.setValue(255,0,255);718 }719 720 btVector3 wheelPosWS = getWheelInfo(v).m_worldTransform.getOrigin();721 722 btVector3 axle = btVector3(723 getWheelInfo(v).m_worldTransform.getBasis()[0][getRightAxis()],724 getWheelInfo(v).m_worldTransform.getBasis()[1][getRightAxis()],725 getWheelInfo(v).m_worldTransform.getBasis()[2][getRightAxis()]);726 727 //debug wheels (cylinders)728 debugDrawer->drawLine(wheelPosWS,wheelPosWS+axle,wheelColor);729 debugDrawer->drawLine(wheelPosWS,getWheelInfo(v).m_raycastInfo.m_contactPointWS,wheelColor);730 731 }732 }733 734 735 707 void* btDefaultVehicleRaycaster::castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result) 736 708 { … … 756 728 return 0; 757 729 } 758 -
code/branches/questsystem5/src/bullet/BulletDynamics/Vehicle/btRaycastVehicle.h
r2907 r2908 18 18 #include "LinearMath/btAlignedObjectArray.h" 19 19 #include "btWheelInfo.h" 20 #include "BulletDynamics/Dynamics/btActionInterface.h"21 20 22 21 class btVehicleTuning; 23 22 24 23 ///rayCast vehicle, very special constraint that turn a rigidbody into a vehicle. 25 class btRaycastVehicle : public bt ActionInterface24 class btRaycastVehicle : public btTypedConstraint 26 25 { 27 26 … … 75 74 virtual ~btRaycastVehicle() ; 76 75 77 78 ///btActionInterface interface 79 virtual void updateAction( btCollisionWorld* collisionWorld, btScalar step) 80 { 81 updateVehicle(step); 82 } 83 84 85 ///btActionInterface interface 86 void debugDraw(btIDebugDraw* debugDrawer); 87 76 88 77 const btTransform& getChassisWorldTransform() const; 89 78 … … 91 80 92 81 virtual void updateVehicle(btScalar step); 93 94 82 95 83 void resetSuspension(); 96 84 … … 188 176 } 189 177 178 virtual void buildJacobian() 179 { 180 //not yet 181 } 182 183 virtual void solveConstraint(btScalar timeStep) 184 { 185 (void)timeStep; 186 //not yet 187 } 190 188 191 189 -
code/branches/questsystem5/src/bullet/LinearMath/btAlignedAllocator.cpp
r2907 r2908 20 20 int gTotalBytesAlignedAllocs = 0;//detect memory leaks 21 21 22 static void *btAllocDefault(size_t size)23 {24 return malloc(size);25 }26 27 static void btFreeDefault(void *ptr)28 {29 free(ptr);30 }31 32 static btAllocFunc *sAllocFunc = btAllocDefault;33 static btFreeFunc *sFreeFunc = btFreeDefault;34 35 36 37 22 #if defined (BT_HAS_ALIGNED_ALLOCATOR) 38 23 #include <malloc.h> … … 65 50 unsigned long offset; 66 51 67 real = (char *) sAllocFunc(size + sizeof(void *) + (alignment-1));52 real = (char *)malloc(size + sizeof(void *) + (alignment-1)); 68 53 if (real) { 69 54 offset = (alignment - (unsigned long)(real + sizeof(void *))) & (alignment-1); … … 82 67 if (ptr) { 83 68 real = *((void **)(ptr)-1); 84 sFreeFunc(real);69 free(real); 85 70 } 86 71 } 87 72 #endif 88 73 74 static void *btAllocDefault(size_t size) 75 { 76 return malloc(size); 77 } 78 79 static void btFreeDefault(void *ptr) 80 { 81 free(ptr); 82 } 89 83 90 84 static btAlignedAllocFunc *sAlignedAllocFunc = btAlignedAllocDefault; 91 85 static btAlignedFreeFunc *sAlignedFreeFunc = btAlignedFreeDefault; 86 static btAllocFunc *sAllocFunc = btAllocDefault; 87 static btFreeFunc *sFreeFunc = btFreeDefault; 92 88 93 89 void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc) -
code/branches/questsystem5/src/bullet/LinearMath/btAlignedAllocator.h
r2907 r2908 39 39 void btAlignedFreeInternal (void* ptr); 40 40 41 #define btAlignedAlloc( size,alignment) btAlignedAllocInternal(size,alignment)41 #define btAlignedAlloc(a,b) btAlignedAllocInternal(a,b) 42 42 #define btAlignedFree(ptr) btAlignedFreeInternal(ptr) 43 43 … … 50 50 typedef void (btFreeFunc)(void *memblock); 51 51 52 ///The developer can let all Bullet memory allocations go through a custom memory allocator, using btAlignedAllocSetCustom 52 void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc); 53 53 void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc); 54 ///If the developer has already an custom aligned allocator, then btAlignedAllocSetCustomAligned can be used. The default aligned allocator pre-allocates extra memory using the non-aligned allocator, and instruments it.55 void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc);56 57 54 58 55 ///The btAlignedAllocator is a portable class for aligned memory allocations. -
code/branches/questsystem5/src/bullet/LinearMath/btAlignedObjectArray.h
r2907 r2908 59 59 return (size ? size*2 : 1); 60 60 } 61 SIMD_FORCE_INLINE void copy(int start,int end, T* dest) const61 SIMD_FORCE_INLINE void copy(int start,int end, T* dest) 62 62 { 63 63 int i; … … 121 121 } 122 122 123 ///Generally it is best to avoid using the copy constructor of an btAlignedObjectArray, and use a (const) reference to the array instead. 124 btAlignedObjectArray(const btAlignedObjectArray& otherArray) 125 { 126 init(); 127 128 int otherSize = otherArray.size(); 129 resize (otherSize); 130 otherArray.copy(0, otherSize, m_data); 131 } 132 123 SIMD_FORCE_INLINE int capacity() const 124 { // return current length of allocated storage 125 return m_capacity; 126 } 133 127 134 135 /// return the number of elements in the array136 128 SIMD_FORCE_INLINE int size() const 137 { 129 { // return length of sequence 138 130 return m_size; 139 131 } … … 150 142 151 143 152 ///clear the array, deallocated memory. Generally it is better to use array.resize(0), to reduce performance overhead of run-time memory (de)allocations.153 144 SIMD_FORCE_INLINE void clear() 154 145 { … … 166 157 } 167 158 168 ///resize changes the number of elements in the array. If the new size is larger, the new elements will be constructed using the optional second argument.169 ///when the new number of elements is smaller, the destructor will be called, but memory will not be freed, to reduce performance overhead of run-time memory (de)allocations.170 159 SIMD_FORCE_INLINE void resize(int newsize, const T& fillData=T()) 171 160 { … … 231 220 232 221 233 /// return the pre-allocated (reserved) elements, this is at least as large as the total number of elements,see size() and reserve()234 SIMD_FORCE_INLINE int capacity() const235 {236 return m_capacity;237 }238 222 239 223 SIMD_FORCE_INLINE void reserve(int _Count) -
code/branches/questsystem5/src/bullet/LinearMath/btConvexHull.cpp
r2907 r2908 263 263 for(btScalar x = btScalar(0.0) ; x<= btScalar(360.0) ; x+= btScalar(45.0)) 264 264 { 265 btScalar s = btSin(SIMD_RADS_PER_DEG*(x));266 btScalar c = btCos(SIMD_RADS_PER_DEG*(x));265 btScalar s = sinf(SIMD_RADS_PER_DEG*(x)); 266 btScalar c = cosf(SIMD_RADS_PER_DEG*(x)); 267 267 int mb = maxdirfiltered(p,count,dir+(u*s+v*c)*btScalar(0.025),allow); 268 268 if(ma==m && mb==m) … … 276 276 for(btScalar xx = x-btScalar(40.0) ; xx <= x ; xx+= btScalar(5.0)) 277 277 { 278 btScalar s = btSin(SIMD_RADS_PER_DEG*(xx));279 btScalar c = btCos(SIMD_RADS_PER_DEG*(xx));278 btScalar s = sinf(SIMD_RADS_PER_DEG*(xx)); 279 btScalar c = cosf(SIMD_RADS_PER_DEG*(xx)); 280 280 int md = maxdirfiltered(p,count,dir+(u*s+v*c)*btScalar(0.025),allow); 281 281 if(mc==m && md==m) -
code/branches/questsystem5/src/bullet/LinearMath/btIDebugDraw.h
r2907 r2908 30 30 31 31 #include "btVector3.h" 32 #include "btTransform.h"33 32 34 33 … … 54 53 DBG_DisableBulletLCP = 512, 55 54 DBG_EnableCCD = 1024, 56 DBG_DrawConstraints = (1 << 11),57 DBG_DrawConstraintLimits = (1 << 12),58 55 DBG_MAX_DEBUG_DRAW_MODE 59 56 }; 60 57 61 58 virtual ~btIDebugDraw() {}; 62 63 virtual void drawLine(const btVector3& from,const btVector3& to, const btVector3& fromColor, const btVector3& toColor)64 {65 drawLine (from, to, fromColor);66 }67 68 virtual void drawBox (const btVector3& boxMin, const btVector3& boxMax, const btVector3& color, btScalar alpha)69 {70 }71 72 virtual void drawSphere (const btVector3& p, btScalar radius, const btVector3& color)73 {74 }75 59 76 60 virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0; … … 126 110 } 127 111 } 128 void drawTransform(const btTransform& transform, btScalar orthoLen)129 {130 btVector3 start = transform.getOrigin();131 drawLine(start, start+transform.getBasis() * btVector3(orthoLen, 0, 0), btVector3(0.7f,0,0));132 drawLine(start, start+transform.getBasis() * btVector3(0, orthoLen, 0), btVector3(0,0.7f,0));133 drawLine(start, start+transform.getBasis() * btVector3(0, 0, orthoLen), btVector3(0,0,0.7f));134 }135 136 void drawArc(const btVector3& center, const btVector3& normal, const btVector3& axis, btScalar radiusA, btScalar radiusB, btScalar minAngle, btScalar maxAngle,137 const btVector3& color, bool drawSect, btScalar stepDegrees = btScalar(10.f))138 {139 const btVector3& vx = axis;140 btVector3 vy = normal.cross(axis);141 btScalar step = stepDegrees * SIMD_RADS_PER_DEG;142 int nSteps = (int)((maxAngle - minAngle) / step);143 if(!nSteps) nSteps = 1;144 btVector3 prev = center + radiusA * vx * btCos(minAngle) + radiusB * vy * btSin(minAngle);145 if(drawSect)146 {147 drawLine(center, prev, color);148 }149 for(int i = 1; i <= nSteps; i++)150 {151 btScalar angle = minAngle + (maxAngle - minAngle) * btScalar(i) / btScalar(nSteps);152 btVector3 next = center + radiusA * vx * btCos(angle) + radiusB * vy * btSin(angle);153 drawLine(prev, next, color);154 prev = next;155 }156 if(drawSect)157 {158 drawLine(center, prev, color);159 }160 }161 void drawSpherePatch(const btVector3& center, const btVector3& up, const btVector3& axis, btScalar radius,162 btScalar minTh, btScalar maxTh, btScalar minPs, btScalar maxPs, const btVector3& color, btScalar stepDegrees = btScalar(10.f))163 {164 btVector3 vA[74];165 btVector3 vB[74];166 btVector3 *pvA = vA, *pvB = vB, *pT;167 btVector3 npole = center + up * radius;168 btVector3 spole = center - up * radius;169 btVector3 arcStart;170 btScalar step = stepDegrees * SIMD_RADS_PER_DEG;171 const btVector3& kv = up;172 const btVector3& iv = axis;173 btVector3 jv = kv.cross(iv);174 bool drawN = false;175 bool drawS = false;176 if(minTh <= -SIMD_HALF_PI)177 {178 minTh = -SIMD_HALF_PI + step;179 drawN = true;180 }181 if(maxTh >= SIMD_HALF_PI)182 {183 maxTh = SIMD_HALF_PI - step;184 drawS = true;185 }186 if(minTh > maxTh)187 {188 minTh = -SIMD_HALF_PI + step;189 maxTh = SIMD_HALF_PI - step;190 drawN = drawS = true;191 }192 int n_hor = (int)((maxTh - minTh) / step) + 1;193 if(n_hor < 2) n_hor = 2;194 btScalar step_h = (maxTh - minTh) / btScalar(n_hor - 1);195 bool isClosed = false;196 if(minPs > maxPs)197 {198 minPs = -SIMD_PI + step;199 maxPs = SIMD_PI;200 isClosed = true;201 }202 else if((maxPs - minPs) >= SIMD_PI * btScalar(2.f))203 {204 isClosed = true;205 }206 else207 {208 isClosed = false;209 }210 int n_vert = (int)((maxPs - minPs) / step) + 1;211 if(n_vert < 2) n_vert = 2;212 btScalar step_v = (maxPs - minPs) / btScalar(n_vert - 1);213 for(int i = 0; i < n_hor; i++)214 {215 btScalar th = minTh + btScalar(i) * step_h;216 btScalar sth = radius * btSin(th);217 btScalar cth = radius * btCos(th);218 for(int j = 0; j < n_vert; j++)219 {220 btScalar psi = minPs + btScalar(j) * step_v;221 btScalar sps = btSin(psi);222 btScalar cps = btCos(psi);223 pvB[j] = center + cth * cps * iv + cth * sps * jv + sth * kv;224 if(i)225 {226 drawLine(pvA[j], pvB[j], color);227 }228 else if(drawS)229 {230 drawLine(spole, pvB[j], color);231 }232 if(j)233 {234 drawLine(pvB[j-1], pvB[j], color);235 }236 else237 {238 arcStart = pvB[j];239 }240 if((i == (n_hor - 1)) && drawN)241 {242 drawLine(npole, pvB[j], color);243 }244 if(isClosed)245 {246 if(j == (n_vert-1))247 {248 drawLine(arcStart, pvB[j], color);249 }250 }251 else252 {253 if(((!i) || (i == (n_hor-1))) && ((!j) || (j == (n_vert-1))))254 {255 drawLine(center, pvB[j], color);256 }257 }258 }259 pT = pvA; pvA = pvB; pvB = pT;260 }261 }262 263 void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btVector3& color)264 {265 drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMin[2]), color);266 drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMin[2]), color);267 drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMin[2]), color);268 drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMin[2]), color);269 drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color);270 drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color);271 drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color);272 drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color);273 drawLine(btVector3(bbMin[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color);274 drawLine(btVector3(bbMax[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color);275 drawLine(btVector3(bbMax[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color);276 drawLine(btVector3(bbMin[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color);277 }278 void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btTransform& trans, const btVector3& color)279 {280 drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), color);281 drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), color);282 drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), color);283 drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), color);284 drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color);285 drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color);286 drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color);287 drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color);288 drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color);289 drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color);290 drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color);291 drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color);292 }293 112 }; 294 113 -
code/branches/questsystem5/src/bullet/LinearMath/btMatrix3x3.h
r2907 r2908 193 193 btScalar(0.0), btScalar(0.0), btScalar(1.0)); 194 194 } 195 196 static const btMatrix3x3& getIdentity()197 {198 static const btMatrix3x3 identityMatrix(btScalar(1.0), btScalar(0.0), btScalar(0.0),199 btScalar(0.0), btScalar(1.0), btScalar(0.0),200 btScalar(0.0), btScalar(0.0), btScalar(1.0));201 return identityMatrix;202 }203 204 195 /**@brief Fill the values of the matrix into a 9 element array 205 196 * @param m The array to be filled */ -
code/branches/questsystem5/src/bullet/LinearMath/btQuadWord.h
r2907 r2908 25 25 #endif 26 26 27 /**@brief The btQuadWord class is base class for btVector3 and btQuaternion.27 /**@brief The btQuadWordStorage class is base class for btVector3 and btQuaternion. 28 28 * Some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword. 29 29 */ 30 30 #ifndef USE_LIBSPE2 31 ATTRIBUTE_ALIGNED16(class) btQuadWord 31 ATTRIBUTE_ALIGNED16(class) btQuadWordStorage 32 32 #else 33 class btQuadWord 33 class btQuadWordStorage 34 34 #endif 35 35 { … … 46 46 return mVec128; 47 47 } 48 protected:49 48 #else //__CELLOS_LV2__ __SPU__ 50 49 btScalar m_floats[4]; 51 50 #endif //__CELLOS_LV2__ __SPU__ 52 51 52 }; 53 54 /** @brief The btQuadWord is base-class for vectors, points */ 55 class btQuadWord : public btQuadWordStorage 56 { 53 57 public: 54 58 … … 131 135 { 132 136 } 133 137 /**@brief Copy constructor */ 138 SIMD_FORCE_INLINE btQuadWord(const btQuadWordStorage& q) 139 { 140 *((btQuadWordStorage*)this) = q; 141 } 134 142 /**@brief Three argument constructor (zeros w) 135 143 * @param x Value of x -
code/branches/questsystem5/src/bullet/LinearMath/btQuaternion.h
r2907 r2908 20 20 21 21 #include "btVector3.h" 22 #include "btQuadWord.h"23 22 24 23 /**@brief The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatrix3x3, btVector3 and btTransform. */ … … 59 58 { 60 59 btScalar d = axis.length(); 61 btAssert(d != btScalar(0.0));60 assert(d != btScalar(0.0)); 62 61 btScalar s = btSin(angle * btScalar(0.5)) / d; 63 62 setValue(axis.x() * s, axis.y() * s, axis.z() * s, … … 178 177 btQuaternion operator/(const btScalar& s) const 179 178 { 180 btAssert(s != btScalar(0.0));179 assert(s != btScalar(0.0)); 181 180 return *this * (btScalar(1.0) / s); 182 181 } … … 186 185 btQuaternion& operator/=(const btScalar& s) 187 186 { 188 btAssert(s != btScalar(0.0));187 assert(s != btScalar(0.0)); 189 188 return *this *= btScalar(1.0) / s; 190 189 } … … 200 199 { 201 200 btScalar s = btSqrt(length2() * q.length2()); 202 btAssert(s != btScalar(0.0));201 assert(s != btScalar(0.0)); 203 202 return btAcos(dot(q) / s); 204 203 } … … 276 275 } 277 276 278 static const btQuaternion& getIdentity()279 {280 static const btQuaternion identityQuat(btScalar(0.),btScalar(0.),btScalar(0.),btScalar(1.));281 return identityQuat;282 }283 284 277 SIMD_FORCE_INLINE const btScalar& getW() const { return m_floats[3]; } 285 278 -
code/branches/questsystem5/src/bullet/LinearMath/btScalar.h
r2907 r2908 26 26 #include <float.h> 27 27 28 #define BT_BULLET_VERSION 27 428 #define BT_BULLET_VERSION 273 29 29 30 30 inline int btGetVersion() … … 46 46 #define ATTRIBUTE_ALIGNED128(a) a 47 47 #else 48 //#define BT_HAS_ALIGNED_ALLOCATOR48 #define BT_HAS_ALIGNED_ALLOCATOR 49 49 #pragma warning(disable : 4324) // disable padding warning 50 50 // #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning. … … 62 62 #define btFsel(a,b,c) __fsel((a),(b),(c)) 63 63 #else 64 65 #if (defined (WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (BT_USE_DOUBLE_PRECISION))66 64 #define BT_USE_SSE 67 #include <emmintrin.h> 68 #endif 69 70 #endif//_XBOX 71 65 #endif 72 66 #endif //__MINGW32__ 73 67 … … 131 125 132 126 #define SIMD_FORCE_INLINE inline 133 ///@todo: check out alignment methods for other platforms/compilers134 ///#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))135 ///#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))136 127 #define ATTRIBUTE_ALIGNED16(a) a 137 128 #define ATTRIBUTE_ALIGNED128(a) a … … 242 233 SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); } 243 234 #endif 244 235 245 236 #endif 246 237 -
code/branches/questsystem5/src/bullet/LinearMath/btTransform.h
r2907 r2908 191 191 192 192 /**@brief Return an identity transform */ 193 static const btTransform& getIdentity() 194 { 195 static const btTransform identityTransform(btMatrix3x3::getIdentity()); 196 return identityTransform; 193 static btTransform getIdentity() 194 { 195 btTransform tr; 196 tr.setIdentity(); 197 return tr; 197 198 } 198 199 -
code/branches/questsystem5/src/bullet/LinearMath/btVector3.h
r2907 r2908 18 18 #define SIMD__VECTOR3_H 19 19 20 21 #include "btScalar.h" 22 #include "btScalar.h" 23 #include "btMinMax.h" 20 #include "btQuadWord.h" 21 24 22 /**@brief btVector3 can be used to represent 3D points and vectors. 25 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 26 24 * Ideally, this class should be replaced by a platform optimized SIMD version that keeps the data in registers 27 25 */ 28 29 ATTRIBUTE_ALIGNED16(class) btVector3 30 { 26 class btVector3 : public btQuadWord { 27 31 28 public: 32 33 #if defined (__SPU__) && defined (__CELLOS_LV2__)34 union {35 vec_float4 mVec128;36 btScalar m_floats[4];37 };38 public:39 vec_float4 get128() const40 {41 return mVec128;42 }43 public:44 #else //__CELLOS_LV2__ __SPU__45 #ifdef BT_USE_SSE // WIN3246 union {47 __m128 mVec128;48 btScalar m_floats[4];49 };50 SIMD_FORCE_INLINE __m128 get128() const51 {52 return mVec128;53 }54 SIMD_FORCE_INLINE void set128(__m128 v128)55 {56 mVec128 = v128;57 }58 #else59 btScalar m_floats[4];60 #endif61 #endif //__CELLOS_LV2__ __SPU__62 63 public:64 65 29 /**@brief No initialization constructor */ 66 30 SIMD_FORCE_INLINE btVector3() {} 67 31 68 32 /**@brief Constructor from btQuadWordStorage (btVector3 inherits from this so is also valid) 33 * Note: Vector3 derives from btQuadWordStorage*/ 34 SIMD_FORCE_INLINE btVector3(const btQuadWordStorage& q) 35 : btQuadWord(q) 36 { 37 } 69 38 70 39 /**@brief Constructor from scalars … … 73 42 * @param z Z value 74 43 */ 75 SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z) 76 { 77 m_floats[0] = x; 78 m_floats[1] = y; 79 m_floats[2] = z; 80 m_floats[3] = btScalar(0.); 81 } 44 SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z) 45 :btQuadWord(x,y,z,btScalar(0.)) 46 { 47 } 48 49 // SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) 50 // : btQuadWord(x,y,z,w) 51 // { 52 // } 82 53 83 54 … … 87 58 { 88 59 89 m_floats[0] += v. m_floats[0]; m_floats[1] += v.m_floats[1];m_floats[2] += v.m_floats[2];60 m_floats[0] += v.x(); m_floats[1] += v.y(); m_floats[2] += v.z(); 90 61 return *this; 91 62 } … … 96 67 SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v) 97 68 { 98 m_floats[0] -= v. m_floats[0]; m_floats[1] -= v.m_floats[1];m_floats[2] -= v.m_floats[2];69 m_floats[0] -= v.x(); m_floats[1] -= v.y(); m_floats[2] -= v.z(); 99 70 return *this; 100 71 } … … 103 74 SIMD_FORCE_INLINE btVector3& operator*=(const btScalar& s) 104 75 { 105 m_floats[0] *= s; m_floats[1] *= s; m_floats[2] *= s;76 m_floats[0] *= s; m_floats[1] *= s; m_floats[2] *= s; 106 77 return *this; 107 78 } … … 119 90 SIMD_FORCE_INLINE btScalar dot(const btVector3& v) const 120 91 { 121 return m_floats[0] * v. m_floats[0] + m_floats[1] * v.m_floats[1] +m_floats[2] * v.m_floats[2];92 return m_floats[0] * v.x() + m_floats[1] * v.y() + m_floats[2] * v.z(); 122 93 } 123 94 … … 178 149 { 179 150 return btVector3( 180 m_floats[1] * v. m_floats[2] -m_floats[2] * v.m_floats[1],181 m_floats[2] * v. m_floats[0] - m_floats[0] * v.m_floats[2],182 m_floats[0] * v. m_floats[1] - m_floats[1] * v.m_floats[0]);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()); 183 154 } 184 155 185 156 SIMD_FORCE_INLINE btScalar triple(const btVector3& v1, const btVector3& v2) const 186 157 { 187 return m_floats[0] * (v1. m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) +188 m_floats[1] * (v1. m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) +189 m_floats[2] * (v1. m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]);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()); 190 161 } 191 162 … … 194 165 SIMD_FORCE_INLINE int minAxis() const 195 166 { 196 return m_floats[0] < m_floats[1] ? (m_floats[0] < m_floats[2] ? 0 : 2) : (m_floats[1] <m_floats[2] ? 1 : 2);167 return m_floats[0] < m_floats[1] ? (m_floats[0] < m_floats[2] ? 0 : 2) : (m_floats[1] < m_floats[2] ? 1 : 2); 197 168 } 198 169 … … 201 172 SIMD_FORCE_INLINE int maxAxis() const 202 173 { 203 return m_floats[0] < m_floats[1] ? (m_floats[1] < m_floats[2] ? 2 : 1) : (m_floats[0] <m_floats[2] ? 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); 204 175 } 205 176 … … 217 188 { 218 189 btScalar s = btScalar(1.0) - rt; 219 m_floats[0] = s * v0. m_floats[0] + rt * v1.m_floats[0];220 m_floats[1] = s * v0. m_floats[1] + rt * v1.m_floats[1];221 m_floats[2] = s * v0. m_floats[2] + rt * v1.m_floats[2];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(); 222 193 //don't do the unused w component 223 194 // m_co[3] = s * v0[3] + rt * v1[3]; … … 229 200 SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const 230 201 { 231 return btVector3(m_floats[0] + (v. m_floats[0]- m_floats[0]) * t,232 m_floats[1] + (v. m_floats[1]- m_floats[1]) * t,233 m_floats[2] + (v. m_floats[2] -m_floats[2]) * t);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); 234 205 } 235 206 … … 238 209 SIMD_FORCE_INLINE btVector3& operator*=(const btVector3& v) 239 210 { 240 m_floats[0] *= v. m_floats[0]; m_floats[1] *= v.m_floats[1];m_floats[2] *= v.m_floats[2];211 m_floats[0] *= v.x(); m_floats[1] *= v.y(); m_floats[2] *= v.z(); 241 212 return *this; 242 213 } 243 214 244 /**@brief Return the x value */ 245 SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; } 246 /**@brief Return the y value */ 247 SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; } 248 /**@brief Return the z value */ 249 SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; } 250 /**@brief Set the x value */ 251 SIMD_FORCE_INLINE void setX(btScalar x) { m_floats[0] = x;}; 252 /**@brief Set the y value */ 253 SIMD_FORCE_INLINE void setY(btScalar y) { m_floats[1] = y;}; 254 /**@brief Set the z value */ 255 SIMD_FORCE_INLINE void setZ(btScalar z) {m_floats[2] = z;}; 256 /**@brief Set the w value */ 257 SIMD_FORCE_INLINE void setW(btScalar w) { m_floats[3] = w;}; 258 /**@brief Return the x value */ 259 SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; } 260 /**@brief Return the y value */ 261 SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; } 262 /**@brief Return the z value */ 263 SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; } 264 /**@brief Return the w value */ 265 SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; } 266 267 //SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; } 268 //SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; } 269 ///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons. 270 SIMD_FORCE_INLINE operator btScalar *() { return &m_floats[0]; } 271 SIMD_FORCE_INLINE operator const btScalar *() const { return &m_floats[0]; } 272 273 SIMD_FORCE_INLINE bool operator==(const btVector3& other) const 274 { 275 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])); 276 } 277 278 SIMD_FORCE_INLINE bool operator!=(const btVector3& other) const 279 { 280 return !(*this == other); 281 } 282 283 /**@brief Set each element to the max of the current values and the values of another btVector3 284 * @param other The other btVector3 to compare with 285 */ 286 SIMD_FORCE_INLINE void setMax(const btVector3& other) 287 { 288 btSetMax(m_floats[0], other.m_floats[0]); 289 btSetMax(m_floats[1], other.m_floats[1]); 290 btSetMax(m_floats[2], other.m_floats[2]); 291 btSetMax(m_floats[3], other.w()); 292 } 293 /**@brief Set each element to the min of the current values and the values of another btVector3 294 * @param other The other btVector3 to compare with 295 */ 296 SIMD_FORCE_INLINE void setMin(const btVector3& other) 297 { 298 btSetMin(m_floats[0], other.m_floats[0]); 299 btSetMin(m_floats[1], other.m_floats[1]); 300 btSetMin(m_floats[2], other.m_floats[2]); 301 btSetMin(m_floats[3], other.w()); 302 } 303 304 SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z) 305 { 306 m_floats[0]=x; 307 m_floats[1]=y; 308 m_floats[2]=z; 309 m_floats[3] = 0.f; 310 } 311 312 void getSkewSymmetricMatrix(btVector3* v0,btVector3* v1,btVector3* v2) const 313 { 314 v0->setValue(0. ,-z() ,y()); 315 v1->setValue(z() ,0. ,-x()); 316 v2->setValue(-y() ,x() ,0.); 317 } 215 318 216 319 217 }; … … 323 221 operator+(const btVector3& v1, const btVector3& v2) 324 222 { 325 return btVector3(v1. m_floats[0] + v2.m_floats[0], v1.m_floats[1] + v2.m_floats[1], v1.m_floats[2] + v2.m_floats[2]);223 return btVector3(v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z()); 326 224 } 327 225 … … 330 228 operator*(const btVector3& v1, const btVector3& v2) 331 229 { 332 return btVector3(v1. m_floats[0] * v2.m_floats[0], v1.m_floats[1] * v2.m_floats[1], v1.m_floats[2] * v2.m_floats[2]);230 return btVector3(v1.x() * v2.x(), v1.y() * v2.y(), v1.z() * v2.z()); 333 231 } 334 232 … … 337 235 operator-(const btVector3& v1, const btVector3& v2) 338 236 { 339 return btVector3(v1. m_floats[0] - v2.m_floats[0], v1.m_floats[1] - v2.m_floats[1], v1.m_floats[2] - v2.m_floats[2]);237 return btVector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z()); 340 238 } 341 239 /**@brief Return the negative of the vector */ … … 343 241 operator-(const btVector3& v) 344 242 { 345 return btVector3(-v. m_floats[0], -v.m_floats[1], -v.m_floats[2]);243 return btVector3(-v.x(), -v.y(), -v.z()); 346 244 } 347 245 … … 350 248 operator*(const btVector3& v, const btScalar& s) 351 249 { 352 return btVector3(v. m_floats[0] * s, v.m_floats[1] * s, v.m_floats[2]* s);250 return btVector3(v.x() * s, v.y() * s, v.z() * s); 353 251 } 354 252 … … 372 270 operator/(const btVector3& v1, const btVector3& v2) 373 271 { 374 return btVector3(v1. m_floats[0] / v2.m_floats[0],v1.m_floats[1] / v2.m_floats[1],v1.m_floats[2] / v2.m_floats[2]);272 return btVector3(v1.x() / v2.x(),v1.y() / v2.y(),v1.z() / v2.z()); 375 273 } 376 274 … … 428 326 } 429 327 430 328 /**@brief Test if each element of the vector is equivalent */ 329 SIMD_FORCE_INLINE bool operator==(const btVector3& p1, const btVector3& p2) 330 { 331 return p1.x() == p2.x() && p1.y() == p2.y() && p1.z() == p2.z(); 332 } 431 333 432 334 SIMD_FORCE_INLINE btScalar btVector3::distance2(const btVector3& v) const … … 503 405 { 504 406 maxIndex = 2; 505 maxVal = m_floats[2];407 maxVal = m_floats[2]; 506 408 } 507 409 if (m_floats[3] > maxVal) … … 536 438 { 537 439 minIndex = 2; 538 minVal = m_floats[2];440 minVal = m_floats[2]; 539 441 } 540 442 if (m_floats[3] < minVal) … … 553 455 return absolute4().maxAxis4(); 554 456 } 555 556 557 558 559 /**@brief Set x,y,z and zero w560 * @param x Value of x561 * @param y Value of y562 * @param z Value of z563 */564 565 566 /* void getValue(btScalar *m) const567 {568 m[0] = m_floats[0];569 m[1] = m_floats[1];570 m[2] =m_floats[2];571 }572 */573 /**@brief Set the values574 * @param x Value of x575 * @param y Value of y576 * @param z Value of z577 * @param w Value of w578 */579 SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)580 {581 m_floats[0]=x;582 m_floats[1]=y;583 m_floats[2]=z;584 m_floats[3]=w;585 }586 587 588 589 457 590 458 }; -
code/branches/questsystem5/src/bullet/changes_orxonox.diff
r2907 r2908 1 Index: btScalar.h 2 =================================================================== 3 --- btScalar.h (revision 2882) 4 +++ btScalar.h (working copy) 5 @@ -236,7 +236,11 @@ 1 --- LinearMath\btScalar.h So Feb 15 18:28:13 2009 2 +++ LinearMath\btScalar.h Sa Feb 14 23:04:53 2009 3 @@ -227,7 +227,11 @@ 6 4 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); } 7 5 SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); } … … 13 11 + SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); } 14 12 + #endif 15 13 16 14 #endif 17 15
Note: See TracChangeset
for help on using the changeset viewer.