// Deform the vertex array according to the links contained in the mesh and the skinning type. void fbxLoader2::ComputeSkinDeformation(FbxAMatrix& pGlobalPosition, FbxMesh* pMesh, FbxTime& pTime, FbxPose* pPose, int frame) { FbxSkin * lSkinDeformer = (FbxSkin *)pMesh->GetDeformer(0, FbxDeformer::eSkin); FbxSkin::EType lSkinningType = lSkinDeformer->GetSkinningType(); if(lSkinningType == FbxSkin::eLinear || lSkinningType == FbxSkin::eRigid) { ComputeLinearDeformation(pGlobalPosition, pMesh, pTime, pPose, frame); } else if(lSkinningType == FbxSkin::eDualQuaternion) { int i = 0; ComputeDualQuaternionDeformation(pGlobalPosition, pMesh, pTime, pPose, frame); } else if(lSkinningType == FbxSkin::eBlend) { int lVertexCount = pMesh->GetControlPointsCount(); FbxVector4* lVertexArrayLinear = new FbxVector4[lVertexCount]; memcpy(lVertexArrayLinear, pMesh->GetControlPoints(), lVertexCount * sizeof(FbxVector4)); FbxVector4* lVertexArrayDQ = new FbxVector4[lVertexCount]; memcpy(lVertexArrayDQ, pMesh->GetControlPoints(), lVertexCount * sizeof(FbxVector4)); ComputeLinearDeformation(pGlobalPosition, pMesh, pTime, pPose, frame); ComputeDualQuaternionDeformation(pGlobalPosition, pMesh, pTime, pPose, frame); } }
// Deform the vertex array according to the links contained in the mesh and the skinning type. void compute_skin_deformation(FbxAMatrix& pGlobalPosition, FbxMesh* pMesh, FbxTime& pTime, FbxVector4* pVertexArray, FbxPose* pPose) { FbxSkin * lSkinDeformer = (FbxSkin *)pMesh->GetDeformer(0, FbxDeformer::eSkin); FbxSkin::EType lSkinningType = lSkinDeformer->GetSkinningType(); if(lSkinningType == FbxSkin::eLinear || lSkinningType == FbxSkin::eRigid) { compute_linear_deformation(pGlobalPosition, pMesh, pTime, pVertexArray, pPose); } else if(lSkinningType == FbxSkin::eDualQuaternion) { compute_dual_quaternion_deformation(pGlobalPosition, pMesh, pTime, pVertexArray, pPose); } else if(lSkinningType == FbxSkin::eBlend) { int lVertexCount = pMesh->GetControlPointsCount(); FbxVector4* lVertexArrayLinear = new FbxVector4[lVertexCount]; memcpy(lVertexArrayLinear, pMesh->GetControlPoints(), lVertexCount * sizeof(FbxVector4)); FbxVector4* lVertexArrayDQ = new FbxVector4[lVertexCount]; memcpy(lVertexArrayDQ, pMesh->GetControlPoints(), lVertexCount * sizeof(FbxVector4)); compute_linear_deformation(pGlobalPosition, pMesh, pTime, lVertexArrayLinear, pPose); compute_dual_quaternion_deformation(pGlobalPosition, pMesh, pTime, lVertexArrayDQ, pPose); // To blend the skinning according to the blend weights // Final vertex = DQSVertex * blend weight + LinearVertex * (1- blend weight) // DQSVertex: vertex that is deformed by dual quaternion skinning method; // LinearVertex: vertex that is deformed by classic linear skinning method; int lBlendWeightsCount = lSkinDeformer->GetControlPointIndicesCount(); for(int lBWIndex = 0; lBWIndex<lBlendWeightsCount; ++lBWIndex) { double lBlendWeight = lSkinDeformer->GetControlPointBlendWeights()[lBWIndex]; pVertexArray[lBWIndex] = lVertexArrayDQ[lBWIndex] * lBlendWeight + lVertexArrayLinear[lBWIndex] * (1 - lBlendWeight); } } }