Fix duplicate name issues (#51)
Fix the naming issues. Now the nodes are identified by pNode->GetUniqueID(), instead of its name. All dictionaries and references to nodes are replaced by its id, instead of its name.
This commit is contained in:
parent
13367dfc66
commit
a2d5c7d87b
|
@ -424,7 +424,7 @@ public:
|
|||
inverseBindMatrices.emplace_back(globalBindposeInverseMatrix);
|
||||
|
||||
jointNodes.push_back(cluster->GetLink());
|
||||
jointNames.push_back(*cluster->GetLink()->GetName() != '\0' ? cluster->GetLink()->GetName() : cluster->GetName());
|
||||
jointIds.push_back(cluster->GetLink()->GetUniqueID());
|
||||
|
||||
const FbxAMatrix globalNodeTransform = cluster->GetLink()->EvaluateGlobalTransform();
|
||||
jointSkinningTransforms.push_back(FbxMatrix(globalNodeTransform * globalBindposeInverseMatrix));
|
||||
|
@ -486,9 +486,9 @@ public:
|
|||
return jointNodes[jointIndex];
|
||||
}
|
||||
|
||||
const char *GetJointName(const int jointIndex) const
|
||||
const long GetJointId(const int jointIndex) const
|
||||
{
|
||||
return jointNames[jointIndex].c_str();
|
||||
return jointIds[jointIndex];
|
||||
}
|
||||
|
||||
const FbxMatrix &GetJointSkinningTransform(const int jointIndex) const
|
||||
|
@ -501,10 +501,10 @@ public:
|
|||
return jointInverseGlobalTransforms[jointIndex];
|
||||
}
|
||||
|
||||
const char *GetRootNode() const
|
||||
const long GetRootNode() const
|
||||
{
|
||||
assert(rootIndex != -1);
|
||||
return jointNames[rootIndex].c_str();
|
||||
return jointIds[rootIndex];
|
||||
}
|
||||
|
||||
const FbxAMatrix &GetInverseBindMatrix(const int jointIndex) const
|
||||
|
@ -526,7 +526,7 @@ public:
|
|||
|
||||
private:
|
||||
int rootIndex;
|
||||
std::vector<std::string> jointNames;
|
||||
std::vector<long> jointIds;
|
||||
std::vector<FbxNode *> jointNodes;
|
||||
std::vector<FbxMatrix> jointSkinningTransforms;
|
||||
std::vector<FbxMatrix> jointInverseGlobalTransforms;
|
||||
|
@ -697,7 +697,7 @@ static void ReadMesh(RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std:
|
|||
const long surfaceId = pMesh->GetUniqueID();
|
||||
|
||||
// Associate the node to this surface
|
||||
int nodeId = raw.GetNodeByName(pNode->GetName());
|
||||
int nodeId = raw.GetNodeById(pNode->GetUniqueID());
|
||||
if (nodeId >= 0) {
|
||||
RawNode &node = raw.GetNode(nodeId);
|
||||
node.surfaceId = surfaceId;
|
||||
|
@ -725,7 +725,7 @@ static void ReadMesh(RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std:
|
|||
if (verboseOutput) {
|
||||
fmt::printf(
|
||||
"mesh %d: %s (skinned: %s)\n", rawSurfaceIndex, meshName,
|
||||
skinning.IsSkinned() ? skinning.GetRootNode() : "NO");
|
||||
skinning.IsSkinned() ? raw.GetNode(raw.GetNodeById(skinning.GetRootNode())).name.c_str() : "NO");
|
||||
}
|
||||
|
||||
// The FbxNode geometric transformation describes how a FbxNodeAttribute is offset from
|
||||
|
@ -758,12 +758,12 @@ static void ReadMesh(RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std:
|
|||
|
||||
RawSurface &rawSurface = raw.GetSurface(rawSurfaceIndex);
|
||||
|
||||
rawSurface.skeletonRootName = (skinning.IsSkinned()) ? skinning.GetRootNode() : pNode->GetName();
|
||||
rawSurface.skeletonRootId = (skinning.IsSkinned()) ? skinning.GetRootNode() : pNode->GetUniqueID();
|
||||
for (int jointIndex = 0; jointIndex < skinning.GetNodeCount(); jointIndex++) {
|
||||
const char *jointName = skinning.GetJointName(jointIndex);
|
||||
raw.GetNode(raw.GetNodeByName(jointName)).isJoint = true;
|
||||
const long jointId = skinning.GetJointId(jointIndex);
|
||||
raw.GetNode(raw.GetNodeById(jointId)).isJoint = true;
|
||||
|
||||
rawSurface.jointNames.emplace_back(jointName);
|
||||
rawSurface.jointIds.emplace_back(jointId);
|
||||
rawSurface.inverseBindMatrices.push_back(toMat4f(skinning.GetInverseBindMatrix(jointIndex)));
|
||||
rawSurface.jointGeometryMins.emplace_back(FLT_MAX, FLT_MAX, FLT_MAX);
|
||||
rawSurface.jointGeometryMaxs.emplace_back(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
|
@ -988,12 +988,12 @@ static void ReadCamera(RawModel &raw, FbxScene *pScene, FbxNode *pNode)
|
|||
const FbxCamera *pCamera = pNode->GetCamera();
|
||||
if (pCamera->ProjectionType.Get() == FbxCamera::EProjectionType::ePerspective) {
|
||||
raw.AddCameraPerspective(
|
||||
"", pNode->GetName(), (float) pCamera->FilmAspectRatio,
|
||||
"", pNode->GetUniqueID(), (float) pCamera->FilmAspectRatio,
|
||||
(float) pCamera->FieldOfViewX, (float) pCamera->FieldOfViewX,
|
||||
(float) pCamera->NearPlane, (float) pCamera->FarPlane);
|
||||
} else {
|
||||
raw.AddCameraOrthographic(
|
||||
"", pNode->GetName(),
|
||||
"", pNode->GetUniqueID(),
|
||||
(float) pCamera->OrthoZoom, (float) pCamera->OrthoZoom,
|
||||
(float) pCamera->FarPlane, (float) pCamera->NearPlane);
|
||||
}
|
||||
|
@ -1069,10 +1069,11 @@ static FbxVector4 computeLocalScale(FbxNode *pNode, FbxTime pTime = FBXSDK_TIME_
|
|||
|
||||
static void ReadNodeHierarchy(
|
||||
RawModel &raw, FbxScene *pScene, FbxNode *pNode,
|
||||
const std::string &parentName, const std::string &path)
|
||||
const long parentId, const std::string &path)
|
||||
{
|
||||
const FbxUInt64 nodeId = pNode->GetUniqueID();
|
||||
const char *nodeName = pNode->GetName();
|
||||
const int nodeIndex = raw.AddNode(nodeName, parentName.c_str());
|
||||
const int nodeIndex = raw.AddNode(nodeId, nodeName, parentId);
|
||||
RawNode &node = raw.GetNode(nodeIndex);
|
||||
|
||||
FbxTransform::EInheritType lInheritType;
|
||||
|
@ -1085,7 +1086,7 @@ static void ReadNodeHierarchy(
|
|||
|
||||
static int warnRrSsCount = 0;
|
||||
static int warnRrsCount = 0;
|
||||
if (lInheritType == FbxTransform::eInheritRrSs && !parentName.empty()) {
|
||||
if (lInheritType == FbxTransform::eInheritRrSs && parentId) {
|
||||
if (++warnRrSsCount == 1) {
|
||||
fmt::printf("Warning: node %s uses unsupported transform inheritance type 'eInheritRrSs'.\n", newPath);
|
||||
fmt::printf(" (Further warnings of this type squelched.)\n");
|
||||
|
@ -1112,19 +1113,19 @@ static void ReadNodeHierarchy(
|
|||
node.rotation = toQuatf(localRotation);
|
||||
node.scale = toVec3f(localScaling);
|
||||
|
||||
if (parentName.size() > 0) {
|
||||
RawNode &parentNode = raw.GetNode(raw.GetNodeByName(parentName.c_str()));
|
||||
if (parentId) {
|
||||
RawNode &parentNode = raw.GetNode(raw.GetNodeById(parentId));
|
||||
// Add unique child name to the parent node.
|
||||
if (std::find(parentNode.childNames.begin(), parentNode.childNames.end(), nodeName) == parentNode.childNames.end()) {
|
||||
parentNode.childNames.push_back(nodeName);
|
||||
if (std::find(parentNode.childIds.begin(), parentNode.childIds.end(), nodeId) == parentNode.childIds.end()) {
|
||||
parentNode.childIds.push_back(nodeId);
|
||||
}
|
||||
} else {
|
||||
// If there is no parent then this is the root node.
|
||||
raw.SetRootNode(nodeName);
|
||||
raw.SetRootNode(nodeId);
|
||||
}
|
||||
|
||||
for (int child = 0; child < pNode->GetChildCount(); child++) {
|
||||
ReadNodeHierarchy(raw, pScene, pNode->GetChild(child), nodeName, newPath);
|
||||
ReadNodeHierarchy(raw, pScene, pNode->GetChild(child), nodeId, newPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1180,7 +1181,7 @@ static void ReadAnimations(RawModel &raw, FbxScene *pScene)
|
|||
bool hasMorphs = false;
|
||||
|
||||
RawChannel channel;
|
||||
channel.nodeIndex = raw.GetNodeByName(pNode->GetName());
|
||||
channel.nodeIndex = raw.GetNodeById(pNode->GetUniqueID());
|
||||
|
||||
for (FbxLongLong frameIndex = firstFrameIndex; frameIndex <= lastFrameIndex; frameIndex++) {
|
||||
FbxTime pTime;
|
||||
|
@ -1423,7 +1424,7 @@ bool LoadFBXFile(RawModel &raw, const char *fbxFileName, const char *textureExte
|
|||
FbxSystemUnit::m.ConvertScene(pScene);
|
||||
}
|
||||
|
||||
ReadNodeHierarchy(raw, pScene, pScene->GetRootNode(), "", "");
|
||||
ReadNodeHierarchy(raw, pScene, pScene->GetRootNode(), 0, "");
|
||||
ReadNodeAttributes(raw, pScene, pScene->GetRootNode(), textureLocations);
|
||||
ReadAnimations(raw, pScene);
|
||||
|
||||
|
|
|
@ -304,7 +304,7 @@ ModelData *Raw2Gltf(
|
|||
|
||||
std::unique_ptr<GLTFData> gltf(new GLTFData(options.outputBinary));
|
||||
|
||||
std::map<std::string, std::shared_ptr<NodeData>> nodesByName;
|
||||
std::map<long, std::shared_ptr<NodeData>> nodesById;
|
||||
std::map<std::string, std::shared_ptr<MaterialData>> materialsByName;
|
||||
std::map<std::string, std::shared_ptr<TextureData>> textureByIndicesKey;
|
||||
std::map<long, std::shared_ptr<MeshData>> meshBySurfaceId;
|
||||
|
@ -326,13 +326,13 @@ ModelData *Raw2Gltf(
|
|||
auto nodeData = gltf->nodes.hold(
|
||||
new NodeData(node.name, node.translation, node.rotation, node.scale, node.isJoint));
|
||||
|
||||
for (const auto &childName : node.childNames) {
|
||||
int childIx = raw.GetNodeByName(childName.c_str());
|
||||
for (const auto &childId : node.childIds) {
|
||||
int childIx = raw.GetNodeById(childId);
|
||||
assert(childIx >= 0);
|
||||
nodeData->AddChildNode(childIx);
|
||||
}
|
||||
assert(nodesByName.find(nodeData->name) == nodesByName.end());
|
||||
nodesByName.insert(std::make_pair(nodeData->name, nodeData));
|
||||
|
||||
nodesById.insert(std::make_pair(node.id, nodeData));
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -367,7 +367,7 @@ ModelData *Raw2Gltf(
|
|||
channel.scales.size(), channel.weights.size());
|
||||
}
|
||||
|
||||
NodeData &nDat = require(nodesByName, node.name);
|
||||
NodeData &nDat = require(nodesById, node.id);
|
||||
if (!channel.translations.empty()) {
|
||||
aDat.AddNodeChannel(nDat, *gltf->AddAccessorAndView(buffer, GLT_VEC3F, channel.translations), "translation");
|
||||
}
|
||||
|
@ -1081,7 +1081,7 @@ ModelData *Raw2Gltf(
|
|||
//
|
||||
// surface skin
|
||||
//
|
||||
if (!rawSurface.jointNames.empty()) {
|
||||
if (!rawSurface.jointIds.empty()) {
|
||||
if (nodeData->skin == -1) {
|
||||
// glTF uses column-major matrices
|
||||
std::vector<Mat4f> inverseBindMatrices;
|
||||
|
@ -1090,14 +1090,14 @@ ModelData *Raw2Gltf(
|
|||
}
|
||||
|
||||
std::vector<uint32_t> jointIndexes;
|
||||
for (const auto &jointName : rawSurface.jointNames) {
|
||||
jointIndexes.push_back(require(nodesByName, jointName).ix);
|
||||
for (const auto &jointId : rawSurface.jointIds) {
|
||||
jointIndexes.push_back(require(nodesById, jointId).ix);
|
||||
}
|
||||
|
||||
// Write out inverseBindMatrices
|
||||
auto accIBM = gltf->AddAccessorAndView(buffer, GLT_MAT4F, inverseBindMatrices);
|
||||
|
||||
auto skeletonRoot = require(nodesByName, rawSurface.skeletonRootName);
|
||||
auto skeletonRoot = require(nodesById, rawSurface.skeletonRootId);
|
||||
auto skin = *gltf->skins.hold(new SkinData(jointIndexes, *accIBM, skeletonRoot));
|
||||
nodeData->SetSkin(skin.ix);
|
||||
}
|
||||
|
@ -1129,16 +1129,16 @@ ModelData *Raw2Gltf(
|
|||
}
|
||||
// Add the camera to the node hierarchy.
|
||||
|
||||
auto iter = nodesByName.find(cam.nodeName);
|
||||
if (iter == nodesByName.end()) {
|
||||
fmt::printf("Warning: Camera node name %s does not exist.\n", cam.nodeName);
|
||||
auto iter = nodesById.find(cam.nodeId);
|
||||
if (iter == nodesById.end()) {
|
||||
fmt::printf("Warning: Camera node id %s does not exist.\n", cam.nodeId);
|
||||
continue;
|
||||
}
|
||||
iter->second->SetCamera(camera.ix);
|
||||
}
|
||||
}
|
||||
|
||||
NodeData &rootNode = require(nodesByName, "RootNode");
|
||||
NodeData &rootNode = require(nodesById, raw.GetRootNode());
|
||||
const SceneData &rootScene = *gltf->scenes.hold(new SceneData(defaultSceneName, rootNode));
|
||||
|
||||
if (options.outputBinary) {
|
||||
|
|
|
@ -193,8 +193,8 @@ int RawModel::AddAnimation(const RawAnimation &animation)
|
|||
int RawModel::AddNode(const RawNode &node)
|
||||
{
|
||||
for (size_t i = 0; i < nodes.size(); i++) {
|
||||
if (Gltf::StringUtils::CompareNoCase(nodes[i].name.c_str(), node.name) == 0) {
|
||||
return (int) i;
|
||||
if (nodes[i].id == node.id) {
|
||||
return (int)i;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,12 +203,12 @@ int RawModel::AddNode(const RawNode &node)
|
|||
}
|
||||
|
||||
int RawModel::AddCameraPerspective(
|
||||
const char *name, const char *nodeName, const float aspectRatio, const float fovDegreesX, const float fovDegreesY, const float nearZ,
|
||||
const char *name, const long nodeId, const float aspectRatio, const float fovDegreesX, const float fovDegreesY, const float nearZ,
|
||||
const float farZ)
|
||||
{
|
||||
RawCamera camera;
|
||||
camera.name = name;
|
||||
camera.nodeName = nodeName;
|
||||
camera.nodeId = nodeId;
|
||||
camera.mode = RawCamera::CAMERA_MODE_PERSPECTIVE;
|
||||
camera.perspective.aspectRatio = aspectRatio;
|
||||
camera.perspective.fovDegreesX = fovDegreesX;
|
||||
|
@ -220,11 +220,11 @@ int RawModel::AddCameraPerspective(
|
|||
}
|
||||
|
||||
int RawModel::AddCameraOrthographic(
|
||||
const char *name, const char *nodeName, const float magX, const float magY, const float nearZ, const float farZ)
|
||||
const char *name, const long nodeId, const float magX, const float magY, const float nearZ, const float farZ)
|
||||
{
|
||||
RawCamera camera;
|
||||
camera.name = name;
|
||||
camera.nodeName = nodeName;
|
||||
camera.nodeId = nodeId;
|
||||
camera.mode = RawCamera::CAMERA_MODE_ORTHOGRAPHIC;
|
||||
camera.orthographic.magX = magX;
|
||||
camera.orthographic.magY = magY;
|
||||
|
@ -234,20 +234,21 @@ int RawModel::AddCameraOrthographic(
|
|||
return (int) cameras.size() - 1;
|
||||
}
|
||||
|
||||
int RawModel::AddNode(const char *name, const char *parentName)
|
||||
int RawModel::AddNode(const long id, const char *name, const long parentId)
|
||||
{
|
||||
assert(name[0] != '\0');
|
||||
|
||||
for (size_t i = 0; i < nodes.size(); i++) {
|
||||
if (Gltf::StringUtils::CompareNoCase(nodes[i].name, name) == 0) {
|
||||
if (nodes[i].id == id ) {
|
||||
return (int) i;
|
||||
}
|
||||
}
|
||||
|
||||
RawNode joint;
|
||||
joint.isJoint = false;
|
||||
joint.id = id;
|
||||
joint.name = name;
|
||||
joint.parentName = parentName;
|
||||
joint.parentId = parentId;
|
||||
joint.surfaceId = 0;
|
||||
joint.translation = Vec3f(0, 0, 0);
|
||||
joint.rotation = Quatf(0, 0, 0, 1);
|
||||
|
@ -455,9 +456,9 @@ void RawModel::CreateMaterialModels(
|
|||
RawSurface &rawSurface = model->GetSurface(surfaceIndex);
|
||||
|
||||
if (model->GetSurfaceCount() > prevSurfaceCount) {
|
||||
const std::vector<std::string> &jointNames = surfaces[sortedTriangles[i].surfaceIndex].jointNames;
|
||||
for (const auto &jointName : jointNames) {
|
||||
const int nodeIndex = GetNodeByName(jointName.c_str());
|
||||
const std::vector<long> &jointIds = surfaces[sortedTriangles[i].surfaceIndex].jointIds;
|
||||
for (const auto &jointId : jointIds) {
|
||||
const int nodeIndex = GetNodeById(jointId);
|
||||
assert(nodeIndex != -1);
|
||||
model->AddNode(GetNode(nodeIndex));
|
||||
}
|
||||
|
@ -515,10 +516,10 @@ void RawModel::CreateMaterialModels(
|
|||
}
|
||||
}
|
||||
|
||||
int RawModel::GetNodeByName(const char *name) const
|
||||
int RawModel::GetNodeById(const long nodeId) const
|
||||
{
|
||||
for (size_t i = 0; i < nodes.size(); i++) {
|
||||
if (nodes[i].name == name) {
|
||||
if (nodes[i].id == nodeId) {
|
||||
return (int) i;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -277,9 +277,9 @@ struct RawSurface
|
|||
{
|
||||
long id;
|
||||
std::string name; // The name of this surface
|
||||
std::string skeletonRootName; // The name of the root of the skeleton.
|
||||
long skeletonRootId; // The id of the root node of the skeleton.
|
||||
Bounds<float, 3> bounds;
|
||||
std::vector<std::string> jointNames;
|
||||
std::vector<long> jointIds;
|
||||
std::vector<Vec3f> jointGeometryMins;
|
||||
std::vector<Vec3f> jointGeometryMaxs;
|
||||
std::vector<Mat4f> inverseBindMatrices;
|
||||
|
@ -306,7 +306,7 @@ struct RawAnimation
|
|||
struct RawCamera
|
||||
{
|
||||
std::string name;
|
||||
std::string nodeName;
|
||||
long nodeId;
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -335,9 +335,10 @@ struct RawCamera
|
|||
struct RawNode
|
||||
{
|
||||
bool isJoint;
|
||||
long id;
|
||||
std::string name;
|
||||
std::string parentName;
|
||||
std::vector<std::string> childNames;
|
||||
long parentId;
|
||||
std::vector<long> childIds;
|
||||
Vec3f translation;
|
||||
Quatf rotation;
|
||||
Vec3f scale;
|
||||
|
@ -362,14 +363,14 @@ public:
|
|||
int AddSurface(const char *name, long surfaceId);
|
||||
int AddAnimation(const RawAnimation &animation);
|
||||
int AddCameraPerspective(
|
||||
const char *name, const char *nodeName, const float aspectRatio, const float fovDegreesX, const float fovDegreesY,
|
||||
const char *name, const long nodeId, const float aspectRatio, const float fovDegreesX, const float fovDegreesY,
|
||||
const float nearZ, const float farZ);
|
||||
int
|
||||
AddCameraOrthographic(const char *name, const char *nodeName, const float magX, const float magY, const float nearZ, const float farZ);
|
||||
AddCameraOrthographic(const char *name, const long nodeId, const float magX, const float magY, const float nearZ, const float farZ);
|
||||
int AddNode(const RawNode &node);
|
||||
int AddNode(const char *name, const char *parentName);
|
||||
void SetRootNode(const char *name) { rootNodeName = name; }
|
||||
const char *GetRootNode() const { return rootNodeName.c_str(); }
|
||||
int AddNode(const long id, const char *name, const long parentId);
|
||||
void SetRootNode(const long nodeId) { rootNodeId = nodeId; }
|
||||
const long GetRootNode() const { return rootNodeId; }
|
||||
|
||||
// Remove unused vertices, textures or materials after removing vertex attributes, textures, materials or surfaces.
|
||||
void Condense();
|
||||
|
@ -413,7 +414,7 @@ public:
|
|||
int GetNodeCount() const { return (int) nodes.size(); }
|
||||
const RawNode &GetNode(const int index) const { return nodes[index]; }
|
||||
RawNode &GetNode(const int index) { return nodes[index]; }
|
||||
int GetNodeByName(const char *name) const;
|
||||
int GetNodeById(const long nodeId) const;
|
||||
|
||||
// Create individual attribute arrays.
|
||||
// Returns true if the vertices store the particular attribute.
|
||||
|
@ -427,7 +428,7 @@ public:
|
|||
std::vector<RawModel> &materialModels, const int maxModelVertices, const int keepAttribs, const bool forceDiscrete) const;
|
||||
|
||||
private:
|
||||
std::string rootNodeName;
|
||||
long rootNodeId;
|
||||
int vertexAttributes;
|
||||
std::unordered_map<RawVertex, int, VertexHasher> vertexHash;
|
||||
std::vector<RawVertex> vertices;
|
||||
|
|
Loading…
Reference in New Issue