浏览代码

Abstract out user property serialisation.

Par Winzell 6 年之前
父节点
当前提交
49892c5e83
共有 5 个文件被更改,包括 103 次插入170 次删除
  1. 2 2
      src/FBX2glTF.cpp
  2. 90 83
      src/fbx/Fbx2Raw.cpp
  3. 2 0
      src/fbx/Fbx2Raw.hpp
  4. 8 85
      src/fbx/FbxMaterialsAccess.cpp
  5. 1 0
      src/fbx/FbxMaterialsAccess.hpp

+ 2 - 2
src/FBX2glTF.cpp

@@ -95,7 +95,7 @@ int main(int argc, char *argv[])
                    "khr-materials-unlit", "Use KHR_materials_unlit extension to specify Unlit shader.",
                    cxxopts::value<bool>(gltfOptions.useKHRMatUnlit))
                (
-                   "user-properties", "Transcribe FBX User Properties into glTF node 'extras'.",
+                   "user-properties", "Transcribe FBX User Properties into glTF node and material 'extras'.",
                    cxxopts::value<bool>(gltfOptions.enableUserProperties))
                (
                    "blend-shape-normals", "Include blend shape normals, if reported present by the FBX SDK.",
@@ -233,7 +233,7 @@ int main(int argc, char *argv[])
 
     } else {
         // in gltf mode, we create a folder and write into that
-        outputFolder = fmt::format("{}_out{}", outputFolder.c_str(), (const char)StringUtils::GetPathSeparator());
+        outputFolder = fmt::format("{}_out{}", outputPath.c_str(), (const char)StringUtils::GetPathSeparator());
         modelPath = outputFolder + StringUtils::GetFileNameString(outputPath) + ".gltf";
     }
     if (!FileUtils::CreatePath(modelPath.c_str())) {

+ 90 - 83
src/fbx/Fbx2Raw.cpp

@@ -445,91 +445,11 @@ static void ReadCamera(RawModel &raw, FbxScene *pScene, FbxNode *pNode)
 
 static void ReadNodeProperty(RawModel &raw, FbxNode *pNode, FbxProperty &prop)
 {
-    using fbxsdk::EFbxType;
     int nodeId = raw.GetNodeById(pNode->GetUniqueID());
-    if (nodeId < 0)
-        return;
-
-    std::string ename;
-    // Convert property type
-    switch (prop.GetPropertyDataType().GetType()) {
-        case eFbxBool:      ename = "eFbxBool";      break;
-        case eFbxChar:      ename = "eFbxChar";      break;
-        case eFbxUChar:     ename = "eFbxUChar";     break;
-        case eFbxShort:     ename = "eFbxShort";     break;
-        case eFbxUShort:    ename = "eFbxUShort";    break;
-        case eFbxInt:       ename = "eFbxInt";       break;
-        case eFbxUInt:      ename = "eFbxUint";      break;
-        case eFbxLongLong:  ename = "eFbxLongLong";  break;
-        case eFbxULongLong: ename = "eFbxULongLong"; break;
-        case eFbxFloat:     ename = "eFbxFloat";     break;
-        case eFbxHalfFloat: ename = "eFbxHalfFloat"; break;
-        case eFbxDouble:    ename = "eFbxDouble";    break;
-        case eFbxDouble2:   ename = "eFbxDouble2";   break;
-        case eFbxDouble3:   ename = "eFbxDouble3";   break;
-        case eFbxDouble4:   ename = "eFbxDouble4";   break;
-        case eFbxString:    ename = "eFbxString";    break;
-
-        // Use this as fallback because it does not give very descriptive names
-        default: ename = prop.GetPropertyDataType().GetName(); break;
-    }
-
-    json p;
-    p["type"] = ename;
-
-    // Convert property value
-    switch (prop.GetPropertyDataType().GetType()) {
-        case eFbxBool:
-        case eFbxChar:
-        case eFbxUChar:
-        case eFbxShort:
-        case eFbxUShort:
-        case eFbxInt:
-        case eFbxUInt:
-        case eFbxLongLong: {
-            p["value"] = prop.EvaluateValue<long long>(FBXSDK_TIME_INFINITE);
-            break;
-        }
-        case eFbxULongLong: {
-            p["value"] = prop.EvaluateValue<unsigned long long>(FBXSDK_TIME_INFINITE);
-            break;
-        }
-        case eFbxFloat:
-        case eFbxHalfFloat:
-        case eFbxDouble: {
-            p["value"] = prop.EvaluateValue<double>(FBXSDK_TIME_INFINITE);
-            break;
-        }
-        case eFbxDouble2: {
-            auto v = prop.EvaluateValue<FbxDouble2>(FBXSDK_TIME_INFINITE);
-            p["value"] = {v[0], v[1]};
-            break;
-        }
-        case eFbxDouble3: {
-            auto v = prop.EvaluateValue<FbxDouble3>(FBXSDK_TIME_INFINITE);
-            p["value"] = {v[0], v[1], v[2]};
-            break;
-        }
-        case eFbxDouble4: {
-            auto v = prop.EvaluateValue<FbxDouble4>(FBXSDK_TIME_INFINITE);
-            p["value"] = {v[0], v[1], v[2], v[3]};
-            break;
-        }
-        case eFbxString: {
-            p["value"] = std::string{prop.Get<FbxString>()};
-            break;
-        }
-        default: {
-            p["value"] = "UNSUPPORTED_VALUE_TYPE";
-            break;
-        }
+    if (nodeId >= 0) {
+        RawNode &node = raw.GetNode(nodeId);
+        node.userProperties.push_back(TranscribeProperty(prop).dump());
     }
-
-    json n;
-    n[prop.GetNameAsCStr()] = p;
-
-    RawNode &node = raw.GetNode(nodeId);
-    node.userProperties.push_back(n.dump());
 }
 
 static void ReadNodeAttributes(
@@ -986,3 +906,90 @@ bool LoadFBXFile(RawModel &raw, const char *fbxFileName, const char *textureExte
 
     return true;
 }
+
+// convenience method for describing a property in JSON
+json TranscribeProperty(FbxProperty &prop)
+{
+    using fbxsdk::EFbxType;
+    std::string ename;
+
+    // Convert property type
+    switch (prop.GetPropertyDataType().GetType()) {
+        case eFbxBool:      ename = "eFbxBool";      break;
+        case eFbxChar:      ename = "eFbxChar";      break;
+        case eFbxUChar:     ename = "eFbxUChar";     break;
+        case eFbxShort:     ename = "eFbxShort";     break;
+        case eFbxUShort:    ename = "eFbxUShort";    break;
+        case eFbxInt:       ename = "eFbxInt";       break;
+        case eFbxUInt:      ename = "eFbxUint";      break;
+        case eFbxLongLong:  ename = "eFbxLongLong";  break;
+        case eFbxULongLong: ename = "eFbxULongLong"; break;
+        case eFbxFloat:     ename = "eFbxFloat";     break;
+        case eFbxHalfFloat: ename = "eFbxHalfFloat"; break;
+        case eFbxDouble:    ename = "eFbxDouble";    break;
+        case eFbxDouble2:   ename = "eFbxDouble2";   break;
+        case eFbxDouble3:   ename = "eFbxDouble3";   break;
+        case eFbxDouble4:   ename = "eFbxDouble4";   break;
+        case eFbxString:    ename = "eFbxString";    break;
+
+            // Use this as fallback because it does not give very descriptive names
+        default: ename = prop.GetPropertyDataType().GetName(); break;
+    }
+
+    json p = {
+        {"type", ename}
+    };
+
+    // Convert property value
+    switch (prop.GetPropertyDataType().GetType()) {
+        case eFbxBool:
+        case eFbxChar:
+        case eFbxUChar:
+        case eFbxShort:
+        case eFbxUShort:
+        case eFbxInt:
+        case eFbxUInt:
+        case eFbxLongLong: {
+            p["value"] = prop.EvaluateValue<long long>(FBXSDK_TIME_INFINITE);
+            break;
+        }
+        case eFbxULongLong: {
+            p["value"] = prop.EvaluateValue<unsigned long long>(FBXSDK_TIME_INFINITE);
+            break;
+        }
+        case eFbxFloat:
+        case eFbxHalfFloat:
+        case eFbxDouble: {
+            p["value"] = prop.EvaluateValue<double>(FBXSDK_TIME_INFINITE);
+            break;
+        }
+        case eFbxDouble2: {
+            auto v = prop.EvaluateValue<FbxDouble2>(FBXSDK_TIME_INFINITE);
+            p["value"] = {v[0], v[1]};
+            break;
+        }
+        case eFbxDouble3: {
+            auto v = prop.EvaluateValue<FbxDouble3>(FBXSDK_TIME_INFINITE);
+            p["value"] = {v[0], v[1], v[2]};
+            break;
+        }
+        case eFbxDouble4: {
+            auto v = prop.EvaluateValue<FbxDouble4>(FBXSDK_TIME_INFINITE);
+            p["value"] = {v[0], v[1], v[2], v[3]};
+            break;
+        }
+        case eFbxString: {
+            p["value"] = std::string{prop.Get<FbxString>()};
+            break;
+        }
+        default: {
+            p["value"] = "UNSUPPORTED_VALUE_TYPE";
+            break;
+        }
+    }
+
+    return {
+        {prop.GetNameAsCStr(), p}
+    };
+}
+

+ 2 - 0
src/fbx/Fbx2Raw.hpp

@@ -12,3 +12,5 @@
 #include "raw/RawModel.hpp"
 
 bool LoadFBXFile(RawModel &raw, const char *fbxFileName, const char *textureExtensions);
+
+json TranscribeProperty(FbxProperty &prop);

+ 8 - 85
src/fbx/FbxMaterialsAccess.cpp

@@ -8,6 +8,7 @@
  */
 
 #include "FbxMaterialsAccess.hpp"
+#include "Fbx2Raw.hpp"
 
 FbxMaterialsAccess::FbxMaterialsAccess(const FbxMesh *pMesh, const std::map<const FbxTexture *, FbxString> &textureLocations) :
     mappingMode(FbxGeometryElement::eNone),
@@ -54,91 +55,13 @@ FbxMaterialsAccess::FbxMaterialsAccess(const FbxMesh *pMesh, const std::map<cons
             userProperties.resize(materialNum + 1);
         }
         if (userProperties[materialNum].empty()) {
-            FbxProperty objectProperty = surfaceMaterial->GetFirstProperty();
-            while (objectProperty.IsValid())
-            {
-                if (objectProperty.GetFlag(FbxPropertyFlags::eUserDefined)) {
-                    std::string ename;
-                    switch (objectProperty.GetPropertyDataType().GetType()) {
-                        case eFbxBool:      ename = "eFbxBool";      break;
-                        case eFbxChar:      ename = "eFbxChar";      break;
-                        case eFbxUChar:     ename = "eFbxUChar";     break;
-                        case eFbxShort:     ename = "eFbxShort";     break;
-                        case eFbxUShort:    ename = "eFbxUShort";    break;
-                        case eFbxInt:       ename = "eFbxInt";       break;
-                        case eFbxUInt:      ename = "eFbxUint";      break;
-                        case eFbxLongLong:  ename = "eFbxLongLong";  break;
-                        case eFbxULongLong: ename = "eFbxULongLong"; break;
-                        case eFbxFloat:     ename = "eFbxFloat";     break;
-                        case eFbxHalfFloat: ename = "eFbxHalfFloat"; break;
-                        case eFbxDouble:    ename = "eFbxDouble";    break;
-                        case eFbxDouble2:   ename = "eFbxDouble2";   break;
-                        case eFbxDouble3:   ename = "eFbxDouble3";   break;
-                        case eFbxDouble4:   ename = "eFbxDouble4";   break;
-                        case eFbxString:    ename = "eFbxString";    break;
-
-                        // Use this as fallback because it does not give very descriptive names
-                        default: ename = objectProperty.GetPropertyDataType().GetName(); break;
-                    }
-
-                    json p;
-                    p["type"] = ename;
-
-                    // Convert property value
-                    switch (objectProperty.GetPropertyDataType().GetType()) {
-                        case eFbxBool:
-                        case eFbxChar:
-                        case eFbxUChar:
-                        case eFbxShort:
-                        case eFbxUShort:
-                        case eFbxInt:
-                        case eFbxUInt:
-                        case eFbxLongLong: {
-                            p["value"] = objectProperty.EvaluateValue<long long>(FBXSDK_TIME_INFINITE);
-                            break;
-                        }
-                        case eFbxULongLong: {
-                            p["value"] = objectProperty.EvaluateValue<unsigned long long>(FBXSDK_TIME_INFINITE);
-                            break;
-                        }
-                        case eFbxFloat:
-                        case eFbxHalfFloat:
-                        case eFbxDouble: {
-                            p["value"] = objectProperty.EvaluateValue<double>(FBXSDK_TIME_INFINITE);
-                            break;
-                        }
-                        case eFbxDouble2: {
-                            auto v = objectProperty.EvaluateValue<FbxDouble2>(FBXSDK_TIME_INFINITE);
-                            p["value"] = { v[0], v[1] };
-                            break;
-                        }
-                        case eFbxDouble3: {
-                            auto v = objectProperty.EvaluateValue<FbxDouble3>(FBXSDK_TIME_INFINITE);
-                            p["value"] = { v[0], v[1], v[2] };
-                            break;
-                        }
-                        case eFbxDouble4: {
-                            auto v = objectProperty.EvaluateValue<FbxDouble4>(FBXSDK_TIME_INFINITE);
-                            p["value"] = { v[0], v[1], v[2], v[3] };
-                            break;
-                        }
-                        case eFbxString: {
-                            p["value"] = std::string{ objectProperty.Get<FbxString>() };
-                            break;
-                        }
-                        default: {
-                            p["value"] = "UNSUPPORTED_VALUE_TYPE";
-                            break;
-                        }
-                    }
-
-                    json n;
-                    n[objectProperty.GetNameAsCStr()] = p;
-
-                    userProperties[materialNum].push_back(n.dump());
-                }
-
-                objectProperty = surfaceMaterial->GetNextProperty(objectProperty);
+            FbxProperty objectProperty = surfaceMaterial->GetFirstProperty();
+            while (objectProperty.IsValid())
+            {
+                if (objectProperty.GetFlag(FbxPropertyFlags::eUserDefined)) {
+                    userProperties[materialNum].push_back(TranscribeProperty(objectProperty).dump());
+                }
+                objectProperty = surfaceMaterial->GetNextProperty(objectProperty);
             }
         }
     }

+ 1 - 0
src/fbx/FbxMaterialsAccess.hpp

@@ -9,6 +9,7 @@
 
 #pragma once
 
+#include "Fbx2Raw.hpp"
 #include "FbxMaterialInfo.hpp"
 #include "FbxTraditionalMaterialInfo.hpp"
 #include "FbxRoughMetMaterialInfo.hpp"