Transcribe FBX Custom Properties
This commit is contained in:
parent
f646be2e47
commit
2e03a3cdea
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue