try to find root joint node for skeleton
authorAngelo Scandaliato <angelo@adtile.me>
Sun, 9 Oct 2016 02:18:13 +0000 (19:18 -0700)
committerAngelo Scandaliato <angelo@adtile.me>
Sun, 9 Oct 2016 02:18:13 +0000 (19:18 -0700)
code/glTFAsset.h
code/glTFAssetWriter.inl
code/glTFExporter.cpp

index 4d95938..247dfd1 100644 (file)
@@ -852,7 +852,7 @@ namespace glTF
     {
         Nullable<mat4> bindShapeMatrix;       //!< Floating-point 4x4 transformation matrix stored in column-major order.
         Ref<Accessor> inverseBindMatrices;    //!< The ID of the accessor containing the floating-point 4x4 inverse-bind matrices.
-        std::vector<std::string/*Ref<Node>*/> jointNames;    //!< Joint names of the joints (nodes with a jointName property) in this skin.
+        std::vector<Ref<Node>> jointNames;    //!< Joint names of the joints (nodes with a jointName property) in this skin.
         std::string name;                     //!< The user-defined name of this object.
 
         Skin() {}
index 5443455..3122130 100644 (file)
@@ -436,7 +436,7 @@ namespace glTF {
         vJointNames.Reserve(unsigned(b.jointNames.size()), w.mAl);
 
         for (size_t i = 0; i < unsigned(b.jointNames.size()); ++i) {
-            vJointNames.PushBack(StringRef(b.jointNames[i]), w.mAl);
+            vJointNames.PushBack(StringRef(b.jointNames[i]->jointName), w.mAl);
         }
         obj.AddMember("jointNames", vJointNames, w.mAl);
 
index b70d081..90c74f3 100644 (file)
@@ -389,6 +389,39 @@ bool FindMeshNode(Ref<Node>& nodeIn, Ref<Node>& meshNode, std::string meshID)
     return false;
 }
 
+/*
+ * Find the root joint of the skeleton.
+ */
+Ref<Node> FindSkeletonRootJoint(Ref<Skin>& skinRef)
+{
+    Ref<Node> candidateNodeRef;
+    Ref<Node> testNodeRef;
+
+    for (unsigned int i = 0; i < skinRef->jointNames.size(); ++i) {
+        candidateNodeRef = skinRef->jointNames[i];
+        bool candidateIsRoot = true;
+
+        for (unsigned int j = 0; j < skinRef->jointNames.size(); ++j) {
+            if (i == j) continue;
+
+            testNodeRef = skinRef->jointNames[j];
+            for (unsigned int k = 0; k < testNodeRef->children.size(); ++k) {
+                std::string childNodeRefID = testNodeRef->children[k]->id;
+
+                if (childNodeRefID.compare(candidateNodeRef->id) == 0) {
+                    candidateIsRoot = false;
+                }
+            }
+        }
+
+        if(candidateIsRoot == true) {
+            return candidateNodeRef;
+        }
+    }
+
+    return candidateNodeRef;
+}
+
 void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer>& bufferRef)
 {
     std::string skinName = aim->mName.C_Str();
@@ -417,7 +450,7 @@ void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer
         // Find the node with id = mName.
         Ref<Node> nodeRef = mAsset.nodes.Get(aib->mName.C_Str());
         nodeRef->jointName = "joint_" + std::to_string(idx_bone);
-        skinRef->jointNames.push_back("joint_" + std::to_string(idx_bone));
+        skinRef->jointNames.push_back(nodeRef);
 
         // Identity Matrix   =====>  skinRef->bindShapeMatrix
         // Temporary. Hard-coded identity matrix here
@@ -456,7 +489,8 @@ void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer
     Ref<Node> meshNode;
     FindMeshNode(rootNode, meshNode, meshRef->id);
 
-    meshNode->skeletons.push_back(mAsset.nodes.Get(aim->mBones[0]->mName.C_Str()));
+    Ref<Node> rootJoint = FindSkeletonRootJoint(skinRef);
+    meshNode->skeletons.push_back(rootJoint);
     meshNode->skin = skinRef;
 }