From 49892c5e83471196b7a3e0afa7be7d2667730e03 Mon Sep 17 00:00:00 2001 From: Par Winzell Date: Fri, 14 Dec 2018 00:05:43 -0800 Subject: [PATCH] Abstract out user property serialisation. --- src/FBX2glTF.cpp | 4 +- src/fbx/Fbx2Raw.cpp | 173 +++++++++++++++++---------------- src/fbx/Fbx2Raw.hpp | 2 + src/fbx/FbxMaterialsAccess.cpp | 93 ++---------------- src/fbx/FbxMaterialsAccess.hpp | 1 + 5 files changed, 103 insertions(+), 170 deletions(-) diff --git a/src/FBX2glTF.cpp b/src/FBX2glTF.cpp index 7f0a205..51eae33 100644 --- a/src/FBX2glTF.cpp +++ b/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(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(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())) { diff --git a/src/fbx/Fbx2Raw.cpp b/src/fbx/Fbx2Raw.cpp index a2678b9..7c7439a 100644 --- a/src/fbx/Fbx2Raw.cpp +++ b/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; + if (nodeId >= 0) { + RawNode &node = raw.GetNode(nodeId); + node.userProperties.push_back(TranscribeProperty(prop).dump()); } - - 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(FBXSDK_TIME_INFINITE); - break; - } - case eFbxULongLong: { - p["value"] = prop.EvaluateValue(FBXSDK_TIME_INFINITE); - break; - } - case eFbxFloat: - case eFbxHalfFloat: - case eFbxDouble: { - p["value"] = prop.EvaluateValue(FBXSDK_TIME_INFINITE); - break; - } - case eFbxDouble2: { - auto v = prop.EvaluateValue(FBXSDK_TIME_INFINITE); - p["value"] = {v[0], v[1]}; - break; - } - case eFbxDouble3: { - auto v = prop.EvaluateValue(FBXSDK_TIME_INFINITE); - p["value"] = {v[0], v[1], v[2]}; - break; - } - case eFbxDouble4: { - auto v = prop.EvaluateValue(FBXSDK_TIME_INFINITE); - p["value"] = {v[0], v[1], v[2], v[3]}; - break; - } - case eFbxString: { - p["value"] = std::string{prop.Get()}; - break; - } - default: { - p["value"] = "UNSUPPORTED_VALUE_TYPE"; - break; - } - } - - 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(FBXSDK_TIME_INFINITE); + break; + } + case eFbxULongLong: { + p["value"] = prop.EvaluateValue(FBXSDK_TIME_INFINITE); + break; + } + case eFbxFloat: + case eFbxHalfFloat: + case eFbxDouble: { + p["value"] = prop.EvaluateValue(FBXSDK_TIME_INFINITE); + break; + } + case eFbxDouble2: { + auto v = prop.EvaluateValue(FBXSDK_TIME_INFINITE); + p["value"] = {v[0], v[1]}; + break; + } + case eFbxDouble3: { + auto v = prop.EvaluateValue(FBXSDK_TIME_INFINITE); + p["value"] = {v[0], v[1], v[2]}; + break; + } + case eFbxDouble4: { + auto v = prop.EvaluateValue(FBXSDK_TIME_INFINITE); + p["value"] = {v[0], v[1], v[2], v[3]}; + break; + } + case eFbxString: { + p["value"] = std::string{prop.Get()}; + break; + } + default: { + p["value"] = "UNSUPPORTED_VALUE_TYPE"; + break; + } + } + + return { + {prop.GetNameAsCStr(), p} + }; +} + diff --git a/src/fbx/Fbx2Raw.hpp b/src/fbx/Fbx2Raw.hpp index 7bb125e..d1ae70c 100644 --- a/src/fbx/Fbx2Raw.hpp +++ b/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); \ No newline at end of file diff --git a/src/fbx/FbxMaterialsAccess.cpp b/src/fbx/FbxMaterialsAccess.cpp index b39381f..13f2c2c 100644 --- a/src/fbx/FbxMaterialsAccess.cpp +++ b/src/fbx/FbxMaterialsAccess.cpp @@ -8,6 +8,7 @@ */ #include "FbxMaterialsAccess.hpp" +#include "Fbx2Raw.hpp" FbxMaterialsAccess::FbxMaterialsAccess(const FbxMesh *pMesh, const std::map &textureLocations) : mappingMode(FbxGeometryElement::eNone), @@ -54,91 +55,13 @@ FbxMaterialsAccess::FbxMaterialsAccess(const FbxMesh *pMesh, const std::mapGetFirstProperty(); - 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(FBXSDK_TIME_INFINITE); - break; - } - case eFbxULongLong: { - p["value"] = objectProperty.EvaluateValue(FBXSDK_TIME_INFINITE); - break; - } - case eFbxFloat: - case eFbxHalfFloat: - case eFbxDouble: { - p["value"] = objectProperty.EvaluateValue(FBXSDK_TIME_INFINITE); - break; - } - case eFbxDouble2: { - auto v = objectProperty.EvaluateValue(FBXSDK_TIME_INFINITE); - p["value"] = { v[0], v[1] }; - break; - } - case eFbxDouble3: { - auto v = objectProperty.EvaluateValue(FBXSDK_TIME_INFINITE); - p["value"] = { v[0], v[1], v[2] }; - break; - } - case eFbxDouble4: { - auto v = objectProperty.EvaluateValue(FBXSDK_TIME_INFINITE); - p["value"] = { v[0], v[1], v[2], v[3] }; - break; - } - case eFbxString: { - p["value"] = std::string{ objectProperty.Get() }; - 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); } } } diff --git a/src/fbx/FbxMaterialsAccess.hpp b/src/fbx/FbxMaterialsAccess.hpp index 69c4aae..229c839 100644 --- a/src/fbx/FbxMaterialsAccess.hpp +++ b/src/fbx/FbxMaterialsAccess.hpp @@ -9,6 +9,7 @@ #pragma once +#include "Fbx2Raw.hpp" #include "FbxMaterialInfo.hpp" #include "FbxTraditionalMaterialInfo.hpp" #include "FbxRoughMetMaterialInfo.hpp"