Hi
I inspect HingeConstraint code, and there is some things a bit weird (also present in “upstream” Bullet), if I remember well my maths (which are years behind me now …)
So I’ ve rewrite the constructor public HingeConstraint(RigidBody rbA, RigidBody rbB, Vector3f pivotInA, Vector3f pivotInB, Vector3f axisInA, Vector3f axisInB) and it seems ok :
Here is the original code :
rbAFrame.origin.set(pivotInA);
// since no frame is given, assume this to be zero angle and just pick rb transform axis
Vector3f rbAxisA1 = stack.vectors.get();
rbA.getCenterOfMassTransform().basis.getColumn(0, rbAxisA1);
float projection = rbAxisA1.dot(axisInA);
if (projection > BulletGlobals.FLT_EPSILON) {
rbAxisA1.scale(projection);
rbAxisA1.sub(axisInA);
} else {
rbA.getCenterOfMassTransform().basis.getColumn(1, rbAxisA1);
}
Vector3f rbAxisA2 = stack.vectors.get();
rbAxisA2.cross(rbAxisA1, axisInA);
rbAFrame.basis.setRow(0, rbAxisA1.x, rbAxisA2.x, axisInA.x);
rbAFrame.basis.setRow(1, rbAxisA1.y, rbAxisA2.y, axisInA.y);
rbAFrame.basis.setRow(2, rbAxisA1.z, rbAxisA2.z, axisInA.z);
Quat4f rotationArc = stack.quats.get(QuaternionUtil.shortestArcQuat(axisInA, axisInB));
Vector3f rbAxisB1 = stack.vectors.get(QuaternionUtil.quatRotate(rotationArc, rbAxisA1));
Vector3f rbAxisB2 = stack.vectors.get();
rbAxisB2.cross(rbAxisB1, axisInB);
rbBFrame.origin.set(pivotInB);
rbBFrame.basis.setRow(0, rbAxisB1.x, rbAxisB2.x, -axisInB.x);
rbBFrame.basis.setRow(1, rbAxisB1.y, rbAxisB2.y, -axisInB.y);
rbBFrame.basis.setRow(2, rbAxisB1.z, rbAxisB2.z, -axisInB.z);
And my code :
rbAFrame.origin.set(pivotInA);
Vector3f rbAxisA1 = stack.vectors.get();
Vector3f rbAxisA2 = stack.vectors.get();
Vector3f tmpVect = stack.vectors.get(axisInA);
rbA.getCenterOfMassTransform().basis.getColumn(0, rbAxisA1);
float projection = axisInA.dot(rbAxisA1);
if (Math.abs(projection) >= 1.0f - BulletGlobals.SIMD_EPSILON) {
rbA.getCenterOfMassTransform().basis.getColumn(1, rbAxisA2);
tmpVect.scale(axisInA.dot(rbAxisA2));
rbAxisA2.sub(tmpVect);
rbAxisA1.cross(rbAxisA2, axisInA);
} else {
tmpVect.scale(projection);
rbAxisA1.sub(tmpVect);
rbAxisA2.cross(axisInA, rbAxisA1);
}
rbAFrame.basis.setRow(0, rbAxisA1.x, rbAxisA2.x, axisInA.x);
rbAFrame.basis.setRow(1, rbAxisA1.y, rbAxisA2.y, axisInA.y);
rbAFrame.basis.setRow(2, rbAxisA1.z, rbAxisA2.z, axisInA.z);
Quat4f rotationArc = stack.quats.get(QuaternionUtil.shortestArcQuat(axisInA, axisInB));
Vector3f rbAxisB1 = stack.vectors.get(QuaternionUtil.quatRotate(rotationArc, rbAxisA1));
Vector3f rbAxisB2 = stack.vectors.get();
rbAxisB2.cross(axisInB, rbAxisB1);
rbBFrame.origin.set(pivotInB);
rbBFrame.basis.setRow(0, rbAxisB1.x, rbAxisB2.x, -axisInB.x);
rbBFrame.basis.setRow(1, rbAxisB1.y, rbAxisB2.y, -axisInB.y);
rbBFrame.basis.setRow(2, rbAxisB1.z, rbAxisB2.z, -axisInB.z);
Maybe I should also post on Bullet forum ?