From 689406fbda12667d42f23a82c384703f4cf55e53 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 4 Sep 2020 07:33:10 +0200 Subject: [PATCH 1/3] Fix Colladat import. --- code/AssetLib/AMF/AMFImporter.cpp | 3 +-- code/AssetLib/AMF/AMFImporter_Geometry.cpp | 2 +- code/AssetLib/AMF/AMFImporter_Postprocess.cpp | 8 ++++++-- code/AssetLib/Collada/ColladaParser.cpp | 8 ++++++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/code/AssetLib/AMF/AMFImporter.cpp b/code/AssetLib/AMF/AMFImporter.cpp index 801f38e85..9c6b09025 100644 --- a/code/AssetLib/AMF/AMFImporter.cpp +++ b/code/AssetLib/AMF/AMFImporter.cpp @@ -327,9 +327,8 @@ void AMFImporter::ParseNode_Root() { } else if (currentName == "metadata") { ParseNode_Metadata(currentNode); } - mNodeElement_Cur = ne; // force restore "current" element } - + mNodeElement_Cur = ne; // force restore "current" element mNodeElement_List.push_back(ne); // add to node element list because its a new object in graph. } diff --git a/code/AssetLib/AMF/AMFImporter_Geometry.cpp b/code/AssetLib/AMF/AMFImporter_Geometry.cpp index 394474b91..7a64c64fd 100644 --- a/code/AssetLib/AMF/AMFImporter_Geometry.cpp +++ b/code/AssetLib/AMF/AMFImporter_Geometry.cpp @@ -134,7 +134,7 @@ void AMFImporter::ParseNode_Vertex(XmlNode &node) { ParseNode_Coordinates(coordNode); coord_read = true; } - if (!coord_read && !coord_read) { + if (!coord_read && !col_read) { mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element } diff --git a/code/AssetLib/AMF/AMFImporter_Postprocess.cpp b/code/AssetLib/AMF/AMFImporter_Postprocess.cpp index a86082cfd..3b09af1f0 100644 --- a/code/AssetLib/AMF/AMFImporter_Postprocess.cpp +++ b/code/AssetLib/AMF/AMFImporter_Postprocess.cpp @@ -739,7 +739,9 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) { } // for(const CAMFImporter_NodeElement* ne: mNodeElement_List) // Check if root element are found. - if (root_el == nullptr) throw DeadlyImportError("Root() element not found."); + if (root_el == nullptr) { + throw DeadlyImportError("Root() element not found."); + } // after that walk through children of root and collect data. Five types of nodes can be placed at top level - in : , , , // and . But at first we must read and because they will be used in . can be read @@ -748,7 +750,9 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) { // 1. // 2. will be converted later when processing triangles list. \sa Postprocess_BuildMeshSet for (const AMFNodeElementBase *root_child : root_el->Child) { - if (root_child->Type == AMFNodeElementBase::ENET_Material) Postprocess_BuildMaterial(*((AMFMaterial *)root_child)); + if (root_child->Type == AMFNodeElementBase::ENET_Material) { + Postprocess_BuildMaterial(*((AMFMaterial *)root_child)); + } } // After "appearance" nodes we must read because it will be used in -> . diff --git a/code/AssetLib/Collada/ColladaParser.cpp b/code/AssetLib/Collada/ColladaParser.cpp index 29739298e..99c0d6863 100644 --- a/code/AssetLib/Collada/ColladaParser.cpp +++ b/code/AssetLib/Collada/ColladaParser.cpp @@ -621,7 +621,9 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll } else if (currentName == "skin") { pController.mMeshId = currentNode.attribute("source").as_string(); } else if (currentName == "bind_shape_matrix") { - const char *content = currentNode.value(); + std::string v; + XmlParser::getValueAsString(currentNode, v); + const char *content = v.c_str(); for (unsigned int a = 0; a < 16; a++) { // read a number content = fast_atoreal_move(content, pController.mBindShapeMatrix[a]); @@ -2163,7 +2165,9 @@ void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, Transform // how many parameters to read per transformation type static const unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 }; - const char *content = node.value(); + std::string value; + XmlParser::getValueAsString(node, value); + const char *content = value.c_str(); // read as many parameters and store in the transformation for (unsigned int a = 0; a < sNumParameters[pType]; a++) { From 0618db1f99c2e6f000c6abc13af52c4f807a490a Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Mon, 7 Sep 2020 20:52:46 +0200 Subject: [PATCH 2/3] AMF: some smaller refactorings to improve readability. --- code/AssetLib/AMF/AMFImporter.cpp | 5 +- code/AssetLib/AMF/AMFImporter.hpp | 20 +++--- code/AssetLib/AMF/AMFImporter_Postprocess.cpp | 67 +++++++++++-------- 3 files changed, 53 insertions(+), 39 deletions(-) diff --git a/code/AssetLib/AMF/AMFImporter.cpp b/code/AssetLib/AMF/AMFImporter.cpp index 9c6b09025..78d9ffe25 100644 --- a/code/AssetLib/AMF/AMFImporter.cpp +++ b/code/AssetLib/AMF/AMFImporter.cpp @@ -115,10 +115,9 @@ bool AMFImporter::Find_NodeElement(const std::string &pID, const AMFNodeElementB return false; } -bool AMFImporter::Find_ConvertedNode(const std::string &pID, std::list &pNodeList, aiNode **pNode) const { +bool AMFImporter::Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const { aiString node_name(pID.c_str()); - - for (aiNode *node : pNodeList) { + for (aiNode *node : nodeArray) { if (node->mName == node_name) { if (pNode != nullptr) { *pNode = node; diff --git a/code/AssetLib/AMF/AMFImporter.hpp b/code/AssetLib/AMF/AMFImporter.hpp index 734cfa977..ae7b39fb7 100644 --- a/code/AssetLib/AMF/AMFImporter.hpp +++ b/code/AssetLib/AMF/AMFImporter.hpp @@ -139,6 +139,10 @@ private: const AMFTexMap *TexMap; ///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face. }; + using AMFMetaDataArray = std::vector; + using MeshArray = std::vector; + using NodeArray = std::vector; + /// Clear all temporary data. void Clear(); @@ -170,13 +174,13 @@ private: /// Check if child elements of node element is metadata and add it to scene node. /// \param [in] pMetadataList - reference to list with collected metadata. /// \param [out] pSceneNode - scene node in which metadata will be added. - void Postprocess_AddMetadata(const std::list &pMetadataList, aiNode &pSceneNode) const; + void Postprocess_AddMetadata(const AMFMetaDataArray &pMetadataList, aiNode &pSceneNode) const; /// To create aiMesh and aiNode for it from . /// \param [in] pNodeElement - reference to node element which kept data. - /// \param [out] pMeshList - reference to a list with all aiMesh of the scene. - /// \param [out] pSceneNode - pointer to place where new aiNode will be created. - void Postprocess_BuildNodeAndObject(const AMFObject &pNodeElement, std::list &pMeshList, aiNode **pSceneNode); + /// \param [out] meshList - reference to a list with all aiMesh of the scene. + /// \param [out] pSceneNode - pointer to place where new aiNode will be created. + void Postprocess_BuildNodeAndObject(const AMFObject &pNodeElement, MeshArray &meshList, aiNode **pSceneNode); /// Create mesh for every in . /// \param [in] pNodeElement - reference to node element which kept data. @@ -189,7 +193,7 @@ private: /// \param [out] pSceneNode - reference to aiNode which will own new aiMesh's. void Postprocess_BuildMeshSet(const AMFMesh &pNodeElement, const std::vector &pVertexCoordinateArray, const std::vector &pVertexColorArray, const AMFColor *pObjectColor, - std::list &pMeshList, aiNode &pSceneNode); + MeshArray &pMeshList, aiNode &pSceneNode); /// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material. /// \param [in] pMaterial - source CAMFImporter_NodeElement_Material. @@ -197,8 +201,8 @@ private: /// Create and add to aiNode's list new part of scene graph defined by . /// \param [in] pConstellation - reference to node. - /// \param [out] pNodeList - reference to aiNode's list. - void Postprocess_BuildConstellation(AMFConstellation &pConstellation, std::list &pNodeList) const; + /// \param [out] nodeArray - reference to aiNode's list. + void Postprocess_BuildConstellation(AMFConstellation &pConstellation, NodeArray &nodeArray) const; /// Build Assimp scene graph in aiScene from collected data. /// \param [out] pScene - pointer to aiScene where tree will be built. @@ -276,7 +280,7 @@ public: void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler); const aiImporterDesc *GetInfo() const; bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const; - bool Find_ConvertedNode(const std::string &pID, std::list &pNodeList, aiNode **pNode) const; + bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const; bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const; void Throw_CloseNotFound(const std::string &nodeName); void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName); diff --git a/code/AssetLib/AMF/AMFImporter_Postprocess.cpp b/code/AssetLib/AMF/AMFImporter_Postprocess.cpp index 3b09af1f0..6d0ec2380 100644 --- a/code/AssetLib/AMF/AMFImporter_Postprocess.cpp +++ b/code/AssetLib/AMF/AMFImporter_Postprocess.cpp @@ -124,7 +124,7 @@ void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElem } } - col_idx++; + ++col_idx; } } } @@ -156,7 +156,9 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string & // R if (!r.empty()) { - if (!Find_NodeElement(r, AMFNodeElementBase::EType::ENET_Texture, &t_tex)) Throw_ID_NotFound(r); + if (!Find_NodeElement(r, AMFNodeElementBase::EType::ENET_Texture, &t_tex)) { + Throw_ID_NotFound(r); + } src_texture[0] = (AMFTexture *)t_tex; src_texture_4check.push_back((AMFTexture *)t_tex); @@ -166,7 +168,9 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string & // G if (!g.empty()) { - if (!Find_NodeElement(g, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(g); + if (!Find_NodeElement(g, AMFNodeElementBase::ENET_Texture, &t_tex)) { + Throw_ID_NotFound(g); + } src_texture[1] = (AMFTexture *)t_tex; src_texture_4check.push_back((AMFTexture *)t_tex); @@ -176,7 +180,9 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string & // B if (!b.empty()) { - if (!Find_NodeElement(b, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(b); + if (!Find_NodeElement(b, AMFNodeElementBase::ENET_Texture, &t_tex)) { + Throw_ID_NotFound(b); + } src_texture[2] = (AMFTexture *)t_tex; src_texture_4check.push_back((AMFTexture *)t_tex); @@ -186,7 +192,9 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string & // A if (!a.empty()) { - if (!Find_NodeElement(a, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(a); + if (!Find_NodeElement(a, AMFNodeElementBase::ENET_Texture, &t_tex)) { + Throw_ID_NotFound(a); + } src_texture[3] = (AMFTexture *)t_tex; src_texture_4check.push_back((AMFTexture *)t_tex); @@ -211,8 +219,9 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string & converted_texture.Depth = src_texture_4check[0]->Depth; // if one of source texture is tiled then converted texture is tiled too. converted_texture.Tiled = false; - for (uint8_t i = 0; i < src_texture_4check.size(); i++) + for (uint8_t i = 0; i < src_texture_4check.size(); ++i) { converted_texture.Tiled |= src_texture_4check[i]->Tiled; + } // Create format hint. strcpy(converted_texture.FormatHint, "rgba0000"); // copy initial string. @@ -309,10 +318,11 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list &metadataList, aiNode &sceneNode) const { +void AMFImporter::Postprocess_AddMetadata(const AMFMetaDataArray &metadataList, aiNode &sceneNode) const { if (metadataList.empty()) { return; } + if (sceneNode.mMetaData != nullptr) { throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong."); } @@ -326,7 +336,7 @@ void AMFImporter::Postprocess_AddMetadata(const std::list &metada } } -void AMFImporter::Postprocess_BuildNodeAndObject(const AMFObject &pNodeElement, std::list &pMeshList, aiNode **pSceneNode) { +void AMFImporter::Postprocess_BuildNodeAndObject(const AMFObject &pNodeElement, MeshArray &meshList, aiNode **pSceneNode) { AMFColor *object_color = nullptr; // create new aiNode and set name as has. @@ -346,14 +356,13 @@ void AMFImporter::Postprocess_BuildNodeAndObject(const AMFObject &pNodeElement, // Create arrays from children of mesh: vertices. PostprocessHelper_CreateMeshDataArray(*((AMFMesh *)ne_child), vertex_arr, color_arr); // Use this arrays as a source when creating every aiMesh - Postprocess_BuildMeshSet(*((AMFMesh *)ne_child), vertex_arr, color_arr, object_color, pMeshList, **pSceneNode); + Postprocess_BuildMeshSet(*((AMFMesh *)ne_child), vertex_arr, color_arr, object_color, meshList, **pSceneNode); } } // for(const CAMFImporter_NodeElement* ne_child: pNodeElement) } void AMFImporter::Postprocess_BuildMeshSet(const AMFMesh &pNodeElement, const std::vector &pVertexCoordinateArray, - const std::vector &pVertexColorArray, - const AMFColor *pObjectColor, std::list &pMeshList, aiNode &pSceneNode) { + const std::vector &pVertexColorArray, const AMFColor *pObjectColor, MeshArray &pMeshList, aiNode &pSceneNode) { std::list mesh_idx; // all data stored in "volume", search for it. @@ -659,7 +668,7 @@ void AMFImporter::Postprocess_BuildMaterial(const AMFMaterial &pMaterial) { mMaterial_Converted.push_back(new_mat); } -void AMFImporter::Postprocess_BuildConstellation(AMFConstellation &pConstellation, std::list &pNodeList) const { +void AMFImporter::Postprocess_BuildConstellation(AMFConstellation &pConstellation, NodeArray &nodeArray) const { aiNode *con_node; std::list ch_node; @@ -682,7 +691,7 @@ void AMFImporter::Postprocess_BuildConstellation(AMFConstellation &pConstellatio // create alias for conveniance AMFInstance &als = *((AMFInstance *)ne); // find referenced object - if (!Find_ConvertedNode(als.ObjectID, pNodeList, &found_node)) Throw_ID_NotFound(als.ObjectID); + if (!Find_ConvertedNode(als.ObjectID, nodeArray, &found_node)) Throw_ID_NotFound(als.ObjectID); // create node for applying transformation t_node = new aiNode; @@ -711,13 +720,13 @@ void AMFImporter::Postprocess_BuildConstellation(AMFConstellation &pConstellatio con_node->mChildren[ch_idx++] = node; // and place "root" of node to node list - pNodeList.push_back(con_node); + nodeArray.push_back(con_node); } void AMFImporter::Postprocess_BuildScene(aiScene *pScene) { - std::list node_list; - std::list mesh_list; - std::list meta_list; + NodeArray nodeArray; + MeshArray mesh_list; + AMFMetaDataArray meta_list; // // Because for AMF "material" is just complex colors mixing so aiMaterial will not be used. @@ -764,7 +773,9 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) { // for mesh and node must be built: object ID assigned to aiNode name and will be used in future for Postprocess_BuildNodeAndObject(*((AMFObject *)root_child), mesh_list, &tnode); - if (tnode != nullptr) node_list.push_back(tnode); + if (tnode != nullptr) { + nodeArray.push_back(tnode); + } } } // for(const CAMFImporter_NodeElement* root_child: root_el->Child) @@ -774,7 +785,7 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) { // 4. if (root_child->Type == AMFNodeElementBase::ENET_Constellation) { // and at top of self abstraction use aiNode. So we can use only aiNode list for creating new aiNode's. - Postprocess_BuildConstellation(*((AMFConstellation *)root_child), node_list); + Postprocess_BuildConstellation(*((AMFConstellation *)root_child), nodeArray); } // 5, @@ -792,17 +803,17 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) { // And at this step we are checking that relations. nl_clean_loop: - if (node_list.size() > 1) { + if (nodeArray.size() > 1) { // walk through all nodes - for (std::list::iterator nl_it = node_list.begin(); nl_it != node_list.end(); ++nl_it) { + for (NodeArray::iterator nl_it = nodeArray.begin(); nl_it != nodeArray.end(); ++nl_it) { // and try to find them in another top nodes. - std::list::const_iterator next_it = nl_it; + NodeArray::const_iterator next_it = nl_it; ++next_it; - for (; next_it != node_list.end(); ++next_it) { + for (; next_it != nodeArray.end(); ++next_it) { if ((*next_it)->FindNode((*nl_it)->mName) != nullptr) { // if current top node(nl_it) found in another top node then erase it from node_list and restart search loop. - node_list.erase(nl_it); + nodeArray.erase(nl_it); goto nl_clean_loop; } @@ -815,10 +826,10 @@ nl_clean_loop: // // // Nodes - if (!node_list.empty()) { - std::list::const_iterator nl_it = node_list.begin(); + if (!nodeArray.empty()) { + NodeArray::const_iterator nl_it = nodeArray.begin(); - pScene->mRootNode->mNumChildren = static_cast(node_list.size()); + pScene->mRootNode->mNumChildren = static_cast(nodeArray.size()); pScene->mRootNode->mChildren = new aiNode *[pScene->mRootNode->mNumChildren]; for (size_t i = 0; i < pScene->mRootNode->mNumChildren; i++) { // Objects and constellation that must be showed placed at top of hierarchy in node. So all aiNode's in node_list must have @@ -831,7 +842,7 @@ nl_clean_loop: // // Meshes if (!mesh_list.empty()) { - std::list::const_iterator ml_it = mesh_list.begin(); + MeshArray::const_iterator ml_it = mesh_list.begin(); pScene->mNumMeshes = static_cast(mesh_list.size()); pScene->mMeshes = new aiMesh *[pScene->mNumMeshes]; From d854f3b84245b22ac150f3cc6e0e48b145c75eb2 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 10 Sep 2020 00:05:53 +0200 Subject: [PATCH 3/3] AMF: fix adding for child-nodes. --- code/AssetLib/AMF/AMFImporter.cpp | 110 ++++++++------ code/AssetLib/AMF/AMFImporter.hpp | 3 +- code/AssetLib/AMF/AMFImporter_Geometry.cpp | 160 ++++++++++++--------- code/AssetLib/AMF/AMFImporter_Material.cpp | 43 ++++-- 4 files changed, 190 insertions(+), 126 deletions(-) diff --git a/code/AssetLib/AMF/AMFImporter.cpp b/code/AssetLib/AMF/AMFImporter.cpp index 78d9ffe25..f2b1216b5 100644 --- a/code/AssetLib/AMF/AMFImporter.cpp +++ b/code/AssetLib/AMF/AMFImporter.cpp @@ -266,7 +266,7 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) { } mXmlParser = new XmlParser(); - if (!mXmlParser->parse( file.get() )) { + if (!mXmlParser->parse(file.get())) { delete mXmlParser; throw DeadlyImportError("Failed to create XML reader for file" + pFile + "."); } @@ -278,6 +278,15 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) { ParseNode_Root(); } // namespace Assimp +void AMFImporter::ParseHelper_Node_Enter(AMFNodeElementBase *node) { + mNodeElement_Cur->Child.push_back(node); // add new element to current element child list. + mNodeElement_Cur = node; +} + +void AMFImporter::ParseHelper_Node_Exit() { + if (mNodeElement_Cur != nullptr) mNodeElement_Cur = mNodeElement_Cur->Parent; +} + // Child.push_back(ne); } mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. @@ -388,31 +400,34 @@ void AMFImporter::ParseNode_Instance(XmlNode &node) { AMFInstance &als = *((AMFInstance *)ne); als.ObjectID = objectid; - if (node.empty()) { - mNodeElement_Cur->Child.push_back(ne); - } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - bool read_flag[6] = { false, false, false, false, false, false }; - std::string currentName = currentNode.name(); - if (currentName == "deltax") { - read_flag[0] = true; - als.Delta.x = (ai_real) std::atof(currentNode.value()); - } else if (currentName == "deltay") { - read_flag[1] = true; - als.Delta.y = (ai_real)std::atof(currentNode.value()); - } else if (currentName == "deltaz") { - read_flag[2] = true; - als.Delta.z = (ai_real)std::atof(currentNode.value()); - } else if (currentName == "rx") { - read_flag[3] = true; - als.Delta.x = (ai_real)std::atof(currentNode.value()); - } else if (currentName == "ry") { - read_flag[4] = true; - als.Delta.y = (ai_real)std::atof(currentNode.value()); - } else if (currentName == "rz") { - read_flag[5] = true; - als.Delta.z = (ai_real)std::atof(currentNode.value()); + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + bool read_flag[6] = { false, false, false, false, false, false }; + std::string currentName = currentNode.name(); + if (currentName == "deltax") { + read_flag[0] = true; + als.Delta.x = (ai_real)std::atof(currentNode.value()); + } else if (currentName == "deltay") { + read_flag[1] = true; + als.Delta.y = (ai_real)std::atof(currentNode.value()); + } else if (currentName == "deltaz") { + read_flag[2] = true; + als.Delta.z = (ai_real)std::atof(currentNode.value()); + } else if (currentName == "rx") { + read_flag[3] = true; + als.Delta.x = (ai_real)std::atof(currentNode.value()); + } else if (currentName == "ry") { + read_flag[4] = true; + als.Delta.y = (ai_real)std::atof(currentNode.value()); + } else if (currentName == "rz") { + read_flag[5] = true; + als.Delta.z = (ai_real)std::atof(currentNode.value()); + } } + ParseHelper_Node_Exit(); + } else { + mNodeElement_Cur->Child.push_back(ne); } mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. @@ -426,7 +441,7 @@ void AMFImporter::ParseNode_Instance(XmlNode &node) { // Multi elements - Yes. // Parent element - . void AMFImporter::ParseNode_Object(XmlNode &node) { - + AMFNodeElementBase *ne(nullptr); // Read attributes for node . @@ -443,19 +458,22 @@ void AMFImporter::ParseNode_Object(XmlNode &node) { // Check for child nodes bool col_read = false; - if (node.empty()) { - mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element - } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string currentName = currentNode.name(); - if (currentName == "color") { - ParseNode_Color(currentNode); - col_read = true; - } else if (currentName == "mesh") { - ParseNode_Mesh(currentNode); - } else if (currentName == "metadata") { - ParseNode_Metadata(currentNode); + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + const std::string currentName = currentNode.name(); + if (currentName == "color") { + ParseNode_Color(currentNode); + col_read = true; + } else if (currentName == "mesh") { + ParseNode_Mesh(currentNode); + } else if (currentName == "metadata") { + ParseNode_Metadata(currentNode); + } } + ParseHelper_Node_Exit(); + } else { + mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element } mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. diff --git a/code/AssetLib/AMF/AMFImporter.hpp b/code/AssetLib/AMF/AMFImporter.hpp index ae7b39fb7..5493a9597 100644 --- a/code/AssetLib/AMF/AMFImporter.hpp +++ b/code/AssetLib/AMF/AMFImporter.hpp @@ -274,7 +274,8 @@ public: /// \param [in] pFile - name of file to be parsed. /// \param [in] pIOHandler - pointer to IO helper object. void ParseFile(const std::string &pFile, IOSystem *pIOHandler); - + void ParseHelper_Node_Enter(AMFNodeElementBase *child); + void ParseHelper_Node_Exit(); bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const; void GetExtensionList(std::set &pExtensionList); void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler); diff --git a/code/AssetLib/AMF/AMFImporter_Geometry.cpp b/code/AssetLib/AMF/AMFImporter_Geometry.cpp index 7a64c64fd..49324842f 100644 --- a/code/AssetLib/AMF/AMFImporter_Geometry.cpp +++ b/code/AssetLib/AMF/AMFImporter_Geometry.cpp @@ -67,19 +67,22 @@ void AMFImporter::ParseNode_Mesh(XmlNode &node) { if (0 != ASSIMP_stricmp(node.name(), "mesh")) { return; } - bool found_verts = false, found_volumes = false; - pugi::xml_node vertNode = node.child("vertices"); - if (!vertNode.empty()) { - ParseNode_Vertices(vertNode); - found_verts = true; - } + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + pugi::xml_node vertNode = node.child("vertices"); + if (!vertNode.empty()) { + ParseNode_Vertices(vertNode); + found_verts = true; + } - pugi::xml_node volumeNode = node.child("volume"); - if (!volumeNode.empty()) { - ParseNode_Volume(volumeNode); - found_volumes = true; - } + pugi::xml_node volumeNode = node.child("volume"); + if (!volumeNode.empty()) { + ParseNode_Volume(volumeNode); + found_volumes = true; + } + ParseHelper_Node_Exit(); + } if (!found_verts && !found_volumes) { mNodeElement_Cur->Child.push_back(ne); @@ -102,7 +105,12 @@ void AMFImporter::ParseNode_Vertices(XmlNode &node) { // Check for child nodes pugi::xml_node vertexNode = node.child("vertex"); if (!vertexNode.empty()) { + ParseHelper_Node_Enter(ne); + ParseNode_Vertex(vertexNode); + + ParseHelper_Node_Exit(); + } else { mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element } // if(!mReader->isEmptyElement()) else @@ -125,15 +133,20 @@ void AMFImporter::ParseNode_Vertex(XmlNode &node) { pugi::xml_node colorNode = node.child("color"); bool col_read = false; bool coord_read = false; - if (!colorNode.empty()) { - ParseNode_Color(colorNode); - col_read = true; - } - pugi::xml_node coordNode = node.child("coordinates"); - if (!coordNode.empty()) { - ParseNode_Coordinates(coordNode); - coord_read = true; + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + if (!colorNode.empty()) { + ParseNode_Color(colorNode); + col_read = true; + } + pugi::xml_node coordNode = node.child("coordinates"); + if (!coordNode.empty()) { + ParseNode_Coordinates(coordNode); + coord_read = true; + } + ParseHelper_Node_Exit(); } + if (!coord_read && !col_read) { mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element } @@ -158,11 +171,23 @@ void AMFImporter::ParseNode_Coordinates(XmlNode &node) { ne = new AMFCoordinates(mNodeElement_Cur); AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + for (XmlNode ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); + if (currentName == "X") { + XmlParser::getValueAsFloat(currentNode, als.Coordinate.x); + } else if (currentName == "Y") { + XmlParser::getValueAsFloat(currentNode, als.Coordinate.y); + } else if (currentName == "Z") { + XmlParser::getValueAsFloat(currentNode, als.Coordinate.z); + } + } - als.Coordinate.x = (ai_real)node.attribute("x").as_float(); - als.Coordinate.y = (ai_real)node.attribute("y").as_float(); - als.Coordinate.z = (ai_real)node.attribute("z").as_float(); - mNodeElement_Cur->Child.push_back(ne); + ParseHelper_Node_Exit(); + } else { + mNodeElement_Cur->Child.push_back(ne); + } mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. } @@ -188,24 +213,26 @@ void AMFImporter::ParseNode_Volume(XmlNode &node) { ((AMFVolume *)ne)->Type = type; // Check for child nodes - if (node.empty()) { - mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element - } - bool col_read = false; - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string currentName = currentNode.name(); - if (currentName == "color") { - if (col_read) Throw_MoreThanOnceDefined(currentName ,"color", "Only one color can be defined for ."); - ParseNode_Color(currentNode); - col_read = true; - } else if (currentName == "triangle") { - ParseNode_Triangle(currentNode); - } else if (currentName == "metadata") { - ParseNode_Metadata(currentNode); - } else if (currentName == "volume") { - ParseNode_Metadata(currentNode); + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + const std::string currentName = currentNode.name(); + if (currentName == "color") { + if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for ."); + ParseNode_Color(currentNode); + col_read = true; + } else if (currentName == "triangle") { + ParseNode_Triangle(currentNode); + } else if (currentName == "metadata") { + ParseNode_Metadata(currentNode); + } else if (currentName == "volume") { + ParseNode_Metadata(currentNode); + } } + ParseHelper_Node_Exit(); + } else { + mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element } mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. @@ -228,36 +255,39 @@ void AMFImporter::ParseNode_Triangle(XmlNode &node) { AMFTriangle &als = *((AMFTriangle *)ne); // alias for convenience - if (node.empty()) { + bool col_read = false, tex_read = false; + bool read_flag[3] = { false, false, false }; + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + const std::string currentName = currentNode.name(); + if (currentName == "color") { + if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for ."); + ParseNode_Color(currentNode); + col_read = true; + } else if (currentName == "texmap") { + ParseNode_TexMap(currentNode); + tex_read = true; + } else if (currentName == "map") { + ParseNode_TexMap(currentNode, true); + tex_read = true; + } else if (currentName == "v1") { + als.V[0] = std::atoi(currentNode.value()); + read_flag[0] = true; + } else if (currentName == "v2") { + als.V[1] = std::atoi(currentNode.value()); + read_flag[1] = true; + } else if (currentName == "v3") { + als.V[2] = std::atoi(currentNode.value()); + read_flag[2] = true; + } + } + ParseHelper_Node_Exit(); + } else { mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element } // Check for child nodes - bool col_read = false, tex_read = false; - bool read_flag[3] = { false, false, false }; - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string currentName = currentNode.name(); - if (currentName == "color") { - if (col_read) Throw_MoreThanOnceDefined(currentName , "color", "Only one color can be defined for ."); - ParseNode_Color(currentNode); - col_read = true; - } else if (currentName == "texmap") { - ParseNode_TexMap(currentNode); - tex_read = true; - } else if (currentName == "map") { - ParseNode_TexMap(currentNode, true); - tex_read = true; - } else if (currentName == "v1") { - als.V[0] = std::atoi(currentNode.value()); - read_flag[0] = true; - } else if (currentName == "v2") { - als.V[1] = std::atoi(currentNode.value()); - read_flag[1] = true; - } else if (currentName == "v3") { - als.V[2] = std::atoi(currentNode.value()); - read_flag[2] = true; - } - } if ((read_flag[0] && read_flag[1] && read_flag[2]) == 0) { throw DeadlyImportError("Not all vertices of the triangle are defined."); } diff --git a/code/AssetLib/AMF/AMFImporter_Material.cpp b/code/AssetLib/AMF/AMFImporter_Material.cpp index 0dde37d35..515b5dab1 100644 --- a/code/AssetLib/AMF/AMFImporter_Material.cpp +++ b/code/AssetLib/AMF/AMFImporter_Material.cpp @@ -49,7 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_AMF_IMPORTER #include "AMFImporter.hpp" -//#include "AMFImporter_Macro.hpp" namespace Assimp { @@ -76,22 +75,24 @@ void AMFImporter::ParseNode_Color(XmlNode &node) { als.Profile = profile; if (!node.empty()) { + ParseHelper_Node_Enter(ne); bool read_flag[4] = { false, false, false, false }; for (pugi::xml_node &child : node.children()) { std::string name = child.name(); if ( name == "r") { read_flag[0] = true; - als.Color.r = (ai_real)::atof(child.value()); + XmlParser::getValueAsFloat(child, als.Color.r); } else if (name == "g") { read_flag[1] = true; - als.Color.g = (ai_real)::atof(child.value()); + XmlParser::getValueAsFloat(child, als.Color.g); } else if (name == "b") { read_flag[2] = true; - als.Color.b = (ai_real)::atof(child.value()); - } else if (name == "g") { + XmlParser::getValueAsFloat(child, als.Color.b); + } else if (name == "a") { read_flag[3] = true; - als.Color.a = (ai_real) ::atof(child.value()); - } + XmlParser::getValueAsFloat(child, als.Color.a); + } + ParseHelper_Node_Exit(); } // check that all components was defined if (!(read_flag[0] && read_flag[1] && read_flag[2])) { @@ -126,6 +127,7 @@ void AMFImporter::ParseNode_Material(XmlNode &node) { // Check for child nodes if (!node.empty()) { bool col_read = false; + ParseHelper_Node_Enter(ne); for (pugi::xml_node &child : node.children()) { const std::string name = child.name(); if (name == "color") { @@ -135,6 +137,7 @@ void AMFImporter::ParseNode_Material(XmlNode &node) { ParseNode_Metadata(child); } } + ParseHelper_Node_Exit(); } else { mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element } @@ -230,15 +233,27 @@ void AMFImporter::ParseNode_Texture(XmlNode &node) { // Texture coordinates for every vertex of triangle. void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) { // Read attributes for node . - std::string rtexid = node.attribute("rtexid").as_string(); - std::string gtexid = node.attribute("gtexid").as_string(); - std::string btexid = node.attribute("btexid").as_string(); - std::string atexid = node.attribute("atexid").as_string(); - + AMFNodeElementBase *ne = new AMFTexMap(mNodeElement_Cur); + AMFTexMap &als = *((AMFTexMap *)ne); // + std::string rtexid, gtexid, btexid, atexid; + if (!node.empty()) { + ParseHelper_Node_Enter(ne); + for (XmlNode ¤tNode : node.children()) { + const std::string ¤tName = currentNode.name(); + if (currentName == "rtexid") { + XmlParser::getValueAsString(node, rtexid); + } else if (currentName == "gtexid") { + XmlParser::getValueAsString(node, gtexid); + } else if (currentName == "btexid") { + XmlParser::getValueAsString(node, btexid); + } else if (currentName == "atexid") { + XmlParser::getValueAsString(node, atexid); + } + } + ParseHelper_Node_Exit(); + } // create new texture coordinates object, alias for convenience - AMFNodeElementBase *ne = new AMFTexMap(mNodeElement_Cur); - AMFTexMap& als = *((AMFTexMap*)ne);// // check data if (rtexid.empty() && gtexid.empty() && btexid.empty()) { throw DeadlyImportError("ParseNode_TexMap. At least one texture ID must be defined.");