24#define HINGE_USE_OBSOLETE_SOLVER false
26#define HINGE_USE_FRAME_OFFSET true
31 const btVector3& axisInA,
const btVector3& axisInB,
bool useReferenceFrameA)
53 btScalar projection = axisInA.dot(rbAxisA1);
66 rbAxisA2 = axisInA.cross(rbAxisA1);
67 rbAxisA1 = rbAxisA2.cross(axisInA);
70 m_rbAFrame.getBasis().setValue(rbAxisA1.getX(), rbAxisA2.getX(), axisInA.getX(),
71 rbAxisA1.getY(), rbAxisA2.getY(), axisInA.getY(),
72 rbAxisA1.getZ(), rbAxisA2.getZ(), axisInA.getZ());
75 btVector3 rbAxisB1 =
quatRotate(rotationArc, rbAxisA1);
76 btVector3 rbAxisB2 = axisInB.cross(rbAxisB1);
79 m_rbBFrame.getBasis().setValue(rbAxisB1.getX(), rbAxisB2.getX(), axisInB.getX(),
80 rbAxisB1.getY(), rbAxisB2.getY(), axisInB.getY(),
81 rbAxisB1.getZ(), rbAxisB2.getZ(), axisInB.getZ());
83#ifndef _BT_USE_CENTER_LIMIT_
95btHingeConstraint::btHingeConstraint(
btRigidBody& rbA,
const btVector3& pivotInA,
const btVector3& axisInA,
bool useReferenceFrameA)
113 btVector3 rbAxisA1, rbAxisA2;
117 m_rbAFrame.getBasis().setValue(rbAxisA1.getX(), rbAxisA2.getX(), axisInA.getX(),
118 rbAxisA1.getY(), rbAxisA2.getY(), axisInA.getY(),
119 rbAxisA1.getZ(), rbAxisA2.getZ(), axisInA.getZ());
124 btVector3 rbAxisB1 =
quatRotate(rotationArc, rbAxisA1);
125 btVector3 rbAxisB2 = axisInB.cross(rbAxisB1);
128 m_rbBFrame.getBasis().setValue(rbAxisB1.getX(), rbAxisB2.getX(), axisInB.getX(),
129 rbAxisB1.getY(), rbAxisB2.getY(), axisInB.getY(),
130 rbAxisB1.getZ(), rbAxisB2.getZ(), axisInB.getZ());
132#ifndef _BT_USE_CENTER_LIMIT_
139 m_solveLimit =
false;
161#ifndef _BT_USE_CENTER_LIMIT_
168 m_solveLimit =
false;
192#ifndef _BT_USE_CENTER_LIMIT_
199 m_solveLimit =
false;
204void btHingeConstraint::buildJacobian()
215 btVector3 relPos = pivotBInW - pivotAInW;
220 normal[0] = relPos.normalized();
224 normal[0].setValue(
btScalar(1.0), 0, 0);
229 for (
int i = 0; i < 3; i++)
248 btVector3 jointAxis0local;
249 btVector3 jointAxis1local;
315btScalar btHingeAccumulatedAngleConstraint::getAccumulatedHingeAngle()
319 return m_accumulatedAngle;
321void btHingeAccumulatedAngleConstraint::setAccumulatedHingeAngle(
btScalar accAngle)
323 m_accumulatedAngle = accAngle;
332 btHingeConstraint::getInfo1(
info);
339 info->m_numConstraintRows = 0;
344 info->m_numConstraintRows = 5;
351 info->m_numConstraintRows++;
361 info->m_numConstraintRows = 0;
367 info->m_numConstraintRows = 6;
395 int i, skip =
info->rowskip;
400 btVector3 pivotAInW = trA.getOrigin();
401 btVector3 pivotBInW = trB.getOrigin();
407 info->m_J1linearAxis[i*skip]=0;
408 info->m_J1linearAxis[i*skip+1]=0;
409 info->m_J1linearAxis[i*skip+2]=0;
411 info->m_J1angularAxis[i*skip]=0;
412 info->m_J1angularAxis[i*skip+1]=0;
413 info->m_J1angularAxis[i*skip+2]=0;
415 info->m_J2linearAxis[i*skip]=0;
416 info->m_J2linearAxis[i*skip+1]=0;
417 info->m_J2linearAxis[i*skip+2]=0;
419 info->m_J2angularAxis[i*skip]=0;
420 info->m_J2angularAxis[i*skip+1]=0;
421 info->m_J2angularAxis[i*skip+2]=0;
423 info->m_constraintError[i*skip]=0.f;
431 info->m_J1linearAxis[0] = 1;
432 info->m_J1linearAxis[skip + 1] = 1;
433 info->m_J1linearAxis[2 * skip + 2] = 1;
435 info->m_J2linearAxis[0] = -1;
436 info->m_J2linearAxis[skip + 1] = -1;
437 info->m_J2linearAxis[2 * skip + 2] = -1;
440 btVector3 a1 = pivotAInW - transA.getOrigin();
442 btVector3* angular0 = (btVector3*)(
info->m_J1angularAxis);
443 btVector3* angular1 = (btVector3*)(
info->m_J1angularAxis + skip);
444 btVector3* angular2 = (btVector3*)(
info->m_J1angularAxis + 2 * skip);
445 btVector3 a1neg = -a1;
446 a1neg.getSkewSymmetricMatrix(angular0, angular1, angular2);
448 btVector3 a2 = pivotBInW - transB.getOrigin();
450 btVector3* angular0 = (btVector3*)(
info->m_J2angularAxis);
451 btVector3* angular1 = (btVector3*)(
info->m_J2angularAxis + skip);
452 btVector3* angular2 = (btVector3*)(
info->m_J2angularAxis + 2 * skip);
453 a2.getSkewSymmetricMatrix(angular0, angular1, angular2);
461 for (i = 0; i < 3; i++)
463 info->m_constraintError[i * skip] = k * (pivotBInW[i] - pivotAInW[i]);
475 btVector3 ax1 = trA.getBasis().getColumn(2);
477 btVector3 p = trA.getBasis().getColumn(0);
478 btVector3 q = trA.getBasis().getColumn(1);
480 int s3 = 3 *
info->rowskip;
481 int s4 = 4 *
info->rowskip;
483 info->m_J1angularAxis[s3 + 0] = p[0];
484 info->m_J1angularAxis[s3 + 1] = p[1];
485 info->m_J1angularAxis[s3 + 2] = p[2];
486 info->m_J1angularAxis[s4 + 0] = q[0];
487 info->m_J1angularAxis[s4 + 1] = q[1];
488 info->m_J1angularAxis[s4 + 2] = q[2];
490 info->m_J2angularAxis[s3 + 0] = -p[0];
491 info->m_J2angularAxis[s3 + 1] = -p[1];
492 info->m_J2angularAxis[s3 + 2] = -p[2];
493 info->m_J2angularAxis[s4 + 0] = -q[0];
494 info->m_J2angularAxis[s4 + 1] = -q[1];
495 info->m_J2angularAxis[s4 + 2] = -q[2];
511 btVector3 ax2 = trB.getBasis().getColumn(2);
512 btVector3 u = ax1.cross(ax2);
513 info->m_constraintError[s3] = k * u.dot(p);
514 info->m_constraintError[s4] = k * u.dot(q);
522#ifdef _BT_USE_CENTER_LIMIT_
527 limit = (limit_err >
btScalar(0.0)) ? 1 : 2;
531 if (limit || powered)
534 srow = nrow *
info->rowskip;
535 info->m_J1angularAxis[srow + 0] = ax1[0];
536 info->m_J1angularAxis[srow + 1] = ax1[1];
537 info->m_J1angularAxis[srow + 2] = ax1[2];
539 info->m_J2angularAxis[srow + 0] = -ax1[0];
540 info->m_J2angularAxis[srow + 1] = -ax1[1];
541 info->m_J2angularAxis[srow + 2] = -ax1[2];
545 if (limit && (lostop == histop))
564 k =
info->fps * currERP;
565 info->m_constraintError[srow] += k * limit_err;
570 if (lostop == histop)
578 info->m_lowerLimit[srow] = 0;
584 info->m_upperLimit[srow] = 0;
587#ifdef _BT_USE_CENTER_LIMIT_
595 vel -= angVelB.dot(ax1);
603 if (newc >
info->m_constraintError[srow])
605 info->m_constraintError[srow] = newc;
614 if (newc < info->m_constraintError[srow])
616 info->m_constraintError[srow] = newc;
621#ifdef _BT_USE_CENTER_LIMIT_
637void btHingeConstraint::updateRHS(
btScalar timeStep)
649 const btVector3 refAxis0 = transA.getBasis() *
m_rbAFrame.getBasis().getColumn(0);
650 const btVector3 refAxis1 = transA.getBasis() *
m_rbAFrame.getBasis().getColumn(1);
651 const btVector3 swingAxis = transB.getBasis() *
m_rbBFrame.getBasis().getColumn(1);
661#ifdef _BT_USE_CENTER_LIMIT_
666 m_solveLimit =
false;
697 vNoHinge.normalize();
709 if (qHinge.getZ() < 0)
710 targetAngle = -targetAngle;
717#ifdef _BT_USE_CENTER_LIMIT_
730 btScalar dAngle = targetAngle - curAngle;
737 int i, s =
info->rowskip;
746 btVector3 ofs = trB.getOrigin() - trA.getOrigin();
764 btVector3 ax1A = trA.getBasis().getColumn(2);
765 btVector3 ax1B = trB.getBasis().getColumn(2);
766 btVector3 ax1 = ax1A * factA + ax1B * factB;
771 ax1 = ax1A * factA + ax1B * factB;
782 btVector3 tmpA, tmpB, relA, relB, p, q;
784 relB = trB.getOrigin() - bodyB_trans.getOrigin();
786 btVector3 projB = ax1 * relB.dot(ax1);
788 btVector3 orthoB = relB - projB;
790 relA = trA.getOrigin() - bodyA_trans.getOrigin();
791 btVector3 projA = ax1 * relA.dot(ax1);
792 btVector3 orthoA = relA - projA;
793 btVector3 totalDist = projA - projB;
795 relA = orthoA + totalDist * factA;
796 relB = orthoB - totalDist * factB;
798 p = orthoB * factA + orthoA * factB;
806 p = trA.getBasis().getColumn(1);
811 tmpA = relA.cross(p);
812 tmpB = relB.cross(p);
813 for (i = 0; i < 3; i++)
info->m_J1angularAxis[s0 + i] = tmpA[i];
814 for (i = 0; i < 3; i++)
info->m_J2angularAxis[s0 + i] = -tmpB[i];
815 tmpA = relA.cross(q);
816 tmpB = relB.cross(q);
823 for (i = 0; i < 3; i++)
info->m_J1angularAxis[s1 + i] = tmpA[i];
824 for (i = 0; i < 3; i++)
info->m_J2angularAxis[s1 + i] = -tmpB[i];
825 tmpA = relA.cross(ax1);
826 tmpB = relB.cross(ax1);
833 for (i = 0; i < 3; i++)
info->m_J1angularAxis[s2 + i] = tmpA[i];
834 for (i = 0; i < 3; i++)
info->m_J2angularAxis[s2 + i] = -tmpB[i];
841 for (i = 0; i < 3; i++)
info->m_J1linearAxis[s0 + i] = p[i];
842 for (i = 0; i < 3; i++)
info->m_J1linearAxis[s1 + i] = q[i];
843 for (i = 0; i < 3; i++)
info->m_J1linearAxis[s2 + i] = ax1[i];
845 for (i = 0; i < 3; i++)
info->m_J2linearAxis[s0 + i] = -p[i];
846 for (i = 0; i < 3; i++)
info->m_J2linearAxis[s1 + i] = -q[i];
847 for (i = 0; i < 3; i++)
info->m_J2linearAxis[s2 + i] = -ax1[i];
852 info->m_constraintError[s0] =
rhs;
853 rhs = k * q.dot(ofs);
854 info->m_constraintError[s1] =
rhs;
855 rhs = k * ax1.dot(ofs);
856 info->m_constraintError[s2] =
rhs;
867 info->m_J1angularAxis[s3 + 0] = p[0];
868 info->m_J1angularAxis[s3 + 1] = p[1];
869 info->m_J1angularAxis[s3 + 2] = p[2];
870 info->m_J1angularAxis[s4 + 0] = q[0];
871 info->m_J1angularAxis[s4 + 1] = q[1];
872 info->m_J1angularAxis[s4 + 2] = q[2];
874 info->m_J2angularAxis[s3 + 0] = -p[0];
875 info->m_J2angularAxis[s3 + 1] = -p[1];
876 info->m_J2angularAxis[s3 + 2] = -p[2];
877 info->m_J2angularAxis[s4 + 0] = -q[0];
878 info->m_J2angularAxis[s4 + 1] = -q[1];
879 info->m_J2angularAxis[s4 + 2] = -q[2];
895 k =
info->fps * normalErp;
897 btVector3 u = ax1A.cross(ax1B);
898 info->m_constraintError[s3] = k * u.dot(p);
899 info->m_constraintError[s4] = k * u.dot(q);
908#ifdef _BT_USE_CENTER_LIMIT_
913 limit = (limit_err >
btScalar(0.0)) ? 1 : 2;
917 if (limit || powered)
920 srow = nrow *
info->rowskip;
921 info->m_J1angularAxis[srow + 0] = ax1[0];
922 info->m_J1angularAxis[srow + 1] = ax1[1];
923 info->m_J1angularAxis[srow + 2] = ax1[2];
925 info->m_J2angularAxis[srow + 0] = -ax1[0];
926 info->m_J2angularAxis[srow + 1] = -ax1[1];
927 info->m_J2angularAxis[srow + 2] = -ax1[2];
931 if (limit && (lostop == histop))
950 k =
info->fps * currERP;
951 info->m_constraintError[srow] += k * limit_err;
956 if (lostop == histop)
964 info->m_lowerLimit[srow] = 0;
970 info->m_upperLimit[srow] = 0;
973#ifdef _BT_USE_CENTER_LIMIT_
981 vel -= angVelB.dot(ax1);
989 if (newc >
info->m_constraintError[srow])
991 info->m_constraintError[srow] = newc;
1000 if (newc < info->m_constraintError[srow])
1002 info->m_constraintError[srow] = newc;
1007#ifdef _BT_USE_CENTER_LIMIT_
1020 if ((axis == -1) || (axis == 5))
1051btScalar btHingeConstraint::getParam(
int num,
int axis)
const
1054 if ((axis == -1) || (axis == 5))
ATTR_WARN_UNUSED_RESULT const size_t num
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
virtual void buildJacobian()
internal method used by the constraint solver, don't use them directly
bool m_useSolveConstraintObsolete
btScalar m_maxMotorImpulse
const btRigidBody & getRigidBodyA() const
btVector3 m_accMotorImpulse
const btRigidBody & getRigidBodyB() const
btScalar m_relaxationFactor
void setMotorTarget(const btQuaternion &q)
btFixedConstraint btRigidBody & rbB
btJacobianEntry m_jacAng[3]
bool m_useOffsetForConstraintFrame
static btVector3 vHinge(0, 0, btScalar(1))
#define HINGE_USE_OBSOLETE_SOLVER
static btScalar btShortestAngularDistance(btScalar accAngle, btScalar curAngle)
static btScalar btNormalizeAnglePositive(btScalar angle)
static btScalar btShortestAngleUpdate(btScalar accAngle, btScalar curAngle)
#define HINGE_USE_FRAME_OFFSET
btScalar getHingeAngle()
The getHingeAngle gives the hinge angle in range [-PI,PI].
bool m_useReferenceFrameA
btScalar getLowerLimit() const
bool m_enableAngularMotor
btScalar getUpperLimit() const
bool getEnableAngularMotor()
@ BT_HINGE_FLAGS_CFM_STOP
@ BT_HINGE_FLAGS_CFM_NORM
@ BT_HINGE_FLAGS_ERP_NORM
@ BT_HINGE_FLAGS_ERP_STOP
btScalar m_accLimitImpulse
btScalar m_motorTargetVelocity
void getInfo2Internal(btConstraintInfo2 *info, const btTransform &transA, const btTransform &transB, const btVector3 &angVelA, const btVector3 &angVelB)
void getInfo2InternalUsingFrameOffset(btConstraintInfo2 *info, const btTransform &transA, const btTransform &transB, const btVector3 &angVelA, const btVector3 &angVelB)
void testLimit(const btTransform &transA, const btTransform &transB)
#define _BT_USE_CENTER_LIMIT_
SIMD_FORCE_INLINE btQuaternion shortestArcQuat(const btVector3 &v0, const btVector3 &v1)
SIMD_FORCE_INLINE btVector3 quatRotate(const btQuaternion &rotation, const btVector3 &v)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians)
SIMD_FORCE_INLINE btScalar btFabs(btScalar x)
SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y)
SIMD_FORCE_INLINE btScalar btFmod(btScalar x, btScalar y)
btSimdScalar m_appliedImpulse
btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact)
internal method used by the constraint solver, don't use them directly
SIMD_FORCE_INLINE btScalar btAdjustAngleToLimits(btScalar angleInRadians, btScalar angleLowerLimitInRadians, btScalar angleUpperLimitInRadians)
#define btAssertConstrParams(_par)
SIMD_FORCE_INLINE void btPlaneSpace1(const T &n, T &p, T &q)
btScalar getBiasFactor() const
Returns limit's bias factor.
btScalar getCorrection() const
Returns correction value evaluated when test() was invoked.
void test(const btScalar angle)
void fit(btScalar &angle) const
btScalar getRelaxationFactor() const
Returns limit's relaxation factor.
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
btScalar getAngle() const
Return the angle [0, 2Pi] of rotation represented by this quaternion.
btQuaternion inverse() const
Return the inverse of this quaternion.
btQuaternion & normalize()
Normalize the quaternion Such that x^2 + y^2 + z^2 +w^2 = 1.
SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3 &axis) const
btScalar getInvMass() const
const btVector3 & getInvInertiaDiagLocal() const
const btTransform & getCenterOfMassTransform() const
const btVector3 & getAngularVelocity() const
const btVector3 & getCenterOfMassPosition() const