49 #include <emmintrin.h>
50 #define btVecSplat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e,e,e,e))
51 static inline __m128 btSimdDot3( __m128 vec0, __m128 vec1 )
53 __m128 result = _mm_mul_ps( vec0, vec1);
54 return _mm_add_ps( btVecSplat( result, 0 ), _mm_add_ps( btVecSplat( result, 1 ), btVecSplat( result, 2 ) ) );
66 __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.
m_contactNormal.mVec128,body1.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.
m_relpos1CrossNormal.mVec128,body1.internalGetDeltaAngularVelocity().mVec128));
67 __m128 deltaVel2Dotn = _mm_sub_ps(btSimdDot3(c.
m_relpos2CrossNormal.mVec128,body2.internalGetDeltaAngularVelocity().mVec128),btSimdDot3((c.
m_contactNormal).mVec128,body2.internalGetDeltaLinearVelocity().mVec128));
68 deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.
m_jacDiagABInv)));
69 deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.
m_jacDiagABInv)));
72 resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1);
73 resultUpperLess = _mm_cmplt_ps(sum,upperLimit1);
74 __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp);
75 deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) );
76 c.
m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
77 __m128 upperMinApplied = _mm_sub_ps(upperLimit1,cpAppliedImp);
78 deltaImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, deltaImpulse), _mm_andnot_ps(resultUpperLess, upperMinApplied) );
80 __m128 linearComponentA = _mm_mul_ps(c.
m_contactNormal.mVec128,body1.internalGetInvMass().mVec128);
81 __m128 linearComponentB = _mm_mul_ps((c.
m_contactNormal).mVec128,body2.internalGetInvMass().mVec128);
82 __m128 impulseMagnitude = deltaImpulse;
83 body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
84 body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.
m_angularComponentA.mVec128,impulseMagnitude));
85 body2.internalGetDeltaLinearVelocity().mVec128 = _mm_sub_ps(body2.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
86 body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.
m_angularComponentB.mVec128,impulseMagnitude));
130 __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.
m_contactNormal.mVec128,body1.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.
m_relpos1CrossNormal.mVec128,body1.internalGetDeltaAngularVelocity().mVec128));
131 __m128 deltaVel2Dotn = _mm_sub_ps(btSimdDot3(c.
m_relpos2CrossNormal.mVec128,body2.internalGetDeltaAngularVelocity().mVec128),btSimdDot3((c.
m_contactNormal).mVec128,body2.internalGetDeltaLinearVelocity().mVec128));
132 deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.
m_jacDiagABInv)));
133 deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.
m_jacDiagABInv)));
136 resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1);
137 resultUpperLess = _mm_cmplt_ps(sum,upperLimit1);
138 __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp);
139 deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) );
140 c.
m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
141 __m128 linearComponentA = _mm_mul_ps(c.
m_contactNormal.mVec128,body1.internalGetInvMass().mVec128);
142 __m128 linearComponentB = _mm_mul_ps((c.
m_contactNormal).mVec128,body2.internalGetInvMass().mVec128);
143 __m128 impulseMagnitude = deltaImpulse;
144 body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
145 body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.
m_angularComponentA.mVec128,impulseMagnitude));
146 body2.internalGetDeltaLinearVelocity().mVec128 = _mm_sub_ps(body2.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
147 body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.
m_angularComponentB.mVec128,impulseMagnitude));
218 __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.
m_contactNormal.mVec128,body1.internalGetPushVelocity().mVec128), btSimdDot3(c.
m_relpos1CrossNormal.mVec128,body1.internalGetTurnVelocity().mVec128));
219 __m128 deltaVel2Dotn = _mm_sub_ps(btSimdDot3(c.
m_relpos2CrossNormal.mVec128,body2.internalGetTurnVelocity().mVec128),btSimdDot3((c.
m_contactNormal).mVec128,body2.internalGetPushVelocity().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)));
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_appliedPushImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
229 __m128 linearComponentA = _mm_mul_ps(c.
m_contactNormal.mVec128,body1.internalGetInvMass().mVec128);
230 __m128 linearComponentB = _mm_mul_ps((c.
m_contactNormal).mVec128,body2.internalGetInvMass().mVec128);
231 __m128 impulseMagnitude = deltaImpulse;
232 body1.internalGetPushVelocity().mVec128 = _mm_add_ps(body1.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
233 body1.internalGetTurnVelocity().mVec128 = _mm_add_ps(body1.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.
m_angularComponentA.mVec128,impulseMagnitude));
234 body2.internalGetPushVelocity().mVec128 = _mm_sub_ps(body2.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
235 body2.internalGetTurnVelocity().mVec128 = _mm_add_ps(body2.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.
m_angularComponentB.mVec128,impulseMagnitude));
255 const unsigned long un =
static_cast<unsigned long>(n);
260 if (un <= 0x00010000UL) {
262 if (un <= 0x00000100UL) {
264 if (un <= 0x00000010UL) {
266 if (un <= 0x00000004UL) {
268 if (un <= 0x00000002UL) {
276 return (
int) (r % un);
286 solverBody->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
287 solverBody->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
288 solverBody->internalGetPushVelocity().setValue(0.f,0.f,0.f);
289 solverBody->internalGetTurnVelocity().setValue(0.f,0.f,0.f);
295 solverBody->m_originalBody = rb;
302 solverBody->m_worldTransform.setIdentity();
303 solverBody->internalSetInvMass(
btVector3(0,0,0));
304 solverBody->m_originalBody = 0;
305 solverBody->m_angularFactor.
setValue(1,1,1);
306 solverBody->m_linearFactor.setValue(1,1,1);
307 solverBody->m_linearVelocity.setValue(0,0,0);
308 solverBody->m_angularVelocity.setValue(0,0,0);
321 btScalar rest = restitution * -rel_vel;
338 loc_lateral *= friction_scaling;
348 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)
393 btScalar denom = relaxation/(denom0+denom1);
406 rel_vel = vel1Dotn+vel2Dotn;
412 solverConstraint.
m_rhs = velocityImpulse;
413 solverConstraint.
m_cfm = cfmSlip;
420 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)
425 colObj0, colObj1, relaxation, desiredVelocity, cfmSlip);
426 return solverConstraint;
485 rel_vel = vel1Dotn+vel2Dotn;
491 solverConstraint.
m_rhs = velocityImpulse;
492 solverConstraint.
m_cfm = cfmSlip;
506 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)
511 colObj0, colObj1, relaxation, desiredVelocity, cfmSlip);
512 return solverConstraint;
519 int solverBodyIdA = -1;
542 return solverBodyIdA;
549 int solverBodyIdA,
int solverBodyIdB,
566 rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin();
567 rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin();
577 #ifdef COMPUTE_IMPULSE_DENOM
594 #endif //COMPUTE_IMPULSE_DENOM
596 btScalar denom = relaxation/(denom0+denom1);
650 btScalar rel_vel = vel1Dotn+vel2Dotn;
653 btScalar velocityError = restitution - rel_vel;
659 erp = infoGlobal.
m_erp;
666 velocityError -= penetration / infoGlobal.
m_timeStep;
669 positionalError = -penetration * erp/infoGlobal.
m_timeStep;
678 solverConstraint.
m_rhs = penetrationImpulse+velocityImpulse;
684 solverConstraint.
m_rhs = velocityImpulse;
687 solverConstraint.
m_cfm = 0.f;
700 int solverBodyIdA,
int solverBodyIdB,
764 if (!solverBodyA || (!solverBodyA->m_originalBody && (!solverBodyB || !solverBodyB->m_originalBody)))
767 int rollingFriction=1;
790 setupContactConstraint(solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal, vel, rel_vel, relaxation, rel_pos1, rel_pos2);
800 solverBodyA->getAngularVelocity(angVelA);
801 solverBodyB->getAngularVelocity(angVelB);
813 if (relAngVel.
length()>0.001)
892 addFrictionConstraint(cp.
m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation,cp.
m_contactMotion1, cp.
m_contactCFM1);
895 addFrictionConstraint(cp.
m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation, cp.
m_contactMotion2, cp.
m_contactCFM2);
917 for (
int i=0;i<numConstraints;i++)
925 for (
int b=0;b<numBodies;b++)
939 for (
int b=0;b<numBodies;b++)
952 for (
int i=0;i<numManifolds;i++)
954 if (!manifoldPtr[i]->getBody0()->isStaticOrKinematicObject())
957 for (
int b=0;b<numBodies;b++)
960 if (manifoldPtr[i]->getBody0()==bodies[b])
968 if (!manifoldPtr[i]->getBody1()->isStaticOrKinematicObject())
971 for (
int b=0;b<numBodies;b++)
973 if (manifoldPtr[i]->getBody1()==bodies[b])
985 for (
int i = 0; i < numBodies; i++)
999 for (
int i=0;i<numBodies;i++)
1019 for (j=0;j<numConstraints;j++)
1033 int totalNumRows = 0;
1038 for (i=0;i<numConstraints;i++)
1050 if (constraints[i]->isEnabled())
1053 if (constraints[i]->isEnabled())
1069 for (i=0;i<numConstraints;i++)
1109 bodyAPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
1110 bodyAPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
1111 bodyAPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f);
1112 bodyAPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f);
1113 bodyBPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
1114 bodyBPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
1115 bodyBPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f);
1116 bodyBPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f);
1132 info2.
cfm = ¤tConstraintRow->
m_cfm;
1187 rel_vel = vel1Dotn+vel2Dotn;
1194 solverConstraint.
m_rhs = penetrationImpulse+velocityImpulse;
1210 for (i=0;i<numManifolds;i++)
1212 manifold = manifoldPtr[i];
1235 for (i=0;i<numNonContactPool;i++)
1239 for (i=0;i<numConstraintPool;i++)
1243 for (i=0;i<numFrictionPool;i++)
1266 for (
int j=0; j<numNonContactPool; ++j) {
1276 for (
int j=0; j<numConstraintPool; ++j) {
1283 for (
int j=0; j<numFrictionPool; ++j) {
1305 for (
int j=0;j<numConstraints;j++)
1307 if (constraints[j]->isEnabled())
1323 for (
int c=0;c<numPoolConstraints;c++)
1332 bool applyFriction =
true;
1371 for (j=0;j<numPoolConstraints;j++)
1383 for (j=0;j<numFrictionPoolConstraints;j++)
1399 for (j=0;j<numRollingFrictionPoolConstraints;j++)
1406 btScalar rollingFrictionMagnitude = rollingFrictionConstraint.
m_friction*totalImpulse;
1407 if (rollingFrictionMagnitude>rollingFrictionConstraint.
m_friction)
1408 rollingFrictionMagnitude = rollingFrictionConstraint.
m_friction;
1410 rollingFrictionConstraint.
m_lowerLimit = -rollingFrictionMagnitude;
1411 rollingFrictionConstraint.
m_upperLimit = rollingFrictionMagnitude;
1433 for (
int j=0;j<numConstraints;j++)
1435 if (constraints[j]->isEnabled())
1446 for (
int j=0;j<numPoolConstraints;j++)
1453 for (
int j=0;j<numFrictionPoolConstraints;j++)
1468 for (
int j=0;j<numRollingFrictionPoolConstraints;j++)
1474 btScalar rollingFrictionMagnitude = rollingFrictionConstraint.
m_friction*totalImpulse;
1475 if (rollingFrictionMagnitude>rollingFrictionConstraint.
m_friction)
1476 rollingFrictionMagnitude = rollingFrictionConstraint.
m_friction;
1478 rollingFrictionConstraint.
m_lowerLimit = -rollingFrictionMagnitude;
1479 rollingFrictionConstraint.
m_upperLimit = rollingFrictionMagnitude;
1502 for (j=0;j<numPoolConstraints;j++)
1518 for (j=0;j<numPoolConstraints;j++)
1532 BT_PROFILE(
"solveGroupCacheFriendlyIterations");
1540 for (
int iteration = 0 ; iteration<
maxIterations ; iteration++)
1543 solveSingleIteration(iteration, bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc);
1557 for (j=0;j<numPoolConstraints;j++)
1576 for (j=0;j<numPoolConstraints;j++)
1636 solveGroupCacheFriendlySetup( bodies, numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);