btSequentialImpulseConstraintSolver.cpp

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 //#define COMPUTE_IMPULSE_DENOM 1
00017 //It is not necessary (redundant) to refresh contact manifolds, this refresh has been moved to the collision algorithms.
00018 
00019 #include "btSequentialImpulseConstraintSolver.h"
00020 #include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
00021 #include "BulletDynamics/Dynamics/btRigidBody.h"
00022 #include "btContactConstraint.h"
00023 #include "btSolve2LinearConstraint.h"
00024 #include "btContactSolverInfo.h"
00025 #include "LinearMath/btIDebugDraw.h"
00026 #include "btJacobianEntry.h"
00027 #include "LinearMath/btMinMax.h"
00028 #include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
00029 #include <new>
00030 #include "LinearMath/btStackAlloc.h"
00031 #include "LinearMath/btQuickprof.h"
00032 #include "btSolverBody.h"
00033 #include "btSolverConstraint.h"
00034 #include "LinearMath/btAlignedObjectArray.h"
00035 #include <string.h> //for memset
00036 
00037 int             gNumSplitImpulseRecoveries = 0;
00038 
00039 btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver()
00040 :m_btSeed2(0)
00041 {
00042 
00043 }
00044 
00045 btSequentialImpulseConstraintSolver::~btSequentialImpulseConstraintSolver()
00046 {
00047 }
00048 
00049 #ifdef USE_SIMD
00050 #include <emmintrin.h>
00051 #define vec_splat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e,e,e,e))
00052 static inline __m128 _vmathVfDot3( __m128 vec0, __m128 vec1 )
00053 {
00054         __m128 result = _mm_mul_ps( vec0, vec1);
00055         return _mm_add_ps( vec_splat( result, 0 ), _mm_add_ps( vec_splat( result, 1 ), vec_splat( result, 2 ) ) );
00056 }
00057 #endif//USE_SIMD
00058 
00059 // Project Gauss Seidel or the equivalent Sequential Impulse
00060 void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& c)
00061 {
00062 #ifdef USE_SIMD
00063         __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse);
00064         __m128  lowerLimit1 = _mm_set1_ps(c.m_lowerLimit);
00065         __m128  upperLimit1 = _mm_set1_ps(c.m_upperLimit);
00066         __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)));
00067         __m128 deltaVel1Dotn    =       _mm_add_ps(_vmathVfDot3(c.m_contactNormal.mVec128,body1.internalGetDeltaLinearVelocity().mVec128), _vmathVfDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetDeltaAngularVelocity().mVec128));
00068         __m128 deltaVel2Dotn    =       _mm_sub_ps(_vmathVfDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetDeltaAngularVelocity().mVec128),_vmathVfDot3((c.m_contactNormal).mVec128,body2.internalGetDeltaLinearVelocity().mVec128));
00069         deltaImpulse    =       _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
00070         deltaImpulse    =       _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
00071         btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse);
00072         btSimdScalar resultLowerLess,resultUpperLess;
00073         resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1);
00074         resultUpperLess = _mm_cmplt_ps(sum,upperLimit1);
00075         __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp);
00076         deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) );
00077         c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
00078         __m128 upperMinApplied = _mm_sub_ps(upperLimit1,cpAppliedImp);
00079         deltaImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, deltaImpulse), _mm_andnot_ps(resultUpperLess, upperMinApplied) );
00080         c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, c.m_appliedImpulse), _mm_andnot_ps(resultUpperLess, upperLimit1) );
00081         __m128  linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.internalGetInvMass().mVec128);
00082         __m128  linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.internalGetInvMass().mVec128);
00083         __m128 impulseMagnitude = deltaImpulse;
00084         body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
00085         body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude));
00086         body2.internalGetDeltaLinearVelocity().mVec128 = _mm_sub_ps(body2.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
00087         body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude));
00088 #else
00089         resolveSingleConstraintRowGeneric(body1,body2,c);
00090 #endif
00091 }
00092 
00093 // Project Gauss Seidel or the equivalent Sequential Impulse
00094  void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGeneric(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& c)
00095 {
00096         btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm;
00097         const btScalar deltaVel1Dotn    =       c.m_contactNormal.dot(body1.internalGetDeltaLinearVelocity())   + c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity());
00098         const btScalar deltaVel2Dotn    =       -c.m_contactNormal.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity());
00099 
00100 //      const btScalar delta_rel_vel    =       deltaVel1Dotn-deltaVel2Dotn;
00101         deltaImpulse    -=      deltaVel1Dotn*c.m_jacDiagABInv;
00102         deltaImpulse    -=      deltaVel2Dotn*c.m_jacDiagABInv;
00103 
00104         const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse;
00105         if (sum < c.m_lowerLimit)
00106         {
00107                 deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse;
00108                 c.m_appliedImpulse = c.m_lowerLimit;
00109         }
00110         else if (sum > c.m_upperLimit) 
00111         {
00112                 deltaImpulse = c.m_upperLimit-c.m_appliedImpulse;
00113                 c.m_appliedImpulse = c.m_upperLimit;
00114         }
00115         else
00116         {
00117                 c.m_appliedImpulse = sum;
00118         }
00119                 body1.internalApplyImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
00120                 body2.internalApplyImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
00121 }
00122 
00123  void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimitSIMD(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& c)
00124 {
00125 #ifdef USE_SIMD
00126         __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse);
00127         __m128  lowerLimit1 = _mm_set1_ps(c.m_lowerLimit);
00128         __m128  upperLimit1 = _mm_set1_ps(c.m_upperLimit);
00129         __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)));
00130         __m128 deltaVel1Dotn    =       _mm_add_ps(_vmathVfDot3(c.m_contactNormal.mVec128,body1.internalGetDeltaLinearVelocity().mVec128), _vmathVfDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetDeltaAngularVelocity().mVec128));
00131         __m128 deltaVel2Dotn    =       _mm_sub_ps(_vmathVfDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetDeltaAngularVelocity().mVec128),_vmathVfDot3((c.m_contactNormal).mVec128,body2.internalGetDeltaLinearVelocity().mVec128));
00132         deltaImpulse    =       _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
00133         deltaImpulse    =       _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
00134         btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse);
00135         btSimdScalar resultLowerLess,resultUpperLess;
00136         resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1);
00137         resultUpperLess = _mm_cmplt_ps(sum,upperLimit1);
00138         __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp);
00139         deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) );
00140         c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
00141         __m128  linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.internalGetInvMass().mVec128);
00142         __m128  linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.internalGetInvMass().mVec128);
00143         __m128 impulseMagnitude = deltaImpulse;
00144         body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
00145         body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude));
00146         body2.internalGetDeltaLinearVelocity().mVec128 = _mm_sub_ps(body2.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
00147         body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude));
00148 #else
00149         resolveSingleConstraintRowLowerLimit(body1,body2,c);
00150 #endif
00151 }
00152 
00153 // Project Gauss Seidel or the equivalent Sequential Impulse
00154  void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimit(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& c)
00155 {
00156         btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm;
00157         const btScalar deltaVel1Dotn    =       c.m_contactNormal.dot(body1.internalGetDeltaLinearVelocity())   + c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity());
00158         const btScalar deltaVel2Dotn    =       -c.m_contactNormal.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity());
00159 
00160         deltaImpulse    -=      deltaVel1Dotn*c.m_jacDiagABInv;
00161         deltaImpulse    -=      deltaVel2Dotn*c.m_jacDiagABInv;
00162         const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse;
00163         if (sum < c.m_lowerLimit)
00164         {
00165                 deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse;
00166                 c.m_appliedImpulse = c.m_lowerLimit;
00167         }
00168         else
00169         {
00170                 c.m_appliedImpulse = sum;
00171         }
00172         body1.internalApplyImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
00173         body2.internalApplyImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
00174 }
00175 
00176 
00177 void    btSequentialImpulseConstraintSolver::resolveSplitPenetrationImpulseCacheFriendly(
00178         btRigidBody& body1,
00179         btRigidBody& body2,
00180         const btSolverConstraint& c)
00181 {
00182                 if (c.m_rhsPenetration)
00183         {
00184                         gNumSplitImpulseRecoveries++;
00185                         btScalar deltaImpulse = c.m_rhsPenetration-btScalar(c.m_appliedPushImpulse)*c.m_cfm;
00186                         const btScalar deltaVel1Dotn    =       c.m_contactNormal.dot(body1.internalGetPushVelocity())  + c.m_relpos1CrossNormal.dot(body1.internalGetTurnVelocity());
00187                         const btScalar deltaVel2Dotn    =       -c.m_contactNormal.dot(body2.internalGetPushVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetTurnVelocity());
00188 
00189                         deltaImpulse    -=      deltaVel1Dotn*c.m_jacDiagABInv;
00190                         deltaImpulse    -=      deltaVel2Dotn*c.m_jacDiagABInv;
00191                         const btScalar sum = btScalar(c.m_appliedPushImpulse) + deltaImpulse;
00192                         if (sum < c.m_lowerLimit)
00193                         {
00194                                 deltaImpulse = c.m_lowerLimit-c.m_appliedPushImpulse;
00195                                 c.m_appliedPushImpulse = c.m_lowerLimit;
00196                         }
00197                         else
00198                         {
00199                                 c.m_appliedPushImpulse = sum;
00200                         }
00201                         body1.internalApplyPushImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
00202                         body2.internalApplyPushImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
00203         }
00204 }
00205 
00206  void btSequentialImpulseConstraintSolver::resolveSplitPenetrationSIMD(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& c)
00207 {
00208 #ifdef USE_SIMD
00209         if (!c.m_rhsPenetration)
00210                 return;
00211 
00212         gNumSplitImpulseRecoveries++;
00213 
00214         __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedPushImpulse);
00215         __m128  lowerLimit1 = _mm_set1_ps(c.m_lowerLimit);
00216         __m128  upperLimit1 = _mm_set1_ps(c.m_upperLimit);
00217         __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhsPenetration), _mm_mul_ps(_mm_set1_ps(c.m_appliedPushImpulse),_mm_set1_ps(c.m_cfm)));
00218         __m128 deltaVel1Dotn    =       _mm_add_ps(_vmathVfDot3(c.m_contactNormal.mVec128,body1.internalGetPushVelocity().mVec128), _vmathVfDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetTurnVelocity().mVec128));
00219         __m128 deltaVel2Dotn    =       _mm_sub_ps(_vmathVfDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetTurnVelocity().mVec128),_vmathVfDot3((c.m_contactNormal).mVec128,body2.internalGetPushVelocity().mVec128));
00220         deltaImpulse    =       _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
00221         deltaImpulse    =       _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
00222         btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse);
00223         btSimdScalar resultLowerLess,resultUpperLess;
00224         resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1);
00225         resultUpperLess = _mm_cmplt_ps(sum,upperLimit1);
00226         __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp);
00227         deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) );
00228         c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
00229         __m128  linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.internalGetInvMass().mVec128);
00230         __m128  linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.internalGetInvMass().mVec128);
00231         __m128 impulseMagnitude = deltaImpulse;
00232         body1.internalGetPushVelocity().mVec128 = _mm_add_ps(body1.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
00233         body1.internalGetTurnVelocity().mVec128 = _mm_add_ps(body1.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude));
00234         body2.internalGetPushVelocity().mVec128 = _mm_sub_ps(body2.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
00235         body2.internalGetTurnVelocity().mVec128 = _mm_add_ps(body2.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude));
00236 #else
00237         resolveSplitPenetrationImpulseCacheFriendly(body1,body2,c);
00238 #endif
00239 }
00240 
00241 
00242 
00243 unsigned long btSequentialImpulseConstraintSolver::btRand2()
00244 {
00245         m_btSeed2 = (1664525L*m_btSeed2 + 1013904223L) & 0xffffffff;
00246         return m_btSeed2;
00247 }
00248 
00249 
00250 
00251 //See ODE: adam's all-int straightforward(?) dRandInt (0..n-1)
00252 int btSequentialImpulseConstraintSolver::btRandInt2 (int n)
00253 {
00254         // seems good; xor-fold and modulus
00255         const unsigned long un = static_cast<unsigned long>(n);
00256         unsigned long r = btRand2();
00257 
00258         // note: probably more aggressive than it needs to be -- might be
00259         //       able to get away without one or two of the innermost branches.
00260         if (un <= 0x00010000UL) {
00261                 r ^= (r >> 16);
00262                 if (un <= 0x00000100UL) {
00263                         r ^= (r >> 8);
00264                         if (un <= 0x00000010UL) {
00265                                 r ^= (r >> 4);
00266                                 if (un <= 0x00000004UL) {
00267                                         r ^= (r >> 2);
00268                                         if (un <= 0x00000002UL) {
00269                                                 r ^= (r >> 1);
00270                                         }
00271                                 }
00272                         }
00273                 }
00274         }
00275 
00276         return (int) (r % un);
00277 }
00278 
00279 
00280 #if 0
00281 void    btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject)
00282 {
00283         btRigidBody* rb = collisionObject? btRigidBody::upcast(collisionObject) : 0;
00284 
00285         solverBody->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
00286         solverBody->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
00287         solverBody->internalGetPushVelocity().setValue(0.f,0.f,0.f);
00288         solverBody->internalGetTurnVelocity().setValue(0.f,0.f,0.f);
00289 
00290         if (rb)
00291         {
00292                 solverBody->internalGetInvMass() = btVector3(rb->getInvMass(),rb->getInvMass(),rb->getInvMass())*rb->getLinearFactor();
00293                 solverBody->m_originalBody = rb;
00294                 solverBody->m_angularFactor = rb->getAngularFactor();
00295         } else
00296         {
00297                 solverBody->internalGetInvMass().setValue(0,0,0);
00298                 solverBody->m_originalBody = 0;
00299                 solverBody->m_angularFactor.setValue(1,1,1);
00300         }
00301 }
00302 #endif
00303 
00304 
00305 
00306 
00307 
00308 btScalar btSequentialImpulseConstraintSolver::restitutionCurve(btScalar rel_vel, btScalar restitution)
00309 {
00310         btScalar rest = restitution * -rel_vel;
00311         return rest;
00312 }
00313 
00314 
00315 
00316 void    applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection);
00317 void    applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection)
00318 {
00319         if (colObj && colObj->hasAnisotropicFriction())
00320         {
00321                 // transform to local coordinates
00322                 btVector3 loc_lateral = frictionDirection * colObj->getWorldTransform().getBasis();
00323                 const btVector3& friction_scaling = colObj->getAnisotropicFriction();
00324                 //apply anisotropic friction
00325                 loc_lateral *= friction_scaling;
00326                 // ... and transform it back to global coordinates
00327                 frictionDirection = colObj->getWorldTransform().getBasis() * loc_lateral;
00328         }
00329 }
00330 
00331 
00332 
00333 btSolverConstraint&     btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis,btRigidBody* solverBodyA,btRigidBody* solverBodyB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip)
00334 {
00335 
00336 
00337         btRigidBody* body0=btRigidBody::upcast(colObj0);
00338         btRigidBody* body1=btRigidBody::upcast(colObj1);
00339 
00340         btSolverConstraint& solverConstraint = m_tmpSolverContactFrictionConstraintPool.expandNonInitializing();
00341         //memset(&solverConstraint,0xff,sizeof(btSolverConstraint));
00342         solverConstraint.m_contactNormal = normalAxis;
00343 
00344         solverConstraint.m_solverBodyA = body0 ? body0 : &getFixedBody();
00345         solverConstraint.m_solverBodyB = body1 ? body1 : &getFixedBody();
00346         solverConstraint.m_frictionIndex = frictionIndex;
00347 
00348         solverConstraint.m_friction = cp.m_combinedFriction;
00349         solverConstraint.m_originalContactPoint = 0;
00350 
00351         solverConstraint.m_appliedImpulse = 0.f;
00352         solverConstraint.m_appliedPushImpulse = 0.f;
00353 
00354         {
00355                 btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal);
00356                 solverConstraint.m_relpos1CrossNormal = ftorqueAxis1;
00357                 solverConstraint.m_angularComponentA = body0 ? body0->getInvInertiaTensorWorld()*ftorqueAxis1*body0->getAngularFactor() : btVector3(0,0,0);
00358         }
00359         {
00360                 btVector3 ftorqueAxis1 = rel_pos2.cross(-solverConstraint.m_contactNormal);
00361                 solverConstraint.m_relpos2CrossNormal = ftorqueAxis1;
00362                 solverConstraint.m_angularComponentB = body1 ? body1->getInvInertiaTensorWorld()*ftorqueAxis1*body1->getAngularFactor() : btVector3(0,0,0);
00363         }
00364 
00365 #ifdef COMPUTE_IMPULSE_DENOM
00366         btScalar denom0 = rb0->computeImpulseDenominator(pos1,solverConstraint.m_contactNormal);
00367         btScalar denom1 = rb1->computeImpulseDenominator(pos2,solverConstraint.m_contactNormal);
00368 #else
00369         btVector3 vec;
00370         btScalar denom0 = 0.f;
00371         btScalar denom1 = 0.f;
00372         if (body0)
00373         {
00374                 vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1);
00375                 denom0 = body0->getInvMass() + normalAxis.dot(vec);
00376         }
00377         if (body1)
00378         {
00379                 vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2);
00380                 denom1 = body1->getInvMass() + normalAxis.dot(vec);
00381         }
00382 
00383 
00384 #endif //COMPUTE_IMPULSE_DENOM
00385         btScalar denom = relaxation/(denom0+denom1);
00386         solverConstraint.m_jacDiagABInv = denom;
00387 
00388 #ifdef _USE_JACOBIAN
00389         solverConstraint.m_jac =  btJacobianEntry (
00390                 rel_pos1,rel_pos2,solverConstraint.m_contactNormal,
00391                 body0->getInvInertiaDiagLocal(),
00392                 body0->getInvMass(),
00393                 body1->getInvInertiaDiagLocal(),
00394                 body1->getInvMass());
00395 #endif //_USE_JACOBIAN
00396 
00397 
00398         {
00399                 btScalar rel_vel;
00400                 btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(body0?body0->getLinearVelocity():btVector3(0,0,0)) 
00401                         + solverConstraint.m_relpos1CrossNormal.dot(body0?body0->getAngularVelocity():btVector3(0,0,0));
00402                 btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(body1?body1->getLinearVelocity():btVector3(0,0,0)) 
00403                         + solverConstraint.m_relpos2CrossNormal.dot(body1?body1->getAngularVelocity():btVector3(0,0,0));
00404 
00405                 rel_vel = vel1Dotn+vel2Dotn;
00406 
00407 //              btScalar positionalError = 0.f;
00408 
00409                 btSimdScalar velocityError =  desiredVelocity - rel_vel;
00410                 btSimdScalar    velocityImpulse = velocityError * btSimdScalar(solverConstraint.m_jacDiagABInv);
00411                 solverConstraint.m_rhs = velocityImpulse;
00412                 solverConstraint.m_cfm = cfmSlip;
00413                 solverConstraint.m_lowerLimit = 0;
00414                 solverConstraint.m_upperLimit = 1e10f;
00415         }
00416 
00417         return solverConstraint;
00418 }
00419 
00420 int     btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& body)
00421 {
00422 #if 0
00423         int solverBodyIdA = -1;
00424 
00425         if (body.getCompanionId() >= 0)
00426         {
00427                 //body has already been converted
00428                 solverBodyIdA = body.getCompanionId();
00429         } else
00430         {
00431                 btRigidBody* rb = btRigidBody::upcast(&body);
00432                 if (rb && rb->getInvMass())
00433                 {
00434                         solverBodyIdA = m_tmpSolverBodyPool.size();
00435                         btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
00436                         initSolverBody(&solverBody,&body);
00437                         body.setCompanionId(solverBodyIdA);
00438                 } else
00439                 {
00440                         return 0;//assume first one is a fixed solver body
00441                 }
00442         }
00443         return solverBodyIdA;
00444 #endif
00445         return 0;
00446 }
00447 #include <stdio.h>
00448 
00449 
00450 
00451 void    btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal)
00452 {
00453         btCollisionObject* colObj0=0,*colObj1=0;
00454 
00455         colObj0 = (btCollisionObject*)manifold->getBody0();
00456         colObj1 = (btCollisionObject*)manifold->getBody1();
00457 
00458 
00459         btRigidBody* solverBodyA = btRigidBody::upcast(colObj0);
00460         btRigidBody* solverBodyB = btRigidBody::upcast(colObj1);
00461 
00462 
00464         if (!solverBodyA && !solverBodyB)
00465                 return;
00466 
00467         btVector3 rel_pos1;
00468         btVector3 rel_pos2;
00469         btScalar relaxation;
00470 
00471         for (int j=0;j<manifold->getNumContacts();j++)
00472         {
00473 
00474                 btManifoldPoint& cp = manifold->getContactPoint(j);
00475 
00476                 if (cp.getDistance() <= manifold->getContactProcessingThreshold())
00477                 {
00478 
00479                         const btVector3& pos1 = cp.getPositionWorldOnA();
00480                         const btVector3& pos2 = cp.getPositionWorldOnB();
00481 
00482                         rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin(); 
00483                         rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin();
00484 
00485 
00486                         relaxation = 1.f;
00487                         btScalar rel_vel;
00488                         btVector3 vel;
00489 
00490                         int frictionIndex = m_tmpSolverContactConstraintPool.size();
00491 
00492                         {
00493                                 btSolverConstraint& solverConstraint = m_tmpSolverContactConstraintPool.expandNonInitializing();
00494                                 btRigidBody* rb0 = btRigidBody::upcast(colObj0);
00495                                 btRigidBody* rb1 = btRigidBody::upcast(colObj1);
00496 
00497                                 solverConstraint.m_solverBodyA = rb0? rb0 : &getFixedBody();
00498                                 solverConstraint.m_solverBodyB = rb1? rb1 : &getFixedBody();
00499 
00500                                 solverConstraint.m_originalContactPoint = &cp;
00501 
00502                                 btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB);
00503                                 solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0*rb0->getAngularFactor() : btVector3(0,0,0);
00504                                 btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB);            
00505                                 solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*-torqueAxis1*rb1->getAngularFactor() : btVector3(0,0,0);
00506                                 {
00507 #ifdef COMPUTE_IMPULSE_DENOM
00508                                         btScalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB);
00509                                         btScalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB);
00510 #else                                                   
00511                                         btVector3 vec;
00512                                         btScalar denom0 = 0.f;
00513                                         btScalar denom1 = 0.f;
00514                                         if (rb0)
00515                                         {
00516                                                 vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1);
00517                                                 denom0 = rb0->getInvMass() + cp.m_normalWorldOnB.dot(vec);
00518                                         }
00519                                         if (rb1)
00520                                         {
00521                                                 vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2);
00522                                                 denom1 = rb1->getInvMass() + cp.m_normalWorldOnB.dot(vec);
00523                                         }
00524 #endif //COMPUTE_IMPULSE_DENOM          
00525 
00526                                         btScalar denom = relaxation/(denom0+denom1);
00527                                         solverConstraint.m_jacDiagABInv = denom;
00528                                 }
00529 
00530                                 solverConstraint.m_contactNormal = cp.m_normalWorldOnB;
00531                                 solverConstraint.m_relpos1CrossNormal = rel_pos1.cross(cp.m_normalWorldOnB);
00532                                 solverConstraint.m_relpos2CrossNormal = rel_pos2.cross(-cp.m_normalWorldOnB);
00533 
00534 
00535                                 btVector3 vel1 = rb0 ? rb0->getVelocityInLocalPoint(rel_pos1) : btVector3(0,0,0);
00536                                 btVector3 vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0);
00537 
00538                                 vel  = vel1 - vel2;
00539 
00540                                 rel_vel = cp.m_normalWorldOnB.dot(vel);
00541 
00542                                 btScalar penetration = cp.getDistance()+infoGlobal.m_linearSlop;
00543 
00544 
00545                                 solverConstraint.m_friction = cp.m_combinedFriction;
00546 
00547                                 btScalar restitution = 0.f;
00548                                 
00549                                 if (cp.m_lifeTime>infoGlobal.m_restingContactRestitutionThreshold)
00550                                 {
00551                                         restitution = 0.f;
00552                                 } else
00553                                 {
00554                                         restitution =  restitutionCurve(rel_vel, cp.m_combinedRestitution);
00555                                         if (restitution <= btScalar(0.))
00556                                         {
00557                                                 restitution = 0.f;
00558                                         };
00559                                 }
00560 
00561 
00563                                 if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
00564                                 {
00565                                         solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor;
00566                                         if (rb0)
00567                                                 rb0->internalApplyImpulse(solverConstraint.m_contactNormal*rb0->getInvMass()*rb0->getLinearFactor(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse);
00568                                         if (rb1)
00569                                                 rb1->internalApplyImpulse(solverConstraint.m_contactNormal*rb1->getInvMass()*rb1->getLinearFactor(),-solverConstraint.m_angularComponentB,-solverConstraint.m_appliedImpulse);
00570                                 } else
00571                                 {
00572                                         solverConstraint.m_appliedImpulse = 0.f;
00573                                 }
00574 
00575                                 solverConstraint.m_appliedPushImpulse = 0.f;
00576 
00577                                 {
00578                                         btScalar rel_vel;
00579                                         btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rb0?rb0->getLinearVelocity():btVector3(0,0,0)) 
00580                                                 + solverConstraint.m_relpos1CrossNormal.dot(rb0?rb0->getAngularVelocity():btVector3(0,0,0));
00581                                         btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rb1?rb1->getLinearVelocity():btVector3(0,0,0)) 
00582                                                 + solverConstraint.m_relpos2CrossNormal.dot(rb1?rb1->getAngularVelocity():btVector3(0,0,0));
00583 
00584                                         rel_vel = vel1Dotn+vel2Dotn;
00585 
00586                                         btScalar positionalError = 0.f;
00587                                         positionalError = -penetration * infoGlobal.m_erp/infoGlobal.m_timeStep;
00588                                         btScalar        velocityError = restitution - rel_vel;// * damping;
00589                                         btScalar  penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
00590                                         btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
00591                                         if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold))
00592                                         {
00593                                                 //combine position and velocity into rhs
00594                                                 solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
00595                                                 solverConstraint.m_rhsPenetration = 0.f;
00596                                         } else
00597                                         {
00598                                                 //split position and velocity into rhs and m_rhsPenetration
00599                                                 solverConstraint.m_rhs = velocityImpulse;
00600                                                 solverConstraint.m_rhsPenetration = penetrationImpulse;
00601                                         }
00602                                         solverConstraint.m_cfm = 0.f;
00603                                         solverConstraint.m_lowerLimit = 0;
00604                                         solverConstraint.m_upperLimit = 1e10f;
00605                                 }
00606 
00607 
00609 
00610 
00611 
00612                                 if (1)
00613                                 {
00614                                         solverConstraint.m_frictionIndex = m_tmpSolverContactFrictionConstraintPool.size();
00615                                         if (!(infoGlobal.m_solverMode & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING) || !cp.m_lateralFrictionInitialized)
00616                                         {
00617                                                 cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel;
00618                                                 btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2();
00619                                                 if (!(infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > SIMD_EPSILON)
00620                                                 {
00621                                                         cp.m_lateralFrictionDir1 /= btSqrt(lat_rel_vel);
00622                                                         if((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
00623                                                         {
00624                                                                 cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB);
00625                                                                 cp.m_lateralFrictionDir2.normalize();//??
00626                                                                 applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2);
00627                                                                 applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2);
00628                                                                 addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
00629                                                         }
00630 
00631                                                         applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1);
00632                                                         applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1);
00633                                                         addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
00634                                                         cp.m_lateralFrictionInitialized = true;
00635                                                 } else
00636                                                 {
00637                                                         //re-calculate friction direction every frame, todo: check if this is really needed
00638                                                         btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2);
00639                                                         if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
00640                                                         {
00641                                                                 applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2);
00642                                                                 applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2);
00643                                                                 addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
00644                                                         }
00645 
00646                                                         applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1);
00647                                                         applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1);
00648                                                         addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
00649 
00650                                                         cp.m_lateralFrictionInitialized = true;
00651                                                 }
00652 
00653                                         } else
00654                                         {
00655                                                 addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation,cp.m_contactMotion1, cp.m_contactCFM1);
00656                                                 if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
00657                                                         addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation, cp.m_contactMotion2, cp.m_contactCFM2);
00658                                         }
00659 
00660                                         if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING)
00661                                         {
00662                                                 {
00663                                                         btSolverConstraint& frictionConstraint1 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex];
00664                                                         if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
00665                                                         {
00666                                                                 frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor;
00667                                                                 if (rb0)
00668                                                                         rb0->internalApplyImpulse(frictionConstraint1.m_contactNormal*rb0->getInvMass()*rb0->getLinearFactor(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse);
00669                                                                 if (rb1)
00670                                                                         rb1->internalApplyImpulse(frictionConstraint1.m_contactNormal*rb1->getInvMass()*rb1->getLinearFactor(),-frictionConstraint1.m_angularComponentB,-frictionConstraint1.m_appliedImpulse);
00671                                                         } else
00672                                                         {
00673                                                                 frictionConstraint1.m_appliedImpulse = 0.f;
00674                                                         }
00675                                                 }
00676 
00677                                                 if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
00678                                                 {
00679                                                         btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex+1];
00680                                                         if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
00681                                                         {
00682                                                                 frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor;
00683                                                                 if (rb0)
00684                                                                         rb0->internalApplyImpulse(frictionConstraint2.m_contactNormal*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse);
00685                                                                 if (rb1)
00686                                                                         rb1->internalApplyImpulse(frictionConstraint2.m_contactNormal*rb1->getInvMass(),-frictionConstraint2.m_angularComponentB,-frictionConstraint2.m_appliedImpulse);
00687                                                         } else
00688                                                         {
00689                                                                 frictionConstraint2.m_appliedImpulse = 0.f;
00690                                                         }
00691                                                 }
00692                                         } else
00693                                         {
00694                                                 btSolverConstraint& frictionConstraint1 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex];
00695                                                 frictionConstraint1.m_appliedImpulse = 0.f;
00696                                                 if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
00697                                                 {
00698                                                         btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex+1];
00699                                                         frictionConstraint2.m_appliedImpulse = 0.f;
00700                                                 }
00701                                         }
00702                                 }
00703                         }
00704 
00705 
00706                 }
00707         }
00708 }
00709 
00710 
00711 btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** /*bodies */,int /*numBodies */,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
00712 {
00713         BT_PROFILE("solveGroupCacheFriendlySetup");
00714         (void)stackAlloc;
00715         (void)debugDrawer;
00716 
00717 
00718         if (!(numConstraints + numManifolds))
00719         {
00720                 //              printf("empty\n");
00721                 return 0.f;
00722         }
00723 
00724         if (1)
00725         {
00726                 int j;
00727                 for (j=0;j<numConstraints;j++)
00728                 {
00729                         btTypedConstraint* constraint = constraints[j];
00730                         constraint->buildJacobian();
00731                 }
00732         }
00733         //btRigidBody* rb0=0,*rb1=0;
00734 
00735         //if (1)
00736         {
00737                 {
00738 
00739                         int totalNumRows = 0;
00740                         int i;
00741                         
00742                         m_tmpConstraintSizesPool.resize(numConstraints);
00743                         //calculate the total number of contraint rows
00744                         for (i=0;i<numConstraints;i++)
00745                         {
00746                                 btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
00747                                 constraints[i]->getInfo1(&info1);
00748                                 totalNumRows += info1.m_numConstraintRows;
00749                         }
00750                         m_tmpSolverNonContactConstraintPool.resize(totalNumRows);
00751 
00752                         
00754                         int currentRow = 0;
00755 
00756                         for (i=0;i<numConstraints;i++)
00757                         {
00758                                 const btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
00759                                 
00760                                 if (info1.m_numConstraintRows)
00761                                 {
00762                                         btAssert(currentRow<totalNumRows);
00763 
00764                                         btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow];
00765                                         btTypedConstraint* constraint = constraints[i];
00766 
00767 
00768 
00769                                         btRigidBody& rbA = constraint->getRigidBodyA();
00770                                         btRigidBody& rbB = constraint->getRigidBodyB();
00771 
00772                                         
00773                                         int j;
00774                                         for ( j=0;j<info1.m_numConstraintRows;j++)
00775                                         {
00776                                                 memset(&currentConstraintRow[j],0,sizeof(btSolverConstraint));
00777                                                 currentConstraintRow[j].m_lowerLimit = -FLT_MAX;
00778                                                 currentConstraintRow[j].m_upperLimit = FLT_MAX;
00779                                                 currentConstraintRow[j].m_appliedImpulse = 0.f;
00780                                                 currentConstraintRow[j].m_appliedPushImpulse = 0.f;
00781                                                 currentConstraintRow[j].m_solverBodyA = &rbA;
00782                                                 currentConstraintRow[j].m_solverBodyB = &rbB;
00783                                         }
00784 
00785                                         rbA.internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
00786                                         rbA.internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
00787                                         rbB.internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
00788                                         rbB.internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
00789 
00790 
00791 
00792                                         btTypedConstraint::btConstraintInfo2 info2;
00793                                         info2.fps = 1.f/infoGlobal.m_timeStep;
00794                                         info2.erp = infoGlobal.m_erp;
00795                                         info2.m_J1linearAxis = currentConstraintRow->m_contactNormal;
00796                                         info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal;
00797                                         info2.m_J2linearAxis = 0;
00798                                         info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal;
00799                                         info2.rowskip = sizeof(btSolverConstraint)/sizeof(btScalar);//check this
00801                                         btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint));
00802                                         info2.m_constraintError = &currentConstraintRow->m_rhs;
00803                                         currentConstraintRow->m_cfm = infoGlobal.m_globalCfm;
00804                                         info2.cfm = &currentConstraintRow->m_cfm;
00805                                         info2.m_lowerLimit = &currentConstraintRow->m_lowerLimit;
00806                                         info2.m_upperLimit = &currentConstraintRow->m_upperLimit;
00807                                         info2.m_numIterations = infoGlobal.m_numIterations;
00808                                         constraints[i]->getInfo2(&info2);
00809 
00811                                         for ( j=0;j<info1.m_numConstraintRows;j++)
00812                                         {
00813                                                 btSolverConstraint& solverConstraint = currentConstraintRow[j];
00814                                                 solverConstraint.m_originalContactPoint = constraint;
00815 
00816                                                 {
00817                                                         const btVector3& ftorqueAxis1 = solverConstraint.m_relpos1CrossNormal;
00818                                                         solverConstraint.m_angularComponentA = constraint->getRigidBodyA().getInvInertiaTensorWorld()*ftorqueAxis1*constraint->getRigidBodyA().getAngularFactor();
00819                                                 }
00820                                                 {
00821                                                         const btVector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal;
00822                                                         solverConstraint.m_angularComponentB = constraint->getRigidBodyB().getInvInertiaTensorWorld()*ftorqueAxis2*constraint->getRigidBodyB().getAngularFactor();
00823                                                 }
00824 
00825                                                 {
00826                                                         btVector3 iMJlA = solverConstraint.m_contactNormal*rbA.getInvMass();
00827                                                         btVector3 iMJaA = rbA.getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal;
00828                                                         btVector3 iMJlB = solverConstraint.m_contactNormal*rbB.getInvMass();//sign of normal?
00829                                                         btVector3 iMJaB = rbB.getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal;
00830 
00831                                                         btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal);
00832                                                         sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal);
00833                                                         sum += iMJlB.dot(solverConstraint.m_contactNormal);
00834                                                         sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal);
00835 
00836                                                         solverConstraint.m_jacDiagABInv = btScalar(1.)/sum;
00837                                                 }
00838 
00839 
00842                                                 {
00843                                                         btScalar rel_vel;
00844                                                         btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rbA.getLinearVelocity()) + solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity());
00845                                                         btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rbB.getLinearVelocity()) + solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity());
00846 
00847                                                         rel_vel = vel1Dotn+vel2Dotn;
00848 
00849                                                         btScalar restitution = 0.f;
00850                                                         btScalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2
00851                                                         btScalar        velocityError = restitution - rel_vel;// * damping;
00852                                                         btScalar        penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
00853                                                         btScalar        velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
00854                                                         solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
00855                                                         solverConstraint.m_appliedImpulse = 0.f;
00856 
00857                                                 }
00858                                         }
00859                                 }
00860                                 currentRow+=m_tmpConstraintSizesPool[i].m_numConstraintRows;
00861                         }
00862                 }
00863 
00864                 {
00865                         int i;
00866                         btPersistentManifold* manifold = 0;
00867 //                      btCollisionObject* colObj0=0,*colObj1=0;
00868 
00869 
00870                         for (i=0;i<numManifolds;i++)
00871                         {
00872                                 manifold = manifoldPtr[i];
00873                                 convertContact(manifold,infoGlobal);
00874                         }
00875                 }
00876         }
00877 
00878         btContactSolverInfo info = infoGlobal;
00879 
00880 
00881 
00882         int numConstraintPool = m_tmpSolverContactConstraintPool.size();
00883         int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size();
00884 
00886         m_orderTmpConstraintPool.resize(numConstraintPool);
00887         m_orderFrictionConstraintPool.resize(numFrictionPool);
00888         {
00889                 int i;
00890                 for (i=0;i<numConstraintPool;i++)
00891                 {
00892                         m_orderTmpConstraintPool[i] = i;
00893                 }
00894                 for (i=0;i<numFrictionPool;i++)
00895                 {
00896                         m_orderFrictionConstraintPool[i] = i;
00897                 }
00898         }
00899 
00900         return 0.f;
00901 
00902 }
00903 
00904 btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(btCollisionObject** /*bodies */,int /*numBodies*/,btPersistentManifold** /*manifoldPtr*/, int /*numManifolds*/,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* /*debugDrawer*/,btStackAlloc* /*stackAlloc*/)
00905 {
00906         BT_PROFILE("solveGroupCacheFriendlyIterations");
00907 
00908         int numConstraintPool = m_tmpSolverContactConstraintPool.size();
00909         int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size();
00910 
00911         //should traverse the contacts random order...
00912         int iteration;
00913         {
00914                 for ( iteration = 0;iteration<infoGlobal.m_numIterations;iteration++)
00915                 {                       
00916 
00917                         int j;
00918                         if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER)
00919                         {
00920                                 if ((iteration & 7) == 0) {
00921                                         for (j=0; j<numConstraintPool; ++j) {
00922                                                 int tmp = m_orderTmpConstraintPool[j];
00923                                                 int swapi = btRandInt2(j+1);
00924                                                 m_orderTmpConstraintPool[j] = m_orderTmpConstraintPool[swapi];
00925                                                 m_orderTmpConstraintPool[swapi] = tmp;
00926                                         }
00927 
00928                                         for (j=0; j<numFrictionPool; ++j) {
00929                                                 int tmp = m_orderFrictionConstraintPool[j];
00930                                                 int swapi = btRandInt2(j+1);
00931                                                 m_orderFrictionConstraintPool[j] = m_orderFrictionConstraintPool[swapi];
00932                                                 m_orderFrictionConstraintPool[swapi] = tmp;
00933                                         }
00934                                 }
00935                         }
00936 
00937                         if (infoGlobal.m_solverMode & SOLVER_SIMD)
00938                         {
00940                                 for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
00941                                 {
00942                                         btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[j];
00943                                         resolveSingleConstraintRowGenericSIMD(*constraint.m_solverBodyA,*constraint.m_solverBodyB,constraint);
00944                                 }
00945 
00946                                 for (j=0;j<numConstraints;j++)
00947                                 {
00948                                         constraints[j]->solveConstraintObsolete(constraints[j]->getRigidBodyA(),constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep);
00949                                 }
00950 
00952                                 int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
00953                                 for (j=0;j<numPoolConstraints;j++)
00954                                 {
00955                                         const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
00956                                         resolveSingleConstraintRowLowerLimitSIMD(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
00957 
00958                                 }
00960                                 int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
00961                                 for (j=0;j<numFrictionPoolConstraints;j++)
00962                                 {
00963                                         btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
00964                                         btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
00965 
00966                                         if (totalImpulse>btScalar(0))
00967                                         {
00968                                                 solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
00969                                                 solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
00970 
00971                                                 resolveSingleConstraintRowGenericSIMD(*solveManifold.m_solverBodyA,     *solveManifold.m_solverBodyB,solveManifold);
00972                                         }
00973                                 }
00974                         } else
00975                         {
00976 
00978                                 for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
00979                                 {
00980                                         btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[j];
00981                                         resolveSingleConstraintRowGeneric(*constraint.m_solverBodyA,*constraint.m_solverBodyB,constraint);
00982                                 }
00983 
00984                                 for (j=0;j<numConstraints;j++)
00985                                 {
00986                                         constraints[j]->solveConstraintObsolete(constraints[j]->getRigidBodyA(),constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep);
00987                                 }
00989                                 int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
00990                                 for (j=0;j<numPoolConstraints;j++)
00991                                 {
00992                                         const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
00993                                         resolveSingleConstraintRowLowerLimit(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
00994                                 }
00996                                 int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
00997                                 for (j=0;j<numFrictionPoolConstraints;j++)
00998                                 {
00999                                         btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
01000                                         btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
01001 
01002                                         if (totalImpulse>btScalar(0))
01003                                         {
01004                                                 solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
01005                                                 solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
01006 
01007                                                 resolveSingleConstraintRowGeneric(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
01008                                         }
01009                                 }
01010                         }
01011 
01012                 }
01013 
01014                 if (infoGlobal.m_splitImpulse)
01015                 {
01016                         if (infoGlobal.m_solverMode & SOLVER_SIMD)
01017                         {
01018                                 for ( iteration = 0;iteration<infoGlobal.m_numIterations;iteration++)
01019                                 {
01020                                         {
01021                                                 int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
01022                                                 int j;
01023                                                 for (j=0;j<numPoolConstraints;j++)
01024                                                 {
01025                                                         const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
01026 
01027                                                         resolveSplitPenetrationSIMD(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
01028                                                 }
01029                                         }
01030                                 }
01031                         }
01032                         else
01033                         {
01034                                 for ( iteration = 0;iteration<infoGlobal.m_numIterations;iteration++)
01035                                 {
01036                                         {
01037                                                 int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
01038                                                 int j;
01039                                                 for (j=0;j<numPoolConstraints;j++)
01040                                                 {
01041                                                         const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
01042 
01043                                                         resolveSplitPenetrationImpulseCacheFriendly(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
01044                                                 }
01045                                         }
01046                                 }
01047                         }
01048                 }
01049                 
01050         }
01051         return 0.f;
01052 }
01053 
01054 
01055 
01057 btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc,btDispatcher* /*dispatcher*/)
01058 {
01059 
01060         
01061 
01062         BT_PROFILE("solveGroup");
01063         //we only implement SOLVER_CACHE_FRIENDLY now
01064         //you need to provide at least some bodies
01065         btAssert(bodies);
01066         btAssert(numBodies);
01067 
01068         int i;
01069 
01070         solveGroupCacheFriendlySetup( bodies, numBodies, manifoldPtr,  numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
01071         solveGroupCacheFriendlyIterations(bodies, numBodies, manifoldPtr,  numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
01072 
01073         int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
01074         int j;
01075 
01076         for (j=0;j<numPoolConstraints;j++)
01077         {
01078 
01079                 const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[j];
01080                 btManifoldPoint* pt = (btManifoldPoint*) solveManifold.m_originalContactPoint;
01081                 btAssert(pt);
01082                 pt->m_appliedImpulse = solveManifold.m_appliedImpulse;
01083                 if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING)
01084                 {
01085                         pt->m_appliedImpulseLateral1 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
01086                         pt->m_appliedImpulseLateral2 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse;
01087                 }
01088 
01089                 //do a callback here?
01090         }
01091 
01092         numPoolConstraints = m_tmpSolverNonContactConstraintPool.size();
01093         for (j=0;j<numPoolConstraints;j++)
01094         {
01095                 const btSolverConstraint& solverConstr = m_tmpSolverNonContactConstraintPool[j];
01096                 btTypedConstraint* constr = (btTypedConstraint*)solverConstr.m_originalContactPoint;
01097                 btScalar sum = constr->internalGetAppliedImpulse();
01098                 sum += solverConstr.m_appliedImpulse;
01099                 constr->internalSetAppliedImpulse(sum);
01100         }
01101 
01102 
01103         if (infoGlobal.m_splitImpulse)
01104         {               
01105                 for ( i=0;i<numBodies;i++)
01106                 {
01107                         btRigidBody* body = btRigidBody::upcast(bodies[i]);
01108                         if (body)
01109                                 body->internalWritebackVelocity(infoGlobal.m_timeStep);
01110                 }
01111         } else
01112         {
01113                 for ( i=0;i<numBodies;i++)
01114                 {
01115                         btRigidBody* body = btRigidBody::upcast(bodies[i]);
01116                         if (body)
01117                                 body->internalWritebackVelocity();
01118                 }
01119         }
01120 
01121 
01122         m_tmpSolverContactConstraintPool.resize(0);
01123         m_tmpSolverNonContactConstraintPool.resize(0);
01124         m_tmpSolverContactFrictionConstraintPool.resize(0);
01125 
01126         return 0.f;
01127 }
01128 
01129 
01130 
01131 
01132 
01133 
01134 
01135 
01136 
01137 void    btSequentialImpulseConstraintSolver::reset()
01138 {
01139         m_btSeed2 = 0;
01140 }
01141 
01142 

Generated on Mon Feb 15 22:17:06 2010 for Bullet Collision Detection & Physics Library by  doxygen 1.6.1