I've implemented an IK system for a grabber arm based on several straight segments, starting from a fixed point. The IK is based on a mass-spring simulation, which eventually rests. What I'm left with is an array of positions in world space, one for each joint position, and an extra one at the end.
I need to convert these world positions into one quaternion rotation for each joint, so that I can build a hierarchy of transformation matrices (I'm using quaternion for the rotation part). each segment of the arm is an instance of a segment model that I want to translate into world space. The hierarchy works by inheriting previous rotations and translations. The issue I'm facing is describing each progressive joint rotation relative to the previous rotations (rather than relative to the world).
So far my approach is:
Initially the grabber arm point upwards, so the root rotation is described as the orientation difference from the vector (0, 1, 0) - (I'm using GL coordinates).
Keep the direction vector of the previous joint,
prevDir, initially (0, 1, 0).
Keep a quaternion of the accumulated rotations,
rotChain, initially the identity quaternion.
From root to tip, for each joint:
- Take the next joint position and subtract the current position and normalize, to get a direction vector
dir. This is why there's an extra point in the array, for the last joint
- Compute the cross product between
dir, which should give a world rotation axis
side, between the previous and current joint. Also compute the dot product,
- Rotate the
rotChain, to bring it into the current joint's orientation.
- Create a quaternion
roton the axis
acos(dot). This should represent the rotation of the current joint relative to the previous one.
rotChain, to add the effect of the current rotation.
This only works as long as all the segments are on the YZ plane, which I think is a fluke. What am I doing wrong?
I'm only using quaternions as I'm trying to invert rotations easily.
As per this answer, I get the sense I could instead directly derive an orientation matrix from
side. Would this work better?