|
@@ -86,7 +86,6 @@ namespace Assimp {
|
|
|
, textures_converted()
|
|
|
, meshes_converted()
|
|
|
, node_anim_chain_bits()
|
|
|
- , mNodeNameInstances()
|
|
|
, mNodeNames()
|
|
|
, anim_fps()
|
|
|
, out(out)
|
|
@@ -142,12 +141,46 @@ namespace Assimp {
|
|
|
|
|
|
void FBXConverter::ConvertRootNode() {
|
|
|
out->mRootNode = new aiNode();
|
|
|
- out->mRootNode->mName.Set("RootNode");
|
|
|
+ std::string unique_name;
|
|
|
+ GetUniqueName("RootNode", unique_name);
|
|
|
+ out->mRootNode->mName.Set(unique_name);
|
|
|
|
|
|
// root has ID 0
|
|
|
ConvertNodes(0L, *out->mRootNode);
|
|
|
}
|
|
|
|
|
|
+ static std::string getAncestorBaseName(const aiNode* node)
|
|
|
+ {
|
|
|
+ const char* nodeName = nullptr;
|
|
|
+ size_t length = 0;
|
|
|
+ while (node && (!nodeName || length == 0))
|
|
|
+ {
|
|
|
+ nodeName = node->mName.C_Str();
|
|
|
+ length = node->mName.length;
|
|
|
+ node = node->mParent;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!nodeName || length == 0)
|
|
|
+ {
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ // could be std::string_view if c++17 available
|
|
|
+ return std::string(nodeName, length);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Make unique name
|
|
|
+ std::string FBXConverter::MakeUniqueNodeName(const Model* const model, const aiNode& parent)
|
|
|
+ {
|
|
|
+ std::string original_name = FixNodeName(model->Name());
|
|
|
+ if (original_name.empty())
|
|
|
+ {
|
|
|
+ original_name = getAncestorBaseName(&parent);
|
|
|
+ }
|
|
|
+ std::string unique_name;
|
|
|
+ GetUniqueName(original_name, unique_name);
|
|
|
+ return unique_name;
|
|
|
+ }
|
|
|
+
|
|
|
void FBXConverter::ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform) {
|
|
|
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
|
|
|
|
|
@@ -179,35 +212,18 @@ namespace Assimp {
|
|
|
|
|
|
aiMatrix4x4 new_abs_transform = parent_transform;
|
|
|
|
|
|
+ std::string unique_name = MakeUniqueNodeName(model, parent);
|
|
|
+
|
|
|
// even though there is only a single input node, the design of
|
|
|
// assimp (or rather: the complicated transformation chain that
|
|
|
// is employed by fbx) means that we may need multiple aiNode's
|
|
|
// to represent a fbx node's transformation.
|
|
|
- GenerateTransformationNodeChain(*model, nodes_chain, post_nodes_chain);
|
|
|
+ const bool need_additional_node = GenerateTransformationNodeChain(*model, unique_name, nodes_chain, post_nodes_chain);
|
|
|
|
|
|
ai_assert(nodes_chain.size());
|
|
|
|
|
|
- std::string original_name = FixNodeName(model->Name());
|
|
|
-
|
|
|
- // check if any of the nodes in the chain has the name the fbx node
|
|
|
- // is supposed to have. If there is none, add another node to
|
|
|
- // preserve the name - people might have scripts etc. that rely
|
|
|
- // on specific node names.
|
|
|
- aiNode* name_carrier = NULL;
|
|
|
- for (aiNode* prenode : nodes_chain) {
|
|
|
- if (!strcmp(prenode->mName.C_Str(), original_name.c_str())) {
|
|
|
- name_carrier = prenode;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!name_carrier) {
|
|
|
- std::string old_original_name = original_name;
|
|
|
- GetUniqueName(old_original_name, original_name);
|
|
|
- nodes_chain.push_back(new aiNode(original_name));
|
|
|
- }
|
|
|
- else {
|
|
|
- original_name = nodes_chain.back()->mName.C_Str();
|
|
|
+ if (need_additional_node) {
|
|
|
+ nodes_chain.push_back(new aiNode(unique_name));
|
|
|
}
|
|
|
|
|
|
//setup metadata on newest node
|
|
@@ -269,11 +285,11 @@ namespace Assimp {
|
|
|
ConvertNodes(model->ID(), *last_parent, new_abs_transform);
|
|
|
|
|
|
if (doc.Settings().readLights) {
|
|
|
- ConvertLights(*model, original_name);
|
|
|
+ ConvertLights(*model, unique_name);
|
|
|
}
|
|
|
|
|
|
if (doc.Settings().readCameras) {
|
|
|
- ConvertCameras(*model, original_name);
|
|
|
+ ConvertCameras(*model, unique_name);
|
|
|
}
|
|
|
|
|
|
nodes.push_back(nodes_chain.front());
|
|
@@ -426,21 +442,16 @@ namespace Assimp {
|
|
|
void FBXConverter::GetUniqueName(const std::string &name, std::string &uniqueName)
|
|
|
{
|
|
|
uniqueName = name;
|
|
|
- int i = 0;
|
|
|
- auto it = mNodeNameInstances.find(name); // duplicate node name instance count
|
|
|
- if (it != mNodeNameInstances.end())
|
|
|
+ auto it_pair = mNodeNames.insert({ name, 0 }); // duplicate node name instance count
|
|
|
+ unsigned int& i = it_pair.first->second;
|
|
|
+ while (!it_pair.second)
|
|
|
{
|
|
|
- i = it->second;
|
|
|
- while (mNodeNames.find(uniqueName) != mNodeNames.end())
|
|
|
- {
|
|
|
- i++;
|
|
|
- std::stringstream ext;
|
|
|
- ext << name << std::setfill('0') << std::setw(3) << i;
|
|
|
- uniqueName = ext.str();
|
|
|
- }
|
|
|
+ i++;
|
|
|
+ std::ostringstream ext;
|
|
|
+ ext << name << std::setfill('0') << std::setw(3) << i;
|
|
|
+ uniqueName = ext.str();
|
|
|
+ it_pair = mNodeNames.insert({ uniqueName, 0 });
|
|
|
}
|
|
|
- mNodeNameInstances[name] = i;
|
|
|
- mNodeNames.insert(uniqueName);
|
|
|
}
|
|
|
|
|
|
const char* FBXConverter::NameTransformationComp(TransformationComp comp) {
|
|
@@ -672,7 +683,7 @@ namespace Assimp {
|
|
|
return name + std::string(MAGIC_NODE_TAG) + "_" + NameTransformationComp(comp);
|
|
|
}
|
|
|
|
|
|
- void FBXConverter::GenerateTransformationNodeChain(const Model& model, std::vector<aiNode*>& output_nodes,
|
|
|
+ bool FBXConverter::GenerateTransformationNodeChain(const Model& model, const std::string& name, std::vector<aiNode*>& output_nodes,
|
|
|
std::vector<aiNode*>& post_output_nodes) {
|
|
|
const PropertyTable& props = model.Props();
|
|
|
const Model::RotOrder rot = model.RotationOrder();
|
|
@@ -787,8 +798,6 @@ namespace Assimp {
|
|
|
// not be guaranteed.
|
|
|
ai_assert(NeedsComplexTransformationChain(model) == is_complex);
|
|
|
|
|
|
- std::string name = FixNodeName(model.Name());
|
|
|
-
|
|
|
// now, if we have more than just Translation, Scaling and Rotation,
|
|
|
// we need to generate a full node chain to accommodate for assimp's
|
|
|
// lack to express pivots and offsets.
|
|
@@ -830,20 +839,20 @@ namespace Assimp {
|
|
|
}
|
|
|
|
|
|
ai_assert(output_nodes.size());
|
|
|
- return;
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
// else, we can just multiply the matrices together
|
|
|
aiNode* nd = new aiNode();
|
|
|
output_nodes.push_back(nd);
|
|
|
- std::string uniqueName;
|
|
|
- GetUniqueName(name, uniqueName);
|
|
|
|
|
|
- nd->mName.Set(uniqueName);
|
|
|
+ // name passed to the method is already unique
|
|
|
+ nd->mName.Set(name);
|
|
|
|
|
|
for (const auto &transform : chain) {
|
|
|
nd->mTransformation = nd->mTransformation * transform;
|
|
|
}
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
void FBXConverter::SetupNodeMetadata(const Model& model, aiNode& nd)
|