From 5146f3dfae54ecc22b59e0f132cbffb97e75a966 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Tue, 22 Jan 2019 10:47:01 -0800 Subject: [PATCH] Bug fix for avatars that have mesh/joint name duplicates This change has two parts. First we do a better job of identifying joints vs meshes in the FBXSerializer. Second we use this information to better handle duplicate names in AnimSkeleton. When a duplicate is detected, allow joints to override meshes. This will ensure that when joints are looked up by name we will not return a mesh object with the same name by mistake. --- libraries/animation/src/AnimSkeleton.cpp | 11 ++++++++++- libraries/fbx/src/FBXSerializer.cpp | 18 ++++++++---------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 16c2c1cc7e..cc48308f17 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -237,8 +237,17 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, _relativeDefaultPoses = _absoluteDefaultPoses; convertAbsolutePosesToRelative(_relativeDefaultPoses); + // build _jointIndicesByName hash for (int i = 0; i < _jointsSize; i++) { - _jointIndicesByName[_joints[i].name] = i; + auto iter = _jointIndicesByName.find(_joints[i].name); + if (iter != _jointIndicesByName.end()) { + // prefer joints over meshes if there is a name collision. + if (_joints[i].isSkeletonJoint && !_joints[iter.value()].isSkeletonJoint) { + iter.value() = i; + } + } else { + _jointIndicesByName.insert(_joints[i].name, i); + } } // build mirror map. diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index 68019c2f4b..4c82b4f5d7 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -131,6 +131,7 @@ public: glm::vec3 geometricTranslation; glm::quat geometricRotation; glm::vec3 geometricScaling; + bool isLimbNode; // is this FBXModel transform is a "LimbNode" i.e. a joint }; glm::mat4 getGlobalTransform(const QMultiMap& _connectionParentMap, @@ -559,9 +560,11 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr glm::vec3 geometricRotation; glm::vec3 rotationMin, rotationMax; + + bool isLimbNode = object.properties.size() >= 3 && object.properties.at(2) == "LimbNode"; FBXModel fbxModel = { name, -1, glm::vec3(), glm::mat4(), glm::quat(), glm::quat(), glm::quat(), - glm::mat4(), glm::vec3(), glm::vec3(), - false, glm::vec3(), glm::quat(), glm::vec3(1.0f) }; + glm::mat4(), glm::vec3(), glm::vec3(), + false, glm::vec3(), glm::quat(), glm::vec3(1.0f), isLimbNode }; ExtractedMesh* mesh = NULL; QVector blendshapes; foreach (const FBXNode& subobject, object.children) { @@ -1258,6 +1261,7 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr // convert the models to joints QVariantList freeJoints = mapping.values("freeJoint"); hfmModel.hasSkeletonJoints = false; + foreach (const QString& modelID, modelIDs) { const FBXModel& fbxModel = fbxModels[modelID]; HFMJoint joint; @@ -1288,6 +1292,8 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr joint.geometricTranslation = fbxModel.geometricTranslation; joint.geometricRotation = fbxModel.geometricRotation; joint.geometricScaling = fbxModel.geometricScaling; + joint.isSkeletonJoint = fbxModel.isLimbNode; + hfmModel.hasSkeletonJoints = (hfmModel.hasSkeletonJoints || joint.isSkeletonJoint); glm::quat combinedRotation = joint.preRotation * joint.rotation * joint.postRotation; @@ -1311,14 +1317,6 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr joint.name = hfmModel.hfmToHifiJointNameMapping.key(fbxModel.name); } - foreach (const QString& childID, _connectionChildMap.values(modelID)) { - QString type = typeFlags.value(childID); - if (!type.isEmpty()) { - hfmModel.hasSkeletonJoints |= (joint.isSkeletonJoint = type.toLower().contains("Skeleton")); - break; - } - } - joint.bindTransformFoundInCluster = false; hfmModel.joints.append(joint);