mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-06 15:20:27 +02:00
mapped the model joint names to hifi compliant joint names in FBX serializer
This commit is contained in:
parent
f7fcf503c2
commit
edab74caa4
5 changed files with 34 additions and 56 deletions
|
@ -23,8 +23,6 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) {
|
||||||
for (auto& joint : hfmModel.joints) {
|
for (auto& joint : hfmModel.joints) {
|
||||||
joints.push_back(joint);
|
joints.push_back(joint);
|
||||||
}
|
}
|
||||||
|
|
||||||
_fbxToHifiJointNameMapping = hfmModel.fbxToHifiJointNameMapping;
|
|
||||||
buildSkeletonFromJoints(joints, hfmModel.jointRotationOffsets);
|
buildSkeletonFromJoints(joints, hfmModel.jointRotationOffsets);
|
||||||
|
|
||||||
// we make a copy of the inverseBindMatrices in order to prevent mutating the model bind pose
|
// we make a copy of the inverseBindMatrices in order to prevent mutating the model bind pose
|
||||||
|
@ -61,14 +59,8 @@ AnimSkeleton::AnimSkeleton(const std::vector<HFMJoint>& joints, const QMap<int,
|
||||||
}
|
}
|
||||||
|
|
||||||
int AnimSkeleton::nameToJointIndex(const QString& jointName) const {
|
int AnimSkeleton::nameToJointIndex(const QString& jointName) const {
|
||||||
|
|
||||||
auto itr = _jointIndicesByName.find(jointName);
|
auto itr = _jointIndicesByName.find(jointName);
|
||||||
if (_fbxToHifiJointNameMapping.contains(jointName)) {
|
if (_jointIndicesByName.end() != itr) {
|
||||||
// if the fbx joint name is different than the hifi standard then look up the
|
|
||||||
// index from the fbx joint name.
|
|
||||||
itr = _jointIndicesByName.find(_fbxToHifiJointNameMapping[jointName]);
|
|
||||||
}
|
|
||||||
if (itr != _jointIndicesByName.end()) {
|
|
||||||
return itr.value();
|
return itr.value();
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -128,13 +120,8 @@ std::vector<int> AnimSkeleton::getChildrenOfJoint(int jointIndex) const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString AnimSkeleton::getJointName(int jointIndex) const {
|
const QString& AnimSkeleton::getJointName(int jointIndex) const {
|
||||||
|
return _joints[jointIndex].name;
|
||||||
QString jointName = _joints[jointIndex].name;
|
|
||||||
if (_fbxToHifiJointNameMapping.contains(_fbxToHifiJointNameMapping.key(jointName))) {
|
|
||||||
jointName = _fbxToHifiJointNameMapping.key(jointName);
|
|
||||||
}
|
|
||||||
return jointName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimPose AnimSkeleton::getAbsolutePose(int jointIndex, const AnimPoseVec& relativePoses) const {
|
AnimPose AnimSkeleton::getAbsolutePose(int jointIndex, const AnimPoseVec& relativePoses) const {
|
||||||
|
@ -258,25 +245,21 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector<HFMJoint>& joints,
|
||||||
_nonMirroredIndices.clear();
|
_nonMirroredIndices.clear();
|
||||||
_mirrorMap.reserve(_jointsSize);
|
_mirrorMap.reserve(_jointsSize);
|
||||||
for (int i = 0; i < _jointsSize; i++) {
|
for (int i = 0; i < _jointsSize; i++) {
|
||||||
QString jointName = _joints[i].name;
|
if (_joints[i].name != "Hips" && _joints[i].name != "Spine" &&
|
||||||
if (_fbxToHifiJointNameMapping.contains(_fbxToHifiJointNameMapping.key(jointName))) {
|
_joints[i].name != "Spine1" && _joints[i].name != "Spine2" &&
|
||||||
jointName = _fbxToHifiJointNameMapping.key(jointName);
|
_joints[i].name != "Neck" && _joints[i].name != "Head" &&
|
||||||
}
|
!((_joints[i].name.startsWith("Left") || _joints[i].name.startsWith("Right")) &&
|
||||||
if (jointName != "Hips" && jointName != "Spine" &&
|
_joints[i].name != "LeftEye" && _joints[i].name != "RightEye")) {
|
||||||
jointName != "Spine1" && jointName != "Spine2" &&
|
|
||||||
jointName != "Neck" && jointName != "Head" &&
|
|
||||||
!((jointName.startsWith("Left") || jointName.startsWith("Right")) &&
|
|
||||||
jointName != "LeftEye" && jointName != "RightEye")) {
|
|
||||||
// HACK: we don't want to mirror some joints so we remember their indices
|
// HACK: we don't want to mirror some joints so we remember their indices
|
||||||
// so we can restore them after a future mirror operation
|
// so we can restore them after a future mirror operation
|
||||||
_nonMirroredIndices.push_back(i);
|
_nonMirroredIndices.push_back(i);
|
||||||
}
|
}
|
||||||
int mirrorJointIndex = -1;
|
int mirrorJointIndex = -1;
|
||||||
if (jointName.startsWith("Left")) {
|
if (_joints[i].name.startsWith("Left")) {
|
||||||
QString mirrorJointName = QString(jointName).replace(0, 4, "Right");
|
QString mirrorJointName = QString(_joints[i].name).replace(0, 4, "Right");
|
||||||
mirrorJointIndex = nameToJointIndex(mirrorJointName);
|
mirrorJointIndex = nameToJointIndex(mirrorJointName);
|
||||||
} else if (jointName.startsWith("Right")) {
|
} else if (_joints[i].name.startsWith("Right")) {
|
||||||
QString mirrorJointName = QString(jointName).replace(0, 5, "Left");
|
QString mirrorJointName = QString(_joints[i].name).replace(0, 5, "Left");
|
||||||
mirrorJointIndex = nameToJointIndex(mirrorJointName);
|
mirrorJointIndex = nameToJointIndex(mirrorJointName);
|
||||||
}
|
}
|
||||||
if (mirrorJointIndex >= 0) {
|
if (mirrorJointIndex >= 0) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
explicit AnimSkeleton(const std::vector<HFMJoint>& joints, const QMap<int, glm::quat> jointOffsets);
|
explicit AnimSkeleton(const std::vector<HFMJoint>& joints, const QMap<int, glm::quat> jointOffsets);
|
||||||
|
|
||||||
int nameToJointIndex(const QString& jointName) const;
|
int nameToJointIndex(const QString& jointName) const;
|
||||||
const QString getJointName(int jointIndex) const;
|
const QString& getJointName(int jointIndex) const;
|
||||||
int getNumJoints() const;
|
int getNumJoints() const;
|
||||||
int getChainDepth(int jointIndex) const;
|
int getChainDepth(int jointIndex) const;
|
||||||
|
|
||||||
|
@ -79,7 +79,6 @@ protected:
|
||||||
std::vector<int> _mirrorMap;
|
std::vector<int> _mirrorMap;
|
||||||
QHash<QString, int> _jointIndicesByName;
|
QHash<QString, int> _jointIndicesByName;
|
||||||
std::vector<std::vector<HFMCluster>> _clusterBindMatrixOriginalValues;
|
std::vector<std::vector<HFMCluster>> _clusterBindMatrixOriginalValues;
|
||||||
QMap<QString, QString> _fbxToHifiJointNameMapping;
|
|
||||||
|
|
||||||
// no copies
|
// no copies
|
||||||
AnimSkeleton(const AnimSkeleton&) = delete;
|
AnimSkeleton(const AnimSkeleton&) = delete;
|
||||||
|
|
|
@ -1437,13 +1437,6 @@ int Avatar::getJointIndex(const QString& name) const {
|
||||||
withValidJointIndicesCache([&]() {
|
withValidJointIndicesCache([&]() {
|
||||||
if (_modelJointIndicesCache.contains(name)) {
|
if (_modelJointIndicesCache.contains(name)) {
|
||||||
result = _modelJointIndicesCache[name] - 1;
|
result = _modelJointIndicesCache[name] - 1;
|
||||||
} else {
|
|
||||||
// doesn't contain name. check the fbx-to-hifi joint name mapping
|
|
||||||
if (_skeletonModel && _skeletonModel->isActive()) {
|
|
||||||
if (_modelJointIndicesCache.contains(_skeletonModel->getHFMModel().fbxToHifiJointNameMapping[name])) {
|
|
||||||
result = _modelJointIndicesCache[_skeletonModel->getHFMModel().fbxToHifiJointNameMapping[name]] - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -419,15 +419,15 @@ QByteArray fileOnUrl(const QByteArray& filepath, const QString& url) {
|
||||||
|
|
||||||
QMap<QString, QString> getJointNameMapping(const QVariantHash& mapping) {
|
QMap<QString, QString> getJointNameMapping(const QVariantHash& mapping) {
|
||||||
static const QString JOINT_NAME_MAPPING_FIELD = "jointMap";
|
static const QString JOINT_NAME_MAPPING_FIELD = "jointMap";
|
||||||
QMap<QString, QString> fbxToHifiJointNameMap;
|
QMap<QString, QString> hfmToHifiJointNameMap;
|
||||||
if (!mapping.isEmpty() && mapping.contains(JOINT_NAME_MAPPING_FIELD) && mapping[JOINT_NAME_MAPPING_FIELD].type() == QVariant::Hash) {
|
if (!mapping.isEmpty() && mapping.contains(JOINT_NAME_MAPPING_FIELD) && mapping[JOINT_NAME_MAPPING_FIELD].type() == QVariant::Hash) {
|
||||||
auto jointNames = mapping[JOINT_NAME_MAPPING_FIELD].toHash();
|
auto jointNames = mapping[JOINT_NAME_MAPPING_FIELD].toHash();
|
||||||
for (auto itr = jointNames.begin(); itr != jointNames.end(); itr++) {
|
for (auto itr = jointNames.begin(); itr != jointNames.end(); itr++) {
|
||||||
fbxToHifiJointNameMap.insert(itr.key(), itr.value().toString());
|
hfmToHifiJointNameMap.insert(itr.key(), itr.value().toString());
|
||||||
qCDebug(modelformat) << "the mapped key " << itr.key() << " has a value of " << fbxToHifiJointNameMap[itr.key()];
|
qCDebug(modelformat) << "the mapped key " << itr.key() << " has a value of " << hfmToHifiJointNameMap[itr.key()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fbxToHifiJointNameMap;
|
return hfmToHifiJointNameMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString, glm::quat> getJointRotationOffsets(const QVariantHash& mapping) {
|
QMap<QString, glm::quat> getJointRotationOffsets(const QVariantHash& mapping) {
|
||||||
|
@ -530,8 +530,8 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
||||||
HFMModel& hfmModel = *hfmModelPtr;
|
HFMModel& hfmModel = *hfmModelPtr;
|
||||||
|
|
||||||
hfmModel.originalURL = url;
|
hfmModel.originalURL = url;
|
||||||
hfmModel.fbxToHifiJointNameMapping.clear();
|
hfmModel.hfmToHifiJointNameMapping.clear();
|
||||||
hfmModel.fbxToHifiJointNameMapping = getJointNameMapping(mapping);
|
hfmModel.hfmToHifiJointNameMapping = getJointNameMapping(mapping);
|
||||||
|
|
||||||
float unitScaleFactor = 1.0f;
|
float unitScaleFactor = 1.0f;
|
||||||
glm::vec3 ambientColor;
|
glm::vec3 ambientColor;
|
||||||
|
@ -600,31 +600,31 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
||||||
hifiGlobalNodeID = id;
|
hifiGlobalNodeID = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name == jointEyeLeftName || name == "EyeL" || name == "joint_Leye" || (hfmModel.fbxToHifiJointNameMapping.contains(jointEyeLeftName) && (name == hfmModel.fbxToHifiJointNameMapping[jointEyeLeftName]))) {
|
if (name == jointEyeLeftName || name == "EyeL" || name == "joint_Leye" || (hfmModel.hfmToHifiJointNameMapping.contains(jointEyeLeftName) && (name == hfmModel.hfmToHifiJointNameMapping[jointEyeLeftName]))) {
|
||||||
jointEyeLeftID = getID(object.properties);
|
jointEyeLeftID = getID(object.properties);
|
||||||
|
|
||||||
} else if (name == jointEyeRightName || name == "EyeR" || name == "joint_Reye" || (hfmModel.fbxToHifiJointNameMapping.contains(jointEyeRightName) && (name == hfmModel.fbxToHifiJointNameMapping[jointEyeRightName]))) {
|
} else if (name == jointEyeRightName || name == "EyeR" || name == "joint_Reye" || (hfmModel.hfmToHifiJointNameMapping.contains(jointEyeRightName) && (name == hfmModel.hfmToHifiJointNameMapping[jointEyeRightName]))) {
|
||||||
jointEyeRightID = getID(object.properties);
|
jointEyeRightID = getID(object.properties);
|
||||||
|
|
||||||
} else if (name == jointNeckName || name == "NeckRot" || name == "joint_neck" || (hfmModel.fbxToHifiJointNameMapping.contains(jointNeckName) && (name == hfmModel.fbxToHifiJointNameMapping[jointNeckName]))) {
|
} else if (name == jointNeckName || name == "NeckRot" || name == "joint_neck" || (hfmModel.hfmToHifiJointNameMapping.contains(jointNeckName) && (name == hfmModel.hfmToHifiJointNameMapping[jointNeckName]))) {
|
||||||
jointNeckID = getID(object.properties);
|
jointNeckID = getID(object.properties);
|
||||||
|
|
||||||
} else if (name == jointRootName || (hfmModel.fbxToHifiJointNameMapping.contains(jointRootName) && (name == hfmModel.fbxToHifiJointNameMapping[jointRootName]))) {
|
} else if (name == jointRootName || (hfmModel.hfmToHifiJointNameMapping.contains(jointRootName) && (name == hfmModel.hfmToHifiJointNameMapping[jointRootName]))) {
|
||||||
jointRootID = getID(object.properties);
|
jointRootID = getID(object.properties);
|
||||||
|
|
||||||
} else if ((name == jointHeadName) || (hfmModel.fbxToHifiJointNameMapping.contains(jointHeadName) && (name == hfmModel.fbxToHifiJointNameMapping[jointHeadName]))) {
|
} else if ((name == jointHeadName) || (hfmModel.hfmToHifiJointNameMapping.contains(jointHeadName) && (name == hfmModel.hfmToHifiJointNameMapping[jointHeadName]))) {
|
||||||
jointHeadID = getID(object.properties);
|
jointHeadID = getID(object.properties);
|
||||||
|
|
||||||
} else if (name == jointLeftHandName || name == "LeftHand" || name == "joint_L_hand" || (hfmModel.fbxToHifiJointNameMapping.contains(jointLeftHandName) && (name == hfmModel.fbxToHifiJointNameMapping[jointLeftHandName]))) {
|
} else if (name == jointLeftHandName || name == "LeftHand" || name == "joint_L_hand" || (hfmModel.hfmToHifiJointNameMapping.contains(jointLeftHandName) && (name == hfmModel.hfmToHifiJointNameMapping[jointLeftHandName]))) {
|
||||||
jointLeftHandID = getID(object.properties);
|
jointLeftHandID = getID(object.properties);
|
||||||
|
|
||||||
} else if (name == jointRightHandName || name == "RightHand" || name == "joint_R_hand" || (hfmModel.fbxToHifiJointNameMapping.contains(jointRightHandName) && (name == hfmModel.fbxToHifiJointNameMapping[jointRightHandName]))) {
|
} else if (name == jointRightHandName || name == "RightHand" || name == "joint_R_hand" || (hfmModel.hfmToHifiJointNameMapping.contains(jointRightHandName) && (name == hfmModel.hfmToHifiJointNameMapping[jointRightHandName]))) {
|
||||||
jointRightHandID = getID(object.properties);
|
jointRightHandID = getID(object.properties);
|
||||||
|
|
||||||
} else if (name == "LeftToe" || name == "joint_L_toe" || name == "LeftToe_End" || (hfmModel.fbxToHifiJointNameMapping.contains("LeftToe") && (name == hfmModel.fbxToHifiJointNameMapping["LeftToe"]))) {
|
} else if (name == "LeftToe" || name == "joint_L_toe" || name == "LeftToe_End" || (hfmModel.hfmToHifiJointNameMapping.contains("LeftToe") && (name == hfmModel.hfmToHifiJointNameMapping["LeftToe"]))) {
|
||||||
jointLeftToeID = getID(object.properties);
|
jointLeftToeID = getID(object.properties);
|
||||||
|
|
||||||
} else if (name == "RightToe" || name == "joint_R_toe" || name == "RightToe_End" || (hfmModel.fbxToHifiJointNameMapping.contains("RightToe") && (name == hfmModel.fbxToHifiJointNameMapping["RightToe"]))) {
|
} else if (name == "RightToe" || name == "joint_R_toe" || name == "RightToe_End" || (hfmModel.hfmToHifiJointNameMapping.contains("RightToe") && (name == hfmModel.hfmToHifiJointNameMapping["RightToe"]))) {
|
||||||
jointRightToeID = getID(object.properties);
|
jointRightToeID = getID(object.properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1398,6 +1398,9 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
||||||
}
|
}
|
||||||
joint.inverseBindRotation = joint.inverseDefaultRotation;
|
joint.inverseBindRotation = joint.inverseDefaultRotation;
|
||||||
joint.name = fbxModel.name;
|
joint.name = fbxModel.name;
|
||||||
|
if (hfmModel.hfmToHifiJointNameMapping.contains(hfmModel.hfmToHifiJointNameMapping.key(joint.name))) {
|
||||||
|
joint.name = hfmModel.hfmToHifiJointNameMapping.key(fbxModel.name);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (const QString& childID, _connectionChildMap.values(modelID)) {
|
foreach (const QString& childID, _connectionChildMap.values(modelID)) {
|
||||||
QString type = typeFlags.value(childID);
|
QString type = typeFlags.value(childID);
|
||||||
|
@ -1833,8 +1836,8 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr
|
||||||
QString jointName = itr.key();
|
QString jointName = itr.key();
|
||||||
glm::quat rotationOffset = itr.value();
|
glm::quat rotationOffset = itr.value();
|
||||||
int jointIndex = hfmModel.getJointIndex(jointName);
|
int jointIndex = hfmModel.getJointIndex(jointName);
|
||||||
if (hfmModel.fbxToHifiJointNameMapping.contains(jointName)) {
|
if (hfmModel.hfmToHifiJointNameMapping.contains(jointName)) {
|
||||||
jointIndex = hfmModel.getJointIndex(hfmModel.fbxToHifiJointNameMapping[jointName]);
|
jointIndex = hfmModel.getJointIndex(hfmModel.hfmToHifiJointNameMapping[jointName]);
|
||||||
}
|
}
|
||||||
if (jointIndex != -1) {
|
if (jointIndex != -1) {
|
||||||
hfmModel.jointRotationOffsets.insert(jointIndex, rotationOffset);
|
hfmModel.jointRotationOffsets.insert(jointIndex, rotationOffset);
|
||||||
|
|
|
@ -312,7 +312,7 @@ public:
|
||||||
QList<QString> blendshapeChannelNames;
|
QList<QString> blendshapeChannelNames;
|
||||||
|
|
||||||
QMap<int, glm::quat> jointRotationOffsets;
|
QMap<int, glm::quat> jointRotationOffsets;
|
||||||
QMap<QString, QString> fbxToHifiJointNameMapping;
|
QMap<QString, QString> hfmToHifiJointNameMapping;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue