diff --git a/code/glTFAsset.h b/code/glTFAsset.h index 4d9593814..247dfd148 100644 --- a/code/glTFAsset.h +++ b/code/glTFAsset.h @@ -852,7 +852,7 @@ namespace glTF { Nullable bindShapeMatrix; //!< Floating-point 4x4 transformation matrix stored in column-major order. Ref inverseBindMatrices; //!< The ID of the accessor containing the floating-point 4x4 inverse-bind matrices. - std::vector*/> jointNames; //!< Joint names of the joints (nodes with a jointName property) in this skin. + std::vector> 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() {} diff --git a/code/glTFAssetWriter.inl b/code/glTFAssetWriter.inl index 544345587..312213096 100644 --- a/code/glTFAssetWriter.inl +++ b/code/glTFAssetWriter.inl @@ -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); diff --git a/code/glTFExporter.cpp b/code/glTFExporter.cpp index b70d0816b..90c74f30e 100644 --- a/code/glTFExporter.cpp +++ b/code/glTFExporter.cpp @@ -389,6 +389,39 @@ bool FindMeshNode(Ref& nodeIn, Ref& meshNode, std::string meshID) return false; } +/* + * Find the root joint of the skeleton. + */ +Ref FindSkeletonRootJoint(Ref& skinRef) +{ + Ref candidateNodeRef; + Ref 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& meshRef, Ref& bufferRef) { std::string skinName = aim->mName.C_Str(); @@ -417,7 +450,7 @@ void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref& meshRef, Ref 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& meshRef, Ref meshNode; FindMeshNode(rootNode, meshNode, meshRef->id); - meshNode->skeletons.push_back(mAsset.nodes.Get(aim->mBones[0]->mName.C_Str())); + Ref rootJoint = FindSkeletonRootJoint(skinRef); + meshNode->skeletons.push_back(rootJoint); meshNode->skin = skinRef; }