vertex program for quaternion/vector bone interpolation

Started by
-1 comments, last by a38750 19 years, 4 months ago
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;


This topic is closed to new replies.

Advertisement