to find the position of a vertex, you will first find the vertex's weights position in bone space, then add the bones position to the weight making the weight now in "model" space, then you will average all the vertex's weights by using the bias factor to get the vertex's final position
To use the bone orientation quaternions to find the weights position, you first find the quaternions conjugate, which is:
orientationConjugate = (-orientation.x, -orientation.y, -orientation.z, orientation.w); // Negate the xyz axis' of the original orientation quaternion, and leave the w component alone
then you do a quaternion/quaternion multiplication with the orientation quaternion and the weights position:
finalWeightPos = orientation * weightPos;
you then multiply the finalWeightPos with the orientations conjugate:
finalWeightPos = finalWeightPos * orientationConjugate
You must do the multiplication in that order because quaternions are "noncomunitive" meaning the order in which you multiply them together DOES matter.
Finally, to get the vertex's final position, you will add the bones position to the weight, then multiply each weights position with it's bias factor (all the weights bias factor for each vertex adds up to 1), then add the resulting positions together to get the final vertex position:
finalWeightPos = finalWeightPos * weightBias; finalWeightPos += bonePos; finalVertexPos += finalWeightPos;
Some links that might be helpfull:
http://www.braynzars...php?p=D3D11MD51
http://www.braynzars...php?p=D3D11MD52
http://www.cprogramm...uaternions.html
http://content.gpwik...ic_Bones_System
so all together maybe something like this:
float3 finalVertexPos = float3(0,0,0);
for(int i = 0; i < numWeights; ++i)
{
Weight currWeight = modelWeights[currVertex.WeightStart + i];
float4 orientation = bones[currWeight.BoneID].Orientation;
float4 orientationConjugate = float4(-orientation.x, -orientation.y, -orientation.z, -orientation.w);
float4 finalWeightPos = (orientation * currWeight.Pos) * orientationConjugate;
finalWeightPos *= currWeight.Bias;
finalWeightPos += bones[currWeight.BoneID].Pos;
finalVertexPos += float3(finalWeightPos.x, finalWeightPos.y, finalWeightPos.z);
}The "Weight" structure will need to have the weights bias factor, position, and bone id
Also, multiplying two quaternions together is not as simple as just "quat1 * quat2". opengl probably has a function to multiply them together, i know directx does (XMQuaternionMultiply).
Otherwise, to multiply two quaternions together: (copied from one of the links i mentioned above)
(Q1 * Q2).w = (w1w2 - x1x2 - y1y2 - z1z2)
(Q1 * Q2).x = (w1x2 + x1w2 + y1z2 - z1y2)
(Q1 * Q2).y = (w1y2 - x1z2 + y1w2 + z1x2)
(Q1 * Q2).z = (w1z2 + x1y2 - y1x2 + z1w2)
The "w" component of the weights position is just zero (w = 0)