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.
This commit is contained in:
Anthony Thibault 2019-01-22 10:47:01 -08:00
parent da7cd6b2f7
commit 5146f3dfae
2 changed files with 18 additions and 11 deletions

View file

@ -237,8 +237,17 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector<HFMJoint>& 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.

View file

@ -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<QString, QString>& _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<ExtractedBlendshape> 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);