Abstract out user property serialisation.
This commit is contained in:
parent
f2cb6a1010
commit
49892c5e83
|
@ -95,7 +95,7 @@ int main(int argc, char *argv[])
|
||||||
"khr-materials-unlit", "Use KHR_materials_unlit extension to specify Unlit shader.",
|
"khr-materials-unlit", "Use KHR_materials_unlit extension to specify Unlit shader.",
|
||||||
cxxopts::value<bool>(gltfOptions.useKHRMatUnlit))
|
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))
|
cxxopts::value<bool>(gltfOptions.enableUserProperties))
|
||||||
(
|
(
|
||||||
"blend-shape-normals", "Include blend shape normals, if reported present by the FBX SDK.",
|
"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 {
|
} else {
|
||||||
// in gltf mode, we create a folder and write into that
|
// 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";
|
modelPath = outputFolder + StringUtils::GetFileNameString(outputPath) + ".gltf";
|
||||||
}
|
}
|
||||||
if (!FileUtils::CreatePath(modelPath.c_str())) {
|
if (!FileUtils::CreatePath(modelPath.c_str())) {
|
||||||
|
|
|
@ -445,91 +445,11 @@ static void ReadCamera(RawModel &raw, FbxScene *pScene, FbxNode *pNode)
|
||||||
|
|
||||||
static void ReadNodeProperty(RawModel &raw, FbxNode *pNode, FbxProperty &prop)
|
static void ReadNodeProperty(RawModel &raw, FbxNode *pNode, FbxProperty &prop)
|
||||||
{
|
{
|
||||||
using fbxsdk::EFbxType;
|
|
||||||
int nodeId = raw.GetNodeById(pNode->GetUniqueID());
|
int nodeId = raw.GetNodeById(pNode->GetUniqueID());
|
||||||
if (nodeId < 0)
|
if (nodeId >= 0) {
|
||||||
return;
|
RawNode &node = raw.GetNode(nodeId);
|
||||||
|
node.userProperties.push_back(TranscribeProperty(prop).dump());
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
json n;
|
|
||||||
n[prop.GetNameAsCStr()] = p;
|
|
||||||
|
|
||||||
RawNode &node = raw.GetNode(nodeId);
|
|
||||||
node.userProperties.push_back(n.dump());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReadNodeAttributes(
|
static void ReadNodeAttributes(
|
||||||
|
@ -986,3 +906,90 @@ bool LoadFBXFile(RawModel &raw, const char *fbxFileName, const char *textureExte
|
||||||
|
|
||||||
return true;
|
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}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,3 +12,5 @@
|
||||||
#include "raw/RawModel.hpp"
|
#include "raw/RawModel.hpp"
|
||||||
|
|
||||||
bool LoadFBXFile(RawModel &raw, const char *fbxFileName, const char *textureExtensions);
|
bool LoadFBXFile(RawModel &raw, const char *fbxFileName, const char *textureExtensions);
|
||||||
|
|
||||||
|
json TranscribeProperty(FbxProperty &prop);
|
|
@ -8,6 +8,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FbxMaterialsAccess.hpp"
|
#include "FbxMaterialsAccess.hpp"
|
||||||
|
#include "Fbx2Raw.hpp"
|
||||||
|
|
||||||
FbxMaterialsAccess::FbxMaterialsAccess(const FbxMesh *pMesh, const std::map<const FbxTexture *, FbxString> &textureLocations) :
|
FbxMaterialsAccess::FbxMaterialsAccess(const FbxMesh *pMesh, const std::map<const FbxTexture *, FbxString> &textureLocations) :
|
||||||
mappingMode(FbxGeometryElement::eNone),
|
mappingMode(FbxGeometryElement::eNone),
|
||||||
|
@ -54,91 +55,13 @@ FbxMaterialsAccess::FbxMaterialsAccess(const FbxMesh *pMesh, const std::map<cons
|
||||||
userProperties.resize(materialNum + 1);
|
userProperties.resize(materialNum + 1);
|
||||||
}
|
}
|
||||||
if (userProperties[materialNum].empty()) {
|
if (userProperties[materialNum].empty()) {
|
||||||
FbxProperty objectProperty = surfaceMaterial->GetFirstProperty();
|
FbxProperty objectProperty = surfaceMaterial->GetFirstProperty();
|
||||||
while (objectProperty.IsValid())
|
while (objectProperty.IsValid())
|
||||||
{
|
{
|
||||||
if (objectProperty.GetFlag(FbxPropertyFlags::eUserDefined)) {
|
if (objectProperty.GetFlag(FbxPropertyFlags::eUserDefined)) {
|
||||||
std::string ename;
|
userProperties[materialNum].push_back(TranscribeProperty(objectProperty).dump());
|
||||||
switch (objectProperty.GetPropertyDataType().GetType()) {
|
}
|
||||||
case eFbxBool: ename = "eFbxBool"; break;
|
objectProperty = surfaceMaterial->GetNextProperty(objectProperty);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Fbx2Raw.hpp"
|
||||||
#include "FbxMaterialInfo.hpp"
|
#include "FbxMaterialInfo.hpp"
|
||||||
#include "FbxTraditionalMaterialInfo.hpp"
|
#include "FbxTraditionalMaterialInfo.hpp"
|
||||||
#include "FbxRoughMetMaterialInfo.hpp"
|
#include "FbxRoughMetMaterialInfo.hpp"
|
||||||
|
|
Loading…
Reference in New Issue