QUOTE
With "free from bind pose information" i mean that the transform gotten from a bone should not include the "resting" position of the bone. For example an animation featuring only rotations should have 0, 0, 0 as translation keys even though the bones themselves are actually translated into position (not during animation).
Am I making any sense?
yes, i now get what you are doing, i'm not sure why you are doing it that way? Basically you are creating your own pre-rotation (a.k.a. joint orient) for your animations. The translation thing seems a bit wierd to me, surely it just means you are doing (original + offset)==translation each frame? (whereas storing keys as just translation would save that additional step?) The only reason i could see for wanting to do something like this is for some form of compression?
QUOTE
A vertex has a "resting" or "binding" position. Then it is animated (translated and/or rotated) by one or several bones. This animation is actually an offset from this resting or binding position.
well, a skeleton (sort of) has a resting position but not a vertex. Storing animation as offsets is pretty pointless imo, you may as well just store them as they are. Any animatable rotation or translation will always need at least one keyframe with every exported animation. (i can create a cube, move it four times and save it as four files. None of those have animation, however none of the translation values match the original and so it should still be taken into account regardless of whether it animates or not). Anyhow, since you will always want at least one key, it doesn't make sense to store the original positions at all - it's just an extra calculation you don't need to perform.
All you need for skinning is mesh data relative to a pose in which your skeleton is in. Ideally this should be the bind pose authored by the artist, however any pose close enough will actually do (assuming no other deformers affect the geometry). Basically, just get the mesh verts and normals in world space, then get the inverse world space matrices for the joints (inclusiveMatrixInverse). Then just calculate a world space transform for each joint, then skin :
CODE
Vertex CalcSkinnedVertex( Matrix& InvWorldBindPose, Matrix& CurrentWorldPoseOfJoint, Vertex& WorldSpaceVertex )
{
// ideally, as an optimisation, you'd pre-calc a temp array of
// (matCurrentWorld * CurrentWorldPoseOfJoint) which would speed
// things up a little bit.
//
return CurrentWorldPoseOfJoint * InvWorldBindPose * WorldSpaceVertex;
}
That works fine for rigid skinning (extracted via joint clusters), however for soft skinning you basically do something along the lines of :
CODE
struct Joint
{
Matrix matInvWorldBind;
Matrix matCurrentWorld;
};
struct SkinWeight
{
Joint* joint;
float w;
};
struct SkinnedVertex {
Vertex OriginalWorld;
int NumWeights;
SkinWeight weights[];
};
Vertex CalcSoftSkinnedVertex( SkinnedVertex& vert )
{
Vertex result(0,0,0);
for( int i=0;i!=vert.NumWeights;++i)
{
SkinWeight & weight = vert.weights[i];
Joint* j = weight.joint;
result += weight.w * CalcSkinnedVertex( j->matInvWorldBind, j->matCurrentWorld, vert.OriginalWorld );
}
return result;
}
To get the vertex weights, you'll need to use the MFnSkinCluster (and ignore lots of zero weights). The skin cluster should also give you some info which joints are used. There are a couple of examples in the devkit that describe how to extract joint and skin clusters.
QUOTE(hObbE @ 07/05/06, 02:22 AM) [snapback]241573[/snapback]
On top of this we have an animation system using keyframes that can animate the local coordinate system of a specific node (yaw pitch roll + translation).
ahh, just re-read this. Thats why you want to centralise the joint orient then. I take it the animation is not done by lerping euler angles? (that would be the likely cause of any remaining errors with the animation).