• entries
743
1924
• views
582804

# Posing

98 views

Not much progress, but just to show that I am doing something, I've got the basic construction of the array of bone matrices working based on rotating each bone via the keyboard.

I'm starting to see now how necessary multiple, weighted bone indices are going to be to get this looking any good, but it is still a step in the right direction.

[LATER]

I've figured out how to do vertex weighting in Milkshape, and my exporter now outputs four bone indices and bone weights per vertex.

I'm loading just two of these per vertex in my viewer and if a vertex has two bone indices, I compute the local space position for the vertex based on both bones, then do a linear interpolation between the two results based on the weight of the first bone to get the final position.

It appears to be working okay and is apparently producing the same deformations as when I animate in Milkshape.

From reading around, though, I appear to be doing everything a bit differently to how this is normally done (therefore I'm doing it wrong in some way).

I'm starting with all the verts defined in local model space. For each bone, I have a matrix. I start by setting each bone's matrix to the identity matrix.

I then traverse the bone tree. For each bone, I compute a matrix. This is basically a translation matrix to move into space local to the location of the bone (taking into account the parent's matrix affect on the current bone position), times a rotation matrix, times an inverse translation matrix to move back to model space.

Every child of the node is then visited and its matrix multiplied by this matrix.

The traversal then continues on, finishing when every child bone has had an opportunity to build its matrix and multiply all its children bone matrices by it.

From here, as vertices are copied into the posed vertex buffer, if the vertex has one bone, it is just D3DXVec3TransformCoord-ed by the matrix of the bone. If it has two bones, I do two transforms then lerp as described above.

Doesn't all feel quite right though. I need to research how this is more normally done. I can't imagine doing the above in a shader. But at least it's working.

[LATER]

Well, I can simplify the code by setting all vertices that only use one or zero bones so that their unused bone indices are anything valid (i.e. zero) and their unused index weights are zero.

This reduces the transformation down to this:

for(std::vector::iterator I=MeshVertices.begin();I!=MeshVertices.end();++I)    {    Vertex3D V=I->Vertex;    D3DXVECTOR3 Pos(0,0,0);    D3DXVECTOR3 Norm(0,0,0);    D3DXVECTOR3 T;    Pos+=*(D3DXVec3TransformCoord(&T,&(V.Pos),&(Bones[I->Bone[0]].Final)))*I->Weight[0];    Pos+=*(D3DXVec3TransformCoord(&T,&(V.Pos),&(Bones[I->Bone[1]].Final)))*I->Weight[1];    Norm+=*(D3DXVec3TransformNormal(&T,&(V.Norm),&(Bones[I->Bone[0]].Final)))*I->Weight[0];    Norm+=*(D3DXVec3TransformNormal(&T,&(V.Norm),&(Bones[I->Bone[1]].Final)))*I->Weight[1];    V.Pos=Pos;    V.Norm=Norm;		    *VertexData++=V;    }

This is running as the vertices are copied from the bind pose model into the vertex buffer (posed) for rendering.

I can imagine implementing that in a shader, although it is less efficient than having three cases (two bones, one bone or no bone).

However, if I ever started using 3 or 4 bones per vertex, the number of cases would be so immense that an approach like above would probably be best.

Shades of John Travolta here. [smile] Good work on the modelling! It's not something I've ever managed to get to grips with.

Quote:
 Original post by benryves Shades of John Travolta here. [smile]

Well, if I had a model of him from Grease, I could just apply a scale to the stomach to bring it up to date.

Quote:
 Original post by benryves Good work on the modelling! It's not something I've ever managed to get to grips with.

Thanks. Wouldn't say I'm exactly to grips with it yet, but this is interesting stuff to play around with.

## Create an account

Register a new account