diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 435eaf9184..91ca2359b4 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -25,6 +25,8 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { } buildSkeletonFromJoints(joints, hfmModel.jointRotationOffsets); + // we make a copy of the inverseBindMatrices in order to prevent mutating the model bind pose + // when we are dealing with a joint offset in the model for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { const HFMMesh& mesh = hfmModel.meshes.at(i); std::vector dummyClustersList; @@ -39,12 +41,11 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { localCluster.inverseBindMatrix = cluster.inverseBindMatrix; localCluster.inverseBindTransform.evalFromRawMatrix(localCluster.inverseBindMatrix); - // we make a copy of the inversebindMatrices in order to prevent mutating the model bind pose + // if we have a joint offset in the fst file then multiply its inverse by the + // model cluster inverse bind matrix if (hfmModel.jointRotationOffsets.contains(cluster.jointIndex)) { AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3()); - if ((hfmModel.clusterBindMatrixOriginalValues.size() > i) && (hfmModel.clusterBindMatrixOriginalValues[i].size() > j)) { - localCluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * hfmModel.clusterBindMatrixOriginalValues[i][j]; - } + localCluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; localCluster.inverseBindTransform.evalFromRawMatrix(localCluster.inverseBindMatrix); } dummyClustersList.push_back(localCluster); diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index 7436609ee1..ab89eb643d 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -63,7 +63,7 @@ public: void dump(const AnimPoseVec& poses) const; std::vector lookUpJointIndices(const std::vector& jointNames) const; - std::vector> _clusterBindMatrixOriginalValues; + const HFMCluster getClusterBindMatricesOriginalValues(const int meshIndex, const int clusterIndex) const { return _clusterBindMatrixOriginalValues[meshIndex][clusterIndex]; } protected: void buildSkeletonFromJoints(const std::vector& joints, const QMap jointOffsets); @@ -78,6 +78,7 @@ protected: std::vector _nonMirroredIndices; std::vector _mirrorMap; QHash _jointIndicesByName; + std::vector> _clusterBindMatrixOriginalValues; // no copies AnimSkeleton(const AnimSkeleton&) = delete; diff --git a/libraries/fbx/src/FBX.h b/libraries/fbx/src/FBX.h index 943db4b7fe..d4072f03d7 100644 --- a/libraries/fbx/src/FBX.h +++ b/libraries/fbx/src/FBX.h @@ -349,7 +349,6 @@ public: Extents meshExtents; QVector animationFrames; - std::vector> clusterBindMatrixOriginalValues; int getJointIndex(const QString& name) const { return jointIndices.value(name) - 1; } QStringList getJointNames() const; diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index e00a82d71f..86d4793aa5 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -114,18 +114,22 @@ void CauterizedModel::updateClusterMatrices() { for (int i = 0; i < (int)_meshStates.size(); i++) { Model::MeshState& state = _meshStates[i]; const HFMMesh& mesh = hfmModel.meshes.at(i); + int meshIndex = i; + for (int j = 0; j < mesh.clusters.size(); j++) { const HFMCluster& cluster = mesh.clusters.at(j); + int clusterIndex = j; + if (_useDualQuaternionSkinning) { auto jointPose = _rig.getJointPose(cluster.jointIndex); Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); Transform clusterTransform; - Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindTransform); + Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindTransform); state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform); state.clusterDualQuaternions[j].setCauterizationParameters(0.0f, jointPose.trans()); } else { auto jointMatrix = _rig.getJointTransform(cluster.jointIndex); - glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, state.clusterMatrices[j]); + glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]); } } } @@ -146,9 +150,11 @@ void CauterizedModel::updateClusterMatrices() { for (int i = 0; i < _cauterizeMeshStates.size(); i++) { Model::MeshState& state = _cauterizeMeshStates[i]; const HFMMesh& mesh = hfmModel.meshes.at(i); + int meshIndex = i; for (int j = 0; j < mesh.clusters.size(); j++) { const HFMCluster& cluster = mesh.clusters.at(j); + int clusterIndex = j; if (_useDualQuaternionSkinning) { if (_cauterizeBoneSet.find(cluster.jointIndex) == _cauterizeBoneSet.end()) { @@ -157,7 +163,7 @@ void CauterizedModel::updateClusterMatrices() { } else { Transform jointTransform(cauterizePose.rot(), cauterizePose.scale(), cauterizePose.trans()); Transform clusterTransform; - Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindTransform); + Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindTransform); state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform); state.clusterDualQuaternions[j].setCauterizationParameters(1.0f, cauterizePose.trans()); } @@ -166,7 +172,7 @@ void CauterizedModel::updateClusterMatrices() { // not cauterized so just copy the value from the non-cauterized version. state.clusterMatrices[j] = _meshStates[i].clusterMatrices[j]; } else { - glm_mat4u_mul(cauterizeMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, state.clusterMatrices[j]); + glm_mat4u_mul(cauterizeMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]); } } } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index a5565d0646..9cefbf65a8 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1418,20 +1418,21 @@ void Model::updateClusterMatrices() { const HFMModel& hfmModel = getHFMModel(); for (int i = 0; i < (int) _meshStates.size(); i++) { MeshState& state = _meshStates[i]; + int meshIndex = i; const HFMMesh& mesh = hfmModel.meshes.at(i); for (int j = 0; j < mesh.clusters.size(); j++) { const HFMCluster& cluster = mesh.clusters.at(j); + int clusterIndex = j; + if (_useDualQuaternionSkinning) { auto jointPose = _rig.getJointPose(cluster.jointIndex); Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); Transform clusterTransform; - Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindTransform); - //Transform::mult(clusterTransform, jointTransform, cluster.inverseBindTransform); + Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindTransform); state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform); } else { auto jointMatrix = _rig.getJointTransform(cluster.jointIndex); - glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, state.clusterMatrices[j]); - // glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); + glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]); } } } diff --git a/libraries/render-utils/src/SoftAttachmentModel.cpp b/libraries/render-utils/src/SoftAttachmentModel.cpp index e45141a838..a6f82e1417 100644 --- a/libraries/render-utils/src/SoftAttachmentModel.cpp +++ b/libraries/render-utils/src/SoftAttachmentModel.cpp @@ -46,31 +46,25 @@ void SoftAttachmentModel::updateClusterMatrices() { for (int i = 0; i < (int) _meshStates.size(); i++) { MeshState& state = _meshStates[i]; const HFMMesh& mesh = hfmModel.meshes.at(i); - + int meshIndex = i; for (int j = 0; j < mesh.clusters.size(); j++) { const HFMCluster& cluster = mesh.clusters.at(j); + int clusterIndex = j; // TODO: cache these look-ups as an optimization int jointIndexOverride = getJointIndexOverride(cluster.jointIndex); + glm::mat4 jointMatrix; + if (jointIndexOverride >= 0 && jointIndexOverride < _rigOverride.getJointStateCount()) { + jointMatrix = _rigOverride.getJointTransform(jointIndexOverride); + } else { + jointMatrix = _rig.getJointTransform(cluster.jointIndex); + } if (_useDualQuaternionSkinning) { - glm::mat4 jointMatrix; - if (jointIndexOverride >= 0 && jointIndexOverride < _rigOverride.getJointStateCount()) { - jointMatrix = _rigOverride.getJointTransform(jointIndexOverride); - } else { - jointMatrix = _rig.getJointTransform(cluster.jointIndex); - } - glm::mat4 m; - glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, m); + glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, m); state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(m); } else { - glm::mat4 jointMatrix; - if (jointIndexOverride >= 0 && jointIndexOverride < _rigOverride.getJointStateCount()) { - jointMatrix = _rigOverride.getJointTransform(jointIndexOverride); - } else { - jointMatrix = _rig.getJointTransform(cluster.jointIndex); - } - glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, state.clusterMatrices[j]); + glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]); } } }