mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 16:10:40 +02:00
Merge pull request #16065 from luiscuenca/fixDuplicatedJoint
BUGZ-186: Make sure joint names are unique
This commit is contained in:
commit
74363a4382
1 changed files with 68 additions and 34 deletions
|
@ -60,74 +60,108 @@ void PrepareJointsTask::configure(const Config& config) {
|
||||||
_passthrough = config.passthrough;
|
_passthrough = config.passthrough;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PrepareJointsTask::run(const baker::BakeContextPointer& context, const Input& input, Output& output) {
|
void PrepareJointsTask::run(const baker::BakeContextPointer& context, const Input& input, Output& output) {
|
||||||
const auto& jointsIn = input.get0();
|
const auto& jointsIn = input.get0();
|
||||||
auto& jointsOut = output.edit0();
|
auto& jointsOut = output.edit0();
|
||||||
|
std::vector<QString> jointNames;
|
||||||
if (_passthrough) {
|
if (_passthrough) {
|
||||||
jointsOut = jointsIn;
|
jointsOut = jointsIn;
|
||||||
} else {
|
} else {
|
||||||
const auto& mapping = input.get1();
|
const auto& mapping = input.get1();
|
||||||
auto& jointRotationOffsets = output.edit1();
|
auto& jointRotationOffsets = output.edit1();
|
||||||
auto& jointIndices = output.edit2();
|
|
||||||
|
|
||||||
bool newJointRot = false;
|
|
||||||
static const QString JOINT_ROTATION_OFFSET2_FIELD = "jointRotationOffset2";
|
static const QString JOINT_ROTATION_OFFSET2_FIELD = "jointRotationOffset2";
|
||||||
QVariantHash fstHashMap = mapping;
|
QVariantHash fstHashMap = mapping;
|
||||||
if (fstHashMap.contains(JOINT_ROTATION_OFFSET2_FIELD)) {
|
bool newJointRot = fstHashMap.contains(JOINT_ROTATION_OFFSET2_FIELD);
|
||||||
newJointRot = true;
|
|
||||||
} else {
|
|
||||||
newJointRot = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get joint renames
|
// Get joint renames
|
||||||
auto jointNameMapping = getJointNameMapping(mapping);
|
QMap<QString, QString> jointNameMapping = getJointNameMapping(mapping);
|
||||||
// Apply joint metadata from FST file mappings
|
// Apply joint metadata from FST file mappings
|
||||||
for (const auto& jointIn : jointsIn) {
|
for (const hfm::Joint& jointIn : jointsIn) {
|
||||||
jointsOut.push_back(jointIn);
|
jointsOut.push_back(jointIn);
|
||||||
auto& jointOut = jointsOut.back();
|
hfm::Joint& jointOut = jointsOut.back();
|
||||||
|
|
||||||
if (!newJointRot) {
|
if (!newJointRot) {
|
||||||
auto jointNameMapKey = jointNameMapping.key(jointIn.name);
|
// Offset rotations are referenced by the new joint's names
|
||||||
|
// We need to assign new joint's names now, before the offsets are read.
|
||||||
|
QString jointNameMapKey = jointNameMapping.key(jointIn.name);
|
||||||
if (jointNameMapping.contains(jointNameMapKey)) {
|
if (jointNameMapping.contains(jointNameMapKey)) {
|
||||||
jointOut.name = jointNameMapKey;
|
jointOut.name = jointNameMapKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jointIndices.insert(jointOut.name, (int)jointsOut.size());
|
jointNames.push_back(jointOut.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get joint rotation offsets from FST file mappings
|
// Get joint rotation offsets from FST file mappings
|
||||||
auto offsets = getJointRotationOffsets(mapping);
|
QMap<QString, glm::quat> offsets = getJointRotationOffsets(mapping);
|
||||||
for (auto itr = offsets.begin(); itr != offsets.end(); itr++) {
|
for (auto itr = offsets.begin(); itr != offsets.end(); itr++) {
|
||||||
QString jointName = itr.key();
|
QString jointName = itr.key();
|
||||||
int jointIndex = jointIndices.value(jointName) - 1;
|
auto jointToOffset = std::find_if(jointsOut.begin(), jointsOut.end(), [jointName](const hfm::Joint& joint) {
|
||||||
|
return (joint.name == jointName && joint.isSkeletonJoint);
|
||||||
|
});
|
||||||
|
if (jointToOffset != jointsOut.end()) {
|
||||||
|
// In case there are named duplicates we'll assign the offset rotation to the first skeleton joint that matches the name.
|
||||||
|
int jointIndex = (int)distance(jointsOut.begin(), jointToOffset);
|
||||||
if (jointIndex >= 0) {
|
if (jointIndex >= 0) {
|
||||||
glm::quat rotationOffset = itr.value();
|
glm::quat rotationOffset = itr.value();
|
||||||
jointRotationOffsets.insert(jointIndex, rotationOffset);
|
jointRotationOffsets.insert(jointIndex, rotationOffset);
|
||||||
qCDebug(model_baker) << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset;
|
qCDebug(model_baker) << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newJointRot) {
|
if (newJointRot) {
|
||||||
for (auto& jointOut : jointsOut) {
|
// Offset rotations are referenced using the original joint's names
|
||||||
auto jointNameMapKey = jointNameMapping.key(jointOut.name);
|
// We need to apply new names now, once we have read the offsets
|
||||||
int mappedIndex = jointIndices.value(jointOut.name);
|
for (size_t i = 0; i < jointsOut.size(); i++) {
|
||||||
|
hfm::Joint& jointOut = jointsOut[i];
|
||||||
|
QString jointNameMapKey = jointNameMapping.key(jointOut.name);
|
||||||
if (jointNameMapping.contains(jointNameMapKey)) {
|
if (jointNameMapping.contains(jointNameMapKey)) {
|
||||||
// delete and replace with hifi name
|
|
||||||
jointIndices.remove(jointOut.name);
|
|
||||||
jointOut.name = jointNameMapKey;
|
jointOut.name = jointNameMapKey;
|
||||||
jointIndices.insert(jointOut.name, mappedIndex);
|
jointNames[i] = jointNameMapKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString APPEND_DUPLICATE_JOINT = "_joint";
|
||||||
|
const QString APPEND_DUPLICATE_MESH = "_mesh";
|
||||||
|
|
||||||
|
// resolve duplicates and set jointIndices
|
||||||
|
auto& jointIndices = output.edit2();
|
||||||
|
for (size_t i = 0; i < jointsOut.size(); i++) {
|
||||||
|
hfm::Joint& jointOut = jointsOut[i];
|
||||||
|
if (jointIndices.contains(jointOut.name)) {
|
||||||
|
int duplicatedJointIndex = jointIndices[jointOut.name] - 1;
|
||||||
|
if (duplicatedJointIndex >= 0) {
|
||||||
|
auto& duplicatedJoint = jointsOut[duplicatedJointIndex];
|
||||||
|
bool areBothJoints = jointOut.isSkeletonJoint && duplicatedJoint.isSkeletonJoint;
|
||||||
|
QString existJointName = jointOut.name;
|
||||||
|
QString appendName;
|
||||||
|
if (areBothJoints) {
|
||||||
|
appendName = APPEND_DUPLICATE_JOINT;
|
||||||
|
qCWarning(model_baker) << "Duplicated skeleton joints found: " << existJointName;
|
||||||
|
} else {
|
||||||
|
appendName = APPEND_DUPLICATE_MESH;
|
||||||
|
qCDebug(model_baker) << "Duplicated joints found. Renaming the mesh joint: " << existJointName;
|
||||||
|
}
|
||||||
|
QString newName = existJointName + appendName;
|
||||||
|
// Make sure the new name is unique
|
||||||
|
int duplicateIndex = 0;
|
||||||
|
while (jointIndices.contains(newName)) {
|
||||||
|
newName = existJointName + appendName + QString::number(++duplicateIndex);
|
||||||
|
}
|
||||||
|
// Find and rename the mesh joint
|
||||||
|
if (!jointOut.isSkeletonJoint) {
|
||||||
|
jointOut.name = newName;
|
||||||
} else {
|
} else {
|
||||||
// nothing mapped to this fbx joint name
|
|
||||||
if (jointNameMapping.contains(jointOut.name)) {
|
|
||||||
// but the name is in the list of hifi names is mapped to a different joint
|
|
||||||
int extraIndex = jointIndices.value(jointOut.name);
|
|
||||||
jointIndices.remove(jointOut.name);
|
jointIndices.remove(jointOut.name);
|
||||||
jointOut.name = "";
|
jointIndices.insert(newName, duplicatedJointIndex);
|
||||||
jointIndices.insert(jointOut.name, extraIndex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
jointIndices.insert(jointOut.name, (int)(i + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue