18# define BT_ADDITIONAL_DEBUG
104#include <emmintrin.h>
106#define btVecSplat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e, e, e, e))
107static inline __m128 btSimdDot3(__m128 vec0, __m128 vec1)
109 __m128 result = _mm_mul_ps(vec0, vec1);
110 return _mm_add_ps(btVecSplat(result, 0), _mm_add_ps(btVecSplat(result, 1), btVecSplat(result, 2)));
113#if defined(BT_ALLOW_SSE4)
117#define USE_FMA3_INSTEAD_FMA4 1
118#define USE_SSE4_DOT 1
120#define SSE4_DP(a, b) _mm_dp_ps(a, b, 0x7f)
121#define SSE4_DP_FP(a, b) _mm_cvtss_f32(_mm_dp_ps(a, b, 0x7f))
124#define DOT_PRODUCT(a, b) SSE4_DP(a, b)
126#define DOT_PRODUCT(a, b) btSimdDot3(a, b)
130#if USE_FMA3_INSTEAD_FMA4
132#define FMADD(a, b, c) _mm_fmadd_ps(a, b, c)
134#define FMNADD(a, b, c) _mm_fnmadd_ps(a, b, c)
137#define FMADD(a, b, c) _mm_macc_ps(a, b, c)
139#define FMNADD(a, b, c) _mm_nmacc_ps(a, b, c)
143#define FMADD(a, b, c) _mm_add_ps(c, _mm_mul_ps(a, b))
145#define FMNADD(a, b, c) _mm_sub_ps(c, _mm_mul_ps(a, b))
158 deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel1Dotn, _mm_set1_ps(c.
m_jacDiagABInv)));
159 deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel2Dotn, _mm_set1_ps(c.
m_jacDiagABInv)));
162 resultLowerLess = _mm_cmplt_ps(
sum, lowerLimit1);
163 resultUpperLess = _mm_cmplt_ps(
sum, upperLimit1);
164 __m128 lowMinApplied = _mm_sub_ps(lowerLimit1, cpAppliedImp);
165 deltaImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse));
166 c.
m_appliedImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess,
sum));
167 __m128 upperMinApplied = _mm_sub_ps(upperLimit1, cpAppliedImp);
168 deltaImpulse = _mm_or_ps(_mm_and_ps(resultUpperLess, deltaImpulse), _mm_andnot_ps(resultUpperLess, upperMinApplied));
172 __m128 impulseMagnitude = deltaImpulse;
183#if defined(BT_ALLOW_SSE4)
190 deltaImpulse = FMNADD(deltaVel1Dotn, tmp, deltaImpulse);
191 deltaImpulse = FMNADD(deltaVel2Dotn, tmp, deltaImpulse);
193 const __m128 maskLower = _mm_cmpgt_ps(tmp, lowerLimit);
194 const __m128 maskUpper = _mm_cmpgt_ps(upperLimit, tmp);
195 deltaImpulse = _mm_blendv_ps(_mm_sub_ps(lowerLimit, c.
m_appliedImpulse), _mm_blendv_ps(_mm_sub_ps(upperLimit, c.
m_appliedImpulse), deltaImpulse, maskUpper), maskLower);
196 c.
m_appliedImpulse = _mm_blendv_ps(lowerLimit, _mm_blendv_ps(upperLimit, tmp, maskUpper), maskLower);
204 return gResolveSingleConstraintRowGeneric_sse2(bodyA, bodyB, c);
216 deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel1Dotn, _mm_set1_ps(c.
m_jacDiagABInv)));
217 deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel2Dotn, _mm_set1_ps(c.
m_jacDiagABInv)));
220 resultLowerLess = _mm_cmplt_ps(
sum, lowerLimit1);
221 resultUpperLess = _mm_cmplt_ps(
sum, upperLimit1);
222 __m128 lowMinApplied = _mm_sub_ps(lowerLimit1, cpAppliedImp);
223 deltaImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse));
224 c.
m_appliedImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess,
sum));
227 __m128 impulseMagnitude = deltaImpulse;
244 deltaImpulse = FMNADD(deltaVel1Dotn, tmp, deltaImpulse);
245 deltaImpulse = FMNADD(deltaVel2Dotn, tmp, deltaImpulse);
247 const __m128 mask = _mm_cmpgt_ps(tmp, lowerLimit);
248 deltaImpulse = _mm_blendv_ps(_mm_sub_ps(lowerLimit, c.
m_appliedImpulse), deltaImpulse, mask);
257 return gResolveSingleConstraintRowLowerLimit_sse2(bodyA, bodyB, c);
330 deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel1Dotn, _mm_set1_ps(c.
m_jacDiagABInv)));
331 deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel2Dotn, _mm_set1_ps(c.
m_jacDiagABInv)));
334 resultLowerLess = _mm_cmplt_ps(
sum, lowerLimit1);
335 resultUpperLess = _mm_cmplt_ps(
sum, upperLimit1);
336 __m128 lowMinApplied = _mm_sub_ps(lowerLimit1, cpAppliedImp);
337 deltaImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse));
338 c.
m_appliedPushImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess,
sum));
341 __m128 impulseMagnitude = deltaImpulse;
402 return gResolveSingleConstraintRowGeneric_sse2;
406 return gResolveSingleConstraintRowLowerLimit_sse2;
411 return gResolveSingleConstraintRowGeneric_sse4_1_fma3;
415 return gResolveSingleConstraintRowLowerLimit_sse4_1_fma3;
430 const unsigned long un =
static_cast<unsigned long>(n);
435 if (un <= 0x00010000UL)
438 if (un <= 0x00000100UL)
441 if (un <= 0x00000010UL)
444 if (un <= 0x00000004UL)
447 if (un <= 0x00000002UL)
456 return (
int)(r % un);
497 if (
btFabs(rel_vel) < velocityThreshold)
500 btScalar rest = restitution * -rel_vel;
512 loc_lateral *= friction_scaling;
518void 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,
const btContactSolverInfo& infoGlobal,
btScalar desiredVelocity,
btScalar cfmSlip)
577 btScalar denom = relaxation / (denom0 + denom1);
586 rel_vel = vel1Dotn + vel2Dotn;
590 btScalar velocityError = desiredVelocity - rel_vel;
599 penetrationImpulse = positionalError * solverConstraint.
m_jacDiagABInv;
602 solverConstraint.
m_rhs = penetrationImpulse + velocityImpulse;
604 solverConstraint.
m_cfm = cfmSlip;
610btSolverConstraint&
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,
const btContactSolverInfo& infoGlobal,
btScalar desiredVelocity,
btScalar cfmSlip)
615 colObj0, colObj1, relaxation, infoGlobal, desiredVelocity, cfmSlip);
616 return solverConstraint;
638 solverConstraint.
m_friction = combinedTorsionalFriction;
669 rel_vel = vel1Dotn + vel2Dotn;
675 solverConstraint.
m_rhs = velocityImpulse;
676 solverConstraint.
m_cfm = cfmSlip;
682btSolverConstraint&
btSequentialImpulseConstraintSolver::addTorsionalFrictionConstraint(
const btVector3& normalAxis,
int solverBodyIdA,
int solverBodyIdB,
int frictionIndex,
btManifoldPoint& cp,
btScalar combinedTorsionalFriction,
const btVector3& rel_pos1,
const btVector3& rel_pos2,
btCollisionObject* colObj0,
btCollisionObject* colObj1,
btScalar relaxation,
btScalar desiredVelocity,
btScalar cfmSlip)
687 colObj0, colObj1, relaxation, desiredVelocity, cfmSlip);
688 return solverConstraint;
694 int solverBodyId = -1;
698 if (isRigidBodyType && !isStaticOrKinematic)
703 if (solverBodyId < 0)
711 else if (isRigidBodyType && isKinematic)
721 const int INVALID_SOLVER_BODY_ID = -1;
728 if (solverBodyId == INVALID_SOLVER_BODY_ID)
741 if (!isMultiBodyType)
759 int solverBodyIdA = -1;
791 return solverBodyIdA;
797 int solverBodyIdA,
int solverBodyIdB,
816 relaxation = infoGlobal.
m_sor;
854#ifdef COMPUTE_IMPULSE_DENOM
873 btScalar denom = relaxation / (denom0 + denom1 + cfm);
944 btScalar rel_vel = vel1Dotn + vel2Dotn;
947 btScalar velocityError = restitution - rel_vel;
953 velocityError -= penetration * invTimeStep;
957 positionalError = -penetration * erp * invTimeStep;
966 solverConstraint.
m_rhs = penetrationImpulse + velocityImpulse;
972 solverConstraint.
m_rhs = velocityImpulse;
982 int solverBodyIdA,
int solverBodyIdB,
1019 int rollingFriction = 1;
1041 rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin();
1052 setupContactConstraint(solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal, relaxation, rel_pos1, rel_pos2);
1061 addTorsionalFrictionConstraint(cp.
m_normalWorldOnB, solverBodyIdA, solverBodyIdB, frictionIndex, cp, cp.
m_combinedSpinningFriction, rel_pos1, rel_pos2, colObj0, colObj1, relaxation);
1071 if (axis0.
length() > 0.001)
1074 if (axis1.
length() > 0.001)
1105 addFrictionConstraint(cp.
m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
1113 addFrictionConstraint(cp.
m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
1122 addFrictionConstraint(cp.
m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
1128 addFrictionConstraint(cp.
m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
1139 addFrictionConstraint(cp.
m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, cp.
m_contactMotion1, cp.
m_frictionCFM);
1142 addFrictionConstraint(cp.
m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, cp.
m_contactMotion2, cp.
m_frictionCFM);
1155 for (i = 0; i < numManifolds; i++)
1157 manifold = manifoldPtr[i];
1222 info2.
cfm = ¤tConstraintRow->
m_cfm;
1282 rel_vel = vel1Dotn + vel2Dotn;
1288 solverConstraint.
m_rhs = penetrationImpulse + velocityImpulse;
1297 for (
int j = 0; j < numConstraints; j++)
1304 int totalNumRows = 0;
1308 for (
int i = 0; i < numConstraints; i++)
1320 if (constraints[i]->isEnabled())
1336 for (
int i = 0; i < numConstraints; i++)
1342 btAssert(currentRow < totalNumRows);
1352 convertJoint(currentConstraintRow, constraint, info1, solverBodyIdA, solverBodyIdB, infoGlobal);
1361 for (
int i = 0; i < numBodies; i++)
1375 for (
int i = 0; i < numBodies; i++)
1419#ifdef BT_ADDITIONAL_DEBUG
1421 for (
int i = 0; i < numConstraints; i++)
1429 for (
int b = 0; b < numBodies; b++)
1442 for (
int b = 0; b < numBodies; b++)
1455 for (
int i = 0; i < numManifolds; i++)
1457 if (!manifoldPtr[i]->getBody0()->isStaticOrKinematicObject())
1460 for (
int b = 0; b < numBodies; b++)
1462 if (manifoldPtr[i]->getBody0() == bodies[b])
1470 if (!manifoldPtr[i]->getBody1()->isStaticOrKinematicObject())
1473 for (
int b = 0; b < numBodies; b++)
1475 if (manifoldPtr[i]->getBody1() == bodies[b])
1509 for (i = 0; i < numNonContactPool; i++)
1513 for (i = 0; i < numConstraintPool; i++)
1517 for (i = 0; i < numFrictionPool; i++)
1529 btScalar leastSquaresResidual = 0.f;
1539 for (
int j = 0; j < numNonContactPool; ++j)
1550 for (
int j = 0; j < numConstraintPool; ++j)
1558 for (
int j = 0; j < numFrictionPool; ++j)
1576 leastSquaresResidual =
btMax(leastSquaresResidual, residual * residual);
1582 for (
int j = 0; j < numConstraints; j++)
1584 if (constraints[j]->isEnabled())
1600 for (
int c = 0; c < numPoolConstraints; c++)
1607 leastSquaresResidual =
btMax(leastSquaresResidual, residual * residual);
1611 bool applyFriction =
true;
1623 leastSquaresResidual =
btMax(leastSquaresResidual, residual * residual);
1637 leastSquaresResidual =
btMax(leastSquaresResidual, residual * residual);
1649 for (j = 0; j < numPoolConstraints; j++)
1653 leastSquaresResidual =
btMax(leastSquaresResidual, residual * residual);
1659 for (j = 0; j < numFrictionPoolConstraints; j++)
1670 leastSquaresResidual =
btMax(leastSquaresResidual, residual * residual);
1676 for (
int j = 0; j < numRollingFrictionPoolConstraints; j++)
1682 btScalar rollingFrictionMagnitude = rollingFrictionConstraint.
m_friction * totalImpulse;
1683 if (rollingFrictionMagnitude > rollingFrictionConstraint.
m_friction)
1684 rollingFrictionMagnitude = rollingFrictionConstraint.
m_friction;
1686 rollingFrictionConstraint.
m_lowerLimit = -rollingFrictionMagnitude;
1687 rollingFrictionConstraint.
m_upperLimit = rollingFrictionMagnitude;
1690 leastSquaresResidual =
btMax(leastSquaresResidual, residual * residual);
1694 return leastSquaresResidual;
1699 BT_PROFILE(
"solveGroupCacheFriendlySplitImpulseIterations");
1704 for (iteration = 0; iteration < infoGlobal.
m_numIterations; iteration++)
1706 btScalar leastSquaresResidual = 0.f;
1710 for (j = 0; j < numPoolConstraints; j++)
1715 leastSquaresResidual =
btMax(leastSquaresResidual, residual * residual);
1718 if (leastSquaresResidual <= infoGlobal.m_leastSquaresResidualThreshold || iteration >= (infoGlobal.
m_numIterations - 1))
1720#ifdef VERBOSE_RESIDUAL_PRINTF
1721 printf(
"residual = %f at iteration #%d\n", leastSquaresResidual, iteration);
1732 BT_PROFILE(
"solveGroupCacheFriendlyIterations");
1740 for (
int iteration = 0; iteration < maxIterations; iteration++)
1747#ifdef VERBOSE_RESIDUAL_PRINTF
1767 for (
int j = iBegin; j < iEnd; j++)
1787 for (
int j = iBegin; j < iEnd; j++)
1810 for (
int i = iBegin; i < iEnd; i++)
@ BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED
@ BT_CONTACT_FLAG_HAS_CONTACT_ERP
@ BT_CONTACT_FLAG_HAS_CONTACT_CFM
@ BT_CONTACT_FLAG_CONTACT_STIFFNESS_DAMPING
@ BT_CONTACT_FLAG_FRICTION_ANCHOR
const T & btMax(const T &a, const T &b)
btScalar dot(const btQuaternion &q1, const btQuaternion &q2)
Calculate the dot product between two quaternions.
@ BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY
@ BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT
BT_ENABLE_GYROPSCOPIC_FORCE flags is enabled by default in Bullet 2.83 and onwards.
@ BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
btScalar btSqrt(btScalar y)
btScalar btFabs(btScalar x)
static btScalar gResolveSingleConstraintRowGeneric_scalar_reference(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &c)
This is the scalar reference implementation of solving a single constraint row, the innerloop of the ...
static btScalar gResolveSingleConstraintRowLowerLimit_scalar_reference(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &c)
static btScalar gResolveSplitPenetrationImpulse_sse2(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &c)
int gNumSplitImpulseRecoveries
static btScalar gResolveSplitPenetrationImpulse_scalar_reference(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &c)
btScalar(* btSingleConstraintRowSolver)(btSolverBody &, btSolverBody &, const btSolverConstraint &)
static T sum(const btAlignedObjectArray< T > &items)
#define btSimdScalar
Until we get other contributions, only use SIMD on Windows, when using Visual Studio 2008 or later,...
void btPlaneSpace1(const T &n, T &p, T &q)
void resizeNoInitialize(int newsize)
resize changes the number of elements in the array.
int size() const
return the number of elements in the array
void resize(int newsize, const T &fillData=T())
T & expandNonInitializing()
T & expand(const T &fillValue=T())
btCollisionObject can be used to manage collision detection objects.
bool isStaticOrKinematicObject() const
btTransform & getWorldTransform()
const btVector3 & getAnisotropicFriction() const
int getInternalType() const
reserved for Bullet internal usage
int getWorldArrayIndex() const
bool hasAnisotropicFriction(int frictionMode=CF_ANISOTROPIC_FRICTION) const
void setCompanionId(int id)
bool isKinematicObject() const
@ CF_ANISOTROPIC_ROLLING_FRICTION
@ CF_ANISOTROPIC_FRICTION
int getCompanionId() const
static int getCpuFeatures()
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations.
ManifoldContactPoint collects and maintains persistent contactpoints.
btScalar m_combinedSpinningFriction
btScalar m_combinedRollingFriction
btScalar getDistance() const
btScalar m_combinedContactStiffness1
btScalar m_combinedRestitution
btVector3 m_lateralFrictionDir2
btScalar m_combinedContactDamping1
const btVector3 & getPositionWorldOnB() const
btScalar m_appliedImpulseLateral2
const btVector3 & getPositionWorldOnA() const
btScalar m_appliedImpulse
btScalar m_appliedImpulseLateral1
btVector3 m_normalWorldOnB
btScalar m_combinedFriction
btScalar m_contactMotion2
btVector3 m_lateralFrictionDir1
btScalar m_contactMotion1
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
const btManifoldPoint & getContactPoint(int index) const
const btCollisionObject * getBody0() const
const btCollisionObject * getBody1() const
int getNumContacts() const
btScalar getContactProcessingThreshold() const
The btRigidBody is the main class for rigid body objects.
btVector3 getVelocityInLocalPoint(const btVector3 &rel_pos) const
const btVector3 & getTotalTorque() const
btScalar getInvMass() const
const btVector3 & getLinearFactor() const
btVector3 computeGyroscopicImpulseImplicit_World(btScalar dt) const
perform implicit force computation in world space
btVector3 computeGyroscopicImpulseImplicit_Body(btScalar step) const
perform implicit force computation in body space (inertial frame)
const btVector3 & getAngularVelocity() const
const btVector3 & getTotalForce() const
const btVector3 & getAngularFactor() const
btScalar computeImpulseDenominator(const btVector3 &pos, const btVector3 &normal) const
static const btRigidBody * upcast(const btCollisionObject *colObj)
to keep collision detection and dynamics separate we don't store a rigidbody pointer but a rigidbody ...
const btMatrix3x3 & getInvInertiaTensorWorld() const
btVector3 computeGyroscopicForceExplicit(btScalar maxGyroscopicForce) const
explicit version is best avoided, it gains energy
const btVector3 & getLinearVelocity() const
btSingleConstraintRowSolver getScalarConstraintRowSolverLowerLimit()
Various implementations of solving a single constraint row using an inequality (lower limit) constrai...
void initSolverBody(btSolverBody *solverBody, btCollisionObject *collisionObject, btScalar timeStep)
btSingleConstraintRowSolver getSSE2ConstraintRowSolverGeneric()
btConstraintArray m_tmpSolverContactConstraintPool
int m_maxOverrideNumSolverIterations
virtual void convertBodies(btCollisionObject **bodies, int numBodies, const btContactSolverInfo &infoGlobal)
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, const btContactSolverInfo &infoGlobal, btScalar desiredVelocity=0., btScalar cfmSlip=0.)
void writeBackJoints(int iBegin, int iEnd, const btContactSolverInfo &infoGlobal)
btConstraintArray m_tmpSolverContactFrictionConstraintPool
virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject **bodies, int numBodies, const btContactSolverInfo &infoGlobal)
btAlignedObjectArray< int > m_orderFrictionConstraintPool
virtual void convertJoints(btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &infoGlobal)
virtual ~btSequentialImpulseConstraintSolver()
btSolverAnalyticsData m_analyticsData
void convertJoint(btSolverConstraint *currentConstraintRow, btTypedConstraint *constraint, const btTypedConstraint::btConstraintInfo1 &info1, int solverBodyIdA, int solverBodyIdB, const btContactSolverInfo &infoGlobal)
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
btSolverConstraint & addTorsionalFrictionConstraint(const btVector3 &normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint &cp, btScalar torsionalFriction, const btVector3 &rel_pos1, const btVector3 &rel_pos2, btCollisionObject *colObj0, btCollisionObject *colObj1, btScalar relaxation, btScalar desiredVelocity=0, btScalar cfmSlip=0.f)
virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifoldPtr, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &infoGlobal, btIDebugDraw *debugDrawer)
virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifoldPtr, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &infoGlobal, btIDebugDraw *debugDrawer)
unsigned long m_btSeed2
m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction
virtual void reset()
clear internal cached data and reset random seed
virtual void convertContacts(btPersistentManifold **manifoldPtr, int numManifolds, const btContactSolverInfo &infoGlobal)
btScalar resolveSingleConstraintRowLowerLimit(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &contactConstraint)
void setupSolverFunctions(bool useSimd)
static void applyAnisotropicFriction(btCollisionObject *colObj, btVector3 &frictionDirection, int frictionMode)
btSingleConstraintRowSolver getSSE2ConstraintRowSolverLowerLimit()
btScalar resolveSingleConstraintRowGeneric(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &contactConstraint)
void setupTorsionalFrictionConstraint(btSolverConstraint &solverConstraint, const btVector3 &normalAxis, int solverBodyIdA, int solverBodyIdB, btManifoldPoint &cp, btScalar combinedTorsionalFriction, const btVector3 &rel_pos1, const btVector3 &rel_pos2, btCollisionObject *colObj0, btCollisionObject *colObj1, btScalar relaxation, btScalar desiredVelocity=0., btScalar cfmSlip=0.)
btScalar m_leastSquaresResidual
void convertContact(btPersistentManifold *manifold, const btContactSolverInfo &infoGlobal)
btAlignedObjectArray< btSolverBody > m_tmpSolverBodyPool
btSingleConstraintRowSolver m_resolveSingleConstraintRowLowerLimit
btSingleConstraintRowSolver getScalarConstraintRowSolverGeneric()
Various implementations of solving a single constraint row using a generic equality constraint,...
btSingleConstraintRowSolver m_resolveSplitPenetrationImpulse
btAlignedObjectArray< btTypedConstraint::btConstraintInfo1 > m_tmpConstraintSizesPool
btAlignedObjectArray< int > m_orderTmpConstraintPool
btAlignedObjectArray< int > m_orderNonContactConstraintPool
btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverGeneric()
void writeBackBodies(int iBegin, int iEnd, const btContactSolverInfo &infoGlobal)
btAlignedObjectArray< int > m_kinematicBodyUniqueIdToSolverBodyTable
virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifoldPtr, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &infoGlobal, btIDebugDraw *debugDrawer)
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, const btContactSolverInfo &infoGlobal, btScalar desiredVelocity=0., btScalar cfmSlip=0.)
btConstraintArray m_tmpSolverNonContactConstraintPool
btSingleConstraintRowSolver m_resolveSingleConstraintRowGeneric
btSequentialImpulseConstraintSolver()
btConstraintArray m_tmpSolverContactRollingFrictionConstraintPool
void setFrictionConstraintImpulse(btSolverConstraint &solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint &cp, const btContactSolverInfo &infoGlobal)
btScalar resolveSingleConstraintRowLowerLimitSIMD(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &contactConstraint)
int getOrInitSolverBody(btCollisionObject &body, btScalar timeStep)
btScalar restitutionCurve(btScalar rel_vel, btScalar restitution, btScalar velocityThreshold)
btScalar resolveSingleConstraintRowGenericSIMD(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &contactConstraint)
btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverLowerLimit()
void writeBackContacts(int iBegin, int iEnd, const btContactSolverInfo &infoGlobal)
virtual btScalar solveSingleIteration(int iteration, btCollisionObject **bodies, int numBodies, btPersistentManifold **manifoldPtr, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &infoGlobal, btIDebugDraw *debugDrawer)
btScalar resolveSplitPenetrationImpulse(btSolverBody &bodyA, btSolverBody &bodyB, const btSolverConstraint &contactConstraint)
void setupContactConstraint(btSolverConstraint &solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint &cp, const btContactSolverInfo &infoGlobal, btScalar &relaxation, const btVector3 &rel_pos1, const btVector3 &rel_pos2)
TypedConstraint is the baseclass for Bullet constraints and vehicles.
virtual void solveConstraintObsolete(btSolverBody &, btSolverBody &, btScalar)
internal method used by the constraint solver, don't use them directly
void setEnabled(bool enabled)
int getOverrideNumSolverIterations() const
virtual void buildJacobian()
internal method used by the constraint solver, don't use them directly
virtual void getInfo2(btConstraintInfo2 *info)=0
internal method used by the constraint solver, don't use them directly
void internalSetAppliedImpulse(btScalar appliedImpulse)
internal method used by the constraint solver, don't use them directly
const btRigidBody & getRigidBodyA() const
btScalar getBreakingImpulseThreshold() const
const btRigidBody & getRigidBodyB() const
virtual void getInfo1(btConstraintInfo1 *info)=0
internal method used by the constraint solver, don't use them directly
const btJointFeedback * getJointFeedback() const
btVector3 can be used to represent 3D points and vectors.
btScalar length() const
Return the length of the vector.
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
btScalar dot(const btVector3 &v) const
Return the dot product.
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
btScalar length2() const
Return the length of the vector squared.
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
btVector3 m_appliedForceBodyA
btVector3 m_appliedTorqueBodyA
btVector3 m_appliedForceBodyB
btVector3 m_appliedTorqueBodyB
int m_numContactManifolds
double m_remainingLeastSquaresResidual
The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packe...
const btVector3 & getPushVelocity() const
const btVector3 & getTurnVelocity() const
const btVector3 & getDeltaLinearVelocity() const
btVector3 & internalGetDeltaAngularVelocity()
btVector3 m_angularVelocity
btRigidBody * m_originalBody
void internalApplyPushImpulse(const btVector3 &linearComponent, const btVector3 &angularComponent, btScalar impulseMagnitude)
btVector3 & internalGetTurnVelocity()
btVector3 m_linearVelocity
void getVelocityInLocalPointNoDelta(const btVector3 &rel_pos, btVector3 &velocity) const
const btVector3 & getDeltaAngularVelocity() const
btTransform m_worldTransform
btVector3 & internalGetPushVelocity()
btVector3 & internalGetDeltaLinearVelocity()
some internal methods, don't use them
void internalSetInvMass(const btVector3 &invMass)
btVector3 m_angularFactor
void internalApplyImpulse(const btVector3 &linearComponent, const btVector3 &angularComponent, const btScalar impulseMagnitude)
btVector3 m_externalTorqueImpulse
const btVector3 & internalGetInvMass() const
btVector3 m_externalForceImpulse
1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and fr...
void * m_originalContactPoint
btVector3 m_contactNormal2
btVector3 m_relpos1CrossNormal
btVector3 m_angularComponentB
btSimdScalar m_appliedImpulse
int m_overrideNumSolverIterations
btScalar m_rhsPenetration
btVector3 m_angularComponentA
btSimdScalar m_appliedPushImpulse
btVector3 m_relpos2CrossNormal
btVector3 m_contactNormal1
btScalar * m_J2angularAxis
btScalar * m_J1linearAxis
btScalar * m_J2linearAxis
btScalar * m_J1angularAxis
btScalar * m_constraintError