JoeWright wrote:What I'm trying to create is a generalized ball and socket joint where both bodies rotate around the 3 axes of the pivot. They don't have to be axis aligned in any way. Each rotation should have a min and max angle. Here is the code that limits the max angle around the pivot's m_front axis:
The geometrical interpretation of a joint like that is much harder than you think.
I will tell you tah bad new first then I will tell you the good new.
The reason is that a geometrical representation you need a frame of reference to make measurement.
For example a hinge is easy because you can fix a pin either on body1 and the angle the relative angle is the body2 rotates around that pin is and independent variable.
For a double hinge of universal you can fix a pin because you can fix a pin on body 1 and a pin on body2 the it is like two hinges, when the angle body1 rotates around the pin fix on body 0 is independent of the angle that body0 rotates around a pin fix on body1, as long as pteh tow refence ping are perpendicular.
For a general ball and socket you have three pins but only two bodies. So you it is difficult to fix any pint on anything.
You will have to pick one frame as the reference frame and then measure the relative angle other body rotate around that frame.
That brink the problems that to calculate the relative angles of a frame relative to another frame depend on the convention other of rotation and it will always run into the citation that you will loss a degree of freedom.
This is what the axis you select to project over the other axis will be aligned with another axis preventing form extraction the angles.
That is in regard for extraction the relative angle from the matrices, but there is a much bigger fundamental problem.
This comes for the fact that independent angular rotation around fix axis do not commute. This is very, very important.
Say you manage to successfully decompose you matrix into three angles and you summit you row so that the toques around that angle are calculated.
Here is the very big problem, the engine will calculate three torques and add then together alone with any other torque that was applied to the body to produce a final net torque. That is what the law of physic say. The problems I that the three angle you calculate will only produce the desired rotation when they are applied to the frame of reference in the order in which you calculated them.
So the only way the that method will work was if the engine applied a torque around the first axis and rotate the body, then a torque around the second body and rotate it, the a torque around the third axis and rotate it, but that is very different that adding the three torque and applying just one final torque to the body to rotate the relative frame.
I hope this was clear to you.
The reason is that when you apply a torque to a body the body to no rotates following any order of Eulers angles the body rotate following the shorter angular path. Fortunately the Rodriguez parameter allows determining the shortest angular path very easy. But the visualization of the joint is different and you will.
Here is what you do to get a control ball and socket.
You need to read the matrices in quaternion form (you can use the newton to get the matrix in quaternion from)
NewtonBodyGetRotation(body, rotation);
You need to establish a relationship between the two matrices of each frame that you want to be enforced. Say you picj body1 as you reference frame, then
Q1 = RelQ * Q0
Q0 = quaternion rotation of body0
Q1 = quaternion rotation of body1
RelQ = relative quaternion rotation that body0 have to rotate to align to body1
Now that you have your relative rotation, you can use the definition of the quaternion to determine how to apply the constraints rows to the joint.
The definition of a quaternion is given by four values
Q (q0, q1, q2, q3)
Where
q0 = cos (angle/2)
(q1, q2, q3) = sin (angle/2) * v(x, y, z)
That is a rotation by angle around the unit vector (x, y, z)
To help with this operation you can use the dMath and quaternion Class in the SDK
You can make a power joint, and angular limited joint or a combination of the two limited and powered.
Let us make the easiest, the powered jopint.
That means you want that to enforce and arbitrary relative rotation RelQ, meaning RelQ is a parameter
Let us call it ReaQp
With that definition and RelQ and you ne to do is figure out the unit vector and the angle
// calculate RelQ
Q0 = NetwonBodyGetRotation(body0);
Q1 = NetwonBodyGetRotation(body1);
// from relation Q1 = RelQ * RelQp * Q0 we get
RealQ = Q1 * (RelQp * Q0).Inverse();
// get the plane of rotation
dVector planeOfRotation (RealQ.q1, RealQ.q2, RealQ.q3)
If (fabs (ReqQ.q0 – 1.0f) < small value) {
planeOfRotation (1, 0, 0);
}
planeOfRotation = planeOfRotation.Normalize();
angle = 2.0f * Acos (RealQ.q0)
// create a coordinate system using planeOfRotation as the fron pin
Matrix rotationFrame (dgGrammSchmidt (planeOfRotation));
// now we need to the tow point to keep to drive to angle to zero
// this is like craeteion a hinge tah spin the body around the plane of rotation
Matrix0 = RelQ * RelQp * bodyMatrix0;
dVector p1 (bodymatrix1.Tranform (Vector(0, somedist, 0) )
dVector p0 (Matrix0.Tranform (Vector(0, somedist, 0) )
AddLenearRow (p0, p1, rotationFrame.m_right);
// add find the two lateral row to heep stability
dVector q1 (bodymatrix1.Tranform (Vector( somedist, 0, 0) )
dVector q0 (Matrix0.Tranform (Vector(0, somedist, 0) )
AddLenearRow (q0, q1, rotationFrame.m_up);
AddLenearRow (q0, q1, rotationFrame.m_right);
see if you undertand teh consept, if you do you soudl be able to make the joing even if my pseudo code is no right,
if you do no teh I can make the joint on teh SDK a post it.