Home | History | Annotate | Download | only in ConstraintSolver
      1 /*
      2 Bullet Continuous Collision Detection and Physics Library
      3 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
      4 
      5 This software is provided 'as-is', without any express or implied warranty.
      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,
      9 subject to the following restrictions:
     10 
     11 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.
     12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
     13 3. This notice may not be removed or altered from any source distribution.
     14 */
     15 
     16 //#define COMPUTE_IMPULSE_DENOM 1
     17 //#define BT_ADDITIONAL_DEBUG
     18 
     19 //It is not necessary (redundant) to refresh contact manifolds, this refresh has been moved to the collision algorithms.
     20 
     21 #include "btSequentialImpulseConstraintSolver.h"
     22 #include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
     23 
     24 #include "LinearMath/btIDebugDraw.h"
     25 #include "LinearMath/btCpuFeatureUtility.h"
     26 
     27 //#include "btJacobianEntry.h"
     28 #include "LinearMath/btMinMax.h"
     29 #include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
     30 #include <new>
     31 #include "LinearMath/btStackAlloc.h"
     32 #include "LinearMath/btQuickprof.h"
     33 //#include "btSolverBody.h"
     34 //#include "btSolverConstraint.h"
     35 #include "LinearMath/btAlignedObjectArray.h"
     36 #include <string.h> //for memset
     37 
     38 int		gNumSplitImpulseRecoveries = 0;
     39 
     40 #include "BulletDynamics/Dynamics/btRigidBody.h"
     41 
     42 
     43 ///This is the scalar reference implementation of solving a single constraint row, the innerloop of the Projected Gauss Seidel/Sequential Impulse constraint solver
     44 ///Below are optional SSE2 and SSE4/FMA3 versions. We assume most hardware has SSE2. For SSE4/FMA3 we perform a CPU feature check.
     45 static btSimdScalar gResolveSingleConstraintRowGeneric_scalar_reference(btSolverBody& body1, btSolverBody& body2, const btSolverConstraint& c)
     46 {
     47 	btScalar deltaImpulse = c.m_rhs - btScalar(c.m_appliedImpulse)*c.m_cfm;
     48 	const btScalar deltaVel1Dotn = c.m_contactNormal1.dot(body1.internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity());
     49 	const btScalar deltaVel2Dotn = c.m_contactNormal2.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity());
     50 
     51 	//	const btScalar delta_rel_vel	=	deltaVel1Dotn-deltaVel2Dotn;
     52 	deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv;
     53 	deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv;
     54 
     55 	const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse;
     56 	if (sum < c.m_lowerLimit)
     57 	{
     58 		deltaImpulse = c.m_lowerLimit - c.m_appliedImpulse;
     59 		c.m_appliedImpulse = c.m_lowerLimit;
     60 	}
     61 	else if (sum > c.m_upperLimit)
     62 	{
     63 		deltaImpulse = c.m_upperLimit - c.m_appliedImpulse;
     64 		c.m_appliedImpulse = c.m_upperLimit;
     65 	}
     66 	else
     67 	{
     68 		c.m_appliedImpulse = sum;
     69 	}
     70 
     71 	body1.internalApplyImpulse(c.m_contactNormal1*body1.internalGetInvMass(), c.m_angularComponentA, deltaImpulse);
     72 	body2.internalApplyImpulse(c.m_contactNormal2*body2.internalGetInvMass(), c.m_angularComponentB, deltaImpulse);
     73 
     74 	return deltaImpulse;
     75 }
     76 
     77 
     78 static btSimdScalar gResolveSingleConstraintRowLowerLimit_scalar_reference(btSolverBody& body1, btSolverBody& body2, const btSolverConstraint& c)
     79 {
     80 	btScalar deltaImpulse = c.m_rhs - btScalar(c.m_appliedImpulse)*c.m_cfm;
     81 	const btScalar deltaVel1Dotn = c.m_contactNormal1.dot(body1.internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity());
     82 	const btScalar deltaVel2Dotn = c.m_contactNormal2.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity());
     83 
     84 	deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv;
     85 	deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv;
     86 	const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse;
     87 	if (sum < c.m_lowerLimit)
     88 	{
     89 		deltaImpulse = c.m_lowerLimit - c.m_appliedImpulse;
     90 		c.m_appliedImpulse = c.m_lowerLimit;
     91 	}
     92 	else
     93 	{
     94 		c.m_appliedImpulse = sum;
     95 	}
     96 	body1.internalApplyImpulse(c.m_contactNormal1*body1.internalGetInvMass(), c.m_angularComponentA, deltaImpulse);
     97 	body2.internalApplyImpulse(c.m_contactNormal2*body2.internalGetInvMass(), c.m_angularComponentB, deltaImpulse);
     98 
     99 	return deltaImpulse;
    100 }
    101 
    102 
    103 
    104 #ifdef USE_SIMD
    105 #include <emmintrin.h>
    106 
    107 
    108 #define btVecSplat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e,e,e,e))
    109 static inline __m128 btSimdDot3( __m128 vec0, __m128 vec1 )
    110 {
    111 	__m128 result = _mm_mul_ps( vec0, vec1);
    112 	return _mm_add_ps( btVecSplat( result, 0 ), _mm_add_ps( btVecSplat( result, 1 ), btVecSplat( result, 2 ) ) );
    113 }
    114 
    115 #if defined (BT_ALLOW_SSE4)
    116 #include <intrin.h>
    117 
    118 #define USE_FMA					1
    119 #define USE_FMA3_INSTEAD_FMA4	1
    120 #define USE_SSE4_DOT			1
    121 
    122 #define SSE4_DP(a, b)			_mm_dp_ps(a, b, 0x7f)
    123 #define SSE4_DP_FP(a, b)		_mm_cvtss_f32(_mm_dp_ps(a, b, 0x7f))
    124 
    125 #if USE_SSE4_DOT
    126 #define DOT_PRODUCT(a, b)		SSE4_DP(a, b)
    127 #else
    128 #define DOT_PRODUCT(a, b)		btSimdDot3(a, b)
    129 #endif
    130 
    131 #if USE_FMA
    132 #if USE_FMA3_INSTEAD_FMA4
    133 // a*b + c
    134 #define FMADD(a, b, c)		_mm_fmadd_ps(a, b, c)
    135 // -(a*b) + c
    136 #define FMNADD(a, b, c)		_mm_fnmadd_ps(a, b, c)
    137 #else // USE_FMA3
    138 // a*b + c
    139 #define FMADD(a, b, c)		_mm_macc_ps(a, b, c)
    140 // -(a*b) + c
    141 #define FMNADD(a, b, c)		_mm_nmacc_ps(a, b, c)
    142 #endif
    143 #else // USE_FMA
    144 // c + a*b
    145 #define FMADD(a, b, c)		_mm_add_ps(c, _mm_mul_ps(a, b))
    146 // c - a*b
    147 #define FMNADD(a, b, c)		_mm_sub_ps(c, _mm_mul_ps(a, b))
    148 #endif
    149 #endif
    150 
    151 // Project Gauss Seidel or the equivalent Sequential Impulse
    152 static btSimdScalar gResolveSingleConstraintRowGeneric_sse2(btSolverBody& body1, btSolverBody& body2, const btSolverConstraint& c)
    153 {
    154 	__m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse);
    155 	__m128	lowerLimit1 = _mm_set1_ps(c.m_lowerLimit);
    156 	__m128	upperLimit1 = _mm_set1_ps(c.m_upperLimit);
    157 	btSimdScalar 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)));
    158 	__m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal1.mVec128, body1.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128, body1.internalGetDeltaAngularVelocity().mVec128));
    159 	__m128 deltaVel2Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal2.mVec128, body2.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos2CrossNormal.mVec128, body2.internalGetDeltaAngularVelocity().mVec128));
    160 	deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel1Dotn, _mm_set1_ps(c.m_jacDiagABInv)));
    161 	deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel2Dotn, _mm_set1_ps(c.m_jacDiagABInv)));
    162 	btSimdScalar sum = _mm_add_ps(cpAppliedImp, deltaImpulse);
    163 	btSimdScalar resultLowerLess, resultUpperLess;
    164 	resultLowerLess = _mm_cmplt_ps(sum, lowerLimit1);
    165 	resultUpperLess = _mm_cmplt_ps(sum, upperLimit1);
    166 	__m128 lowMinApplied = _mm_sub_ps(lowerLimit1, cpAppliedImp);
    167 	deltaImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse));
    168 	c.m_appliedImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum));
    169 	__m128 upperMinApplied = _mm_sub_ps(upperLimit1, cpAppliedImp);
    170 	deltaImpulse = _mm_or_ps(_mm_and_ps(resultUpperLess, deltaImpulse), _mm_andnot_ps(resultUpperLess, upperMinApplied));
    171 	c.m_appliedImpulse = _mm_or_ps(_mm_and_ps(resultUpperLess, c.m_appliedImpulse), _mm_andnot_ps(resultUpperLess, upperLimit1));
    172 	__m128	linearComponentA = _mm_mul_ps(c.m_contactNormal1.mVec128, body1.internalGetInvMass().mVec128);
    173 	__m128	linearComponentB = _mm_mul_ps((c.m_contactNormal2).mVec128, body2.internalGetInvMass().mVec128);
    174 	__m128 impulseMagnitude = deltaImpulse;
    175 	body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128, _mm_mul_ps(linearComponentA, impulseMagnitude));
    176 	body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128, _mm_mul_ps(c.m_angularComponentA.mVec128, impulseMagnitude));
    177 	body2.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaLinearVelocity().mVec128, _mm_mul_ps(linearComponentB, impulseMagnitude));
    178 	body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128, _mm_mul_ps(c.m_angularComponentB.mVec128, impulseMagnitude));
    179 	return deltaImpulse;
    180 }
    181 
    182 
    183 // Enhanced version of gResolveSingleConstraintRowGeneric_sse2 with SSE4.1 and FMA3
    184 static btSimdScalar gResolveSingleConstraintRowGeneric_sse4_1_fma3(btSolverBody& body1, btSolverBody& body2, const btSolverConstraint& c)
    185 {
    186 #if defined (BT_ALLOW_SSE4)
    187 	__m128 tmp					= _mm_set_ps1(c.m_jacDiagABInv);
    188 	__m128 deltaImpulse			= _mm_set_ps1(c.m_rhs - btScalar(c.m_appliedImpulse)*c.m_cfm);
    189 	const __m128 lowerLimit		= _mm_set_ps1(c.m_lowerLimit);
    190 	const __m128 upperLimit		= _mm_set_ps1(c.m_upperLimit);
    191 	const __m128 deltaVel1Dotn	= _mm_add_ps(DOT_PRODUCT(c.m_contactNormal1.mVec128, body1.internalGetDeltaLinearVelocity().mVec128), DOT_PRODUCT(c.m_relpos1CrossNormal.mVec128, body1.internalGetDeltaAngularVelocity().mVec128));
    192 	const __m128 deltaVel2Dotn	= _mm_add_ps(DOT_PRODUCT(c.m_contactNormal2.mVec128, body2.internalGetDeltaLinearVelocity().mVec128), DOT_PRODUCT(c.m_relpos2CrossNormal.mVec128, body2.internalGetDeltaAngularVelocity().mVec128));
    193 	deltaImpulse				= FMNADD(deltaVel1Dotn, tmp, deltaImpulse);
    194 	deltaImpulse				= FMNADD(deltaVel2Dotn, tmp, deltaImpulse);
    195 	tmp							= _mm_add_ps(c.m_appliedImpulse, deltaImpulse); // sum
    196 	const __m128 maskLower		= _mm_cmpgt_ps(tmp, lowerLimit);
    197 	const __m128 maskUpper		= _mm_cmpgt_ps(upperLimit, tmp);
    198 	deltaImpulse				= _mm_blendv_ps(_mm_sub_ps(lowerLimit, c.m_appliedImpulse), _mm_blendv_ps(_mm_sub_ps(upperLimit, c.m_appliedImpulse), deltaImpulse, maskUpper), maskLower);
    199 	c.m_appliedImpulse			= _mm_blendv_ps(lowerLimit, _mm_blendv_ps(upperLimit, tmp, maskUpper), maskLower);
    200 	body1.internalGetDeltaLinearVelocity().mVec128	= FMADD(_mm_mul_ps(c.m_contactNormal1.mVec128, body1.internalGetInvMass().mVec128), deltaImpulse, body1.internalGetDeltaLinearVelocity().mVec128);
    201 	body1.internalGetDeltaAngularVelocity().mVec128 = FMADD(c.m_angularComponentA.mVec128, deltaImpulse, body1.internalGetDeltaAngularVelocity().mVec128);
    202 	body2.internalGetDeltaLinearVelocity().mVec128	= FMADD(_mm_mul_ps(c.m_contactNormal2.mVec128, body2.internalGetInvMass().mVec128), deltaImpulse, body2.internalGetDeltaLinearVelocity().mVec128);
    203 	body2.internalGetDeltaAngularVelocity().mVec128 = FMADD(c.m_angularComponentB.mVec128, deltaImpulse, body2.internalGetDeltaAngularVelocity().mVec128);
    204 	return deltaImpulse;
    205 #else
    206 	return gResolveSingleConstraintRowGeneric_sse2(body1,body2,c);
    207 #endif
    208 }
    209 
    210 
    211 
    212 static btSimdScalar gResolveSingleConstraintRowLowerLimit_sse2(btSolverBody& body1, btSolverBody& body2, const btSolverConstraint& c)
    213 {
    214 	__m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse);
    215 	__m128	lowerLimit1 = _mm_set1_ps(c.m_lowerLimit);
    216 	__m128	upperLimit1 = _mm_set1_ps(c.m_upperLimit);
    217 	btSimdScalar 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)));
    218 	__m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal1.mVec128, body1.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128, body1.internalGetDeltaAngularVelocity().mVec128));
    219 	__m128 deltaVel2Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal2.mVec128, body2.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos2CrossNormal.mVec128, body2.internalGetDeltaAngularVelocity().mVec128));
    220 	deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel1Dotn, _mm_set1_ps(c.m_jacDiagABInv)));
    221 	deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel2Dotn, _mm_set1_ps(c.m_jacDiagABInv)));
    222 	btSimdScalar sum = _mm_add_ps(cpAppliedImp, deltaImpulse);
    223 	btSimdScalar resultLowerLess, resultUpperLess;
    224 	resultLowerLess = _mm_cmplt_ps(sum, lowerLimit1);
    225 	resultUpperLess = _mm_cmplt_ps(sum, upperLimit1);
    226 	__m128 lowMinApplied = _mm_sub_ps(lowerLimit1, cpAppliedImp);
    227 	deltaImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse));
    228 	c.m_appliedImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum));
    229 	__m128	linearComponentA = _mm_mul_ps(c.m_contactNormal1.mVec128, body1.internalGetInvMass().mVec128);
    230 	__m128	linearComponentB = _mm_mul_ps(c.m_contactNormal2.mVec128, body2.internalGetInvMass().mVec128);
    231 	__m128 impulseMagnitude = deltaImpulse;
    232 	body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128, _mm_mul_ps(linearComponentA, impulseMagnitude));
    233 	body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128, _mm_mul_ps(c.m_angularComponentA.mVec128, impulseMagnitude));
    234 	body2.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaLinearVelocity().mVec128, _mm_mul_ps(linearComponentB, impulseMagnitude));
    235 	body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128, _mm_mul_ps(c.m_angularComponentB.mVec128, impulseMagnitude));
    236 	return deltaImpulse;
    237 }
    238 
    239 
    240 // Enhanced version of gResolveSingleConstraintRowGeneric_sse2 with SSE4.1 and FMA3
    241 static btSimdScalar gResolveSingleConstraintRowLowerLimit_sse4_1_fma3(btSolverBody& body1, btSolverBody& body2, const btSolverConstraint& c)
    242 {
    243 #ifdef BT_ALLOW_SSE4
    244 	__m128 tmp					= _mm_set_ps1(c.m_jacDiagABInv);
    245 	__m128 deltaImpulse			= _mm_set_ps1(c.m_rhs - btScalar(c.m_appliedImpulse)*c.m_cfm);
    246 	const __m128 lowerLimit		= _mm_set_ps1(c.m_lowerLimit);
    247 	const __m128 deltaVel1Dotn	= _mm_add_ps(DOT_PRODUCT(c.m_contactNormal1.mVec128, body1.internalGetDeltaLinearVelocity().mVec128), DOT_PRODUCT(c.m_relpos1CrossNormal.mVec128, body1.internalGetDeltaAngularVelocity().mVec128));
    248 	const __m128 deltaVel2Dotn	= _mm_add_ps(DOT_PRODUCT(c.m_contactNormal2.mVec128, body2.internalGetDeltaLinearVelocity().mVec128), DOT_PRODUCT(c.m_relpos2CrossNormal.mVec128, body2.internalGetDeltaAngularVelocity().mVec128));
    249 	deltaImpulse				= FMNADD(deltaVel1Dotn, tmp, deltaImpulse);
    250 	deltaImpulse				= FMNADD(deltaVel2Dotn, tmp, deltaImpulse);
    251 	tmp							= _mm_add_ps(c.m_appliedImpulse, deltaImpulse);
    252 	const __m128 mask			= _mm_cmpgt_ps(tmp, lowerLimit);
    253 	deltaImpulse				= _mm_blendv_ps(_mm_sub_ps(lowerLimit, c.m_appliedImpulse), deltaImpulse, mask);
    254 	c.m_appliedImpulse			= _mm_blendv_ps(lowerLimit, tmp, mask);
    255 	body1.internalGetDeltaLinearVelocity().mVec128	= FMADD(_mm_mul_ps(c.m_contactNormal1.mVec128, body1.internalGetInvMass().mVec128), deltaImpulse, body1.internalGetDeltaLinearVelocity().mVec128);
    256 	body1.internalGetDeltaAngularVelocity().mVec128 = FMADD(c.m_angularComponentA.mVec128, deltaImpulse, body1.internalGetDeltaAngularVelocity().mVec128);
    257 	body2.internalGetDeltaLinearVelocity().mVec128	= FMADD(_mm_mul_ps(c.m_contactNormal2.mVec128, body2.internalGetInvMass().mVec128), deltaImpulse, body2.internalGetDeltaLinearVelocity().mVec128);
    258 	body2.internalGetDeltaAngularVelocity().mVec128 = FMADD(c.m_angularComponentB.mVec128, deltaImpulse, body2.internalGetDeltaAngularVelocity().mVec128);
    259 	return deltaImpulse;
    260 #else
    261 	return gResolveSingleConstraintRowLowerLimit_sse2(body1,body2,c);
    262 #endif //BT_ALLOW_SSE4
    263 }
    264 
    265 
    266 #endif //USE_SIMD
    267 
    268 
    269 
    270 btSimdScalar btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
    271 {
    272 #ifdef USE_SIMD
    273 	return m_resolveSingleConstraintRowGeneric(body1, body2, c);
    274 #else
    275 	return resolveSingleConstraintRowGeneric(body1,body2,c);
    276 #endif
    277 }
    278 
    279 // Project Gauss Seidel or the equivalent Sequential Impulse
    280 btSimdScalar btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGeneric(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
    281 {
    282 	return gResolveSingleConstraintRowGeneric_scalar_reference(body1, body2, c);
    283 }
    284 
    285 btSimdScalar btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
    286 {
    287 #ifdef USE_SIMD
    288 	return m_resolveSingleConstraintRowLowerLimit(body1, body2, c);
    289 #else
    290 	return resolveSingleConstraintRowLowerLimit(body1,body2,c);
    291 #endif
    292 }
    293 
    294 
    295 btSimdScalar btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimit(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
    296 {
    297 	return gResolveSingleConstraintRowLowerLimit_scalar_reference(body1,body2,c);
    298 }
    299 
    300 
    301 void	btSequentialImpulseConstraintSolver::resolveSplitPenetrationImpulseCacheFriendly(
    302         btSolverBody& body1,
    303         btSolverBody& body2,
    304         const btSolverConstraint& c)
    305 {
    306 		if (c.m_rhsPenetration)
    307         {
    308 			gNumSplitImpulseRecoveries++;
    309 			btScalar deltaImpulse = c.m_rhsPenetration-btScalar(c.m_appliedPushImpulse)*c.m_cfm;
    310 			const btScalar deltaVel1Dotn	=	c.m_contactNormal1.dot(body1.internalGetPushVelocity()) 	+ c.m_relpos1CrossNormal.dot(body1.internalGetTurnVelocity());
    311 			const btScalar deltaVel2Dotn	=	c.m_contactNormal2.dot(body2.internalGetPushVelocity())		+ c.m_relpos2CrossNormal.dot(body2.internalGetTurnVelocity());
    312 
    313 			deltaImpulse	-=	deltaVel1Dotn*c.m_jacDiagABInv;
    314 			deltaImpulse	-=	deltaVel2Dotn*c.m_jacDiagABInv;
    315 			const btScalar sum = btScalar(c.m_appliedPushImpulse) + deltaImpulse;
    316 			if (sum < c.m_lowerLimit)
    317 			{
    318 				deltaImpulse = c.m_lowerLimit-c.m_appliedPushImpulse;
    319 				c.m_appliedPushImpulse = c.m_lowerLimit;
    320 			}
    321 			else
    322 			{
    323 				c.m_appliedPushImpulse = sum;
    324 			}
    325 			body1.internalApplyPushImpulse(c.m_contactNormal1*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
    326 			body2.internalApplyPushImpulse(c.m_contactNormal2*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
    327         }
    328 }
    329 
    330  void btSequentialImpulseConstraintSolver::resolveSplitPenetrationSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
    331 {
    332 #ifdef USE_SIMD
    333 	if (!c.m_rhsPenetration)
    334 		return;
    335 
    336 	gNumSplitImpulseRecoveries++;
    337 
    338 	__m128 cpAppliedImp = _mm_set1_ps(c.m_appliedPushImpulse);
    339 	__m128	lowerLimit1 = _mm_set1_ps(c.m_lowerLimit);
    340 	__m128	upperLimit1 = _mm_set1_ps(c.m_upperLimit);
    341 	__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)));
    342 	__m128 deltaVel1Dotn	=	_mm_add_ps(btSimdDot3(c.m_contactNormal1.mVec128,body1.internalGetPushVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetTurnVelocity().mVec128));
    343 	__m128 deltaVel2Dotn	=	_mm_add_ps(btSimdDot3(c.m_contactNormal2.mVec128,body2.internalGetPushVelocity().mVec128), btSimdDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetTurnVelocity().mVec128));
    344 	deltaImpulse	=	_mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
    345 	deltaImpulse	=	_mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
    346 	btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse);
    347 	btSimdScalar resultLowerLess,resultUpperLess;
    348 	resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1);
    349 	resultUpperLess = _mm_cmplt_ps(sum,upperLimit1);
    350 	__m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp);
    351 	deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) );
    352 	c.m_appliedPushImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
    353 	__m128	linearComponentA = _mm_mul_ps(c.m_contactNormal1.mVec128,body1.internalGetInvMass().mVec128);
    354 	__m128	linearComponentB = _mm_mul_ps(c.m_contactNormal2.mVec128,body2.internalGetInvMass().mVec128);
    355 	__m128 impulseMagnitude = deltaImpulse;
    356 	body1.internalGetPushVelocity().mVec128 = _mm_add_ps(body1.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
    357 	body1.internalGetTurnVelocity().mVec128 = _mm_add_ps(body1.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude));
    358 	body2.internalGetPushVelocity().mVec128 = _mm_add_ps(body2.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
    359 	body2.internalGetTurnVelocity().mVec128 = _mm_add_ps(body2.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude));
    360 #else
    361 	resolveSplitPenetrationImpulseCacheFriendly(body1,body2,c);
    362 #endif
    363 }
    364 
    365 
    366  btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver()
    367 	 : m_resolveSingleConstraintRowGeneric(gResolveSingleConstraintRowGeneric_scalar_reference),
    368 	 m_resolveSingleConstraintRowLowerLimit(gResolveSingleConstraintRowLowerLimit_scalar_reference),
    369 	 m_btSeed2(0)
    370  {
    371 
    372 #ifdef USE_SIMD
    373 	 m_resolveSingleConstraintRowGeneric = gResolveSingleConstraintRowGeneric_sse2;
    374 	 m_resolveSingleConstraintRowLowerLimit=gResolveSingleConstraintRowLowerLimit_sse2;
    375 #endif //USE_SIMD
    376 
    377 #ifdef BT_ALLOW_SSE4
    378 	 int cpuFeatures = btCpuFeatureUtility::getCpuFeatures();
    379 	 if ((cpuFeatures & btCpuFeatureUtility::CPU_FEATURE_FMA3) && (cpuFeatures & btCpuFeatureUtility::CPU_FEATURE_SSE4_1))
    380 	 {
    381 		m_resolveSingleConstraintRowGeneric = gResolveSingleConstraintRowGeneric_sse4_1_fma3;
    382 		m_resolveSingleConstraintRowLowerLimit = gResolveSingleConstraintRowLowerLimit_sse4_1_fma3;
    383 	 }
    384 #endif//BT_ALLOW_SSE4
    385 
    386  }
    387 
    388  btSequentialImpulseConstraintSolver::~btSequentialImpulseConstraintSolver()
    389  {
    390  }
    391 
    392  btSingleConstraintRowSolver	btSequentialImpulseConstraintSolver::getScalarConstraintRowSolverGeneric()
    393  {
    394 	 return gResolveSingleConstraintRowGeneric_scalar_reference;
    395  }
    396 
    397  btSingleConstraintRowSolver	btSequentialImpulseConstraintSolver::getScalarConstraintRowSolverLowerLimit()
    398  {
    399 	 return gResolveSingleConstraintRowLowerLimit_scalar_reference;
    400  }
    401 
    402 
    403 #ifdef USE_SIMD
    404  btSingleConstraintRowSolver	btSequentialImpulseConstraintSolver::getSSE2ConstraintRowSolverGeneric()
    405  {
    406 	 return gResolveSingleConstraintRowGeneric_sse2;
    407  }
    408  btSingleConstraintRowSolver	btSequentialImpulseConstraintSolver::getSSE2ConstraintRowSolverLowerLimit()
    409  {
    410 	 return gResolveSingleConstraintRowLowerLimit_sse2;
    411  }
    412 #ifdef BT_ALLOW_SSE4
    413  btSingleConstraintRowSolver	btSequentialImpulseConstraintSolver::getSSE4_1ConstraintRowSolverGeneric()
    414  {
    415 	 return gResolveSingleConstraintRowGeneric_sse4_1_fma3;
    416  }
    417  btSingleConstraintRowSolver	btSequentialImpulseConstraintSolver::getSSE4_1ConstraintRowSolverLowerLimit()
    418  {
    419 	 return gResolveSingleConstraintRowLowerLimit_sse4_1_fma3;
    420  }
    421 #endif //BT_ALLOW_SSE4
    422 #endif //USE_SIMD
    423 
    424 unsigned long btSequentialImpulseConstraintSolver::btRand2()
    425 {
    426 	m_btSeed2 = (1664525L*m_btSeed2 + 1013904223L) & 0xffffffff;
    427 	return m_btSeed2;
    428 }
    429 
    430 
    431 
    432 //See ODE: adam's all-int straightforward(?) dRandInt (0..n-1)
    433 int btSequentialImpulseConstraintSolver::btRandInt2 (int n)
    434 {
    435 	// seems good; xor-fold and modulus
    436 	const unsigned long un = static_cast<unsigned long>(n);
    437 	unsigned long r = btRand2();
    438 
    439 	// note: probably more aggressive than it needs to be -- might be
    440 	//       able to get away without one or two of the innermost branches.
    441 	if (un <= 0x00010000UL) {
    442 		r ^= (r >> 16);
    443 		if (un <= 0x00000100UL) {
    444 			r ^= (r >> 8);
    445 			if (un <= 0x00000010UL) {
    446 				r ^= (r >> 4);
    447 				if (un <= 0x00000004UL) {
    448 					r ^= (r >> 2);
    449 					if (un <= 0x00000002UL) {
    450 						r ^= (r >> 1);
    451 					}
    452 				}
    453 			}
    454 		}
    455 	}
    456 
    457 	return (int) (r % un);
    458 }
    459 
    460 
    461 
    462 void	btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject, btScalar timeStep)
    463 {
    464 
    465 	btRigidBody* rb = collisionObject? btRigidBody::upcast(collisionObject) : 0;
    466 
    467 	solverBody->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
    468 	solverBody->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
    469 	solverBody->internalGetPushVelocity().setValue(0.f,0.f,0.f);
    470 	solverBody->internalGetTurnVelocity().setValue(0.f,0.f,0.f);
    471 
    472 	if (rb)
    473 	{
    474 		solverBody->m_worldTransform = rb->getWorldTransform();
    475 		solverBody->internalSetInvMass(btVector3(rb->getInvMass(),rb->getInvMass(),rb->getInvMass())*rb->getLinearFactor());
    476 		solverBody->m_originalBody = rb;
    477 		solverBody->m_angularFactor = rb->getAngularFactor();
    478 		solverBody->m_linearFactor = rb->getLinearFactor();
    479 		solverBody->m_linearVelocity = rb->getLinearVelocity();
    480 		solverBody->m_angularVelocity = rb->getAngularVelocity();
    481 		solverBody->m_externalForceImpulse = rb->getTotalForce()*rb->getInvMass()*timeStep;
    482 		solverBody->m_externalTorqueImpulse = rb->getTotalTorque()*rb->getInvInertiaTensorWorld()*timeStep ;
    483 
    484 	} else
    485 	{
    486 		solverBody->m_worldTransform.setIdentity();
    487 		solverBody->internalSetInvMass(btVector3(0,0,0));
    488 		solverBody->m_originalBody = 0;
    489 		solverBody->m_angularFactor.setValue(1,1,1);
    490 		solverBody->m_linearFactor.setValue(1,1,1);
    491 		solverBody->m_linearVelocity.setValue(0,0,0);
    492 		solverBody->m_angularVelocity.setValue(0,0,0);
    493 		solverBody->m_externalForceImpulse.setValue(0,0,0);
    494 		solverBody->m_externalTorqueImpulse.setValue(0,0,0);
    495 	}
    496 
    497 
    498 }
    499 
    500 
    501 
    502 
    503 
    504 
    505 btScalar btSequentialImpulseConstraintSolver::restitutionCurve(btScalar rel_vel, btScalar restitution)
    506 {
    507 	btScalar rest = restitution * -rel_vel;
    508 	return rest;
    509 }
    510 
    511 
    512 
    513 void	btSequentialImpulseConstraintSolver::applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection, int frictionMode)
    514 {
    515 
    516 
    517 	if (colObj && colObj->hasAnisotropicFriction(frictionMode))
    518 	{
    519 		// transform to local coordinates
    520 		btVector3 loc_lateral = frictionDirection * colObj->getWorldTransform().getBasis();
    521 		const btVector3& friction_scaling = colObj->getAnisotropicFriction();
    522 		//apply anisotropic friction
    523 		loc_lateral *= friction_scaling;
    524 		// ... and transform it back to global coordinates
    525 		frictionDirection = colObj->getWorldTransform().getBasis() * loc_lateral;
    526 	}
    527 
    528 }
    529 
    530 
    531 
    532 
    533 void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstraint& solverConstraint, const btVector3& normalAxis,int  solverBodyIdA,int solverBodyIdB,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip)
    534 {
    535 
    536 
    537 	btSolverBody& solverBodyA = m_tmpSolverBodyPool[solverBodyIdA];
    538 	btSolverBody& solverBodyB = m_tmpSolverBodyPool[solverBodyIdB];
    539 
    540 	btRigidBody* body0 = m_tmpSolverBodyPool[solverBodyIdA].m_originalBody;
    541 	btRigidBody* body1 = m_tmpSolverBodyPool[solverBodyIdB].m_originalBody;
    542 
    543 	solverConstraint.m_solverBodyIdA = solverBodyIdA;
    544 	solverConstraint.m_solverBodyIdB = solverBodyIdB;
    545 
    546 	solverConstraint.m_friction = cp.m_combinedFriction;
    547 	solverConstraint.m_originalContactPoint = 0;
    548 
    549 	solverConstraint.m_appliedImpulse = 0.f;
    550 	solverConstraint.m_appliedPushImpulse = 0.f;
    551 
    552 	if (body0)
    553 	{
    554 		solverConstraint.m_contactNormal1 = normalAxis;
    555 		btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal1);
    556 		solverConstraint.m_relpos1CrossNormal = ftorqueAxis1;
    557 		solverConstraint.m_angularComponentA = body0->getInvInertiaTensorWorld()*ftorqueAxis1*body0->getAngularFactor();
    558 	}else
    559 	{
    560 		solverConstraint.m_contactNormal1.setZero();
    561 		solverConstraint.m_relpos1CrossNormal.setZero();
    562 		solverConstraint.m_angularComponentA .setZero();
    563 	}
    564 
    565 	if (body1)
    566 	{
    567 		solverConstraint.m_contactNormal2 = -normalAxis;
    568 		btVector3 ftorqueAxis1 = rel_pos2.cross(solverConstraint.m_contactNormal2);
    569 		solverConstraint.m_relpos2CrossNormal = ftorqueAxis1;
    570 		solverConstraint.m_angularComponentB = body1->getInvInertiaTensorWorld()*ftorqueAxis1*body1->getAngularFactor();
    571 	} else
    572 	{
    573 		solverConstraint.m_contactNormal2.setZero();
    574 		solverConstraint.m_relpos2CrossNormal.setZero();
    575 		solverConstraint.m_angularComponentB.setZero();
    576 	}
    577 
    578 	{
    579 		btVector3 vec;
    580 		btScalar denom0 = 0.f;
    581 		btScalar denom1 = 0.f;
    582 		if (body0)
    583 		{
    584 			vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1);
    585 			denom0 = body0->getInvMass() + normalAxis.dot(vec);
    586 		}
    587 		if (body1)
    588 		{
    589 			vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2);
    590 			denom1 = body1->getInvMass() + normalAxis.dot(vec);
    591 		}
    592 		btScalar denom = relaxation/(denom0+denom1);
    593 		solverConstraint.m_jacDiagABInv = denom;
    594 	}
    595 
    596 	{
    597 
    598 
    599 		btScalar rel_vel;
    600 		btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(body0?solverBodyA.m_linearVelocity+solverBodyA.m_externalForceImpulse:btVector3(0,0,0))
    601 			+ solverConstraint.m_relpos1CrossNormal.dot(body0?solverBodyA.m_angularVelocity:btVector3(0,0,0));
    602 		btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(body1?solverBodyB.m_linearVelocity+solverBodyB.m_externalForceImpulse:btVector3(0,0,0))
    603 			+ solverConstraint.m_relpos2CrossNormal.dot(body1?solverBodyB.m_angularVelocity:btVector3(0,0,0));
    604 
    605 		rel_vel = vel1Dotn+vel2Dotn;
    606 
    607 //		btScalar positionalError = 0.f;
    608 
    609 		btScalar velocityError =  desiredVelocity - rel_vel;
    610 		btScalar velocityImpulse = velocityError * solverConstraint.m_jacDiagABInv;
    611 		solverConstraint.m_rhs = velocityImpulse;
    612 		solverConstraint.m_rhsPenetration = 0.f;
    613 		solverConstraint.m_cfm = cfmSlip;
    614 		solverConstraint.m_lowerLimit = -solverConstraint.m_friction;
    615 		solverConstraint.m_upperLimit = solverConstraint.m_friction;
    616 
    617 	}
    618 }
    619 
    620 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, btScalar desiredVelocity, btScalar cfmSlip)
    621 {
    622 	btSolverConstraint& solverConstraint = m_tmpSolverContactFrictionConstraintPool.expandNonInitializing();
    623 	solverConstraint.m_frictionIndex = frictionIndex;
    624 	setupFrictionConstraint(solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2,
    625 							colObj0, colObj1, relaxation, desiredVelocity, cfmSlip);
    626 	return solverConstraint;
    627 }
    628 
    629 
    630 void btSequentialImpulseConstraintSolver::setupRollingFrictionConstraint(	btSolverConstraint& solverConstraint, const btVector3& normalAxis1,int solverBodyIdA,int  solverBodyIdB,
    631 									btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,
    632 									btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation,
    633 									btScalar desiredVelocity, btScalar cfmSlip)
    634 
    635 {
    636 	btVector3 normalAxis(0,0,0);
    637 
    638 
    639 	solverConstraint.m_contactNormal1 = normalAxis;
    640 	solverConstraint.m_contactNormal2 = -normalAxis;
    641 	btSolverBody& solverBodyA = m_tmpSolverBodyPool[solverBodyIdA];
    642 	btSolverBody& solverBodyB = m_tmpSolverBodyPool[solverBodyIdB];
    643 
    644 	btRigidBody* body0 = m_tmpSolverBodyPool[solverBodyIdA].m_originalBody;
    645 	btRigidBody* body1 = m_tmpSolverBodyPool[solverBodyIdB].m_originalBody;
    646 
    647 	solverConstraint.m_solverBodyIdA = solverBodyIdA;
    648 	solverConstraint.m_solverBodyIdB = solverBodyIdB;
    649 
    650 	solverConstraint.m_friction = cp.m_combinedRollingFriction;
    651 	solverConstraint.m_originalContactPoint = 0;
    652 
    653 	solverConstraint.m_appliedImpulse = 0.f;
    654 	solverConstraint.m_appliedPushImpulse = 0.f;
    655 
    656 	{
    657 		btVector3 ftorqueAxis1 = -normalAxis1;
    658 		solverConstraint.m_relpos1CrossNormal = ftorqueAxis1;
    659 		solverConstraint.m_angularComponentA = body0 ? body0->getInvInertiaTensorWorld()*ftorqueAxis1*body0->getAngularFactor() : btVector3(0,0,0);
    660 	}
    661 	{
    662 		btVector3 ftorqueAxis1 = normalAxis1;
    663 		solverConstraint.m_relpos2CrossNormal = ftorqueAxis1;
    664 		solverConstraint.m_angularComponentB = body1 ? body1->getInvInertiaTensorWorld()*ftorqueAxis1*body1->getAngularFactor() : btVector3(0,0,0);
    665 	}
    666 
    667 
    668 	{
    669 		btVector3 iMJaA = body0?body0->getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal:btVector3(0,0,0);
    670 		btVector3 iMJaB = body1?body1->getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal:btVector3(0,0,0);
    671 		btScalar sum = 0;
    672 		sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal);
    673 		sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal);
    674 		solverConstraint.m_jacDiagABInv = btScalar(1.)/sum;
    675 	}
    676 
    677 	{
    678 
    679 
    680 		btScalar rel_vel;
    681 		btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(body0?solverBodyA.m_linearVelocity+solverBodyA.m_externalForceImpulse:btVector3(0,0,0))
    682 			+ solverConstraint.m_relpos1CrossNormal.dot(body0?solverBodyA.m_angularVelocity:btVector3(0,0,0));
    683 		btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(body1?solverBodyB.m_linearVelocity+solverBodyB.m_externalForceImpulse:btVector3(0,0,0))
    684 			+ solverConstraint.m_relpos2CrossNormal.dot(body1?solverBodyB.m_angularVelocity:btVector3(0,0,0));
    685 
    686 		rel_vel = vel1Dotn+vel2Dotn;
    687 
    688 //		btScalar positionalError = 0.f;
    689 
    690 		btSimdScalar velocityError =  desiredVelocity - rel_vel;
    691 		btSimdScalar	velocityImpulse = velocityError * btSimdScalar(solverConstraint.m_jacDiagABInv);
    692 		solverConstraint.m_rhs = velocityImpulse;
    693 		solverConstraint.m_cfm = cfmSlip;
    694 		solverConstraint.m_lowerLimit = -solverConstraint.m_friction;
    695 		solverConstraint.m_upperLimit = solverConstraint.m_friction;
    696 
    697 	}
    698 }
    699 
    700 
    701 
    702 
    703 
    704 
    705 
    706 
    707 btSolverConstraint&	btSequentialImpulseConstraintSolver::addRollingFrictionConstraint(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, btScalar desiredVelocity, btScalar cfmSlip)
    708 {
    709 	btSolverConstraint& solverConstraint = m_tmpSolverContactRollingFrictionConstraintPool.expandNonInitializing();
    710 	solverConstraint.m_frictionIndex = frictionIndex;
    711 	setupRollingFrictionConstraint(solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2,
    712 							colObj0, colObj1, relaxation, desiredVelocity, cfmSlip);
    713 	return solverConstraint;
    714 }
    715 
    716 
    717 int	btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& body,btScalar timeStep)
    718 {
    719 
    720 	int solverBodyIdA = -1;
    721 
    722 	if (body.getCompanionId() >= 0)
    723 	{
    724 		//body has already been converted
    725 		solverBodyIdA = body.getCompanionId();
    726         btAssert(solverBodyIdA < m_tmpSolverBodyPool.size());
    727 	} else
    728 	{
    729 		btRigidBody* rb = btRigidBody::upcast(&body);
    730 		//convert both active and kinematic objects (for their velocity)
    731 		if (rb && (rb->getInvMass() || rb->isKinematicObject()))
    732 		{
    733 			solverBodyIdA = m_tmpSolverBodyPool.size();
    734 			btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
    735 			initSolverBody(&solverBody,&body,timeStep);
    736 			body.setCompanionId(solverBodyIdA);
    737 		} else
    738 		{
    739 
    740 			if (m_fixedBodyId<0)
    741 			{
    742 				m_fixedBodyId = m_tmpSolverBodyPool.size();
    743 				btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
    744 				initSolverBody(&fixedBody,0,timeStep);
    745 			}
    746 			return m_fixedBodyId;
    747 //			return 0;//assume first one is a fixed solver body
    748 		}
    749 	}
    750 
    751 	return solverBodyIdA;
    752 
    753 }
    754 #include <stdio.h>
    755 
    756 
    757 void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstraint& solverConstraint,
    758 																 int solverBodyIdA, int solverBodyIdB,
    759 																 btManifoldPoint& cp, const btContactSolverInfo& infoGlobal,
    760 																 btScalar& relaxation,
    761 																 const btVector3& rel_pos1, const btVector3& rel_pos2)
    762 {
    763 
    764 		//	const btVector3& pos1 = cp.getPositionWorldOnA();
    765 		//	const btVector3& pos2 = cp.getPositionWorldOnB();
    766 
    767 			btSolverBody* bodyA = &m_tmpSolverBodyPool[solverBodyIdA];
    768 			btSolverBody* bodyB = &m_tmpSolverBodyPool[solverBodyIdB];
    769 
    770 			btRigidBody* rb0 = bodyA->m_originalBody;
    771 			btRigidBody* rb1 = bodyB->m_originalBody;
    772 
    773 //			btVector3 rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin();
    774 //			btVector3 rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin();
    775 			//rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin();
    776 			//rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin();
    777 
    778 			relaxation = 1.f;
    779 
    780 			btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB);
    781 			solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0*rb0->getAngularFactor() : btVector3(0,0,0);
    782 			btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB);
    783 			solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*-torqueAxis1*rb1->getAngularFactor() : btVector3(0,0,0);
    784 
    785 				{
    786 #ifdef COMPUTE_IMPULSE_DENOM
    787 					btScalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB);
    788 					btScalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB);
    789 #else
    790 					btVector3 vec;
    791 					btScalar denom0 = 0.f;
    792 					btScalar denom1 = 0.f;
    793 					if (rb0)
    794 					{
    795 						vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1);
    796 						denom0 = rb0->getInvMass() + cp.m_normalWorldOnB.dot(vec);
    797 					}
    798 					if (rb1)
    799 					{
    800 						vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2);
    801 						denom1 = rb1->getInvMass() + cp.m_normalWorldOnB.dot(vec);
    802 					}
    803 #endif //COMPUTE_IMPULSE_DENOM
    804 
    805 					btScalar denom = relaxation/(denom0+denom1);
    806 					solverConstraint.m_jacDiagABInv = denom;
    807 				}
    808 
    809 				if (rb0)
    810 				{
    811 					solverConstraint.m_contactNormal1 = cp.m_normalWorldOnB;
    812 					solverConstraint.m_relpos1CrossNormal = torqueAxis0;
    813 				} else
    814 				{
    815 					solverConstraint.m_contactNormal1.setZero();
    816 					solverConstraint.m_relpos1CrossNormal.setZero();
    817 				}
    818 				if (rb1)
    819 				{
    820 					solverConstraint.m_contactNormal2 = -cp.m_normalWorldOnB;
    821 					solverConstraint.m_relpos2CrossNormal = -torqueAxis1;
    822 				}else
    823 				{
    824 					solverConstraint.m_contactNormal2.setZero();
    825 					solverConstraint.m_relpos2CrossNormal.setZero();
    826 				}
    827 
    828 				btScalar restitution = 0.f;
    829 				btScalar penetration = cp.getDistance()+infoGlobal.m_linearSlop;
    830 
    831 				{
    832 					btVector3 vel1,vel2;
    833 
    834 					vel1 = rb0? rb0->getVelocityInLocalPoint(rel_pos1) : btVector3(0,0,0);
    835 					vel2 = rb1? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0);
    836 
    837 	//			btVector3 vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0);
    838 					btVector3 vel  = vel1 - vel2;
    839 					btScalar rel_vel = cp.m_normalWorldOnB.dot(vel);
    840 
    841 
    842 
    843 					solverConstraint.m_friction = cp.m_combinedFriction;
    844 
    845 
    846 					restitution =  restitutionCurve(rel_vel, cp.m_combinedRestitution);
    847 					if (restitution <= btScalar(0.))
    848 					{
    849 						restitution = 0.f;
    850 					};
    851 				}
    852 
    853 
    854 				///warm starting (or zero if disabled)
    855 				if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
    856 				{
    857 					solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor;
    858 					if (rb0)
    859 						bodyA->internalApplyImpulse(solverConstraint.m_contactNormal1*bodyA->internalGetInvMass()*rb0->getLinearFactor(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse);
    860 					if (rb1)
    861 						bodyB->internalApplyImpulse(-solverConstraint.m_contactNormal2*bodyB->internalGetInvMass()*rb1->getLinearFactor(),-solverConstraint.m_angularComponentB,-(btScalar)solverConstraint.m_appliedImpulse);
    862 				} else
    863 				{
    864 					solverConstraint.m_appliedImpulse = 0.f;
    865 				}
    866 
    867 				solverConstraint.m_appliedPushImpulse = 0.f;
    868 
    869 				{
    870 
    871 					btVector3 externalForceImpulseA = bodyA->m_originalBody ? bodyA->m_externalForceImpulse: btVector3(0,0,0);
    872 					btVector3 externalTorqueImpulseA = bodyA->m_originalBody ? bodyA->m_externalTorqueImpulse: btVector3(0,0,0);
    873 					btVector3 externalForceImpulseB = bodyB->m_originalBody ? bodyB->m_externalForceImpulse: btVector3(0,0,0);
    874 					btVector3 externalTorqueImpulseB = bodyB->m_originalBody ?bodyB->m_externalTorqueImpulse : btVector3(0,0,0);
    875 
    876 
    877 					btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(bodyA->m_linearVelocity+externalForceImpulseA)
    878 						+ solverConstraint.m_relpos1CrossNormal.dot(bodyA->m_angularVelocity+externalTorqueImpulseA);
    879 					btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(bodyB->m_linearVelocity+externalForceImpulseB)
    880 						+ solverConstraint.m_relpos2CrossNormal.dot(bodyB->m_angularVelocity+externalTorqueImpulseB);
    881 					btScalar rel_vel = vel1Dotn+vel2Dotn;
    882 
    883 					btScalar positionalError = 0.f;
    884 					btScalar	velocityError = restitution - rel_vel;// * damping;
    885 
    886 
    887 					btScalar erp = infoGlobal.m_erp2;
    888 					if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold))
    889 					{
    890 						erp = infoGlobal.m_erp;
    891 					}
    892 
    893 					if (penetration>0)
    894 					{
    895 						positionalError = 0;
    896 
    897 						velocityError -= penetration / infoGlobal.m_timeStep;
    898 					} else
    899 					{
    900 						positionalError = -penetration * erp/infoGlobal.m_timeStep;
    901 					}
    902 
    903 					btScalar  penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
    904 					btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
    905 
    906 					if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold))
    907 					{
    908 						//combine position and velocity into rhs
    909 						solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;//-solverConstraint.m_contactNormal1.dot(bodyA->m_externalForce*bodyA->m_invMass-bodyB->m_externalForce/bodyB->m_invMass)*solverConstraint.m_jacDiagABInv;
    910 						solverConstraint.m_rhsPenetration = 0.f;
    911 
    912 					} else
    913 					{
    914 						//split position and velocity into rhs and m_rhsPenetration
    915 						solverConstraint.m_rhs = velocityImpulse;
    916 						solverConstraint.m_rhsPenetration = penetrationImpulse;
    917 					}
    918 					solverConstraint.m_cfm = 0.f;
    919 					solverConstraint.m_lowerLimit = 0;
    920 					solverConstraint.m_upperLimit = 1e10f;
    921 				}
    922 
    923 
    924 
    925 
    926 }
    927 
    928 
    929 
    930 void btSequentialImpulseConstraintSolver::setFrictionConstraintImpulse( btSolverConstraint& solverConstraint,
    931 																		int solverBodyIdA, int solverBodyIdB,
    932 																 btManifoldPoint& cp, const btContactSolverInfo& infoGlobal)
    933 {
    934 
    935 	btSolverBody* bodyA = &m_tmpSolverBodyPool[solverBodyIdA];
    936 	btSolverBody* bodyB = &m_tmpSolverBodyPool[solverBodyIdB];
    937 
    938 	btRigidBody* rb0 = bodyA->m_originalBody;
    939 	btRigidBody* rb1 = bodyB->m_originalBody;
    940 
    941 	{
    942 		btSolverConstraint& frictionConstraint1 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex];
    943 		if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
    944 		{
    945 			frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor;
    946 			if (rb0)
    947 				bodyA->internalApplyImpulse(frictionConstraint1.m_contactNormal1*rb0->getInvMass()*rb0->getLinearFactor(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse);
    948 			if (rb1)
    949 				bodyB->internalApplyImpulse(-frictionConstraint1.m_contactNormal2*rb1->getInvMass()*rb1->getLinearFactor(),-frictionConstraint1.m_angularComponentB,-(btScalar)frictionConstraint1.m_appliedImpulse);
    950 		} else
    951 		{
    952 			frictionConstraint1.m_appliedImpulse = 0.f;
    953 		}
    954 	}
    955 
    956 	if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
    957 	{
    958 		btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex+1];
    959 		if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
    960 		{
    961 			frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2  * infoGlobal.m_warmstartingFactor;
    962 			if (rb0)
    963 				bodyA->internalApplyImpulse(frictionConstraint2.m_contactNormal1*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse);
    964 			if (rb1)
    965 				bodyB->internalApplyImpulse(-frictionConstraint2.m_contactNormal2*rb1->getInvMass(),-frictionConstraint2.m_angularComponentB,-(btScalar)frictionConstraint2.m_appliedImpulse);
    966 		} else
    967 		{
    968 			frictionConstraint2.m_appliedImpulse = 0.f;
    969 		}
    970 	}
    971 }
    972 
    973 
    974 
    975 
    976 void	btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal)
    977 {
    978 	btCollisionObject* colObj0=0,*colObj1=0;
    979 
    980 	colObj0 = (btCollisionObject*)manifold->getBody0();
    981 	colObj1 = (btCollisionObject*)manifold->getBody1();
    982 
    983 	int solverBodyIdA = getOrInitSolverBody(*colObj0,infoGlobal.m_timeStep);
    984 	int solverBodyIdB = getOrInitSolverBody(*colObj1,infoGlobal.m_timeStep);
    985 
    986 //	btRigidBody* bodyA = btRigidBody::upcast(colObj0);
    987 //	btRigidBody* bodyB = btRigidBody::upcast(colObj1);
    988 
    989 	btSolverBody* solverBodyA = &m_tmpSolverBodyPool[solverBodyIdA];
    990 	btSolverBody* solverBodyB = &m_tmpSolverBodyPool[solverBodyIdB];
    991 
    992 
    993 
    994 	///avoid collision response between two static objects
    995 	if (!solverBodyA || (solverBodyA->m_invMass.fuzzyZero() && (!solverBodyB || solverBodyB->m_invMass.fuzzyZero())))
    996 		return;
    997 
    998 	int rollingFriction=1;
    999 	for (int j=0;j<manifold->getNumContacts();j++)
   1000 	{
   1001 
   1002 		btManifoldPoint& cp = manifold->getContactPoint(j);
   1003 
   1004 		if (cp.getDistance() <= manifold->getContactProcessingThreshold())
   1005 		{
   1006 			btVector3 rel_pos1;
   1007 			btVector3 rel_pos2;
   1008 			btScalar relaxation;
   1009 
   1010 
   1011 			int frictionIndex = m_tmpSolverContactConstraintPool.size();
   1012 			btSolverConstraint& solverConstraint = m_tmpSolverContactConstraintPool.expandNonInitializing();
   1013 			btRigidBody* rb0 = btRigidBody::upcast(colObj0);
   1014 			btRigidBody* rb1 = btRigidBody::upcast(colObj1);
   1015 			solverConstraint.m_solverBodyIdA = solverBodyIdA;
   1016 			solverConstraint.m_solverBodyIdB = solverBodyIdB;
   1017 
   1018 			solverConstraint.m_originalContactPoint = &cp;
   1019 
   1020 			const btVector3& pos1 = cp.getPositionWorldOnA();
   1021 			const btVector3& pos2 = cp.getPositionWorldOnB();
   1022 
   1023 			rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin();
   1024 			rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin();
   1025 
   1026 			btVector3 vel1;// = rb0 ? rb0->getVelocityInLocalPoint(rel_pos1) : btVector3(0,0,0);
   1027 			btVector3 vel2;// = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0);
   1028 
   1029 			solverBodyA->getVelocityInLocalPointNoDelta(rel_pos1,vel1);
   1030 			solverBodyB->getVelocityInLocalPointNoDelta(rel_pos2,vel2 );
   1031 
   1032 			btVector3 vel  = vel1 - vel2;
   1033 			btScalar rel_vel = cp.m_normalWorldOnB.dot(vel);
   1034 
   1035 			setupContactConstraint(solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal, relaxation, rel_pos1, rel_pos2);
   1036 
   1037 
   1038 
   1039 //			const btVector3& pos1 = cp.getPositionWorldOnA();
   1040 //			const btVector3& pos2 = cp.getPositionWorldOnB();
   1041 
   1042 			/////setup the friction constraints
   1043 
   1044 			solverConstraint.m_frictionIndex = m_tmpSolverContactFrictionConstraintPool.size();
   1045 
   1046 			btVector3 angVelA(0,0,0),angVelB(0,0,0);
   1047 			if (rb0)
   1048 				angVelA = rb0->getAngularVelocity();
   1049 			if (rb1)
   1050 				angVelB = rb1->getAngularVelocity();
   1051 			btVector3 relAngVel = angVelB-angVelA;
   1052 
   1053 			if ((cp.m_combinedRollingFriction>0.f) && (rollingFriction>0))
   1054 			{
   1055 				//only a single rollingFriction per manifold
   1056 				rollingFriction--;
   1057 				if (relAngVel.length()>infoGlobal.m_singleAxisRollingFrictionThreshold)
   1058 				{
   1059 					relAngVel.normalize();
   1060 					applyAnisotropicFriction(colObj0,relAngVel,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
   1061 					applyAnisotropicFriction(colObj1,relAngVel,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
   1062 					if (relAngVel.length()>0.001)
   1063 						addRollingFrictionConstraint(relAngVel,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
   1064 
   1065 				} else
   1066 				{
   1067 					addRollingFrictionConstraint(cp.m_normalWorldOnB,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
   1068 					btVector3 axis0,axis1;
   1069 					btPlaneSpace1(cp.m_normalWorldOnB,axis0,axis1);
   1070 					applyAnisotropicFriction(colObj0,axis0,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
   1071 					applyAnisotropicFriction(colObj1,axis0,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
   1072 					applyAnisotropicFriction(colObj0,axis1,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
   1073 					applyAnisotropicFriction(colObj1,axis1,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
   1074 					if (axis0.length()>0.001)
   1075 						addRollingFrictionConstraint(axis0,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
   1076 					if (axis1.length()>0.001)
   1077 						addRollingFrictionConstraint(axis1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
   1078 
   1079 				}
   1080 			}
   1081 
   1082 			///Bullet has several options to set the friction directions
   1083 			///By default, each contact has only a single friction direction that is recomputed automatically very frame
   1084 			///based on the relative linear velocity.
   1085 			///If the relative velocity it zero, it will automatically compute a friction direction.
   1086 
   1087 			///You can also enable two friction directions, using the SOLVER_USE_2_FRICTION_DIRECTIONS.
   1088 			///In that case, the second friction direction will be orthogonal to both contact normal and first friction direction.
   1089 			///
   1090 			///If you choose SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION, then the friction will be independent from the relative projected velocity.
   1091 			///
   1092 			///The user can manually override the friction directions for certain contacts using a contact callback,
   1093 			///and set the cp.m_lateralFrictionInitialized to true
   1094 			///In that case, you can set the target relative motion in each friction direction (cp.m_contactMotion1 and cp.m_contactMotion2)
   1095 			///this will give a conveyor belt effect
   1096 			///
   1097 			if (!(infoGlobal.m_solverMode & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING) || !cp.m_lateralFrictionInitialized)
   1098 			{
   1099 				cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel;
   1100 				btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2();
   1101 				if (!(infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > SIMD_EPSILON)
   1102 				{
   1103 					cp.m_lateralFrictionDir1 *= 1.f/btSqrt(lat_rel_vel);
   1104 					applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
   1105 					applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
   1106 					addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
   1107 
   1108 					if((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
   1109 					{
   1110 						cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB);
   1111 						cp.m_lateralFrictionDir2.normalize();//??
   1112 						applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
   1113 						applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
   1114 						addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
   1115 					}
   1116 
   1117 				} else
   1118 				{
   1119 					btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2);
   1120 
   1121 					applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
   1122 					applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
   1123 					addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
   1124 
   1125 					if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
   1126 					{
   1127 						applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
   1128 						applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
   1129 						addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
   1130 					}
   1131 
   1132 
   1133 					if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) && (infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION))
   1134 					{
   1135 						cp.m_lateralFrictionInitialized = true;
   1136 					}
   1137 				}
   1138 
   1139 			} else
   1140 			{
   1141 				addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation,cp.m_contactMotion1, cp.m_contactCFM1);
   1142 
   1143 				if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
   1144 					addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation, cp.m_contactMotion2, cp.m_contactCFM2);
   1145 
   1146 			}
   1147 			setFrictionConstraintImpulse( solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal);
   1148 
   1149 
   1150 
   1151 
   1152 		}
   1153 	}
   1154 }
   1155 
   1156 void btSequentialImpulseConstraintSolver::convertContacts(btPersistentManifold** manifoldPtr,int numManifolds, const btContactSolverInfo& infoGlobal)
   1157 {
   1158 	int i;
   1159 	btPersistentManifold* manifold = 0;
   1160 //			btCollisionObject* colObj0=0,*colObj1=0;
   1161 
   1162 
   1163 	for (i=0;i<numManifolds;i++)
   1164 	{
   1165 		manifold = manifoldPtr[i];
   1166 		convertContact(manifold,infoGlobal);
   1167 	}
   1168 }
   1169 
   1170 btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
   1171 {
   1172 	m_fixedBodyId = -1;
   1173 	BT_PROFILE("solveGroupCacheFriendlySetup");
   1174 	(void)debugDrawer;
   1175 
   1176 	m_maxOverrideNumSolverIterations = 0;
   1177 
   1178 #ifdef BT_ADDITIONAL_DEBUG
   1179 	 //make sure that dynamic bodies exist for all (enabled) constraints
   1180 	for (int i=0;i<numConstraints;i++)
   1181 	{
   1182 		btTypedConstraint* constraint = constraints[i];
   1183 		if (constraint->isEnabled())
   1184 		{
   1185 			if (!constraint->getRigidBodyA().isStaticOrKinematicObject())
   1186 			{
   1187 				bool found=false;
   1188 				for (int b=0;b<numBodies;b++)
   1189 				{
   1190 
   1191 					if (&constraint->getRigidBodyA()==bodies[b])
   1192 					{
   1193 						found = true;
   1194 						break;
   1195 					}
   1196 				}
   1197 				btAssert(found);
   1198 			}
   1199 			if (!constraint->getRigidBodyB().isStaticOrKinematicObject())
   1200 			{
   1201 				bool found=false;
   1202 				for (int b=0;b<numBodies;b++)
   1203 				{
   1204 					if (&constraint->getRigidBodyB()==bodies[b])
   1205 					{
   1206 						found = true;
   1207 						break;
   1208 					}
   1209 				}
   1210 				btAssert(found);
   1211 			}
   1212 		}
   1213 	}
   1214     //make sure that dynamic bodies exist for all contact manifolds
   1215     for (int i=0;i<numManifolds;i++)
   1216     {
   1217         if (!manifoldPtr[i]->getBody0()->isStaticOrKinematicObject())
   1218         {
   1219             bool found=false;
   1220             for (int b=0;b<numBodies;b++)
   1221             {
   1222 
   1223                 if (manifoldPtr[i]->getBody0()==bodies[b])
   1224                 {
   1225                     found = true;
   1226                     break;
   1227                 }
   1228             }
   1229             btAssert(found);
   1230         }
   1231         if (!manifoldPtr[i]->getBody1()->isStaticOrKinematicObject())
   1232         {
   1233             bool found=false;
   1234             for (int b=0;b<numBodies;b++)
   1235             {
   1236                 if (manifoldPtr[i]->getBody1()==bodies[b])
   1237                 {
   1238                     found = true;
   1239                     break;
   1240                 }
   1241             }
   1242             btAssert(found);
   1243         }
   1244     }
   1245 #endif //BT_ADDITIONAL_DEBUG
   1246 
   1247 
   1248 	for (int i = 0; i < numBodies; i++)
   1249 	{
   1250 		bodies[i]->setCompanionId(-1);
   1251 	}
   1252 
   1253 
   1254 	m_tmpSolverBodyPool.reserve(numBodies+1);
   1255 	m_tmpSolverBodyPool.resize(0);
   1256 
   1257 	//btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
   1258     //initSolverBody(&fixedBody,0);
   1259 
   1260 	//convert all bodies
   1261 
   1262 
   1263 	for (int i=0;i<numBodies;i++)
   1264 	{
   1265 		int bodyId = getOrInitSolverBody(*bodies[i],infoGlobal.m_timeStep);
   1266 
   1267 		btRigidBody* body = btRigidBody::upcast(bodies[i]);
   1268 		if (body && body->getInvMass())
   1269 		{
   1270 			btSolverBody& solverBody = m_tmpSolverBodyPool[bodyId];
   1271 			btVector3 gyroForce (0,0,0);
   1272 			if (body->getFlags()&BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT)
   1273 			{
   1274 				gyroForce = body->computeGyroscopicForceExplicit(infoGlobal.m_maxGyroscopicForce);
   1275 				solverBody.m_externalTorqueImpulse -= gyroForce*body->getInvInertiaTensorWorld()*infoGlobal.m_timeStep;
   1276 			}
   1277 			if (body->getFlags()&BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD)
   1278 			{
   1279 				gyroForce = body->computeGyroscopicImpulseImplicit_World(infoGlobal.m_timeStep);
   1280 				solverBody.m_externalTorqueImpulse += gyroForce;
   1281 			}
   1282 			if (body->getFlags()&BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY)
   1283 			{
   1284 				gyroForce = body->computeGyroscopicImpulseImplicit_Body(infoGlobal.m_timeStep);
   1285 				solverBody.m_externalTorqueImpulse += gyroForce;
   1286 
   1287 			}
   1288 
   1289 
   1290 		}
   1291 	}
   1292 
   1293 	if (1)
   1294 	{
   1295 		int j;
   1296 		for (j=0;j<numConstraints;j++)
   1297 		{
   1298 			btTypedConstraint* constraint = constraints[j];
   1299 			constraint->buildJacobian();
   1300 			constraint->internalSetAppliedImpulse(0.0f);
   1301 		}
   1302 	}
   1303 
   1304 	//btRigidBody* rb0=0,*rb1=0;
   1305 
   1306 	//if (1)
   1307 	{
   1308 		{
   1309 
   1310 			int totalNumRows = 0;
   1311 			int i;
   1312 
   1313 			m_tmpConstraintSizesPool.resizeNoInitialize(numConstraints);
   1314 			//calculate the total number of contraint rows
   1315 			for (i=0;i<numConstraints;i++)
   1316 			{
   1317 				btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
   1318 				btJointFeedback* fb = constraints[i]->getJointFeedback();
   1319 				if (fb)
   1320 				{
   1321 					fb->m_appliedForceBodyA.setZero();
   1322 					fb->m_appliedTorqueBodyA.setZero();
   1323 					fb->m_appliedForceBodyB.setZero();
   1324 					fb->m_appliedTorqueBodyB.setZero();
   1325 				}
   1326 
   1327 				if (constraints[i]->isEnabled())
   1328 				{
   1329 				}
   1330 				if (constraints[i]->isEnabled())
   1331 				{
   1332 					constraints[i]->getInfo1(&info1);
   1333 				} else
   1334 				{
   1335 					info1.m_numConstraintRows = 0;
   1336 					info1.nub = 0;
   1337 				}
   1338 				totalNumRows += info1.m_numConstraintRows;
   1339 			}
   1340 			m_tmpSolverNonContactConstraintPool.resizeNoInitialize(totalNumRows);
   1341 
   1342 
   1343 			///setup the btSolverConstraints
   1344 			int currentRow = 0;
   1345 
   1346 			for (i=0;i<numConstraints;i++)
   1347 			{
   1348 				const btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
   1349 
   1350 				if (info1.m_numConstraintRows)
   1351 				{
   1352 					btAssert(currentRow<totalNumRows);
   1353 
   1354 					btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow];
   1355 					btTypedConstraint* constraint = constraints[i];
   1356 					btRigidBody& rbA = constraint->getRigidBodyA();
   1357 					btRigidBody& rbB = constraint->getRigidBodyB();
   1358 
   1359 					int solverBodyIdA = getOrInitSolverBody(rbA,infoGlobal.m_timeStep);
   1360                     int solverBodyIdB = getOrInitSolverBody(rbB,infoGlobal.m_timeStep);
   1361 
   1362                     btSolverBody* bodyAPtr = &m_tmpSolverBodyPool[solverBodyIdA];
   1363                     btSolverBody* bodyBPtr = &m_tmpSolverBodyPool[solverBodyIdB];
   1364 
   1365 
   1366 
   1367 
   1368 					int overrideNumSolverIterations = constraint->getOverrideNumSolverIterations() > 0 ? constraint->getOverrideNumSolverIterations() : infoGlobal.m_numIterations;
   1369 					if (overrideNumSolverIterations>m_maxOverrideNumSolverIterations)
   1370 						m_maxOverrideNumSolverIterations = overrideNumSolverIterations;
   1371 
   1372 
   1373 					int j;
   1374 					for ( j=0;j<info1.m_numConstraintRows;j++)
   1375 					{
   1376 						memset(&currentConstraintRow[j],0,sizeof(btSolverConstraint));
   1377 						currentConstraintRow[j].m_lowerLimit = -SIMD_INFINITY;
   1378 						currentConstraintRow[j].m_upperLimit = SIMD_INFINITY;
   1379 						currentConstraintRow[j].m_appliedImpulse = 0.f;
   1380 						currentConstraintRow[j].m_appliedPushImpulse = 0.f;
   1381 						currentConstraintRow[j].m_solverBodyIdA = solverBodyIdA;
   1382 						currentConstraintRow[j].m_solverBodyIdB = solverBodyIdB;
   1383 						currentConstraintRow[j].m_overrideNumSolverIterations = overrideNumSolverIterations;
   1384 					}
   1385 
   1386 					bodyAPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
   1387 					bodyAPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
   1388 					bodyAPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f);
   1389 					bodyAPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f);
   1390 					bodyBPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
   1391 					bodyBPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
   1392 					bodyBPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f);
   1393 					bodyBPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f);
   1394 
   1395 
   1396 					btTypedConstraint::btConstraintInfo2 info2;
   1397 					info2.fps = 1.f/infoGlobal.m_timeStep;
   1398 					info2.erp = infoGlobal.m_erp;
   1399 					info2.m_J1linearAxis = currentConstraintRow->m_contactNormal1;
   1400 					info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal;
   1401 					info2.m_J2linearAxis = currentConstraintRow->m_contactNormal2;
   1402 					info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal;
   1403 					info2.rowskip = sizeof(btSolverConstraint)/sizeof(btScalar);//check this
   1404 					///the size of btSolverConstraint needs be a multiple of btScalar
   1405 		            btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint));
   1406 					info2.m_constraintError = &currentConstraintRow->m_rhs;
   1407 					currentConstraintRow->m_cfm = infoGlobal.m_globalCfm;
   1408 					info2.m_damping = infoGlobal.m_damping;
   1409 					info2.cfm = &currentConstraintRow->m_cfm;
   1410 					info2.m_lowerLimit = &currentConstraintRow->m_lowerLimit;
   1411 					info2.m_upperLimit = &currentConstraintRow->m_upperLimit;
   1412 					info2.m_numIterations = infoGlobal.m_numIterations;
   1413 					constraints[i]->getInfo2(&info2);
   1414 
   1415 					///finalize the constraint setup
   1416 					for ( j=0;j<info1.m_numConstraintRows;j++)
   1417 					{
   1418 						btSolverConstraint& solverConstraint = currentConstraintRow[j];
   1419 
   1420 						if (solverConstraint.m_upperLimit>=constraints[i]->getBreakingImpulseThreshold())
   1421 						{
   1422 							solverConstraint.m_upperLimit = constraints[i]->getBreakingImpulseThreshold();
   1423 						}
   1424 
   1425 						if (solverConstraint.m_lowerLimit<=-constraints[i]->getBreakingImpulseThreshold())
   1426 						{
   1427 							solverConstraint.m_lowerLimit = -constraints[i]->getBreakingImpulseThreshold();
   1428 						}
   1429 
   1430 						solverConstraint.m_originalContactPoint = constraint;
   1431 
   1432 						{
   1433 							const btVector3& ftorqueAxis1 = solverConstraint.m_relpos1CrossNormal;
   1434 							solverConstraint.m_angularComponentA = constraint->getRigidBodyA().getInvInertiaTensorWorld()*ftorqueAxis1*constraint->getRigidBodyA().getAngularFactor();
   1435 						}
   1436 						{
   1437 							const btVector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal;
   1438 							solverConstraint.m_angularComponentB = constraint->getRigidBodyB().getInvInertiaTensorWorld()*ftorqueAxis2*constraint->getRigidBodyB().getAngularFactor();
   1439 						}
   1440 
   1441 						{
   1442 							btVector3 iMJlA = solverConstraint.m_contactNormal1*rbA.getInvMass();
   1443 							btVector3 iMJaA = rbA.getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal;
   1444 							btVector3 iMJlB = solverConstraint.m_contactNormal2*rbB.getInvMass();//sign of normal?
   1445 							btVector3 iMJaB = rbB.getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal;
   1446 
   1447 							btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal1);
   1448 							sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal);
   1449 							sum += iMJlB.dot(solverConstraint.m_contactNormal2);
   1450 							sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal);
   1451 							btScalar fsum = btFabs(sum);
   1452 							btAssert(fsum > SIMD_EPSILON);
   1453 							solverConstraint.m_jacDiagABInv = fsum>SIMD_EPSILON?btScalar(1.)/sum : 0.f;
   1454 						}
   1455 
   1456 
   1457 
   1458 						{
   1459 							btScalar rel_vel;
   1460 							btVector3 externalForceImpulseA = bodyAPtr->m_originalBody ? bodyAPtr->m_externalForceImpulse : btVector3(0,0,0);
   1461 							btVector3 externalTorqueImpulseA = bodyAPtr->m_originalBody ? bodyAPtr->m_externalTorqueImpulse : btVector3(0,0,0);
   1462 
   1463 							btVector3 externalForceImpulseB = bodyBPtr->m_originalBody ? bodyBPtr->m_externalForceImpulse : btVector3(0,0,0);
   1464 							btVector3 externalTorqueImpulseB = bodyBPtr->m_originalBody ?bodyBPtr->m_externalTorqueImpulse : btVector3(0,0,0);
   1465 
   1466 							btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(rbA.getLinearVelocity()+externalForceImpulseA)
   1467 												+ solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity()+externalTorqueImpulseA);
   1468 
   1469 							btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(rbB.getLinearVelocity()+externalForceImpulseB)
   1470 																+ solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity()+externalTorqueImpulseB);
   1471 
   1472 							rel_vel = vel1Dotn+vel2Dotn;
   1473 							btScalar restitution = 0.f;
   1474 							btScalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2
   1475 							btScalar	velocityError = restitution - rel_vel * info2.m_damping;
   1476 							btScalar	penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
   1477 							btScalar	velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
   1478 							solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
   1479 							solverConstraint.m_appliedImpulse = 0.f;
   1480 
   1481 
   1482 						}
   1483 					}
   1484 				}
   1485 				currentRow+=m_tmpConstraintSizesPool[i].m_numConstraintRows;
   1486 			}
   1487 		}
   1488 
   1489 		convertContacts(manifoldPtr,numManifolds,infoGlobal);
   1490 
   1491 	}
   1492 
   1493 //	btContactSolverInfo info = infoGlobal;
   1494 
   1495 
   1496 	int numNonContactPool = m_tmpSolverNonContactConstraintPool.size();
   1497 	int numConstraintPool = m_tmpSolverContactConstraintPool.size();
   1498 	int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size();
   1499 
   1500 	///@todo: use stack allocator for such temporarily memory, same for solver bodies/constraints
   1501 	m_orderNonContactConstraintPool.resizeNoInitialize(numNonContactPool);
   1502 	if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
   1503 		m_orderTmpConstraintPool.resizeNoInitialize(numConstraintPool*2);
   1504 	else
   1505 		m_orderTmpConstraintPool.resizeNoInitialize(numConstraintPool);
   1506 
   1507 	m_orderFrictionConstraintPool.resizeNoInitialize(numFrictionPool);
   1508 	{
   1509 		int i;
   1510 		for (i=0;i<numNonContactPool;i++)
   1511 		{
   1512 			m_orderNonContactConstraintPool[i] = i;
   1513 		}
   1514 		for (i=0;i<numConstraintPool;i++)
   1515 		{
   1516 			m_orderTmpConstraintPool[i] = i;
   1517 		}
   1518 		for (i=0;i<numFrictionPool;i++)
   1519 		{
   1520 			m_orderFrictionConstraintPool[i] = i;
   1521 		}
   1522 	}
   1523 
   1524 	return 0.f;
   1525 
   1526 }
   1527 
   1528 
   1529 btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration, btCollisionObject** /*bodies */,int /*numBodies*/,btPersistentManifold** /*manifoldPtr*/, int /*numManifolds*/,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* /*debugDrawer*/)
   1530 {
   1531 
   1532 	int numNonContactPool = m_tmpSolverNonContactConstraintPool.size();
   1533 	int numConstraintPool = m_tmpSolverContactConstraintPool.size();
   1534 	int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size();
   1535 
   1536 	if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER)
   1537 	{
   1538 		if (1)			// uncomment this for a bit less random ((iteration & 7) == 0)
   1539 		{
   1540 
   1541 			for (int j=0; j<numNonContactPool; ++j) {
   1542 				int tmp = m_orderNonContactConstraintPool[j];
   1543 				int swapi = btRandInt2(j+1);
   1544 				m_orderNonContactConstraintPool[j] = m_orderNonContactConstraintPool[swapi];
   1545 				m_orderNonContactConstraintPool[swapi] = tmp;
   1546 			}
   1547 
   1548 			//contact/friction constraints are not solved more than
   1549 			if (iteration< infoGlobal.m_numIterations)
   1550 			{
   1551 				for (int j=0; j<numConstraintPool; ++j) {
   1552 					int tmp = m_orderTmpConstraintPool[j];
   1553 					int swapi = btRandInt2(j+1);
   1554 					m_orderTmpConstraintPool[j] = m_orderTmpConstraintPool[swapi];
   1555 					m_orderTmpConstraintPool[swapi] = tmp;
   1556 				}
   1557 
   1558 				for (int j=0; j<numFrictionPool; ++j) {
   1559 					int tmp = m_orderFrictionConstraintPool[j];
   1560 					int swapi = btRandInt2(j+1);
   1561 					m_orderFrictionConstraintPool[j] = m_orderFrictionConstraintPool[swapi];
   1562 					m_orderFrictionConstraintPool[swapi] = tmp;
   1563 				}
   1564 			}
   1565 		}
   1566 	}
   1567 
   1568 	if (infoGlobal.m_solverMode & SOLVER_SIMD)
   1569 	{
   1570 		///solve all joint constraints, using SIMD, if available
   1571 		for (int j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
   1572 		{
   1573 			btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[m_orderNonContactConstraintPool[j]];
   1574 			if (iteration < constraint.m_overrideNumSolverIterations)
   1575 				resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[constraint.m_solverBodyIdA],m_tmpSolverBodyPool[constraint.m_solverBodyIdB],constraint);
   1576 		}
   1577 
   1578 		if (iteration< infoGlobal.m_numIterations)
   1579 		{
   1580 			for (int j=0;j<numConstraints;j++)
   1581 			{
   1582 				if (constraints[j]->isEnabled())
   1583 				{
   1584 					int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA(),infoGlobal.m_timeStep);
   1585 					int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep);
   1586 					btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid];
   1587 					btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid];
   1588 					constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep);
   1589 				}
   1590 			}
   1591 
   1592 			///solve all contact constraints using SIMD, if available
   1593 			if (infoGlobal.m_solverMode & SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS)
   1594 			{
   1595 				int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
   1596 				int multiplier = (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)? 2 : 1;
   1597 
   1598 				for (int c=0;c<numPoolConstraints;c++)
   1599 				{
   1600 					btScalar totalImpulse =0;
   1601 
   1602 					{
   1603 						const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[c]];
   1604 						resolveSingleConstraintRowLowerLimitSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
   1605 						totalImpulse = solveManifold.m_appliedImpulse;
   1606 					}
   1607 					bool applyFriction = true;
   1608 					if (applyFriction)
   1609 					{
   1610 						{
   1611 
   1612 							btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[c*multiplier]];
   1613 
   1614 							if (totalImpulse>btScalar(0))
   1615 							{
   1616 								solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
   1617 								solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
   1618 
   1619 								resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
   1620 							}
   1621 						}
   1622 
   1623 						if (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)
   1624 						{
   1625 
   1626 							btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[c*multiplier+1]];
   1627 
   1628 							if (totalImpulse>btScalar(0))
   1629 							{
   1630 								solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
   1631 								solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
   1632 
   1633 								resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
   1634 							}
   1635 						}
   1636 					}
   1637 				}
   1638 
   1639 			}
   1640 			else//SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS
   1641 			{
   1642 				//solve the friction constraints after all contact constraints, don't interleave them
   1643 				int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
   1644 				int j;
   1645 
   1646 				for (j=0;j<numPoolConstraints;j++)
   1647 				{
   1648 					const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
   1649 					resolveSingleConstraintRowLowerLimitSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
   1650 
   1651 				}
   1652 
   1653 
   1654 
   1655 				///solve all friction constraints, using SIMD, if available
   1656 
   1657 				int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
   1658 				for (j=0;j<numFrictionPoolConstraints;j++)
   1659 				{
   1660 					btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
   1661 					btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
   1662 
   1663 					if (totalImpulse>btScalar(0))
   1664 					{
   1665 						solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
   1666 						solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
   1667 
   1668 						resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
   1669 					}
   1670 				}
   1671 
   1672 
   1673 				int numRollingFrictionPoolConstraints = m_tmpSolverContactRollingFrictionConstraintPool.size();
   1674 				for (j=0;j<numRollingFrictionPoolConstraints;j++)
   1675 				{
   1676 
   1677 					btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[j];
   1678 					btScalar totalImpulse = m_tmpSolverContactConstraintPool[rollingFrictionConstraint.m_frictionIndex].m_appliedImpulse;
   1679 					if (totalImpulse>btScalar(0))
   1680 					{
   1681 						btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction*totalImpulse;
   1682 						if (rollingFrictionMagnitude>rollingFrictionConstraint.m_friction)
   1683 							rollingFrictionMagnitude = rollingFrictionConstraint.m_friction;
   1684 
   1685 						rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude;
   1686 						rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude;
   1687 
   1688 						resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA],m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB],rollingFrictionConstraint);
   1689 					}
   1690 				}
   1691 
   1692 
   1693 			}
   1694 		}
   1695 	} else
   1696 	{
   1697 		//non-SIMD version
   1698 		///solve all joint constraints
   1699 		for (int j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
   1700 		{
   1701 			btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[m_orderNonContactConstraintPool[j]];
   1702 			if (iteration < constraint.m_overrideNumSolverIterations)
   1703 				resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[constraint.m_solverBodyIdA],m_tmpSolverBodyPool[constraint.m_solverBodyIdB],constraint);
   1704 		}
   1705 
   1706 		if (iteration< infoGlobal.m_numIterations)
   1707 		{
   1708 			for (int j=0;j<numConstraints;j++)
   1709 			{
   1710 				if (constraints[j]->isEnabled())
   1711 				{
   1712 					int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA(),infoGlobal.m_timeStep);
   1713 					int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep);
   1714 					btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid];
   1715 					btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid];
   1716 					constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep);
   1717 				}
   1718 			}
   1719 			///solve all contact constraints
   1720 			int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
   1721 			for (int j=0;j<numPoolConstraints;j++)
   1722 			{
   1723 				const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
   1724 				resolveSingleConstraintRowLowerLimit(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
   1725 			}
   1726 			///solve all friction constraints
   1727 			int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
   1728 			for (int j=0;j<numFrictionPoolConstraints;j++)
   1729 			{
   1730 				btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
   1731 				btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
   1732 
   1733 				if (totalImpulse>btScalar(0))
   1734 				{
   1735 					solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
   1736 					solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
   1737 
   1738 					resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
   1739 				}
   1740 			}
   1741 
   1742 			int numRollingFrictionPoolConstraints = m_tmpSolverContactRollingFrictionConstraintPool.size();
   1743 			for (int j=0;j<numRollingFrictionPoolConstraints;j++)
   1744 			{
   1745 				btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[j];
   1746 				btScalar totalImpulse = m_tmpSolverContactConstraintPool[rollingFrictionConstraint.m_frictionIndex].m_appliedImpulse;
   1747 				if (totalImpulse>btScalar(0))
   1748 				{
   1749 					btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction*totalImpulse;
   1750 					if (rollingFrictionMagnitude>rollingFrictionConstraint.m_friction)
   1751 						rollingFrictionMagnitude = rollingFrictionConstraint.m_friction;
   1752 
   1753 					rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude;
   1754 					rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude;
   1755 
   1756 					resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA],m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB],rollingFrictionConstraint);
   1757 				}
   1758 			}
   1759 		}
   1760 	}
   1761 	return 0.f;
   1762 }
   1763 
   1764 
   1765 void btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
   1766 {
   1767 	int iteration;
   1768 	if (infoGlobal.m_splitImpulse)
   1769 	{
   1770 		if (infoGlobal.m_solverMode & SOLVER_SIMD)
   1771 		{
   1772 			for ( iteration = 0;iteration<infoGlobal.m_numIterations;iteration++)
   1773 			{
   1774 				{
   1775 					int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
   1776 					int j;
   1777 					for (j=0;j<numPoolConstraints;j++)
   1778 					{
   1779 						const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
   1780 
   1781 						resolveSplitPenetrationSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
   1782 					}
   1783 				}
   1784 			}
   1785 		}
   1786 		else
   1787 		{
   1788 			for ( iteration = 0;iteration<infoGlobal.m_numIterations;iteration++)
   1789 			{
   1790 				{
   1791 					int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
   1792 					int j;
   1793 					for (j=0;j<numPoolConstraints;j++)
   1794 					{
   1795 						const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
   1796 
   1797 						resolveSplitPenetrationImpulseCacheFriendly(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
   1798 					}
   1799 				}
   1800 			}
   1801 		}
   1802 	}
   1803 }
   1804 
   1805 btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
   1806 {
   1807 	BT_PROFILE("solveGroupCacheFriendlyIterations");
   1808 
   1809 	{
   1810 		///this is a special step to resolve penetrations (just for contacts)
   1811 		solveGroupCacheFriendlySplitImpulseIterations(bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer);
   1812 
   1813 		int maxIterations = m_maxOverrideNumSolverIterations > infoGlobal.m_numIterations? m_maxOverrideNumSolverIterations : infoGlobal.m_numIterations;
   1814 
   1815 		for ( int iteration = 0 ; iteration< maxIterations ; iteration++)
   1816 		//for ( int iteration = maxIterations-1  ; iteration >= 0;iteration--)
   1817 		{
   1818 			solveSingleIteration(iteration, bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer);
   1819 		}
   1820 
   1821 	}
   1822 	return 0.f;
   1823 }
   1824 
   1825 btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(btCollisionObject** bodies,int numBodies,const btContactSolverInfo& infoGlobal)
   1826 {
   1827 	int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
   1828 	int i,j;
   1829 
   1830 	if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
   1831 	{
   1832 		for (j=0;j<numPoolConstraints;j++)
   1833 		{
   1834 			const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[j];
   1835 			btManifoldPoint* pt = (btManifoldPoint*) solveManifold.m_originalContactPoint;
   1836 			btAssert(pt);
   1837 			pt->m_appliedImpulse = solveManifold.m_appliedImpulse;
   1838 		//	float f = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
   1839 			//	printf("pt->m_appliedImpulseLateral1 = %f\n", f);
   1840 			pt->m_appliedImpulseLateral1 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
   1841 			//printf("pt->m_appliedImpulseLateral1 = %f\n", pt->m_appliedImpulseLateral1);
   1842 			if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
   1843 			{
   1844 				pt->m_appliedImpulseLateral2 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse;
   1845 			}
   1846 			//do a callback here?
   1847 		}
   1848 	}
   1849 
   1850 	numPoolConstraints = m_tmpSolverNonContactConstraintPool.size();
   1851 	for (j=0;j<numPoolConstraints;j++)
   1852 	{
   1853 		const btSolverConstraint& solverConstr = m_tmpSolverNonContactConstraintPool[j];
   1854 		btTypedConstraint* constr = (btTypedConstraint*)solverConstr.m_originalContactPoint;
   1855 		btJointFeedback* fb = constr->getJointFeedback();
   1856 		if (fb)
   1857 		{
   1858 			fb->m_appliedForceBodyA += solverConstr.m_contactNormal1*solverConstr.m_appliedImpulse*constr->getRigidBodyA().getLinearFactor()/infoGlobal.m_timeStep;
   1859 			fb->m_appliedForceBodyB += solverConstr.m_contactNormal2*solverConstr.m_appliedImpulse*constr->getRigidBodyB().getLinearFactor()/infoGlobal.m_timeStep;
   1860 			fb->m_appliedTorqueBodyA += solverConstr.m_relpos1CrossNormal* constr->getRigidBodyA().getAngularFactor()*solverConstr.m_appliedImpulse/infoGlobal.m_timeStep;
   1861 			fb->m_appliedTorqueBodyB += solverConstr.m_relpos2CrossNormal* constr->getRigidBodyB().getAngularFactor()*solverConstr.m_appliedImpulse/infoGlobal.m_timeStep; /*RGM ???? */
   1862 
   1863 		}
   1864 
   1865 		constr->internalSetAppliedImpulse(solverConstr.m_appliedImpulse);
   1866 		if (btFabs(solverConstr.m_appliedImpulse)>=constr->getBreakingImpulseThreshold())
   1867 		{
   1868 			constr->setEnabled(false);
   1869 		}
   1870 	}
   1871 
   1872 
   1873 
   1874 	for ( i=0;i<m_tmpSolverBodyPool.size();i++)
   1875 	{
   1876 		btRigidBody* body = m_tmpSolverBodyPool[i].m_originalBody;
   1877 		if (body)
   1878 		{
   1879 			if (infoGlobal.m_splitImpulse)
   1880 				m_tmpSolverBodyPool[i].writebackVelocityAndTransform(infoGlobal.m_timeStep, infoGlobal.m_splitImpulseTurnErp);
   1881 			else
   1882 				m_tmpSolverBodyPool[i].writebackVelocity();
   1883 
   1884 			m_tmpSolverBodyPool[i].m_originalBody->setLinearVelocity(
   1885 				m_tmpSolverBodyPool[i].m_linearVelocity+
   1886 				m_tmpSolverBodyPool[i].m_externalForceImpulse);
   1887 
   1888 			m_tmpSolverBodyPool[i].m_originalBody->setAngularVelocity(
   1889 				m_tmpSolverBodyPool[i].m_angularVelocity+
   1890 				m_tmpSolverBodyPool[i].m_externalTorqueImpulse);
   1891 
   1892 			if (infoGlobal.m_splitImpulse)
   1893 				m_tmpSolverBodyPool[i].m_originalBody->setWorldTransform(m_tmpSolverBodyPool[i].m_worldTransform);
   1894 
   1895 			m_tmpSolverBodyPool[i].m_originalBody->setCompanionId(-1);
   1896 		}
   1897 	}
   1898 
   1899 	m_tmpSolverContactConstraintPool.resizeNoInitialize(0);
   1900 	m_tmpSolverNonContactConstraintPool.resizeNoInitialize(0);
   1901 	m_tmpSolverContactFrictionConstraintPool.resizeNoInitialize(0);
   1902 	m_tmpSolverContactRollingFrictionConstraintPool.resizeNoInitialize(0);
   1903 
   1904 	m_tmpSolverBodyPool.resizeNoInitialize(0);
   1905 	return 0.f;
   1906 }
   1907 
   1908 
   1909 
   1910 /// btSequentialImpulseConstraintSolver Sequentially applies impulses
   1911 btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btDispatcher* /*dispatcher*/)
   1912 {
   1913 
   1914 	BT_PROFILE("solveGroup");
   1915 	//you need to provide at least some bodies
   1916 
   1917 	solveGroupCacheFriendlySetup( bodies, numBodies, manifoldPtr,  numManifolds,constraints, numConstraints,infoGlobal,debugDrawer);
   1918 
   1919 	solveGroupCacheFriendlyIterations(bodies, numBodies, manifoldPtr,  numManifolds,constraints, numConstraints,infoGlobal,debugDrawer);
   1920 
   1921 	solveGroupCacheFriendlyFinish(bodies, numBodies, infoGlobal);
   1922 
   1923 	return 0.f;
   1924 }
   1925 
   1926 void	btSequentialImpulseConstraintSolver::reset()
   1927 {
   1928 	m_btSeed2 = 0;
   1929 }
   1930