// ref. vertex_transformations.h, construct_deformed_cube_instance_matrix() public Matrix ConstructDeformedCubeInstanceMatrix(ref Vector4UByte boneIndices, ref Vector4 boneWeights, out Matrix localMatrix) { localMatrix = LocalMatrix; Matrix ret = localMatrix; if (EnableSkinning) { Vector3 offset = ComputeBoneOffset(ref boneIndices, ref boneWeights); Vector3 translationM = ret.Translation; translationM += offset; ret.Translation = translationM; } return ret; }
public Vector3 ComputeBoneOffset(ref Vector4UByte boneIndices, ref Vector4 boneWeights) { Matrix bonesMatrix = new Matrix(); Vector4 bone0 = GetNormalizedBone(boneIndices[0]); Vector4 bone1 = GetNormalizedBone(boneIndices[1]); Vector4 bone2 = GetNormalizedBone(boneIndices[2]); Vector4 bone3 = GetNormalizedBone(boneIndices[3]); bonesMatrix.SetRow(0, bone0); bonesMatrix.SetRow(1, bone1); bonesMatrix.SetRow(2, bone2); bonesMatrix.SetRow(3, bone3); return Denormalize(Vector4.Transform(boneWeights, bonesMatrix), BoneRange); }
// http://web.stanford.edu/class/cs248/pdf/class_13_skinning.pdf private Matrix ComputeSkinning(Vector4UByte indices, ref VRageMath.Vector4 weights) { // TODO: Optmize Matrix ret = new Matrix(); for (int it = 0; it < 4; it++) { float weight = weights[it]; if (weight == 0) break; // NOTE: m_skinTransforms are already transposed Matrix transform; Matrix.Transpose(ref m_skinTransforms[m_skeletonIndices[indices[it]]], out transform); transform *= weight; ret += transform; } return ret; }