From 1b9b0f9fc96d7f8c6fd96089d36ee8bce3aa8d64 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 17 Oct 2014 16:51:55 -0700 Subject: [PATCH 1/3] Look for and store the "Skeleton" type flag so that we can offer only skeleton joints in the dropdown. --- interface/src/ModelUploader.cpp | 4 +++- libraries/fbx/src/FBXReader.cpp | 19 ++++++++++++++++++- libraries/fbx/src/FBXReader.h | 2 ++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/interface/src/ModelUploader.cpp b/interface/src/ModelUploader.cpp index 7077c44287..3d772f7d96 100644 --- a/interface/src/ModelUploader.cpp +++ b/interface/src/ModelUploader.cpp @@ -785,7 +785,9 @@ QComboBox* ModelPropertiesDialog::createJointBox(bool withNone) const { box->addItem("(none)"); } foreach (const FBXJoint& joint, _geometry.joints) { - box->addItem(joint.name); + if (joint.isSkeletonJoint || !_geometry.hasSkeletonJoints) { + box->addItem(joint.name); + } } return box; } diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 43d23160f7..abeb27f4ab 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1015,6 +1015,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) QHash textureFilenames; QHash textureContent; QHash materials; + QHash typeFlags; QHash diffuseTextures; QHash bumpTextures; QHash specularTextures; @@ -1323,6 +1324,12 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) material.id = getID(object.properties); materials.insert(material.id, material); + } else if (object.name == "NodeAttribute") { + foreach (const FBXNode& subobject, object.children) { + if (subobject.name == "TypeFlags") { + typeFlags.insert(getID(object.properties), subobject.properties.at(0).toString()); + } + } } else if (object.name == "Deformer") { if (object.properties.last() == "Cluster") { Cluster cluster; @@ -1461,12 +1468,13 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) // convert the models to joints QVariantList freeJoints = mapping.values("freeJoint"); + geometry.hasSkeletonJoints = false; foreach (const QString& modelID, modelIDs) { const FBXModel& model = models[modelID]; FBXJoint joint; joint.isFree = freeJoints.contains(model.name); joint.parentIndex = model.parentIndex; - + // get the indices of all ancestors starting with the first free one (if any) int jointIndex = geometry.joints.size(); joint.freeLineage.append(jointIndex); @@ -1506,6 +1514,15 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) joint.name = model.name; joint.shapePosition = glm::vec3(0.f); joint.shapeType = UNKNOWN_SHAPE; + + foreach (const QString& childID, childMap.values(modelID)) { + QString type = typeFlags.value(childID); + if (!type.isEmpty()) { + geometry.hasSkeletonJoints |= (joint.isSkeletonJoint = type.toLower().contains("Skeleton")); + break; + } + } + geometry.joints.append(joint); geometry.jointIndices.insert(model.name, geometry.joints.size()); diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 6a7a0904da..cbf0cfcca6 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -80,6 +80,7 @@ public: glm::vec3 shapePosition; // in joint frame glm::quat shapeRotation; // in joint frame Shape::Type shapeType; + bool isSkeletonJoint; }; @@ -182,6 +183,7 @@ public: QVector joints; QHash jointIndices; ///< 1-based, so as to more easily detect missing indices + bool hasSkeletonJoints; QVector meshes; From 1940fe67a072877b4f23466d9a4f889b3e5ac8a9 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 17 Oct 2014 16:57:15 -0700 Subject: [PATCH 2/3] Add jointEyeLeft/jointEyeRight/jointNeck to list of nodes we check for on upload. --- interface/src/ModelUploader.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/interface/src/ModelUploader.cpp b/interface/src/ModelUploader.cpp index 3d772f7d96..2a5812574e 100644 --- a/interface/src/ModelUploader.cpp +++ b/interface/src/ModelUploader.cpp @@ -161,13 +161,15 @@ bool ModelUploader::zip() { } QVariantHash joints = mapping.value(JOINT_FIELD).toHash(); if (!joints.contains("jointEyeLeft")) { - joints.insert("jointEyeLeft", geometry.jointIndices.contains("EyeLeft") ? "EyeLeft" : "LeftEye"); + joints.insert("jointEyeLeft", geometry.jointIndices.contains("jointEyeLeft") ? "jointEyeLeft" : + (geometry.jointIndices.contains("EyeLeft") ? "EyeLeft" : "LeftEye")); } if (!joints.contains("jointEyeRight")) { - joints.insert("jointEyeRight", geometry.jointIndices.contains("EyeRight") ? "EyeRight" : "RightEye"); + joints.insert("jointEyeRight", geometry.jointIndices.contains("jointEyeRight") ? "jointEyeRight" : + geometry.jointIndices.contains("EyeRight") ? "EyeRight" : "RightEye"); } if (!joints.contains("jointNeck")) { - joints.insert("jointNeck", "Neck"); + joints.insert("jointNeck", geometry.jointIndices.contains("jointNeck") ? "jointNeck" : "Neck"); } if (!joints.contains("jointRoot")) { joints.insert("jointRoot", "Hips"); From c979ace92457664be486bb6d10baa0448f239862 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 17 Oct 2014 17:34:27 -0700 Subject: [PATCH 3/3] Read the unit scale factor and include it in the offset scale. --- interface/src/ModelUploader.cpp | 2 +- libraries/fbx/src/FBXReader.cpp | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/interface/src/ModelUploader.cpp b/interface/src/ModelUploader.cpp index 2a5812574e..b117197f48 100644 --- a/interface/src/ModelUploader.cpp +++ b/interface/src/ModelUploader.cpp @@ -157,7 +157,7 @@ bool ModelUploader::zip() { // mixamo/autodesk defaults if (!mapping.contains(SCALE_FIELD)) { - mapping.insert(SCALE_FIELD, geometry.author == "www.makehuman.org" ? 150.0 : 15.0); + mapping.insert(SCALE_FIELD, 15.0); } QVariantHash joints = mapping.value(JOINT_FIELD).toHash(); if (!joints.contains("jointEyeLeft")) { diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index abeb27f4ab..d700228ea5 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1073,6 +1073,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) QMultiHash blendshapeChannelIndices; FBXGeometry geometry; + float unitScaleFactor = 1.0f; foreach (const FBXNode& child, node.children) { if (child.name == "FBXHeaderExtension") { foreach (const FBXNode& object, child.children) { @@ -1095,6 +1096,17 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) } } } + } else if (child.name == "GlobalSettings") { + foreach (const FBXNode& object, child.children) { + if (object.name == "Properties70") { + foreach (const FBXNode& subobject, object.children) { + if (subobject.name == "P" && subobject.properties.size() >= 5 && + subobject.properties.at(0) == "UnitScaleFactor") { + unitScaleFactor = subobject.properties.at(4).toFloat(); + } + } + } + } } else if (child.name == "Objects") { foreach (const FBXNode& object, child.children) { if (object.name == "Geometry") { @@ -1412,7 +1424,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) } // get offset transform from mapping - float offsetScale = mapping.value("scale", 1.0f).toFloat(); + float offsetScale = mapping.value("scale", 1.0f).toFloat() * unitScaleFactor; glm::quat offsetRotation = glm::quat(glm::radians(glm::vec3(mapping.value("rx").toFloat(), mapping.value("ry").toFloat(), mapping.value("rz").toFloat()))); geometry.offset = glm::translate(glm::vec3(mapping.value("tx").toFloat(), mapping.value("ty").toFloat(),