瀏覽代碼

Merge pull request #41 from lyuma/preserve_skeletons

Preserve skeletons which do not contain a mesh
K. S. Ernest (iFire) Lee 2 年之前
父節點
當前提交
6304faddf9
共有 6 個文件被更改,包括 59 次插入8 次删除
  1. 13 4
      src/fbx/Fbx2Raw.cpp
  2. 12 0
      src/gltf/Raw2Gltf.cpp
  3. 14 1
      src/gltf/properties/SkinData.cpp
  4. 5 0
      src/gltf/properties/SkinData.hpp
  5. 3 2
      src/raw/RawModel.cpp
  6. 12 1
      src/raw/RawModel.hpp

+ 13 - 4
src/fbx/Fbx2Raw.cpp

@@ -688,10 +688,19 @@ static void ReadNodeHierarchy(
     FbxScene* pScene,
     FbxScene* pScene,
     FbxNode* pNode,
     FbxNode* pNode,
     const long parentId,
     const long parentId,
-    const std::string& path) {
+    const std::string& path,
+    int extraSkinIx) {
   const FbxUInt64 nodeId = pNode->GetUniqueID();
   const FbxUInt64 nodeId = pNode->GetUniqueID();
   const char* nodeName = pNode->GetName();
   const char* nodeName = pNode->GetName();
-  const int nodeIndex = raw.AddNode(nodeId, nodeName, parentId);
+  FbxSkeleton *skel = pNode->GetSkeleton();
+  if (skel == nullptr) {
+    extraSkinIx = -1;
+  } else {
+    if (skel->IsSkeletonRoot()) {
+      extraSkinIx = raw.CreateExtraSkinIndex();
+    }
+  }
+  const int nodeIndex = raw.AddNode(nodeId, nodeName, parentId, extraSkinIx);
   RawNode& node = raw.GetNode(nodeIndex);
   RawNode& node = raw.GetNode(nodeIndex);
 
 
   FbxTransform::EInheritType lInheritType;
   FbxTransform::EInheritType lInheritType;
@@ -745,7 +754,7 @@ static void ReadNodeHierarchy(
     raw.SetRootNode(nodeId);
     raw.SetRootNode(nodeId);
   }
   }
   for (int child = 0; child < pNode->GetChildCount(); child++) {
   for (int child = 0; child < pNode->GetChildCount(); child++) {
-    ReadNodeHierarchy(raw, pScene, pNode->GetChild(child), nodeId, newPath);
+    ReadNodeHierarchy(raw, pScene, pNode->GetChild(child), nodeId, newPath, extraSkinIx);
   }
   }
 }
 }
 
 
@@ -1174,7 +1183,7 @@ bool LoadFBXFile(
   // this is always 0.01, but let's opt for clarity.
   // this is always 0.01, but let's opt for clarity.
   scaleFactor = FbxSystemUnit::m.GetConversionFactorFrom(FbxSystemUnit::cm);
   scaleFactor = FbxSystemUnit::m.GetConversionFactorFrom(FbxSystemUnit::cm);
 
 
-  ReadNodeHierarchy(raw, pScene, pScene->GetRootNode(), 0, "");
+  ReadNodeHierarchy(raw, pScene, pScene->GetRootNode(), 0, "", -1);
   ReadNodeAttributes(raw, pScene, pScene->GetRootNode(), textureLocations);
   ReadNodeAttributes(raw, pScene, pScene->GetRootNode(), textureLocations);
   ReadAnimations(raw, pScene, options);
   ReadAnimations(raw, pScene, options);
 
 

+ 12 - 0
src/gltf/Raw2Gltf.cpp

@@ -853,6 +853,18 @@ ModelData* Raw2Gltf(
       }
       }
     }
     }
 
 
+    std::vector<std::vector<uint32_t>> extraJointIndexes;
+    extraJointIndexes.resize(raw.GetExtraSkinCount());
+    for (int i = 0; i < raw.GetNodeCount(); i++) {
+      const RawNode& node = raw.GetNode(i);
+      if (node.extraSkinIx >= 0) {
+        extraJointIndexes[node.extraSkinIx].push_back(i);
+      }
+    }
+    for (int i = 0; i < extraJointIndexes.size(); i++) {
+      gltf->skins.hold(new SkinData(extraJointIndexes[i], true));
+    }
+
     //
     //
     // cameras
     // cameras
     //
     //

+ 14 - 1
src/gltf/properties/SkinData.cpp

@@ -18,9 +18,22 @@ SkinData::SkinData(
     : Holdable(),
     : Holdable(),
       joints(joints),
       joints(joints),
       inverseBindMatrices(inverseBindMatricesAccessor.ix),
       inverseBindMatrices(inverseBindMatricesAccessor.ix),
-      skeletonRootNode(skeletonRootNode.ix) {}
+      skeletonRootNode(skeletonRootNode.ix),
+      isExtraSkin(false) {}
+
+SkinData::SkinData(
+    const std::vector<uint32_t> joints,
+    bool isExtraSkin)
+    : Holdable(),
+      joints(joints),
+      inverseBindMatrices(0),
+      skeletonRootNode(0),
+      isExtraSkin(true) {}
 
 
 json SkinData::serialize() const {
 json SkinData::serialize() const {
+  if (isExtraSkin) {
+    return {{"joints", joints}};
+  }
   return {
   return {
       {"joints", joints},
       {"joints", joints},
       {"inverseBindMatrices", inverseBindMatrices},
       {"inverseBindMatrices", inverseBindMatrices},

+ 5 - 0
src/gltf/properties/SkinData.hpp

@@ -16,9 +16,14 @@ struct SkinData : Holdable {
       const AccessorData& inverseBindMatricesAccessor,
       const AccessorData& inverseBindMatricesAccessor,
       const NodeData& skeletonRootNode);
       const NodeData& skeletonRootNode);
 
 
+  SkinData(
+      const std::vector<uint32_t> joints,
+      bool isExtraSkin);
+
   json serialize() const override;
   json serialize() const override;
 
 
   const std::vector<uint32_t> joints;
   const std::vector<uint32_t> joints;
   const uint32_t skeletonRootNode;
   const uint32_t skeletonRootNode;
   const uint32_t inverseBindMatrices;
   const uint32_t inverseBindMatrices;
+  const bool isExtraSkin;
 };
 };

+ 3 - 2
src/raw/RawModel.cpp

@@ -69,7 +69,7 @@ size_t RawVertex::Difference(const RawVertex& other) const {
   return attributes;
   return attributes;
 }
 }
 
 
-RawModel::RawModel() : vertexAttributes(0) {}
+RawModel::RawModel() : nextExtraSkinIx(0), rootNodeId(0), vertexAttributes(0), globalMaxWeights(0) {}
 
 
 void RawModel::AddVertexAttribute(const RawVertexAttribute attrib) {
 void RawModel::AddVertexAttribute(const RawVertexAttribute attrib) {
   vertexAttributes |= attrib;
   vertexAttributes |= attrib;
@@ -311,7 +311,7 @@ int RawModel::AddCameraOrthographic(
   return (int)cameras.size() - 1;
   return (int)cameras.size() - 1;
 }
 }
 
 
-int RawModel::AddNode(const long id, const char* name, const long parentId) {
+int RawModel::AddNode(const long id, const char* name, const long parentId, const int extraSkinIx) {
   assert(name[0] != '\0');
   assert(name[0] != '\0');
 
 
   for (size_t i = 0; i < nodes.size(); i++) {
   for (size_t i = 0; i < nodes.size(); i++) {
@@ -330,6 +330,7 @@ int RawModel::AddNode(const long id, const char* name, const long parentId) {
   joint.translation = Vec3f(0, 0, 0);
   joint.translation = Vec3f(0, 0, 0);
   joint.rotation = Quatf(0, 0, 0, 1);
   joint.rotation = Quatf(0, 0, 0, 1);
   joint.scale = Vec3f(1, 1, 1);
   joint.scale = Vec3f(1, 1, 1);
+  joint.extraSkinIx = extraSkinIx;
 
 
   nodes.emplace_back(joint);
   nodes.emplace_back(joint);
   return (int)nodes.size() - 1;
   return (int)nodes.size() - 1;

+ 12 - 1
src/raw/RawModel.hpp

@@ -355,6 +355,7 @@ struct RawNode {
   long surfaceId;
   long surfaceId;
   long lightIx;
   long lightIx;
   std::vector<std::string> userProperties;
   std::vector<std::string> userProperties;
+  int extraSkinIx;
 };
 };
 
 
 class RawModel {
 class RawModel {
@@ -410,7 +411,7 @@ class RawModel {
       const float nearZ,
       const float nearZ,
       const float farZ);
       const float farZ);
   int AddNode(const RawNode& node);
   int AddNode(const RawNode& node);
-  int AddNode(const long id, const char* name, const long parentId);
+  int AddNode(const long id, const char* name, const long parentId, const int extraSkinIx);
   void SetRootNode(const long nodeId) {
   void SetRootNode(const long nodeId) {
     rootNodeId = nodeId;
     rootNodeId = nodeId;
   }
   }
@@ -541,9 +542,19 @@ class RawModel {
       const int keepAttribs,
       const int keepAttribs,
       const bool forceDiscrete) const;
       const bool forceDiscrete) const;
 
 
+  int CreateExtraSkinIndex() {
+    int ret = nextExtraSkinIx;
+    nextExtraSkinIx++;
+    return ret;
+  }
+  int GetExtraSkinCount() const {
+    return nextExtraSkinIx;
+  }
+
  private:
  private:
   Vec3f getFaceNormal(int verts[3]) const;
   Vec3f getFaceNormal(int verts[3]) const;
 
 
+  int nextExtraSkinIx;
   long rootNodeId;
   long rootNodeId;
   int vertexAttributes;
   int vertexAttributes;
   int globalMaxWeights;
   int globalMaxWeights;