Transcribe FBX Custom Properties

This commit is contained in:
Michael Ranieri 2018-10-12 12:14:03 -07:00 committed by Pär Winzell
parent f646be2e47
commit 2e03a3cdea
5 changed files with 117 additions and 1 deletions

View File

@ -19,7 +19,7 @@
#include <cassert> #include <cassert>
#include <cmath> #include <cmath>
#include "FBX2glTF.h" #include "gltf/Raw2Gltf.hpp"
#include "utils/File_Utils.hpp" #include "utils/File_Utils.hpp"
#include "utils/String_Utils.hpp" #include "utils/String_Utils.hpp"
@ -382,6 +382,95 @@ 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;
}
}
json n;
n[prop.GetNameAsCStr()] = p;
RawNode &node = raw.GetNode(nodeId);
node.userProperties.push_back(n.dump());
}
static void ReadNodeAttributes( static void ReadNodeAttributes(
RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std::map<const FbxTexture *, FbxString> &textureLocations) RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std::map<const FbxTexture *, FbxString> &textureLocations)
{ {
@ -389,6 +478,17 @@ static void ReadNodeAttributes(
return; return;
} }
// Only support non-animated user defined properties for now
FbxProperty objectProperty = pNode->GetFirstProperty();
while (objectProperty.IsValid())
{
if (objectProperty.GetFlag(FbxPropertyFlags::eUserDefined)) {
ReadNodeProperty(raw, pNode, objectProperty);
}
objectProperty = pNode->GetNextProperty(objectProperty);
}
FbxNodeAttribute *pNodeAttribute = pNode->GetNodeAttribute(); FbxNodeAttribute *pNodeAttribute = pNode->GetNodeAttribute();
if (pNodeAttribute != nullptr) { if (pNodeAttribute != nullptr) {
const FbxNodeAttribute::EType attributeType = pNodeAttribute->GetAttributeType(); const FbxNodeAttribute::EType attributeType = pNodeAttribute->GetAttributeType();

View File

@ -335,6 +335,8 @@ ModelData *Raw2Gltf(
auto nodeData = gltf->nodes.hold( auto nodeData = gltf->nodes.hold(
new NodeData(node.name, node.translation, node.rotation, node.scale, node.isJoint)); new NodeData(node.name, node.translation, node.rotation, node.scale, node.isJoint));
nodeData->userProperties = node.userProperties;
for (const auto &childId : node.childIds) { for (const auto &childId : node.childIds) {
int childIx = raw.GetNodeById(childId); int childIx = raw.GetNodeById(childId);
assert(childIx >= 0); assert(childIx >= 0);

View File

@ -85,5 +85,17 @@ json NodeData::serialize() const
result["camera"] = camera; result["camera"] = camera;
} }
} }
for (const auto& i : userProperties)
{
auto& prop_map = result["extras"]["fromFBX"]["userProperties"];
json j = json::parse(i);
for (const auto& k : json::iterator_wrapper(j))
{
prop_map[k.key()] = k.value();
}
}
return result; return result;
} }

View File

@ -32,4 +32,5 @@ struct NodeData : Holdable
int32_t camera; int32_t camera;
int32_t skin; int32_t skin;
std::vector<std::string> skeletons; std::vector<std::string> skeletons;
std::vector<std::string> userProperties;
}; };

View File

@ -404,6 +404,7 @@ struct RawNode
Quatf rotation; Quatf rotation;
Vec3f scale; Vec3f scale;
long surfaceId; long surfaceId;
std::vector<std::string> userProperties;
}; };
class RawModel class RawModel