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:
David Ávila 2017-12-06 19:43:18 +01:00 committed by Pär Winzell
parent 13367dfc66
commit a2d5c7d87b
4 changed files with 68 additions and 65 deletions

View File

@ -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);

View File

@ -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) {

View File

@ -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;
}
}

View File

@ -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;