You could use 2 arrays of pre-calculated vertices, I suppose. But, for large meshes, those arrays could be pretty big.
Perhaps the most straightforward way would be to just use the inverse matrix to calculate the final vertex positions.
// Transform all verticesfor each vertex m4x4 bone1Matrix = skeleton.currentFrame.Matrix[ vertex.boneIndex1 ]; m4x4 bone2Matrix = skeleton.currentFrame.Matrix[ vertex.boneIndex2 ]; // Multiply current matrices with the inverse matrix and vert v1 = bone1Matrix * skeleton.BasePose.InverseMatrix[vertex.boneIndex1] * skeleton.Mesh.vertex; v2 = bone2Matrix * skeleton.BasePose.InverseMatrix[vertex.boneIndex2] * skeleton.Mesh.vertex; // result (weights are both 0.5) // Store into result vRes = v1 * weight1 + v2 * weight2; skeleton.skinnedResult.vertex = vRes;
Does that work?
Because several vertices may be influenced by the same bone, you can also calculate an array of
// finalMatrix = array of size(numBones)finalMatrix[boneIndex] = boneMatrix[boneIndex]*inverseMatrix[boneIndex]...Then, in your loop, calculate:v1 = finalMatrix[boneIndex1]*meshVert;v2 = finalMatrix[boneIndex2]*meshVert;
Quote:skinning shaders only have 1 set of vertices either
Not sure what you mean by this. Shaders can be written to use multiple bone indices and matrices. Is that your concern?
A common algorithm to use with a shader is to calculate an array of finalMatrices = boneMatrix * inverseMatrix for each bone, as mentioned above.
...
The vertex position is calculated in the shader, given an array of those finalMatrices:
pos = vector4( 0, 0, 0, 1);v = input_mesh_vertex;numWeights = number_of_weights_for_this_vertex;weight[numWeights] = array_of_weights, usually passed in shader input structure per-vertexboneIndex = array_of_bone_indices, usually passed in shader input per-vertexsumWeights = 0;for( int n=0; n < numWeights-1; n++){ pos += finalMatrix[ boneIndex[n] ] * v * weight[n]; sumWeights += weight[n];}pos += finalMatrix[ boneIndex[numWeights-1]] * v * ( 1 - sumWeights );
This shader code, by the way, may have to have the order of multiplications reversed. I.e., pos += weight[n] * v * finalMatrix[boneIndex[n]], etc.
[Edited by - Buckeye on February 19, 2010 8:39:26 AM]