51 #include <emmintrin.h>
52 #define btVecSplat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e,e,e,e))
53 static inline __m128 btSimdDot3( __m128 vec0, __m128 vec1 )
55 __m128 result = _mm_mul_ps( vec0, vec1);
56 return _mm_add_ps( btVecSplat( result, 0 ), _mm_add_ps( btVecSplat( result, 1 ), btVecSplat( result, 2 ) ) );
70 deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.
m_jacDiagABInv)));
71 deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.
m_jacDiagABInv)));
74 resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1);
75 resultUpperLess = _mm_cmplt_ps(sum,upperLimit1);
76 __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp);
77 deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) );
78 c.
m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
79 __m128 upperMinApplied = _mm_sub_ps(upperLimit1,cpAppliedImp);
80 deltaImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, deltaImpulse), _mm_andnot_ps(resultUpperLess, upperMinApplied) );
84 __m128 impulseMagnitude = deltaImpulse;
134 deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.
m_jacDiagABInv)));
135 deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.
m_jacDiagABInv)));
138 resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1);
139 resultUpperLess = _mm_cmplt_ps(sum,upperLimit1);
140 __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp);
141 deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) );
142 c.
m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
145 __m128 impulseMagnitude = deltaImpulse;
222 deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.
m_jacDiagABInv)));
223 deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.
m_jacDiagABInv)));
226 resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1);
227 resultUpperLess = _mm_cmplt_ps(sum,upperLimit1);
228 __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp);
229 deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) );
230 c.
m_appliedPushImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
233 __m128 impulseMagnitude = deltaImpulse;
257 const unsigned long un =
static_cast<unsigned long>(n);
262 if (un <= 0x00010000UL) {
264 if (un <= 0x00000100UL) {
266 if (un <= 0x00000010UL) {
268 if (un <= 0x00000004UL) {
270 if (un <= 0x00000002UL) {
278 return (
int) (r % un);
328 btScalar rest = restitution * -rel_vel;
344 loc_lateral *= friction_scaling;
354 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)
413 btScalar denom = relaxation/(denom0+denom1);
426 rel_vel = vel1Dotn+vel2Dotn;
432 solverConstraint.
m_rhs = velocityImpulse;
433 solverConstraint.
m_cfm = cfmSlip;
440 btSolverConstraint&
btSequentialImpulseConstraintSolver::addFrictionConstraint(
const btVector3& normalAxis,
int solverBodyIdA,
int solverBodyIdB,
int frictionIndex,
btManifoldPoint& cp,
const btVector3& rel_pos1,
const btVector3& rel_pos2,
btCollisionObject* colObj0,
btCollisionObject* colObj1,
btScalar relaxation,
btScalar desiredVelocity,
btScalar cfmSlip)
445 colObj0, colObj1, relaxation, desiredVelocity, cfmSlip);
446 return solverConstraint;
506 rel_vel = vel1Dotn+vel2Dotn;
512 solverConstraint.
m_rhs = velocityImpulse;
513 solverConstraint.
m_cfm = cfmSlip;
527 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)
532 colObj0, colObj1, relaxation, desiredVelocity, cfmSlip);
533 return solverConstraint;
540 int solverBodyIdA = -1;
571 return solverBodyIdA;
578 int solverBodyIdA,
int solverBodyIdB,
606 #ifdef COMPUTE_IMPULSE_DENOM
623 #endif //COMPUTE_IMPULSE_DENOM
625 btScalar denom = relaxation/(denom0+denom1);
701 btScalar rel_vel = vel1Dotn+vel2Dotn;
704 btScalar velocityError = restitution - rel_vel;
710 erp = infoGlobal.
m_erp;
717 velocityError -= penetration / infoGlobal.
m_timeStep;
720 positionalError = -penetration * erp/infoGlobal.
m_timeStep;
729 solverConstraint.
m_rhs = penetrationImpulse+velocityImpulse;
735 solverConstraint.
m_rhs = velocityImpulse;
738 solverConstraint.
m_cfm = 0.f;
751 int solverBodyIdA,
int solverBodyIdB,
818 int rollingFriction=1;
844 rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin();
855 setupContactConstraint(solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal, relaxation, rel_pos1, rel_pos2);
882 if (relAngVel.
length()>0.001)
961 addFrictionConstraint(cp.
m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation,cp.
m_contactMotion1, cp.
m_contactCFM1);
964 addFrictionConstraint(cp.
m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation, cp.
m_contactMotion2, cp.
m_contactCFM2);
983 for (i=0;i<numManifolds;i++)
985 manifold = manifoldPtr[i];
998 #ifdef BT_ADDITIONAL_DEBUG
1000 for (
int i=0;i<numConstraints;i++)
1008 for (
int b=0;b<numBodies;b++)
1022 for (
int b=0;b<numBodies;b++)
1035 for (
int i=0;i<numManifolds;i++)
1037 if (!manifoldPtr[i]->getBody0()->isStaticOrKinematicObject())
1040 for (
int b=0;b<numBodies;b++)
1043 if (manifoldPtr[i]->getBody0()==bodies[b])
1051 if (!manifoldPtr[i]->getBody1()->isStaticOrKinematicObject())
1054 for (
int b=0;b<numBodies;b++)
1056 if (manifoldPtr[i]->getBody1()==bodies[b])
1065 #endif //BT_ADDITIONAL_DEBUG
1068 for (
int i = 0; i < numBodies; i++)
1082 for (
int i=0;i<numBodies;i++)
1102 for (j=0;j<numConstraints;j++)
1116 int totalNumRows = 0;
1121 for (i=0;i<numConstraints;i++)
1133 if (constraints[i]->isEnabled())
1136 if (constraints[i]->isEnabled())
1152 for (i=0;i<numConstraints;i++)
1215 info2.
cfm = ¤tConstraintRow->
m_cfm;
1278 rel_vel = vel1Dotn+vel2Dotn;
1284 solverConstraint.
m_rhs = penetrationImpulse+velocityImpulse;
1316 for (i=0;i<numNonContactPool;i++)
1320 for (i=0;i<numConstraintPool;i++)
1324 for (i=0;i<numFrictionPool;i++)
1347 for (
int j=0; j<numNonContactPool; ++j) {
1357 for (
int j=0; j<numConstraintPool; ++j) {
1364 for (
int j=0; j<numFrictionPool; ++j) {
1386 for (
int j=0;j<numConstraints;j++)
1388 if (constraints[j]->isEnabled())
1404 for (
int c=0;c<numPoolConstraints;c++)
1413 bool applyFriction =
true;
1452 for (j=0;j<numPoolConstraints;j++)
1465 for (j=0;j<numFrictionPoolConstraints;j++)
1482 for (j=0;j<numRollingFrictionPoolConstraints;j++)
1489 btScalar rollingFrictionMagnitude = rollingFrictionConstraint.
m_friction*totalImpulse;
1490 if (rollingFrictionMagnitude>rollingFrictionConstraint.
m_friction)
1491 rollingFrictionMagnitude = rollingFrictionConstraint.
m_friction;
1493 rollingFrictionConstraint.
m_lowerLimit = -rollingFrictionMagnitude;
1494 rollingFrictionConstraint.
m_upperLimit = rollingFrictionMagnitude;
1516 for (
int j=0;j<numConstraints;j++)
1518 if (constraints[j]->isEnabled())
1529 for (
int j=0;j<numPoolConstraints;j++)
1536 for (
int j=0;j<numFrictionPoolConstraints;j++)
1551 for (
int j=0;j<numRollingFrictionPoolConstraints;j++)
1557 btScalar rollingFrictionMagnitude = rollingFrictionConstraint.
m_friction*totalImpulse;
1558 if (rollingFrictionMagnitude>rollingFrictionConstraint.
m_friction)
1559 rollingFrictionMagnitude = rollingFrictionConstraint.
m_friction;
1561 rollingFrictionConstraint.
m_lowerLimit = -rollingFrictionMagnitude;
1562 rollingFrictionConstraint.
m_upperLimit = rollingFrictionMagnitude;
1585 for (j=0;j<numPoolConstraints;j++)
1601 for (j=0;j<numPoolConstraints;j++)
1615 BT_PROFILE(
"solveGroupCacheFriendlyIterations");
1623 for (
int iteration = 0 ; iteration<
maxIterations ; iteration++)
1626 solveSingleIteration(iteration, bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer);
1640 for (j=0;j<numPoolConstraints;j++)
1659 for (j=0;j<numPoolConstraints;j++)
btScalar * m_constraintError
btScalar getInvMass() const
static T sum(const btAlignedObjectArray< T > &items)
btVector3 m_linearVelocity
static const btRigidBody * upcast(const btCollisionObject *colObj)
to keep collision detection and dynamics separate we don't store a rigidbody pointer but a rigidbody ...
btVector3 m_angularVelocity
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
int m_overrideNumSolverIterations
btScalar * m_J2angularAxis
virtual ~btSequentialImpulseConstraintSolver()
virtual void getInfo1(btConstraintInfo1 *info)=0
internal method used by the constraint solver, don't use them directly
btConstraintArray m_tmpSolverContactFrictionConstraintPool
const btVector3 & getTotalForce() const
btConstraintArray m_tmpSolverContactRollingFrictionConstraintPool
btVector3 m_lateralFrictionDir1
void resolveSingleConstraintRowGenericSIMD(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &contactConstraint)
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
btVector3 m_relpos1CrossNormal
void internalApplyImpulse(const btVector3 &linearComponent, const btVector3 &angularComponent, const btScalar impulseMagnitude)
const btVector3 & getAngularFactor() const
btScalar m_appliedImpulseLateral1
btScalar m_rhsPenetration
virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject **bodies, int numBodies, const btContactSolverInfo &infoGlobal)
virtual void getInfo2(btConstraintInfo2 *info)=0
internal method used by the constraint solver, don't use them directly
btScalar m_combinedRestitution
virtual btScalar solveGroup(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifold, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &info, btIDebugDraw *debugDrawer, btDispatcher *dispatcher)
btSequentialImpulseConstraintSolver Sequentially applies impulses
1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and fr...
void btPlaneSpace1(const T &n, T &p, T &q)
void resizeNoInitialize(int newsize)
resize changes the number of elements in the array.
btScalar btSqrt(btScalar y)
btScalar m_appliedImpulse
btVector3 m_relpos2CrossNormal
const btVector3 & getTotalTorque() const
btScalar getBreakingImpulseThreshold() const
btScalar computeImpulseDenominator(const btVector3 &pos, const btVector3 &normal) const
virtual btScalar solveSingleIteration(int iteration, btCollisionObject **bodies, int numBodies, btPersistentManifold **manifoldPtr, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &infoGlobal, btIDebugDraw *debugDrawer)
btVector3 computeGyroscopicForce(btScalar maxGyroscopicForce) const
ManifoldContactPoint collects and maintains persistent contactpoints.
btScalar * m_J1angularAxis
const btCollisionObject * getBody0() const
btScalar m_contactMotion1
void getVelocityInLocalPointNoDelta(const btVector3 &rel_pos, btVector3 &velocity) const
btAlignedObjectArray< int > m_orderTmpConstraintPool
void initSolverBody(btSolverBody *solverBody, btCollisionObject *collisionObject, btScalar timeStep)
virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifoldPtr, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &infoGlobal, btIDebugDraw *debugDrawer)
void resolveSingleConstraintRowLowerLimitSIMD(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &contactConstraint)
btScalar restitutionCurve(btScalar rel_vel, btScalar restitution)
btScalar dot(const btVector3 &v) const
Return the dot product.
virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifoldPtr, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &infoGlobal, btIDebugDraw *debugDrawer)
btVector3 m_externalTorqueImpulse
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
const btVector3 & getAnisotropicFriction() const
btVector3 m_appliedForceBodyB
btVector3 getVelocityInLocalPoint(const btVector3 &rel_pos) const
const btJointFeedback * getJointFeedback() const
int getOrInitSolverBody(btCollisionObject &body, btScalar timeStep)
btVector3 m_externalForceImpulse
btVector3 & internalGetTurnVelocity()
#define btSimdScalar
Until we get other contributions, only use SIMD on Windows, when using Visual Studio 2008 or later...
btVector3 m_angularComponentA
btScalar m_combinedRollingFriction
btAlignedObjectArray< btSolverBody > m_tmpSolverBodyPool
void internalSetInvMass(const btVector3 &invMass)
btTransform & getWorldTransform()
btVector3 m_normalWorldOnB
btScalar * m_J1linearAxis
int size() const
return the number of elements in the array
btVector3 m_appliedForceBodyA
void setFrictionConstraintImpulse(btSolverConstraint &solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint &cp, const btContactSolverInfo &infoGlobal)
bool isKinematicObject() const
virtual void convertContacts(btPersistentManifold **manifoldPtr, int numManifolds, const btContactSolverInfo &infoGlobal)
btVector3 m_angularFactor
btScalar m_appliedImpulseLateral2
btConstraintArray m_tmpSolverContactConstraintPool
const btVector3 & getAngularVelocity() const
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
bool isStaticOrKinematicObject() const
btCollisionObject can be used to manage collision detection objects.
btScalar getContactProcessingThreshold() const
The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations...
The btRigidBody is the main class for rigid body objects.
btScalar length() const
Return the length of the vector.
btVector3 m_angularComponentB
void resolveSingleConstraintRowGeneric(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &contactConstraint)
int m_maxOverrideNumSolverIterations
const btManifoldPoint & getContactPoint(int index) const
void setCompanionId(int id)
const btVector3 & internalGetInvMass() const
const btVector3 & getPositionWorldOnB() const
btVector3 can be used to represent 3D points and vectors.
btSolverConstraint & addFrictionConstraint(const btVector3 &normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint &cp, const btVector3 &rel_pos1, const btVector3 &rel_pos2, btCollisionObject *colObj0, btCollisionObject *colObj1, btScalar relaxation, btScalar desiredVelocity=0., btScalar cfmSlip=0.)
int getCompanionId() const
btScalar length2() const
Return the length of the vector squared.
virtual void solveConstraintObsolete(btSolverBody &, btSolverBody &, btScalar)
internal method used by the constraint solver, don't use them directly
void convertContact(btPersistentManifold *manifold, const btContactSolverInfo &infoGlobal)
void resolveSingleConstraintRowLowerLimit(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &contactConstraint)
btVector3 m_appliedTorqueBodyB
btSimdScalar m_appliedPushImpulse
btSolverConstraint & 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=0, btScalar cfmSlip=0.f)
The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packe...
void * m_originalContactPoint
btAlignedObjectArray< btTypedConstraint::btConstraintInfo1 > m_tmpConstraintSizesPool
btScalar * m_J2linearAxis
bool hasAnisotropicFriction(int frictionMode=CF_ANISOTROPIC_FRICTION) const
TypedConstraint is the baseclass for Bullet constraints and vehicles.
void resize(int newsize, const T &fillData=T())
void 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=0., btScalar cfmSlip=0.)
btRigidBody * m_originalBody
void internalApplyPushImpulse(const btVector3 &linearComponent, const btVector3 &angularComponent, btScalar impulseMagnitude)
int getNumContacts() const
btVector3 & internalGetDeltaLinearVelocity()
some internal methods, don't use them
const btRigidBody & getRigidBodyA() const
void resolveSplitPenetrationSIMD(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &contactConstraint)
int gNumSplitImpulseRecoveries
void setEnabled(bool enabled)
virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifoldPtr, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &infoGlobal, btIDebugDraw *debugDrawer)
static float4 cross(const float4 &a, const float4 &b)
void setupRollingFrictionConstraint(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=0., btScalar cfmSlip=0.)
btScalar m_contactMotion2
const btMatrix3x3 & getInvInertiaTensorWorld() const
btScalar m_combinedFriction
bool m_lateralFrictionInitialized
T & expand(const T &fillValue=T())
btVector3 m_appliedTorqueBodyA
const btVector3 & getPositionWorldOnA() const
btVector3 & internalGetPushVelocity()
btVector3 m_contactNormal1
btAlignedObjectArray< int > m_orderFrictionConstraintPool
const btVector3 & getLinearVelocity() const
void setupContactConstraint(btSolverConstraint &solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint &cp, const btContactSolverInfo &infoGlobal, btScalar &relaxation, const btVector3 &rel_pos1, const btVector3 &rel_pos2)
btAlignedObjectArray< int > m_orderNonContactConstraintPool
btVector3 & internalGetDeltaAngularVelocity()
void internalSetAppliedImpulse(btScalar appliedImpulse)
internal method used by the constraint solver, don't use them directly
virtual void reset()
clear internal cached data and reset random seed
unsigned long m_btSeed2
m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction ...
btVector3 m_lateralFrictionDir2
btSimdScalar m_appliedImpulse
btScalar getDistance() const
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
const btVector3 & getLinearFactor() const
T & expandNonInitializing()
The BT_ENABLE_GYROPSCOPIC_FORCE can easily introduce instability So generally it is best to not enabl...
const btRigidBody & getRigidBodyB() const
static void applyAnisotropicFriction(btCollisionObject *colObj, btVector3 &frictionDirection, int frictionMode)
int getOverrideNumSolverIterations() const
const btCollisionObject * getBody1() const
btSequentialImpulseConstraintSolver()
virtual void buildJacobian()
internal method used by the constraint solver, don't use them directly
btConstraintArray m_tmpSolverNonContactConstraintPool
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
btVector3 m_contactNormal2
void resolveSplitPenetrationImpulseCacheFriendly(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &contactConstraint)
btScalar btFabs(btScalar x)
btTransform m_worldTransform