I'm confusing myself over this, can anyone help me?
I've got bones which have an orientation and position, stored as quaternions and vectors. Something like this:
struct bone_t {
quat ref_pose_orientation;
vector3 ref_pose_position;
};
struct bone_instance_t {
bone_t *bone;
quat orientation;
vector3 position; //not actually animating this at the moment
};
I calculate the absolute versions of these each frame (ie. relative to the root bone instance). These are passed to the vertex program as bone_quat and bone_pos below. They're interpolated to make quat and trans, and then I rotate the vertex position by quat and translate by trans.
I don't really know if this is right though. I've only been able to test the rotation on its own so far and that works alright. What I don't get is how the translation works. What exactly should I be pre-translating the vertex positions with? An interpolation of the reference pose orientations/positions for each influential bone?
All the documentation I can find makes each bone into a matrix and then "interpolates" the matrices in the v.p., and because I have no idea what's actually happening when this is done, I can't do the interpolation manually with quats and vectors. I'd rather not use matrices because they need more space in program.local.
Also is the XPD command a 1 step operation?
Thanks,
Frank
!!ARBvp1.0
ATTRIB weights = vertex.attrib[6];
ATTRIB bone_indices = vertex.attrib[7];
PARAM bone_quat[40] = { program.local[0..39] };
PARAM bone_pos[40] = { program.local[40..79] };
PARAM bones_offset = program.local[80];
TEMP pos, trans, quat, t1, t2;
ADDRESS a0;
# four bone lerp of quats and linear interpolation of trans:
# quat = lerp(bone_quat[t1.x], weights.x, bone_quat[t1.y], weights.y, etc.)
# trans = bone_pos[t1.x]*weights.x + bone_pos[t1.y]*weights.y + etc.
SUB t1, bone_indices.x, bones_offset.xxxx;
ARL a0.x, t1.x;
MUL quat, bone_quat[a0.x], weights.x;
MUL trans, bone_pos[a0.x], weights.x;
ARL a0.x, t1.y;
MAD quat, bone_quat[a0.x], weights.y, quat;
MAD trans, bone_pos[a0.x], weights.y, trans;
ARL a0.x, t1.z;
MAD quat, bone_quat[a0.x], weights.z, quat;
MAD trans, bone_pos[a0.x], weights.z, trans;
ARL a0.x, t1.w;
MAD quat, bone_quat[a0.x], weights.w, quat;
MAD trans, bone_pos[a0.x], weights.w, trans;
# renormalize
DP4 t2.w, quat, quat;
RSQ t2.w, t2.w;
MUL quat, quat, t2.w;
# transform position with interpolated bone (pos=quat*pos*quat_conjugate; pos+=trans;)
MOV pos.xyz, vertex.position;
XPD t1, quat, pos;
MAD t1.xyz, quat.w, pos, t1;
DP3 t1.w, quat, -pos;
XPD pos, t1, -quat;
MAD pos.xyz, t1.w, -quat, pos;
MAD pos.xyz, quat.w, t1, pos;
MOV pos.w, vertex.position.w;
ADD pos.xyz, pos, trans;