diff --git a/code/AssetLib/AMF/AMFImporter.cpp b/code/AssetLib/AMF/AMFImporter.cpp index 3bb18b0ab..87dfe4904 100644 --- a/code/AssetLib/AMF/AMFImporter.cpp +++ b/code/AssetLib/AMF/AMFImporter.cpp @@ -5,8 +5,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2020, assimp team - - All rights reserved. Redistribution and use of this software in source and binary forms, @@ -82,7 +80,7 @@ void AMFImporter::Clear() { mTexture_Converted.clear(); // Delete all elements if (!mNodeElement_List.empty()) { - for (CAMFImporter_NodeElement *ne : mNodeElement_List) { + for (AMFNodeElementBase *ne : mNodeElement_List) { delete ne; } @@ -90,8 +88,14 @@ void AMFImporter::Clear() { } } +AMFImporter::AMFImporter() : + mNodeElement_Cur(nullptr), + mXmlParser(nullptr) { + // empty +} + AMFImporter::~AMFImporter() { - if (mReader != nullptr) delete mReader; + delete mXmlParser; // Clear() is accounting if data already is deleted. So, just check again if all data is deleted. Clear(); } @@ -100,10 +104,12 @@ AMFImporter::~AMFImporter() { /************************************************************ Functions: find set ************************************************************/ /*********************************************************************************************************************************************/ -bool AMFImporter::Find_NodeElement(const std::string &pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement **pNodeElement) const { - for (CAMFImporter_NodeElement *ne : mNodeElement_List) { +bool AMFImporter::Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const { + for (AMFNodeElementBase *ne : mNodeElement_List) { if ((ne->ID == pID) && (ne->Type == pType)) { - if (pNodeElement != nullptr) *pNodeElement = ne; + if (pNodeElement != nullptr) { + *pNodeElement = ne; + } return true; } @@ -117,7 +123,9 @@ bool AMFImporter::Find_ConvertedNode(const std::string &pID, std::list for (aiNode *node : pNodeList) { if (node->mName == node_name) { - if (pNode != nullptr) *pNode = node; + if (pNode != nullptr) { + *pNode = node; + } return true; } @@ -129,7 +137,9 @@ bool AMFImporter::Find_ConvertedNode(const std::string &pID, std::list bool AMFImporter::Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const { for (const SPP_Material &mat : mMaterial_Converted) { if (mat.ID == pID) { - if (pConvertedMaterial != nullptr) *pConvertedMaterial = &mat; + if (pConvertedMaterial != nullptr) { + *pConvertedMaterial = &mat; + } return true; } @@ -142,20 +152,20 @@ bool AMFImporter::Find_ConvertedMaterial(const std::string &pID, const SPP_Mater /************************************************************ Functions: throw set ***********************************************************/ /*********************************************************************************************************************************************/ -void AMFImporter::Throw_CloseNotFound(const std::string &pNode) { - throw DeadlyImportError("Close tag for node <" + pNode + "> not found. Seems file is corrupt."); +void AMFImporter::Throw_CloseNotFound(const std::string &nodeName) { + throw DeadlyImportError("Close tag for node <" + nodeName + "> not found. Seems file is corrupt."); } -void AMFImporter::Throw_IncorrectAttr(const std::string &pAttrName) { - throw DeadlyImportError("Node <" + std::string(mReader->getNodeName()) + "> has incorrect attribute \"" + pAttrName + "\"."); +void AMFImporter::Throw_IncorrectAttr(const std::string &nodeName, const std::string &attrName) { + throw DeadlyImportError("Node <" + nodeName + "> has incorrect attribute \"" + attrName + "\"."); } -void AMFImporter::Throw_IncorrectAttrValue(const std::string &pAttrName) { - throw DeadlyImportError("Attribute \"" + pAttrName + "\" in node <" + std::string(mReader->getNodeName()) + "> has incorrect value."); +void AMFImporter::Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &attrName) { + throw DeadlyImportError("Attribute \"" + attrName + "\" in node <" + nodeName + "> has incorrect value."); } -void AMFImporter::Throw_MoreThanOnceDefined(const std::string &pNodeType, const std::string &pDescription) { - throw DeadlyImportError("\"" + pNodeType + "\" node can be used only once in " + mReader->getNodeName() + ". Description: " + pDescription); +void AMFImporter::Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) { + throw DeadlyImportError("\"" + pNodeType + "\" node can be used only once in " + nodeName + ". Description: " + pDescription); } void AMFImporter::Throw_ID_NotFound(const std::string &pID) const { @@ -166,8 +176,10 @@ void AMFImporter::Throw_ID_NotFound(const std::string &pID) const { /************************************************************* Functions: XML set ************************************************************/ /*********************************************************************************************************************************************/ -void AMFImporter::XML_CheckNode_MustHaveChildren() { - if (mReader->isEmptyElement()) throw DeadlyImportError(std::string("Node <") + mReader->getNodeName() + "> must have children."); +void AMFImporter::XML_CheckNode_MustHaveChildren(pugi::xml_node &node) { + if (node.children().begin() == node.children().end()) { + throw DeadlyImportError(std::string("Node <") + node.name() + "> must have children."); + } } void AMFImporter::XML_CheckNode_SkipUnsupported(const std::string &pParentNodeName) { @@ -211,9 +223,10 @@ casu_cres: } } -bool AMFImporter::XML_SearchNode(const std::string &pNodeName) { +bool AMFImporter::XML_SearchNode(const std::string &nodeName) { + mXmlParser->h(nodeName); while (mReader->read()) { - if ((mReader->getNodeType() == irr::io::EXN_ELEMENT) && XML_CheckNode_NameEqual(pNodeName)) return true; + if ((mReader->getNodeType() == irr::io::EXN_ELEMENT) && XML_CheckNode_NameEqual(nodeName)) return true; } return false; @@ -366,23 +379,24 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) { std::unique_ptr file(pIOHandler->Open(pFile, "rb")); // Check whether we can read from the file - if (file.get() == NULL) throw DeadlyImportError("Failed to open AMF file " + pFile + "."); + if (file.get() == nullptr) { + throw DeadlyImportError("Failed to open AMF file " + pFile + "."); + } - // generate a XML reader for it - std::unique_ptr mIOWrapper(new CIrrXML_IOStreamReader(file.get())); - mReader = irr::io::createIrrXMLReader(mIOWrapper.get()); - if (!mReader) throw DeadlyImportError("Failed to create XML reader for file" + pFile + "."); - // - // start reading - // search for root tag - if (XML_SearchNode("amf")) - ParseNode_Root(); - else + mXmlParser = new XmlParser(); + if (!mXmlParser->parse( file.get() ) { + delete mXmlParser; + throw DeadlyImportError("Failed to create XML reader for file" + pFile + "."); + } + + // Start reading, search for root tag + if (!mXmlParser->hasNode("amf")) { throw DeadlyImportError("Root node \"amf\" not found."); + } + + ParseNode_Root(); delete mReader; - // restore old XMLreader - mReader = OldReader; } // -#include #include "assimp/types.h" #include #include +#include +#include // Header files, stdlib. #include @@ -99,22 +99,22 @@ namespace Assimp { /// class AMFImporter : public BaseImporter { private: - struct SPP_Material;// forward declaration + struct SPP_Material; // forward declaration - /// \struct SPP_Composite - /// Data type for post-processing step. More suitable container for part of material's composition. + /// \struct SPP_Composite + /// Data type for post-processing step. More suitable container for part of material's composition. struct SPP_Composite { - SPP_Material* Material;///< Pointer to material - part of composition. - std::string Formula;///< Formula for calculating ratio of \ref Material. + SPP_Material *Material; ///< Pointer to material - part of composition. + std::string Formula; ///< Formula for calculating ratio of \ref Material. }; /// \struct SPP_Material /// Data type for post-processing step. More suitable container for material. struct SPP_Material { - std::string ID;///< Material ID. - std::list Metadata;///< Metadata of material. - AMFColor* Color;///< Color of material. - std::list Composition;///< List of child materials if current material is composition of few another. + std::string ID; ///< Material ID. + std::list Metadata; ///< Metadata of material. + AMFColor *Color; ///< Color of material. + std::list Composition; ///< List of child materials if current material is composition of few another. /// Return color calculated for specified coordinate. /// \param [in] pX - "x" coordinate. @@ -127,176 +127,179 @@ private: /// Data type for post-processing step. More suitable container for texture. struct SPP_Texture { std::string ID; - size_t Width, Height, Depth; - bool Tiled; - char FormatHint[9];// 8 for string + 1 for terminator. - uint8_t *Data; + size_t Width, Height, Depth; + bool Tiled; + char FormatHint[9]; // 8 for string + 1 for terminator. + uint8_t *Data; }; /// Data type for post-processing step. Contain face data. struct SComplexFace { - aiFace Face;///< Face vertices. - const AMFColor* Color;///< Face color. Equal to nullptr if color is not set for the face. - const AMFTexMap* TexMap;///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face. + aiFace Face; ///< Face vertices. + const AMFColor *Color; ///< Face color. Equal to nullptr if color is not set for the face. + const AMFTexMap *TexMap; ///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face. }; - /// Clear all temporary data. - void Clear(); + /// Clear all temporary data. + void Clear(); - /// Get data stored in and place it to arrays. - /// \param [in] pNodeElement - reference to node element which kept data. - /// \param [in] pVertexCoordinateArray - reference to vertices coordinates kept in . - /// \param [in] pVertexColorArray - reference to vertices colors for all & pVertexCoordinateArray, - std::vector& pVertexColorArray) const; + /// Get data stored in and place it to arrays. + /// \param [in] pNodeElement - reference to node element which kept data. + /// \param [in] pVertexCoordinateArray - reference to vertices coordinates kept in . + /// \param [in] pVertexColorArray - reference to vertices colors for all &pVertexCoordinateArray, + std::vector &pVertexColorArray) const; - /// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new - /// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it - /// to converted textures list. - /// Any of source ID's can be absent(empty string) or even one ID only specified. But at least one ID must be specified. - /// \param [in] pID_R - ID of source "red" texture. - /// \param [in] pID_G - ID of source "green" texture. - /// \param [in] pID_B - ID of source "blue" texture. - /// \param [in] pID_A - ID of source "alpha" texture. - /// \return index of the texture in array of the converted textures. - size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A); + /// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new + /// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it + /// to converted textures list. + /// Any of source ID's can be absent(empty string) or even one ID only specified. But at least one ID must be specified. + /// \param [in] pID_R - ID of source "red" texture. + /// \param [in] pID_G - ID of source "green" texture. + /// \param [in] pID_B - ID of source "blue" texture. + /// \param [in] pID_A - ID of source "alpha" texture. + /// \return index of the texture in array of the converted textures. + size_t PostprocessHelper_GetTextureID_Or_Create(const std::string &pID_R, const std::string &pID_G, const std::string &pID_B, const std::string &pID_A); - /// Separate input list by texture IDs. This step is needed because aiMesh can contain mesh which is use only one texture (or set: diffuse, bump etc). - /// \param [in] pInputList - input list with faces. Some of them can contain color or texture mapping, or both of them, or nothing. Will be cleared after - /// processing. - /// \param [out] pOutputList_Separated - output list of the faces lists. Separated faces list by used texture IDs. Will be cleared before processing. - void PostprocessHelper_SplitFacesByTextureID(std::list& pInputList, std::list >& pOutputList_Separated); + /// Separate input list by texture IDs. This step is needed because aiMesh can contain mesh which is use only one texture (or set: diffuse, bump etc). + /// \param [in] pInputList - input list with faces. Some of them can contain color or texture mapping, or both of them, or nothing. Will be cleared after + /// processing. + /// \param [out] pOutputList_Separated - output list of the faces lists. Separated faces list by used texture IDs. Will be cleared before processing. + void PostprocessHelper_SplitFacesByTextureID(std::list &pInputList, std::list> &pOutputList_Separated); - /// 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; + /// 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; - /// 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); + /// 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); - /// Create mesh for every in . - /// \param [in] pNodeElement - reference to node element which kept data. - /// \param [in] pVertexCoordinateArray - reference to vertices coordinates for all 's. - /// \param [in] pVertexColorArray - reference to vertices colors for all 's. If color for vertex is not set then corresponding member of array - /// contain nullptr. - /// \param [in] pObjectColor - pointer to colors for . If color is not set then argument contain nullptr. - /// \param [in] pMaterialList - reference to a list with defined materials. - /// \param [out] pMeshList - reference to a list with all aiMesh of the scene. - /// \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); + /// Create mesh for every in . + /// \param [in] pNodeElement - reference to node element which kept data. + /// \param [in] pVertexCoordinateArray - reference to vertices coordinates for all 's. + /// \param [in] pVertexColorArray - reference to vertices colors for all 's. If color for vertex is not set then corresponding member of array + /// contain nullptr. + /// \param [in] pObjectColor - pointer to colors for . If color is not set then argument contain nullptr. + /// \param [in] pMaterialList - reference to a list with defined materials. + /// \param [out] pMeshList - reference to a list with all aiMesh of the scene. + /// \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); - /// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material. - /// \param [in] pMaterial - source CAMFImporter_NodeElement_Material. - void Postprocess_BuildMaterial(const AMFMaterial& pMaterial); + /// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material. + /// \param [in] pMaterial - source CAMFImporter_NodeElement_Material. + void Postprocess_BuildMaterial(const AMFMaterial &pMaterial); - /// 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; + /// 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; - /// Build Assimp scene graph in aiScene from collected data. - /// \param [out] pScene - pointer to aiScene where tree will be built. - void Postprocess_BuildScene(aiScene* pScene); + /// Build Assimp scene graph in aiScene from collected data. + /// \param [out] pScene - pointer to aiScene where tree will be built. + void Postprocess_BuildScene(aiScene *pScene); - /// Decode Base64-encoded data. - /// \param [in] pInputBase64 - reference to input Base64-encoded string. - /// \param [out] pOutputData - reference to output array for decoded data. - void ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector& pOutputData) const; + /// Decode Base64-encoded data. + /// \param [in] pInputBase64 - reference to input Base64-encoded string. + /// \param [out] pOutputData - reference to output array for decoded data. + void ParseHelper_Decode_Base64(const std::string &pInputBase64, std::vector &pOutputData) const; - /// Parse node of the file. - void ParseNode_Root(XmlNode &root); + /// Parse node of the file. + void ParseNode_Root(XmlNode &root); - /// Parse node of the file. - void ParseNode_Constellation(XmlNode &node); + /// Parse node of the file. + void ParseNode_Constellation(XmlNode &node); - /// Parse node of the file. - void ParseNode_Instance(XmlNode &node); + /// Parse node of the file. + void ParseNode_Instance(XmlNode &node); - /// Parse node of the file. - void ParseNode_Material(XmlNode &node); + /// Parse node of the file. + void ParseNode_Material(XmlNode &node); - /// Parse node. - void ParseNode_Metadata(XmlNode &node); + /// Parse node. + void ParseNode_Metadata(XmlNode &node); - /// Parse node of the file. - void ParseNode_Object(XmlNode &node); + /// Parse node of the file. + void ParseNode_Object(XmlNode &node); - /// Parse node of the file. - void ParseNode_Texture(XmlNode &node); + /// Parse node of the file. + void ParseNode_Texture(XmlNode &node); - /// Parse node of the file. - void ParseNode_Coordinates(XmlNode &node); + /// Parse node of the file. + void ParseNode_Coordinates(XmlNode &node); - /// Parse node of the file. - void ParseNode_Edge(XmlNode &node); + /// Parse node of the file. + void ParseNode_Edge(XmlNode &node); - /// Parse node of the file. - void ParseNode_Mesh(XmlNode &node); + /// Parse node of the file. + void ParseNode_Mesh(XmlNode &node); - /// Parse node of the file. - void ParseNode_Triangle(XmlNode &node); + /// Parse node of the file. + void ParseNode_Triangle(XmlNode &node); - /// Parse node of the file. - void ParseNode_Vertex(XmlNode &node); + /// Parse node of the file. + void ParseNode_Vertex(XmlNode &node); - /// Parse node of the file. - void ParseNode_Vertices(XmlNode &node); + /// Parse node of the file. + void ParseNode_Vertices(XmlNode &node); - /// Parse node of the file. - void ParseNode_Volume(XmlNode &node); + /// Parse node of the file. + void ParseNode_Volume(XmlNode &node); - /// Parse node of the file. - void ParseNode_Color(XmlNode &node); + /// Parse node of the file. + void ParseNode_Color(XmlNode &node); - /// Parse of node of the file. - /// \param [in] pUseOldName - if true then use old name of node(and children) - , instead of new name - . - void ParseNode_TexMap(XmlNode &node, const bool pUseOldName = false); + /// Parse of node of the file. + /// \param [in] pUseOldName - if true then use old name of node(and children) - , instead of new name - . + void ParseNode_TexMap(XmlNode &node, const bool pUseOldName = false); public: - /// Default constructor. - AMFImporter() AI_NO_EXCEPT - : mNodeElement_Cur(nullptr) - , mXmlParser(nullptr) { - // empty - } + /// Default constructor. + AMFImporter() AI_NO_EXCEPT; - /// Default destructor. - ~AMFImporter(); + /// Default destructor. + ~AMFImporter(); - /// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph. - /// Also exception can be thrown if trouble will found. - /// \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); + /// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph. + /// Also exception can be thrown if trouble will found. + /// \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); - 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); - const aiImporterDesc* GetInfo ()const; + 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); + 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_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); + void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName); + void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription); + void Throw_ID_NotFound(const std::string &pID) const; + void XML_CheckNode_MustHaveChildren(pugi::xml_node &node); - AMFImporter(const AMFImporter& pScene) = delete; - AMFImporter& operator=(const AMFImporter& pScene) = delete; + AMFImporter(const AMFImporter &pScene) = delete; + AMFImporter &operator=(const AMFImporter &pScene) = delete; private: static const aiImporterDesc Description; - AMFNodeElementBase* mNodeElement_Cur;///< Current element. - std::list mNodeElement_List;///< All elements of scene graph. - XmlParser *mXmlParser; - //irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object + AMFNodeElementBase *mNodeElement_Cur; ///< Current element. + std::list mNodeElement_List; ///< All elements of scene graph. + XmlParser *mXmlParser; std::string mUnit; - std::list mMaterial_Converted;///< List of converted materials for postprocessing step. - std::list mTexture_Converted;///< List of converted textures for postprocessing step. - + std::list mMaterial_Converted; ///< List of converted materials for postprocessing step. + std::list mTexture_Converted; ///< List of converted textures for postprocessing step. }; -}// namespace Assimp +} // namespace Assimp #endif // INCLUDED_AI_AMF_IMPORTER_H diff --git a/code/AssetLib/AMF/AMFImporter_Geometry.cpp b/code/AssetLib/AMF/AMFImporter_Geometry.cpp index 45be05df1..d96613cae 100644 --- a/code/AssetLib/AMF/AMFImporter_Geometry.cpp +++ b/code/AssetLib/AMF/AMFImporter_Geometry.cpp @@ -5,8 +5,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2020, assimp team - - All rights reserved. Redistribution and use of this software in source and binary forms, @@ -51,22 +49,39 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AMFImporter.hpp" #include "AMFImporter_Macro.hpp" -namespace Assimp -{ +#include + +namespace Assimp { // // // A 3D mesh hull. // Multi elements - Yes. // Parent element - . -void AMFImporter::ParseNode_Mesh() -{ -CAMFImporter_NodeElement* ne; +void AMFImporter::ParseNode_Mesh(XmlNode &node) { + AMFNodeElementBase *ne = nullptr; - // create new mesh object. - ne = new CAMFImporter_NodeElement_Mesh(mNodeElement_Cur); - // Check for child nodes - if(!mReader->isEmptyElement()) + // create new mesh object. + ne = new AMFMesh(mNodeElement_Cur); + // Check for child nodes + 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; + } + + pugi::xml_node volumeNode = node.child("volume"); + if (!volumeNode.empty()) { + ParseNode_Volume(volumeNode); + found_volumes = true; + } + + /*if(!mReader->isEmptyElement()) { bool vert_read = false; @@ -87,12 +102,14 @@ CAMFImporter_NodeElement* ne; MACRO_NODECHECK_LOOPEND("mesh"); ParseHelper_Node_Exit(); }// if(!mReader->isEmptyElement()) - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - }// if(!mReader->isEmptyElement()) else + else*/ + // Add element to child list of current element + if (!found_verts && !found_volumes) { + mNodeElement_Cur->Child.push_back(ne); + } // if(!mReader->isEmptyElement()) else - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. + // and to node element list because its a new object in graph. + mNodeElement_List.push_back(ne); } // @@ -100,27 +117,34 @@ CAMFImporter_NodeElement* ne; // The list of vertices to be used in defining triangles. // Multi elements - No. // Parent element - . -void AMFImporter::ParseNode_Vertices() -{ -CAMFImporter_NodeElement* ne; +void AMFImporter::ParseNode_Vertices(XmlNode &node) { + AMFNodeElementBase *ne = nullptr; - // create new mesh object. - ne = new CAMFImporter_NodeElement_Vertices(mNodeElement_Cur); - // Check for child nodes - if(!mReader->isEmptyElement()) - { - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("vertices"); - if(XML_CheckNode_NameEqual("vertex")) { ParseNode_Vertex(); continue; } - MACRO_NODECHECK_LOOPEND("vertices"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - }// if(!mReader->isEmptyElement()) else + // create new mesh object. + ne = new AMFVertices(mNodeElement_Cur); + // Check for child nodes + pugi::xml_node vertexNode = node.child("vertex"); + if (!vertexNode.empty()) { + ParseNode_Vertex(vertexNode); + } else { + mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element + } // if(!mReader->isEmptyElement()) else - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. + /*if (!mReader->isEmptyElement()) { + ParseHelper_Node_Enter(ne); + MACRO_NODECHECK_LOOPBEGIN("vertices"); + if (XML_CheckNode_NameEqual("vertex")) { + ParseNode_Vertex(); + continue; + } + MACRO_NODECHECK_LOOPEND("vertices"); + ParseHelper_Node_Exit(); + } // if(!mReader->isEmptyElement()) + else { + mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element + } // if(!mReader->isEmptyElement()) else*/ + + mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. } // @@ -128,52 +152,64 @@ CAMFImporter_NodeElement* ne; // A vertex to be referenced in triangles. // Multi elements - Yes. // Parent element - . -void AMFImporter::ParseNode_Vertex() -{ -CAMFImporter_NodeElement* ne; +void AMFImporter::ParseNode_Vertex(XmlNode &node) { + AMFNodeElementBase *ne = nullptr; - // create new mesh object. - ne = new CAMFImporter_NodeElement_Vertex(mNodeElement_Cur); - // Check for child nodes - if(!mReader->isEmptyElement()) - { - bool col_read = false; - bool coord_read = false; + // create new mesh object. + ne = new AMFVertex(mNodeElement_Cur); + 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 (!coord_read && !coord_read) { + mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element + } - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("vertex"); - if(XML_CheckNode_NameEqual("color")) - { - // Check if data already defined. - if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for ."); - // read data and set flag about it - ParseNode_Color(); - col_read = true; + // Check for child nodes +/* if (!mReader->isEmptyElement()) { - continue; - } + ParseHelper_Node_Enter(ne); + MACRO_NODECHECK_LOOPBEGIN("vertex"); + if (XML_CheckNode_NameEqual("color")) { + // Check if data already defined. + if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for ."); + // read data and set flag about it + ParseNode_Color(); + col_read = true; - if(XML_CheckNode_NameEqual("coordinates")) - { - // Check if data already defined. - if(coord_read) Throw_MoreThanOnceDefined("coordinates", "Only one coordinates set can be defined for ."); - // read data and set flag about it - ParseNode_Coordinates(); - coord_read = true; + continue; + } - continue; - } + if (XML_CheckNode_NameEqual("coordinates")) { + // Check if data already defined. + if (coord_read) Throw_MoreThanOnceDefined("coordinates", "Only one coordinates set can be defined for ."); + // read data and set flag about it + ParseNode_Coordinates(); + coord_read = true; - if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; } - MACRO_NODECHECK_LOOPEND("vertex"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - }// if(!mReader->isEmptyElement()) else + continue; + } - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. + if (XML_CheckNode_NameEqual("metadata")) { + ParseNode_Metadata(); + continue; + } + MACRO_NODECHECK_LOOPEND("vertex"); + ParseHelper_Node_Exit(); + } // if(!mReader->isEmptyElement()) + else { + mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element + } // if(!mReader->isEmptyElement()) else + */ + mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. } // @@ -186,37 +222,42 @@ CAMFImporter_NodeElement* ne; // , , // Multi elements - No. // X, Y, or Z coordinate, respectively, of a vertex position in space. -void AMFImporter::ParseNode_Coordinates() -{ -CAMFImporter_NodeElement* ne; +void AMFImporter::ParseNode_Coordinates(XmlNode &node) { + AMFNodeElementBase *ne = nullptr; - // create new color object. - ne = new CAMFImporter_NodeElement_Coordinates(mNodeElement_Cur); + // create new color object. + ne = new AMFCoordinates(mNodeElement_Cur); - CAMFImporter_NodeElement_Coordinates& als = *((CAMFImporter_NodeElement_Coordinates*)ne);// alias for convenience + AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience - // Check for child nodes - if(!mReader->isEmptyElement()) - { - bool read_flag[3] = { false, false, false }; + if (node.attributes().begin() != node.attributes().end()) { + 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(); + } else { + mNodeElement_Cur->Child.push_back(ne); + } - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("coordinates"); - MACRO_NODECHECK_READCOMP_F("x", read_flag[0], als.Coordinate.x); - MACRO_NODECHECK_READCOMP_F("y", read_flag[1], als.Coordinate.y); - MACRO_NODECHECK_READCOMP_F("z", read_flag[2], als.Coordinate.z); - MACRO_NODECHECK_LOOPEND("coordinates"); - ParseHelper_Node_Exit(); - // check that all components was defined - if((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all coordinate's components are defined."); + /*// Check for child nodes + if (!mReader->isEmptyElement()) { + bool read_flag[3] = { false, false, false }; - }// if(!mReader->isEmptyElement()) - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - }// if(!mReader->isEmptyElement()) else + ParseHelper_Node_Enter(ne); + MACRO_NODECHECK_LOOPBEGIN("coordinates"); + MACRO_NODECHECK_READCOMP_F("x", read_flag[0], als.Coordinate.x); + MACRO_NODECHECK_READCOMP_F("y", read_flag[1], als.Coordinate.y); + MACRO_NODECHECK_READCOMP_F("z", read_flag[2], als.Coordinate.z); + MACRO_NODECHECK_LOOPEND("coordinates"); + ParseHelper_Node_Exit(); + // check that all components was defined + if ((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all coordinate's components are defined."); - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. + } // if(!mReader->isEmptyElement()) + else { + mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element + } // if(!mReader->isEmptyElement()) else*/ + + mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. } // . -void AMFImporter::ParseNode_Volume() -{ -std::string materialid; -std::string type; -CAMFImporter_NodeElement* ne; +void AMFImporter::ParseNode_Volume(XmlNode &node) { + std::string materialid; + std::string type; + AMFNodeElementBase *ne = new AMFVolume(mNodeElement_Cur); - // Read attributes for node . - MACRO_ATTRREAD_LOOPBEG; - MACRO_ATTRREAD_CHECK_RET("materialid", materialid, mReader->getAttributeValue); - MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue); - MACRO_ATTRREAD_LOOPEND; + // Read attributes for node . + /*MACRO_ATTRREAD_LOOPBEG; + MACRO_ATTRREAD_CHECK_RET("materialid", materialid, mReader->getAttributeValue); + MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue); + MACRO_ATTRREAD_LOOPEND;*/ - // create new object. - ne = new CAMFImporter_NodeElement_Volume(mNodeElement_Cur); - // and assign read data - ((CAMFImporter_NodeElement_Volume*)ne)->MaterialID = materialid; - ((CAMFImporter_NodeElement_Volume*)ne)->Type = type; - // Check for child nodes - if(!mReader->isEmptyElement()) - { - bool col_read = false; + // create new object. + //ne = new CAMFImporter_NodeElement_Volume(mNodeElement_Cur); + // and assign read data + + ((AMFVolume *)ne)->MaterialID = node.attribute("materialid").as_string(); + + ((AMFVolume *)ne)->Type = type; + // Check for child nodes + if (!mReader->isEmptyElement()) { + bool col_read = false; - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("volume"); - if(XML_CheckNode_NameEqual("color")) - { - // Check if data already defined. - if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for ."); - // read data and set flag about it - ParseNode_Color(); - col_read = true; + ParseHelper_Node_Enter(ne); + MACRO_NODECHECK_LOOPBEGIN("volume"); + if (XML_CheckNode_NameEqual("color")) { + // Check if data already defined. + if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for ."); + // read data and set flag about it + ParseNode_Color(); + col_read = true; - continue; - } + continue; + } - if(XML_CheckNode_NameEqual("triangle")) { ParseNode_Triangle(); continue; } - if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; } - MACRO_NODECHECK_LOOPEND("volume"); - ParseHelper_Node_Exit(); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - }// if(!mReader->isEmptyElement()) else + if (XML_CheckNode_NameEqual("triangle")) { + ParseNode_Triangle(); + continue; + } + if (XML_CheckNode_NameEqual("metadata")) { + ParseNode_Metadata(); + continue; + } + MACRO_NODECHECK_LOOPEND("volume"); + ParseHelper_Node_Exit(); + } // if(!mReader->isEmptyElement()) + else { + mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element + } // if(!mReader->isEmptyElement()) else - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. + mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. } // @@ -286,72 +331,67 @@ CAMFImporter_NodeElement* ne; // , , // Multi elements - No. // Index of the desired vertices in a triangle or edge. -void AMFImporter::ParseNode_Triangle() -{ -CAMFImporter_NodeElement* ne; +void AMFImporter::ParseNode_Triangle() { + CAMFImporter_NodeElement *ne; - // create new color object. - ne = new CAMFImporter_NodeElement_Triangle(mNodeElement_Cur); + // create new color object. + ne = new CAMFImporter_NodeElement_Triangle(mNodeElement_Cur); - CAMFImporter_NodeElement_Triangle& als = *((CAMFImporter_NodeElement_Triangle*)ne);// alias for convenience + CAMFImporter_NodeElement_Triangle &als = *((CAMFImporter_NodeElement_Triangle *)ne); // alias for convenience - // Check for child nodes - if(!mReader->isEmptyElement()) - { - bool col_read = false, tex_read = false; - bool read_flag[3] = { false, false, false }; + // Check for child nodes + if (!mReader->isEmptyElement()) { + bool col_read = false, tex_read = false; + bool read_flag[3] = { false, false, false }; - ParseHelper_Node_Enter(ne); - MACRO_NODECHECK_LOOPBEGIN("triangle"); - if(XML_CheckNode_NameEqual("color")) - { - // Check if data already defined. - if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for ."); - // read data and set flag about it - ParseNode_Color(); - col_read = true; + ParseHelper_Node_Enter(ne); + MACRO_NODECHECK_LOOPBEGIN("triangle"); + if (XML_CheckNode_NameEqual("color")) { + // Check if data already defined. + if (col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for ."); + // read data and set flag about it + ParseNode_Color(); + col_read = true; - continue; - } + continue; + } - if(XML_CheckNode_NameEqual("texmap"))// new name of node: "texmap". - { - // Check if data already defined. - if(tex_read) Throw_MoreThanOnceDefined("texmap", "Only one texture coordinate can be defined for ."); - // read data and set flag about it - ParseNode_TexMap(); - tex_read = true; + if (XML_CheckNode_NameEqual("texmap")) // new name of node: "texmap". + { + // Check if data already defined. + if (tex_read) Throw_MoreThanOnceDefined("texmap", "Only one texture coordinate can be defined for ."); + // read data and set flag about it + ParseNode_TexMap(); + tex_read = true; - continue; - } - else if(XML_CheckNode_NameEqual("map"))// old name of node: "map". - { - // Check if data already defined. - if(tex_read) Throw_MoreThanOnceDefined("map", "Only one texture coordinate can be defined for ."); - // read data and set flag about it - ParseNode_TexMap(true); - tex_read = true; + continue; + } else if (XML_CheckNode_NameEqual("map")) // old name of node: "map". + { + // Check if data already defined. + if (tex_read) Throw_MoreThanOnceDefined("map", "Only one texture coordinate can be defined for ."); + // read data and set flag about it + ParseNode_TexMap(true); + tex_read = true; - continue; - } + continue; + } - MACRO_NODECHECK_READCOMP_U32("v1", read_flag[0], als.V[0]); - MACRO_NODECHECK_READCOMP_U32("v2", read_flag[1], als.V[1]); - MACRO_NODECHECK_READCOMP_U32("v3", read_flag[2], als.V[2]); - MACRO_NODECHECK_LOOPEND("triangle"); - ParseHelper_Node_Exit(); - // check that all components was defined - if((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all vertices of the triangle are defined."); + MACRO_NODECHECK_READCOMP_U32("v1", read_flag[0], als.V[0]); + MACRO_NODECHECK_READCOMP_U32("v2", read_flag[1], als.V[1]); + MACRO_NODECHECK_READCOMP_U32("v3", read_flag[2], als.V[2]); + MACRO_NODECHECK_LOOPEND("triangle"); + ParseHelper_Node_Exit(); + // check that all components was defined + if ((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all vertices of the triangle are defined."); - }// if(!mReader->isEmptyElement()) - else - { - mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element - }// if(!mReader->isEmptyElement()) else + } // if(!mReader->isEmptyElement()) + else { + mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element + } // if(!mReader->isEmptyElement()) else - mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph. + mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. } -}// namespace Assimp +} // namespace Assimp #endif // !ASSIMP_BUILD_NO_AMF_IMPORTER diff --git a/code/AssetLib/AMF/AMFImporter_Material.cpp b/code/AssetLib/AMF/AMFImporter_Material.cpp index 0d0e756a1..df627dc0c 100644 --- a/code/AssetLib/AMF/AMFImporter_Material.cpp +++ b/code/AssetLib/AMF/AMFImporter_Material.cpp @@ -51,8 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AMFImporter.hpp" //#include "AMFImporter_Macro.hpp" -namespace Assimp -{ +namespace Assimp { // , and . @@ -79,18 +78,19 @@ void AMFImporter::ParseNode_Color(XmlNode &node) { if (!node.empty()) { bool read_flag[4] = { false, false, false, false }; for (pugi::xml_node &child : node.children()) { - if (child.name() == "r") { + std::string name = child.name(); + if ( name == "r") { read_flag[0] = true; - als.Color.r = atof(child.value()); - } else if (child.name() == "g") { + als.Color.r = (ai_real)::atof(child.value()); + } else if (name == "g") { read_flag[1] = true; - als.Color.g = atof(child.value()); - } else if (child.name() == "b") { + als.Color.g = (ai_real)::atof(child.value()); + } else if (name == "b") { read_flag[2] = true; - als.Color.b = atof(child.value()); - } else if (child.name() == "g") { + als.Color.b = (ai_real)::atof(child.value()); + } else if (name == "g") { read_flag[3] = true; - als.Color.a = atof(child.value()); + als.Color.a = (ai_real) ::atof(child.value()); } } // check that all components was defined @@ -127,10 +127,11 @@ void AMFImporter::ParseNode_Material(XmlNode &node) { if (!node.empty()) { bool col_read = false; for (pugi::xml_node &child : node.children()) { - if (child.name() == "color") { + const std::string name = child.name(); + if (name == "color") { col_read = true; ParseNode_Color(child); - } else if (child.name() == "metadata") { + } else if (name == "metadata") { ParseNode_Metadata(child); } } @@ -256,44 +257,46 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) { if (!pUseOldName) { for (pugi::xml_attribute &attr : node.attributes()) { - if (attr.name() == "utex1") { + const std::string name = attr.name(); + if (name == "utex1") { read_flag[0] = true; als.TextureCoordinate[0].x = attr.as_float(); - } else if (attr.name() == "utex2") { + } else if (name == "utex2") { read_flag[1] = true; als.TextureCoordinate[1].x = attr.as_float(); - } else if (attr.name() == "utex3") { + } else if (name == "utex3") { read_flag[2] = true; als.TextureCoordinate[2].x = attr.as_float(); - } else if (attr.name() == "vtex1") { + } else if (name == "vtex1") { read_flag[3] = true; als.TextureCoordinate[0].y = attr.as_float(); - } else if (attr.name() == "vtex2") { + } else if (name == "vtex2") { read_flag[4] = true; als.TextureCoordinate[1].y = attr.as_float(); - } else if (attr.name() == "vtex3") { + } else if (name == "vtex3") { read_flag[5] = true; als.TextureCoordinate[0].y = attr.as_float(); } } } else { for (pugi::xml_attribute &attr : node.attributes()) { - if (attr.name() == "u") { + const std::string name = attr.name(); + if (name == "u") { read_flag[0] = true; als.TextureCoordinate[0].x = attr.as_float(); - } else if (attr.name() == "u2") { + } else if (name == "u2") { read_flag[1] = true; als.TextureCoordinate[1].x = attr.as_float(); - } else if (attr.name() == "u3") { + } else if (name == "u3") { read_flag[2] = true; als.TextureCoordinate[2].x = attr.as_float(); - } else if (attr.name() == "v1") { + } else if (name == "v1") { read_flag[3] = true; als.TextureCoordinate[0].y = attr.as_float(); - } else if (attr.name() == "v2") { + } else if (name == "v2") { read_flag[4] = true; als.TextureCoordinate[1].y = attr.as_float(); - } else if (attr.name() == "v3") { + } else if (name == "v3") { read_flag[5] = true; als.TextureCoordinate[0].y = attr.as_float(); } diff --git a/code/AssetLib/AMF/AMFImporter_Node.hpp b/code/AssetLib/AMF/AMFImporter_Node.hpp index e399c0afd..81e0312b6 100644 --- a/code/AssetLib/AMF/AMFImporter_Node.hpp +++ b/code/AssetLib/AMF/AMFImporter_Node.hpp @@ -5,8 +5,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2020, assimp team - - All rights reserved. Redistribution and use of this software in source and binary forms, diff --git a/code/AssetLib/AMF/AMFImporter_Postprocess.cpp b/code/AssetLib/AMF/AMFImporter_Postprocess.cpp index 596b0235c..3b6336c95 100644 --- a/code/AssetLib/AMF/AMFImporter_Postprocess.cpp +++ b/code/AssetLib/AMF/AMFImporter_Postprocess.cpp @@ -5,8 +5,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2020, assimp team - - All rights reserved. Redistribution and use of this software in source and binary forms, @@ -83,39 +81,41 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /* return tcol; } -void AMFImporter::PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh &pNodeElement, std::vector &pVertexCoordinateArray, - std::vector &pVertexColorArray) const { - CAMFImporter_NodeElement_Vertices *vn = nullptr; +void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElement, std::vector &pVertexCoordinateArray, + std::vector &pVertexColorArray) const { + AMFVertex *vn = nullptr; size_t col_idx; // All data stored in "vertices", search for it. - for (CAMFImporter_NodeElement *ne_child : pNodeElement.Child) { - if (ne_child->Type == CAMFImporter_NodeElement::ENET_Vertices) vn = (CAMFImporter_NodeElement_Vertices *)ne_child; + for (AMFNodeElementBase *ne_child : pNodeElement.Child) { + if (ne_child->Type == AMFNodeElementBase::ENET_Vertices) { + vn = (AMFVertex *)ne_child; + } } // If "vertices" not found then no work for us. - if (vn == nullptr) return; + if (vn == nullptr) { + return; + } pVertexCoordinateArray.reserve(vn->Child.size()); // all coordinates stored as child and we need to reserve space for future push_back's. pVertexColorArray.resize(vn->Child.size()); // colors count equal vertices count. col_idx = 0; // Inside vertices collect all data and place to arrays - for (CAMFImporter_NodeElement *vn_child : vn->Child) { + for (AMFNodeElementBase *vn_child : vn->Child) { // vertices, colors - if (vn_child->Type == CAMFImporter_NodeElement::ENET_Vertex) { + if (vn_child->Type == AMFNodeElementBase::ENET_Vertex) { // by default clear color for current vertex pVertexColorArray[col_idx] = nullptr; - for (CAMFImporter_NodeElement *vtx : vn_child->Child) { - if (vtx->Type == CAMFImporter_NodeElement::ENET_Coordinates) { - pVertexCoordinateArray.push_back(((CAMFImporter_NodeElement_Coordinates *)vtx)->Coordinate); - + for (AMFNodeElementBase *vtx : vn_child->Child) { + if (vtx->Type == AMFNodeElementBase::ENET_Coordinates) { + pVertexCoordinateArray.push_back(((AMFCoordinates *)vtx)->Coordinate); continue; } - if (vtx->Type == CAMFImporter_NodeElement::ENET_Color) { - pVertexColorArray[col_idx] = (CAMFImporter_NodeElement_Color *)vtx; - + if (vtx->Type == AMFNodeElementBase::ENET_Color) { + pVertexColorArray[col_idx] = (AMFColor *)vtx; continue; } } // for(CAMFImporter_NodeElement* vtx: vn_child->Child) @@ -146,59 +146,77 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string & } } - // // Converted texture not found, create it. - // - CAMFImporter_NodeElement_Texture *src_texture[4]{ nullptr }; - std::vector src_texture_4check; + AMFTexture *src_texture[4] { + nullptr + }; + std::vector src_texture_4check; SPP_Texture converted_texture; { // find all specified source textures - CAMFImporter_NodeElement *t_tex; - + AMFNodeElementBase *t_tex; + // R if (!pID_R.empty()) { - if (!Find_NodeElement(pID_R, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_R); + pugi::xml_node *node = mXmlParser->findNode(pID_R); + if (nullptr == node) { + throw DeadlyImportError("Id not found " + pID_R + "."); + } + //if (!Find_NodeElement(pID_R, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_R); - src_texture[0] = (CAMFImporter_NodeElement_Texture *)t_tex; - src_texture_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex); + src_texture[0] = (AMFTexture *)t_tex; + src_texture_4check.push_back((AMFTexture *)t_tex); } else { src_texture[0] = nullptr; } // G if (!pID_G.empty()) { - if (!Find_NodeElement(pID_G, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_G); + pugi::xml_node *node = mXmlParser->findNode(pID_G); + if (nullptr == node) { + throw DeadlyImportError("Id not found " + pID_G + "."); + } - src_texture[1] = (CAMFImporter_NodeElement_Texture *)t_tex; - src_texture_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex); + //if (!Find_NodeElement(pID_G, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_G); + + src_texture[1] = (AMFTexture *)t_tex; + src_texture_4check.push_back((AMFTexture *)t_tex); } else { src_texture[1] = nullptr; } // B if (!pID_B.empty()) { - if (!Find_NodeElement(pID_B, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_B); + //if (!Find_NodeElement(pID_B, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_B); + pugi::xml_node *node = mXmlParser->findNode(pID_B); + if (nullptr == node) { + throw DeadlyImportError("Id not found " + pID_B + "."); + } - src_texture[2] = (CAMFImporter_NodeElement_Texture *)t_tex; - src_texture_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex); + src_texture[2] = (AMFTexture *)t_tex; + src_texture_4check.push_back((AMFTexture *)t_tex); } else { src_texture[2] = nullptr; } // A if (!pID_A.empty()) { - if (!Find_NodeElement(pID_A, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_A); + pugi::xml_node *node = mXmlParser->findNode(pID_A); + if (nullptr == node) { + throw DeadlyImportError("Id not found " + pID_A + "."); + } - src_texture[3] = (CAMFImporter_NodeElement_Texture *)t_tex; - src_texture_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex); + //if (!Find_NodeElement(pID_A, AMFNodeElementBase::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_A); + + src_texture[3] = (AMFTexture *)t_tex; + src_texture_4check.push_back((AMFTexture *)t_tex); } else { src_texture[3] = nullptr; } } // END: find all specified source textures // check that all textures has same size - if (src_texture_4check.size() > 1) { + if (!src_texture_4check.empty() ) { for (size_t i = 0, i_e = (src_texture_4check.size() - 1); i < i_e; i++) { if ((src_texture_4check[i]->Width != src_texture_4check[i + 1]->Width) || (src_texture_4check[i]->Height != src_texture_4check[i + 1]->Height) || (src_texture_4check[i]->Depth != src_texture_4check[i + 1]->Depth)) { @@ -255,7 +273,7 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string & auto CopyTextureData = [&](const std::string &pID, const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void { if (!pID.empty()) { for (size_t idx_target = pOffset, idx_src = 0; idx_target < tex_size; idx_target += pStep, idx_src++) { - CAMFImporter_NodeElement_Texture *tex = src_texture[pSrcTexNum]; + AMFTexture *tex = src_texture[pSrcTexNum]; ai_assert(tex); converted_texture.Data[idx_target] = tex->Data.at(idx_src); } @@ -276,7 +294,7 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string & } void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list &pInputList, std::list> &pOutputList_Separated) { - auto texmap_is_equal = [](const CAMFImporter_NodeElement_TexMap *pTexMap1, const CAMFImporter_NodeElement_TexMap *pTexMap2) -> bool { + auto texmap_is_equal = [](const AMFTexMap *pTexMap1, const AMFTexMap *pTexMap2) -> bool { if ((pTexMap1 == nullptr) && (pTexMap2 == nullptr)) return true; if (pTexMap1 == nullptr) return false; if (pTexMap2 == nullptr) return false; @@ -313,56 +331,61 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list &metadataList, aiNode &sceneNode) const { - if (!metadataList.empty()) { - if (sceneNode.mMetaData != nullptr) throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong."); +void AMFImporter::Postprocess_AddMetadata(const std::list &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."); + } - // copy collected metadata to output node. - sceneNode.mMetaData = aiMetadata::Alloc(static_cast(metadataList.size())); - size_t meta_idx(0); + // copy collected metadata to output node. + sceneNode.mMetaData = aiMetadata::Alloc(static_cast(metadataList.size())); + size_t meta_idx(0); - for (const CAMFImporter_NodeElement_Metadata &metadata : metadataList) { - sceneNode.mMetaData->Set(static_cast(meta_idx++), metadata.Type, aiString(metadata.Value)); - } - } // if(!metadataList.empty()) + for (const AMFMetadata &metadata : metadataList) { + sceneNode.mMetaData->Set(static_cast(meta_idx++), metadata.Type, aiString(metadata.Value)); + } } -void AMFImporter::Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object &pNodeElement, std::list &pMeshList, aiNode **pSceneNode) { - CAMFImporter_NodeElement_Color *object_color = nullptr; +void AMFImporter::Postprocess_BuildNodeAndObject(const AMFObject &pNodeElement, std::list &pMeshList, aiNode **pSceneNode) { + AMFColor *object_color = nullptr; // create new aiNode and set name as has. *pSceneNode = new aiNode; (*pSceneNode)->mName = pNodeElement.ID; // read mesh and color - for (const CAMFImporter_NodeElement *ne_child : pNodeElement.Child) { + for (const AMFNodeElementBase *ne_child : pNodeElement.Child) { std::vector vertex_arr; - std::vector color_arr; + std::vector color_arr; // color for object - if (ne_child->Type == CAMFImporter_NodeElement::ENET_Color) object_color = (CAMFImporter_NodeElement_Color *)ne_child; + if (ne_child->Type == AMFNodeElementBase::ENET_Color) { + object_color = (AMFColor *) ne_child; + } - if (ne_child->Type == CAMFImporter_NodeElement::ENET_Mesh) { + if (ne_child->Type == AMFNodeElementBase::ENET_Mesh) { // Create arrays from children of mesh: vertices. - PostprocessHelper_CreateMeshDataArray(*((CAMFImporter_NodeElement_Mesh *)ne_child), vertex_arr, color_arr); + PostprocessHelper_CreateMeshDataArray(*((AMFMesh *)ne_child), vertex_arr, color_arr); // Use this arrays as a source when creating every aiMesh - Postprocess_BuildMeshSet(*((CAMFImporter_NodeElement_Mesh *)ne_child), vertex_arr, color_arr, object_color, pMeshList, **pSceneNode); + Postprocess_BuildMeshSet(*((AMFMesh *)ne_child), vertex_arr, color_arr, object_color, pMeshList, **pSceneNode); } } // for(const CAMFImporter_NodeElement* ne_child: pNodeElement) } -void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &pNodeElement, const std::vector &pVertexCoordinateArray, - const std::vector &pVertexColorArray, - const CAMFImporter_NodeElement_Color *pObjectColor, std::list &pMeshList, aiNode &pSceneNode) { +void AMFImporter::Postprocess_BuildMeshSet(const AMFMesh &pNodeElement, const std::vector &pVertexCoordinateArray, + const std::vector &pVertexColorArray, + const AMFColor *pObjectColor, std::list &pMeshList, aiNode &pSceneNode) { std::list mesh_idx; // all data stored in "volume", search for it. - for (const CAMFImporter_NodeElement *ne_child : pNodeElement.Child) { - const CAMFImporter_NodeElement_Color *ne_volume_color = nullptr; + for (const AMFNodeElementBase *ne_child : pNodeElement.Child) { + const AMFColor *ne_volume_color = nullptr; const SPP_Material *cur_mat = nullptr; - if (ne_child->Type == CAMFImporter_NodeElement::ENET_Volume) { + if (ne_child->Type == AMFNodeElementBase::ENET_Volume) { /******************* Get faces *******************/ - const CAMFImporter_NodeElement_Volume *ne_volume = reinterpret_cast(ne_child); + const AMFVolume *ne_volume = reinterpret_cast(ne_child); std::list complex_faces_list; // List of the faces of the volume. std::list> complex_faces_toplist; // List of the face list for every mesh. @@ -373,13 +396,13 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh & } // inside "volume" collect all data and place to arrays or create new objects - for (const CAMFImporter_NodeElement *ne_volume_child : ne_volume->Child) { + for (const AMFNodeElementBase *ne_volume_child : ne_volume->Child) { // color for volume - if (ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Color) { - ne_volume_color = reinterpret_cast(ne_volume_child); - } else if (ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Triangle) // triangles, triangles colors + if (ne_volume_child->Type == AMFNodeElementBase::ENET_Color) { + ne_volume_color = reinterpret_cast(ne_volume_child); + } else if (ne_volume_child->Type == AMFNodeElementBase::ENET_Triangle) // triangles, triangles colors { - const CAMFImporter_NodeElement_Triangle &tri_al = *reinterpret_cast(ne_volume_child); + const AMFTriangle &tri_al = *reinterpret_cast(ne_volume_child); SComplexFace complex_face; @@ -388,11 +411,11 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh & complex_face.TexMap = nullptr; // get data from triangle children: color, texture coordinates. if (tri_al.Child.size()) { - for (const CAMFImporter_NodeElement *ne_triangle_child : tri_al.Child) { - if (ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_Color) - complex_face.Color = reinterpret_cast(ne_triangle_child); - else if (ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_TexMap) - complex_face.TexMap = reinterpret_cast(ne_triangle_child); + for (const AMFNodeElementBase *ne_triangle_child : tri_al.Child) { + if (ne_triangle_child->Type == AMFNodeElementBase::ENET_Color) + complex_face.Color = reinterpret_cast(ne_triangle_child); + else if (ne_triangle_child->Type == AMFNodeElementBase::ENET_TexMap) + complex_face.TexMap = reinterpret_cast(ne_triangle_child); } } // if(tri_al.Child.size()) @@ -422,15 +445,18 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh & if (face.Face.mIndices[idx_vert] > *pBiggerThan) { rv = face.Face.mIndices[idx_vert]; found = true; - break; } } - if (found) break; + if (found) { + break; + } } - if (!found) return *pBiggerThan; + if (!found) { + return *pBiggerThan; + } } else { rv = pFaceList.front().Face.mIndices[0]; } // if(pBiggerThan != nullptr) else @@ -505,9 +531,9 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh & tmesh->mNumFaces = static_cast(face_list_cur.size()); tmesh->mFaces = new aiFace[tmesh->mNumFaces]; - // Create vertices list and optimize indices. Optimisation mean following.In AMF all volumes use one big list of vertices. And one volume + // Create vertices list and optimize indices. Optimization mean following.In AMF all volumes use one big list of vertices. And one volume // can use only part of vertices list, for example: vertices list contain few thousands of vertices and volume use vertices 1, 3, 10. - // Do you need all this thousands of garbage? Of course no. So, optimisation step transformate sparse indices set to continuous. + // Do you need all this thousands of garbage? Of course no. So, optimization step transform sparse indices set to continuous. size_t VertexCount_Max = tmesh->mNumFaces * 3; // 3 - triangles. std::vector vert_arr, texcoord_arr; std::vector col_arr; @@ -566,7 +592,7 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh & size_t idx_vert_new = vert_arr.size(); ///TODO: clean unused vertices. "* 2": in certain cases - mesh full of triangle colors - vert_arr will contain duplicated vertices for /// colored triangles and initial vertices (for colored vertices) which in real became unused. This part need more thinking about - /// optimisation. + /// optimization. bool *idx_vert_used; idx_vert_used = new bool[VertexCount_Max * 2]; @@ -639,15 +665,15 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh & } // if(mesh_idx.size() > 0) } -void AMFImporter::Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material &pMaterial) { +void AMFImporter::Postprocess_BuildMaterial(const AMFMaterial &pMaterial) { SPP_Material new_mat; new_mat.ID = pMaterial.ID; - for (const CAMFImporter_NodeElement *mat_child : pMaterial.Child) { - if (mat_child->Type == CAMFImporter_NodeElement::ENET_Color) { - new_mat.Color = (CAMFImporter_NodeElement_Color *)mat_child; - } else if (mat_child->Type == CAMFImporter_NodeElement::ENET_Metadata) { - new_mat.Metadata.push_back((CAMFImporter_NodeElement_Metadata *)mat_child); + for (const AMFNodeElementBase *mat_child : pMaterial.Child) { + if (mat_child->Type == AMFNodeElementBase::ENET_Color) { + new_mat.Color = (AMFColor*)mat_child; + } else if (mat_child->Type == AMFNodeElementBase::ENET_Metadata) { + new_mat.Metadata.push_back((AMFMetadata *)mat_child); } } // for(const CAMFImporter_NodeElement* mat_child; pMaterial.Child) @@ -655,7 +681,7 @@ void AMFImporter::Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Mater mMaterial_Converted.push_back(new_mat); } -void AMFImporter::Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation &pConstellation, std::list &pNodeList) const { +void AMFImporter::Postprocess_BuildConstellation(AMFConstellation &pConstellation, std::list &pNodeList) const { aiNode *con_node; std::list ch_node; @@ -672,8 +698,8 @@ void AMFImporter::Postprocess_BuildConstellation(CAMFImporter_NodeElement_Conste aiNode *t_node; aiNode *found_node; - if (ne->Type == CAMFImporter_NodeElement::ENET_Metadata) continue; - if (ne->Type != CAMFImporter_NodeElement::ENET_Instance) throw DeadlyImportError("Only nodes can be in ."); + if (ne->Type == AMFNodeElementBase::ENET_Metadata) continue; + if (ne->Type != AMFNodeElementBase::ENET_Instance) throw DeadlyImportError("Only nodes can be in ."); // create alias for conveniance CAMFImporter_NodeElement_Instance &als = *((CAMFImporter_NodeElement_Instance *)ne); @@ -723,10 +749,10 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) { pScene->mRootNode->mParent = nullptr; pScene->mFlags |= AI_SCENE_FLAGS_ALLOW_SHARED; // search for root() element - CAMFImporter_NodeElement *root_el = nullptr; + AMFNodeElementBase *root_el = nullptr; - for (CAMFImporter_NodeElement *ne : mNodeElement_List) { - if (ne->Type != CAMFImporter_NodeElement::ENET_Root) continue; + for (AMFNodeElementBase *ne : mNodeElement_List) { + if (ne->Type != AMFNodeElementBase::ENET_Root) continue; root_el = ne; @@ -742,15 +768,15 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) { // // 1. // 2. will be converted later when processing triangles list. \sa Postprocess_BuildMeshSet - for (const CAMFImporter_NodeElement *root_child : root_el->Child) { - if (root_child->Type == CAMFImporter_NodeElement::ENET_Material) Postprocess_BuildMaterial(*((CAMFImporter_NodeElement_Material *)root_child)); + for (const AMFNodeElementBase *root_child : root_el->Child) { + if (root_child->Type == AMFNodeElementBase::ENET_Material) Postprocess_BuildMaterial(*((CAMFImporter_NodeElement_Material *)root_child)); } // After "appearance" nodes we must read because it will be used in -> . // // 3. - for (const CAMFImporter_NodeElement *root_child : root_el->Child) { - if (root_child->Type == CAMFImporter_NodeElement::ENET_Object) { + for (const AMFNodeElementBase *root_child : root_el->Child) { + if (root_child->Type == AMFNodeElementBase::ENET_Object) { aiNode *tnode = nullptr; // for mesh and node must be built: object ID assigned to aiNode name and will be used in future for @@ -761,15 +787,15 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) { // And finally read rest of nodes. // - for (const CAMFImporter_NodeElement *root_child : root_el->Child) { + for (const AMFNodeElementBase *root_child : root_el->Child) { // 4. - if (root_child->Type == CAMFImporter_NodeElement::ENET_Constellation) { + 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(*((CAMFImporter_NodeElement_Constellation *)root_child), node_list); + Postprocess_BuildConstellation(*((AMFConstellation *)root_child), node_list); } // 5, - if (root_child->Type == CAMFImporter_NodeElement::ENET_Metadata) meta_list.push_back((CAMFImporter_NodeElement_Metadata *)root_child); + if (root_child->Type == AMFNodeElementBase::ENET_Metadata) meta_list.push_back((CAMFImporter_NodeElement_Metadata *)root_child); } // for(const CAMFImporter_NodeElement* root_child: root_el->Child) // at now we can add collected metadata to root node diff --git a/code/AssetLib/Collada/ColladaParser.cpp b/code/AssetLib/Collada/ColladaParser.cpp index c4d1c5f5a..c773f137f 100644 --- a/code/AssetLib/Collada/ColladaParser.cpp +++ b/code/AssetLib/Collada/ColladaParser.cpp @@ -68,7 +68,7 @@ using namespace Assimp::Formatter; // Constructor to be privately used by Importer ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) : mFileName(pFile), - mReader(nullptr), + mXmlParser(), mDataLibrary(), mAccessorLibrary(), mMeshLibrary(), @@ -116,16 +116,19 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) : throw DeadlyImportError("Failed to open file '" + pFile + "'."); } } - + pugi::xml_node *root = mXmlParser.parse(daefile.get()); // generate a XML reader for it - std::unique_ptr mIOWrapper(new CIrrXML_IOStreamReader(daefile.get())); + if (nullptr == root) { + ThrowException("Unable to read file, malformed XML"); + } + /*std::unique_ptr mIOWrapper(new CIrrXML_IOStreamReader(daefile.get())); mReader = irr::io::createIrrXMLReader(mIOWrapper.get()); if (!mReader) { ThrowException("Unable to read file, malformed XML"); - } + }*/ // start reading - ReadContents(); + ReadContents(*root); // read embedded textures if (zip_archive && zip_archive->isOpen()) { @@ -136,7 +139,6 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) : // ------------------------------------------------------------------------------------------------ // Destructor, private as well ColladaParser::~ColladaParser() { - delete mReader; for (NodeLibrary::iterator it = mNodeLibrary.begin(); it != mNodeLibrary.end(); ++it) delete it->second; for (MeshLibrary::iterator it = mMeshLibrary.begin(); it != mMeshLibrary.end(); ++it) @@ -252,8 +254,28 @@ ai_real ColladaParser::ReadFloatFromTextContent() { // ------------------------------------------------------------------------------------------------ // Reads the contents of the file -void ColladaParser::ReadContents() { - while (mReader->read()) { +void ColladaParser::ReadContents(XmlNode &node) { + for (pugi::xml_node &curNode : node.children()) { + pugi::xml_attribute attr = curNode.attribute("version"); + if (attr) { + const char *version = attr.as_string(); + aiString v; + v.Set(version); + mAssetMetaData.emplace(AI_METADATA_SOURCE_FORMAT_VERSION, v); + if (!::strncmp(version, "1.5", 3)) { + mFormat = FV_1_5_n; + ASSIMP_LOG_DEBUG("Collada schema version is 1.5.n"); + } else if (!::strncmp(version, "1.4", 3)) { + mFormat = FV_1_4_n; + ASSIMP_LOG_DEBUG("Collada schema version is 1.4.n"); + } else if (!::strncmp(version, "1.3", 3)) { + mFormat = FV_1_3_n; + ASSIMP_LOG_DEBUG("Collada schema version is 1.3.n"); + } + } + ReadStructure(curNode); + } + /*while (mReader->read()) { // handle the root element "COLLADA" if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (IsElement("COLLADA")) { @@ -287,47 +309,77 @@ void ColladaParser::ReadContents() { } else { // skip everything else silently } - } + }*/ } // ------------------------------------------------------------------------------------------------ // Reads the structure of the file -void ColladaParser::ReadStructure() { - while (mReader->read()) { - // beginning of elements - if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if (IsElement("asset")) - ReadAssetInfo(); - else if (IsElement("library_animations")) - ReadAnimationLibrary(); - else if (IsElement("library_animation_clips")) - ReadAnimationClipLibrary(); - else if (IsElement("library_controllers")) - ReadControllerLibrary(); - else if (IsElement("library_images")) - ReadImageLibrary(); - else if (IsElement("library_materials")) - ReadMaterialLibrary(); - else if (IsElement("library_effects")) - ReadEffectLibrary(); - else if (IsElement("library_geometries")) - ReadGeometryLibrary(); - else if (IsElement("library_visual_scenes")) - ReadSceneLibrary(); - else if (IsElement("library_lights")) - ReadLightLibrary(); - else if (IsElement("library_cameras")) - ReadCameraLibrary(); - else if (IsElement("library_nodes")) - ReadSceneNode(NULL); /* some hacking to reuse this piece of code */ - else if (IsElement("scene")) - ReadScene(); - else - SkipElement(); - } else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - break; - } +void ColladaParser::ReadStructure(XmlNode &node) { + for (pugi::xml_node curNode : node.children()) { + const std::string name = std::string(curNode.name()); + if (name == "asset") + ReadAssetInfo(curNode); + else if (name == "library_animations") + ReadAnimationLibrary(curNode); + else if (name == "library_animation_clips") + ReadAnimationClipLibrary(curNode); + else if (name == "library_controllers") + ReadControllerLibrary(curNode); + else if (name == "library_images") + ReadImageLibrary(curNode); + else if (name == "library_materials") + ReadMaterialLibrary(curNode); + else if (name == "library_effects") + ReadEffectLibrary(curNode); + else if (name == "library_geometries") + ReadGeometryLibrary(curNode); + else if (name == "library_visual_scenes") + ReadSceneLibrary(curNode); + else if (name == "library_lights") + ReadLightLibrary(curNode); + else if (name == "library_cameras") + ReadCameraLibrary(curNode); + else if (name == "library_nodes") + ReadSceneNode(NULL); /* some hacking to reuse this piece of code */ + else if (name == "scene") + ReadScene(curNode); + //else + // SkipElement(); } + /* while (mReader->read()) { + // beginning of elements + if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { + if (IsElement("asset")) + ReadAssetInfo(); + else if (IsElement("library_animations")) + ReadAnimationLibrary(); + else if (IsElement("library_animation_clips")) + ReadAnimationClipLibrary(); + else if (IsElement("library_controllers")) + ReadControllerLibrary(); + else if (IsElement("library_images")) + ReadImageLibrary(); + else if (IsElement("library_materials")) + ReadMaterialLibrary(); + else if (IsElement("library_effects")) + ReadEffectLibrary(); + else if (IsElement("library_geometries")) + ReadGeometryLibrary(); + else if (IsElement("library_visual_scenes")) + ReadSceneLibrary(); + else if (IsElement("library_lights")) + ReadLightLibrary(); + else if (IsElement("library_cameras")) + ReadCameraLibrary(); + else if (IsElement("library_nodes")) + ReadSceneNode(NULL); // some hacking to reuse this piece of code + else if (IsElement("scene")) + ReadScene(); + else + SkipElement(); + } else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { + break; + }*/ PostProcessRootAnimations(); PostProcessControllers(); @@ -335,11 +387,32 @@ void ColladaParser::ReadStructure() { // ------------------------------------------------------------------------------------------------ // Reads asset information such as coordinate system information and legal blah -void ColladaParser::ReadAssetInfo() { - if (mReader->isEmptyElement()) - return; +void ColladaParser::ReadAssetInfo(XmlNode &node) { + /* if (mReader->isEmptyElement()) + return;*/ - while (mReader->read()) { + for (pugi::xml_node &curNode : node.children()) { + const std::string name = std::string(curNode.name()); + if (name == "unit") { + pugi::xml_attribute attr = curNode.attribute("meter"); + mUnitSize = 1.f; + if (attr) { + mUnitSize = attr.as_double(); + } + } else if (name == "up_axis") { + const char *content = curNode.value(); + if (strncmp(content, "X_UP", 4) == 0) { + mUpDirection = UP_X; + } else if (strncmp(content, "Z_UP", 4) == 0) { + mUpDirection = UP_Z; + } else { + mUpDirection = UP_Y; + } + } else if (name == "contributor") { + ReadMetaDataItem(curNode, mAssetMetaData); + } + } + /*while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (IsElement("unit")) { // read unit data from the element's attributes @@ -376,12 +449,12 @@ void ColladaParser::ReadAssetInfo() { break; } - } + }*/ } // ------------------------------------------------------------------------------------------------ // Reads the contributor info -void ColladaParser::ReadContributorInfo() { +/*void ColladaParser::ReadContributorInfo(XmlNode & node) { if (mReader->isEmptyElement()) return; @@ -394,7 +467,7 @@ void ColladaParser::ReadContributorInfo() { break; } } -} +}*/ static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVector &key_renaming, size_t &found_index) { for (size_t i = 0; i < key_renaming.size(); ++i) { @@ -404,15 +477,36 @@ static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVecto } } found_index = std::numeric_limits::max(); + return false; } // ------------------------------------------------------------------------------------------------ // Reads a single string metadata item -void ColladaParser::ReadMetaDataItem(StringMetaData &metadata) { +void ColladaParser::ReadMetaDataItem(XmlNode &node, StringMetaData &metadata) { const Collada::MetaKeyPairVector &key_renaming = GetColladaAssimpMetaKeysCamelCase(); + + const std::string name = node.name(); + if (!name.empty()) { + const char *value_char = node.value(); + if (nullptr != value_char) { + aiString aistr; + aistr.Set(value_char); + + std::string camel_key_str(name); + ToCamelCase(camel_key_str); + + size_t found_index; + if (FindCommonKey(camel_key_str, key_renaming, found_index)) { + metadata.emplace(key_renaming[found_index].second, aistr); + } else { + metadata.emplace(camel_key_str, aistr); + } + } + } + // Metadata such as created, keywords, subject etc - const char *key_char = mReader->getNodeName(); + /*const char *key_char = mReader->getNodeName(); if (key_char != nullptr) { const std::string key_str(key_char); const char *value_char = TestTextContent(); @@ -432,16 +526,53 @@ void ColladaParser::ReadMetaDataItem(StringMetaData &metadata) { } TestClosing(key_str.c_str()); } else - SkipElement(); + SkipElement();*/ } // ------------------------------------------------------------------------------------------------ // Reads the animation clips -void ColladaParser::ReadAnimationClipLibrary() { - if (mReader->isEmptyElement()) +void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) { + /*if (mReader->isEmptyElement()) + return;*/ + if (node.empty()) { return; + } - while (mReader->read()) { + std::string animName; + pugi::xml_attribute nameAttr = node.attribute("name"); + if (nameAttr) { + animName = nameAttr.as_string(); + } else { + pugi::xml_attribute idAttr = node.attribute("id"); + if (idAttr) { + animName = idAttr.as_string(); + } else { + animName = std::string("animation_") + to_string(mAnimationClipLibrary.size()); + } + } + + std::pair> clip; + clip.first = animName; + + for (pugi::xml_node &curNode : node.children()) { + const std::string currentName = curNode.name(); + if (currentName == "instance_animation") { + pugi::xml_attribute url = curNode.attribute("url"); + if (url) { + const std::string urlName = url.as_string(); + if (urlName[0] != '#') { + ThrowException("Unknown reference format"); + } + clip.second.push_back(url); + } + } + + if (clip.second.size() > 0) { + mAnimationClipLibrary.push_back(clip); + } + } + + /* while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (IsElement("animation_clip")) { // optional name given as an attribute @@ -497,7 +628,7 @@ void ColladaParser::ReadAnimationClipLibrary() { break; } - } + }*/ } void ColladaParser::PostProcessControllers() { @@ -517,46 +648,53 @@ void ColladaParser::PostProcessControllers() { // ------------------------------------------------------------------------------------------------ // Re-build animations from animation clip library, if present, otherwise combine single-channel animations void ColladaParser::PostProcessRootAnimations() { - if (mAnimationClipLibrary.size() > 0) { - Animation temp; + if (mAnimationClipLibrary.empty()) { + mAnims.CombineSingleChannelAnimations(); + return; + } - for (AnimationClipLibrary::iterator it = mAnimationClipLibrary.begin(); it != mAnimationClipLibrary.end(); ++it) { - std::string clipName = it->first; + Animation temp; - Animation *clip = new Animation(); - clip->mName = clipName; + for (AnimationClipLibrary::iterator it = mAnimationClipLibrary.begin(); it != mAnimationClipLibrary.end(); ++it) { + std::string clipName = it->first; - temp.mSubAnims.push_back(clip); + Animation *clip = new Animation(); + clip->mName = clipName; - for (std::vector::iterator a = it->second.begin(); a != it->second.end(); ++a) { - std::string animationID = *a; + temp.mSubAnims.push_back(clip); - AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID); + for (std::vector::iterator a = it->second.begin(); a != it->second.end(); ++a) { + std::string animationID = *a; - if (animation != mAnimationLibrary.end()) { - Animation *pSourceAnimation = animation->second; + AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID); - pSourceAnimation->CollectChannelsRecursively(clip->mChannels); - } + if (animation != mAnimationLibrary.end()) { + Animation *pSourceAnimation = animation->second; + + pSourceAnimation->CollectChannelsRecursively(clip->mChannels); } } - - mAnims = temp; - - // Ensure no double deletes. - temp.mSubAnims.clear(); - } else { - mAnims.CombineSingleChannelAnimations(); } + + mAnims = temp; + + // Ensure no double deletes. + temp.mSubAnims.clear(); } // ------------------------------------------------------------------------------------------------ // Reads the animation library -void ColladaParser::ReadAnimationLibrary() { - if (mReader->isEmptyElement()) - return; +void ColladaParser::ReadAnimationLibrary(XmlNode &node) { + /*if (mReader->isEmptyElement()) + return;*/ + for (pugi::xml_node &curNode : node.children()) { + const std::string currentName = curNode.name(); + if (currentName == "animation") { + ReadAnimation(curNode, &mAnims); + } + } - while (mReader->read()) { + /*while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (IsElement("animation")) { // delegate the reading. Depending on the inner elements it will be a container or a anim channel @@ -571,14 +709,17 @@ void ColladaParser::ReadAnimationLibrary() { break; } - } + }*/ } // ------------------------------------------------------------------------------------------------ // Reads an animation into the given parent structure -void ColladaParser::ReadAnimation(Collada::Animation *pParent) { - if (mReader->isEmptyElement()) +void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) { + if (node.empty()) { return; + } + /*if (mReader->isEmptyElement()) + return;*/ // an element may be a container for grouping sub-elements or an animation channel // this is the channel collection by ID, in case it has channels @@ -589,11 +730,22 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) { // optional name given as an attribute std::string animName; - std::string animID; - int indexName = TestAttribute("name"); - int indexID = TestAttribute("id"); + pugi::xml_attribute nameAttr = node.attribute("name"); + if (nameAttr) { + animName = nameAttr.as_string(); + } else { + animName = "animation"; + } - if (indexID >= 0) + std::string animID; + pugi::xml_attribute idAttr = node.attribute("id"); + if (idAttr) { + animID = idAttr.as_string(); + } + /* int indexName = TestAttribute("name"); + int indexID = TestAttribute("id");*/ + + /*if (indexID >= 0) animID = mReader->getAttributeValue(indexID); if (indexName >= 0) @@ -602,8 +754,44 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) { animName = animID; else animName = "animation"; + */ + for (pugi::xml_node &curNode : node.children()) { + const std::string currentName = curNode.name(); + if (currentName == "animation") { + if (!anim) { + anim = new Animation; + anim->mName = animName; + pParent->mSubAnims.push_back(anim); + } - while (mReader->read()) { + // recurse into the sub-element + ReadAnimation(curNode, anim); + } else if (currentName == "source") { + ReadSource(curNode); + } else if (currentName == "sampler") { + pugi::xml_attribute sampler_id = curNode.attribute("id"); + if (sampler_id) { + std::string id = sampler_id.as_string(); + ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first; + + // have it read into a channel + ReadAnimationSampler(curNode, newChannel->second); + } else if (currentName == "channel") { + pugi::xml_attribute target = curNode.attribute("target"); + pugi::xml_attribute source = curNode.attribute("source"); + std::string source_name = source.as_string(); + if (source_name[0] == '#') { + source_name = source_name.substr(1, source_name.size() - 1); + } + ChannelMap::iterator cit = channels.find(source_name); + if (cit != channels.end()) { + cit->second.mTarget = target.as_string(); + } + } + } + } + + /*while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { // we have subanimations if (IsElement("animation")) { @@ -652,7 +840,7 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) { break; } - } + }*/ // it turned out to have channels - add them if (!channels.empty()) { @@ -679,7 +867,7 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) { for (ChannelMap::const_iterator it = channels.begin(); it != channels.end(); ++it) anim->mChannels.push_back(it->second); - if (indexID >= 0) { + if (idAttr >= 0) { mAnimationLibrary[animID] = anim; } } @@ -688,8 +876,16 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) { // ------------------------------------------------------------------------------------------------ // Reads an animation sampler into the given anim channel -void ColladaParser::ReadAnimationSampler(Collada::AnimationChannel &pChannel) { - while (mReader->read()) { +void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel) { + for (pugi::xml_node &curNode : node.children()) { + const std::string currentName = curNode.name(); + if (currentName == "input") { + pugi::xml_attribute semantic = curNode.attribute("semantic"); + if (semantic) { + } + } + } + /*while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (IsElement("input")) { int indexSemantic = GetAttribute("semantic"); @@ -723,14 +919,17 @@ void ColladaParser::ReadAnimationSampler(Collada::AnimationChannel &pChannel) { break; } - } + }*/ } // ------------------------------------------------------------------------------------------------ // Reads the skeleton controller library -void ColladaParser::ReadControllerLibrary() { - if (mReader->isEmptyElement()) +void ColladaParser::ReadControllerLibrary(XmlNode &node) { + if (node.empty()) { return; + } + /*if (mReader->isEmptyElement()) + return;*/ while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { @@ -759,7 +958,7 @@ void ColladaParser::ReadControllerLibrary() { // ------------------------------------------------------------------------------------------------ // Reads a controller into the given mesh structure -void ColladaParser::ReadController(Collada::Controller &pController) { +void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pController) { // initial values pController.mType = Skin; pController.mMethod = Normalized; @@ -838,7 +1037,7 @@ void ColladaParser::ReadController(Collada::Controller &pController) { // ------------------------------------------------------------------------------------------------ // Reads the joint definitions for the given controller -void ColladaParser::ReadControllerJoints(Collada::Controller &pController) { +void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pController) { while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { // Input channels for joint data. Two possible semantics: "JOINT" and "INV_BIND_MATRIX" @@ -879,7 +1078,7 @@ void ColladaParser::ReadControllerJoints(Collada::Controller &pController) { // ------------------------------------------------------------------------------------------------ // Reads the joint weights for the given controller -void ColladaParser::ReadControllerWeights(Collada::Controller &pController) { +void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pController) { // read vertex count from attributes and resize the array accordingly int indexCount = GetAttribute("count"); size_t vertexCount = (size_t)mReader->getAttributeValueAsInt(indexCount); @@ -963,9 +1162,12 @@ void ColladaParser::ReadControllerWeights(Collada::Controller &pController) { // ------------------------------------------------------------------------------------------------ // Reads the image library contents -void ColladaParser::ReadImageLibrary() { - if (mReader->isEmptyElement()) +void ColladaParser::ReadImageLibrary(XmlNode &node) { + if (node.empty()) { return; + } + /*if (mReader->isEmptyElement()) + return;*/ while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { @@ -994,7 +1196,7 @@ void ColladaParser::ReadImageLibrary() { // ------------------------------------------------------------------------------------------------ // Reads an image entry into the given image -void ColladaParser::ReadImage(Collada::Image &pImage) { +void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) { while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { // Need to run different code paths here, depending on the Collada XSD version @@ -1080,9 +1282,12 @@ void ColladaParser::ReadImage(Collada::Image &pImage) { // ------------------------------------------------------------------------------------------------ // Reads the material library -void ColladaParser::ReadMaterialLibrary() { - if (mReader->isEmptyElement()) +void ColladaParser::ReadMaterialLibrary(XmlNode &node) { + if (node.empty()) { return; + } + /*if (mReader->isEmptyElement()) + return;*/ std::map names; while (mReader->read()) { @@ -1129,9 +1334,12 @@ void ColladaParser::ReadMaterialLibrary() { // ------------------------------------------------------------------------------------------------ // Reads the light library -void ColladaParser::ReadLightLibrary() { - if (mReader->isEmptyElement()) +void ColladaParser::ReadLightLibrary(XmlNode &node) { + if (node.empty()) { return; + } + /*if (mReader->isEmptyElement()) + return;*/ while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { @@ -1158,9 +1366,12 @@ void ColladaParser::ReadLightLibrary() { // ------------------------------------------------------------------------------------------------ // Reads the camera library -void ColladaParser::ReadCameraLibrary() { - if (mReader->isEmptyElement()) +void ColladaParser::ReadCameraLibrary(XmlNode &node) { + if (node.empty()) { return; + } + /*if (mReader->isEmptyElement()) + return;*/ while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { @@ -1192,7 +1403,7 @@ void ColladaParser::ReadCameraLibrary() { // ------------------------------------------------------------------------------------------------ // Reads a material entry into the given material -void ColladaParser::ReadMaterial(Collada::Material &pMaterial) { +void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) { while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (IsElement("material")) { @@ -1222,7 +1433,7 @@ void ColladaParser::ReadMaterial(Collada::Material &pMaterial) { // ------------------------------------------------------------------------------------------------ // Reads a light entry into the given light -void ColladaParser::ReadLight(Collada::Light &pLight) { +void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) { while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (IsElement("light")) { @@ -1300,34 +1511,26 @@ void ColladaParser::ReadLight(Collada::Light &pLight) { // ------------------------------------------------------------------------------------------------ // Reads a camera entry into the given light -void ColladaParser::ReadCamera(Collada::Camera& camera) -{ - while (mReader->read()) - { +void ColladaParser::ReadCamera(XmlNode &node, Collada::Camera &camera) { + while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (IsElement("camera")) { SkipElement(); - } - else if (IsElement("orthographic")) { + } else if (IsElement("orthographic")) { camera.mOrtho = true; - } - else if (IsElement("xfov") || IsElement("xmag")) { + } else if (IsElement("xfov") || IsElement("xmag")) { camera.mHorFov = ReadFloatFromTextContent(); TestClosing((camera.mOrtho ? "xmag" : "xfov")); - } - else if (IsElement("yfov") || IsElement("ymag")) { + } else if (IsElement("yfov") || IsElement("ymag")) { camera.mVerFov = ReadFloatFromTextContent(); TestClosing((camera.mOrtho ? "ymag" : "yfov")); - } - else if (IsElement("aspect_ratio")) { + } else if (IsElement("aspect_ratio")) { camera.mAspect = ReadFloatFromTextContent(); TestClosing("aspect_ratio"); - } - else if (IsElement("znear")) { + } else if (IsElement("znear")) { camera.mZNear = ReadFloatFromTextContent(); TestClosing("znear"); - } - else if (IsElement("zfar")) { + } else if (IsElement("zfar")) { camera.mZFar = ReadFloatFromTextContent(); TestClosing("zfar"); } @@ -1340,10 +1543,13 @@ void ColladaParser::ReadCamera(Collada::Camera& camera) // ------------------------------------------------------------------------------------------------ // Reads the effect library -void ColladaParser::ReadEffectLibrary() { - if (mReader->isEmptyElement()) { +void ColladaParser::ReadEffectLibrary(XmlNode &node) { + if (node.empty()) { return; } + /*if (mReader->isEmptyElement()) { + return; + }*/ while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { @@ -1371,7 +1577,7 @@ void ColladaParser::ReadEffectLibrary() { // ------------------------------------------------------------------------------------------------ // Reads an effect entry into the given effect -void ColladaParser::ReadEffect(Collada::Effect &pEffect) { +void ColladaParser::ReadEffect(XmlNode &node, Collada::Effect &pEffect) { // for the moment we don't support any other type of effect. while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { @@ -1390,7 +1596,7 @@ void ColladaParser::ReadEffect(Collada::Effect &pEffect) { // ------------------------------------------------------------------------------------------------ // Reads an COMMON effect profile -void ColladaParser::ReadEffectProfileCommon(Collada::Effect &pEffect) { +void ColladaParser::ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect) { while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (IsElement("newparam")) { @@ -1496,10 +1702,13 @@ void ColladaParser::ReadEffectProfileCommon(Collada::Effect &pEffect) { // ------------------------------------------------------------------------------------------------ // Read texture wrapping + UV transform settings from a profile==Maya chunk -void ColladaParser::ReadSamplerProperties(Sampler &out) { - if (mReader->isEmptyElement()) { +void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) { + if (node.empty()) { return; } + /*if (mReader->isEmptyElement()) { + return; + }*/ while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { @@ -1576,9 +1785,12 @@ void ColladaParser::ReadSamplerProperties(Sampler &out) { // ------------------------------------------------------------------------------------------------ // Reads an effect entry containing a color or a texture defining that color -void ColladaParser::ReadEffectColor(aiColor4D &pColor, Sampler &pSampler) { - if (mReader->isEmptyElement()) +void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &pSampler) { + if (node.empty()) { return; + } + /*if (mReader->isEmptyElement()) + return;*/ // Save current element name const std::string curElem = mReader->getNodeName(); @@ -1639,7 +1851,7 @@ void ColladaParser::ReadEffectColor(aiColor4D &pColor, Sampler &pSampler) { // ------------------------------------------------------------------------------------------------ // Reads an effect entry containing a float -void ColladaParser::ReadEffectFloat(ai_real &pFloat) { +void ColladaParser::ReadEffectFloat(XmlNode &node, ai_real &pFloat) { while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (IsElement("float")) { @@ -1661,7 +1873,7 @@ void ColladaParser::ReadEffectFloat(ai_real &pFloat) { // ------------------------------------------------------------------------------------------------ // Reads an effect parameter specification of any kind -void ColladaParser::ReadEffectParam(Collada::EffectParam &pParam) { +void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam) { while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (IsElement("surface")) { @@ -1707,9 +1919,12 @@ void ColladaParser::ReadEffectParam(Collada::EffectParam &pParam) { // ------------------------------------------------------------------------------------------------ // Reads the geometry library contents -void ColladaParser::ReadGeometryLibrary() { - if (mReader->isEmptyElement()) +void ColladaParser::ReadGeometryLibrary(XmlNode &node) { + if (node.empty()) { return; + } + /*if (mReader->isEmptyElement()) + return;*/ while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { @@ -1755,9 +1970,12 @@ void ColladaParser::ReadGeometryLibrary() { // ------------------------------------------------------------------------------------------------ // Reads a geometry from the geometry library. -void ColladaParser::ReadGeometry(Collada::Mesh &pMesh) { - if (mReader->isEmptyElement()) +void ColladaParser::ReadGeometry(XmlNode &node, Collada::Mesh &pMesh) { + if (node.empty()) { return; + } + /*if (mReader->isEmptyElement()) + return;*/ while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { @@ -1779,9 +1997,12 @@ void ColladaParser::ReadGeometry(Collada::Mesh &pMesh) { // ------------------------------------------------------------------------------------------------ // Reads a mesh from the geometry library -void ColladaParser::ReadMesh(Mesh &pMesh) { - if (mReader->isEmptyElement()) +void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) { + if (node.empty()) { return; + } + /*if (mReader->isEmptyElement()) + return;*/ while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { @@ -1814,7 +2035,7 @@ void ColladaParser::ReadMesh(Mesh &pMesh) { // ------------------------------------------------------------------------------------------------ // Reads a source element -void ColladaParser::ReadSource() { +void ColladaParser::ReadSource(XmlNode &node) { int indexID = GetAttribute("id"); std::string sourceID = mReader->getAttributeValue(indexID); @@ -1846,7 +2067,7 @@ void ColladaParser::ReadSource() { // ------------------------------------------------------------------------------------------------ // Reads a data array holding a number of floats, and stores it in the global library -void ColladaParser::ReadDataArray() { +void ColladaParser::ReadDataArray(XmlNode &node) { std::string elmName = mReader->getNodeName(); bool isStringArray = (elmName == "IDREF_array" || elmName == "Name_array"); bool isEmptyElement = mReader->isEmptyElement(); @@ -1904,7 +2125,7 @@ void ColladaParser::ReadDataArray() { // ------------------------------------------------------------------------------------------------ // Reads an accessor and stores it in the global library -void ColladaParser::ReadAccessor(const std::string &pID) { +void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) { // read accessor attributes int attrSource = GetAttribute("source"); const char *source = mReader->getAttributeValue(attrSource); @@ -2009,7 +2230,7 @@ void ColladaParser::ReadAccessor(const std::string &pID) { // ------------------------------------------------------------------------------------------------ // Reads input declarations of per-vertex mesh data into the given mesh -void ColladaParser::ReadVertexData(Mesh &pMesh) { +void ColladaParser::ReadVertexData(XmlNode &node, Mesh &pMesh) { // extract the ID of the element. Not that we care, but to catch strange referencing schemes we should warn about int attrID = GetAttribute("id"); pMesh.mVertexID = mReader->getAttributeValue(attrID); @@ -2033,7 +2254,7 @@ void ColladaParser::ReadVertexData(Mesh &pMesh) { // ------------------------------------------------------------------------------------------------ // Reads input declarations of per-index mesh data into the given mesh -void ColladaParser::ReadIndexData(Mesh &pMesh) { +void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) { std::vector vcount; std::vector perIndexData; @@ -2128,7 +2349,7 @@ void ColladaParser::ReadIndexData(Mesh &pMesh) { // ------------------------------------------------------------------------------------------------ // Reads a single input channel element and stores it in the given array, if valid -void ColladaParser::ReadInputChannel(std::vector &poChannels) { +void ColladaParser::ReadInputChannel(XmlNode &node, std::vector &poChannels) { InputChannel channel; // read semantic @@ -2170,7 +2391,7 @@ void ColladaParser::ReadInputChannel(std::vector &poChannels) { // ------------------------------------------------------------------------------------------------ // Reads a

primitive index list and assembles the mesh data into the given mesh -size_t ColladaParser::ReadPrimitives(Mesh &pMesh, std::vector &pPerIndexChannels, +size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector &pPerIndexChannels, size_t pNumPrimitives, const std::vector &pVCount, PrimitiveType pPrimType) { // determine number of indices coming per vertex // find the offset index for all per-vertex channels @@ -2337,7 +2558,8 @@ size_t ColladaParser::ReadPrimitives(Mesh &pMesh, std::vector &pPe ///@note This function willn't work correctly if both PerIndex and PerVertex channels have same channels. ///For example if TEXCOORD present in both and tags this function will create wrong uv coordinates. ///It's not clear from COLLADA documentation is this allowed or not. For now only exporter fixed to avoid such behavior -void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh &pMesh, std::vector &pPerIndexChannels, size_t currentPrimitive, const std::vector &indices) { +void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh &pMesh, + std::vector &pPerIndexChannels, size_t currentPrimitive, const std::vector &indices) { // calculate the base offset of the vertex whose attributes we ant to copy size_t baseOffset = currentPrimitive * numOffsets * numPoints + currentVertex * numOffsets; @@ -2355,7 +2577,8 @@ void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t n pMesh.mFacePosIndices.push_back(indices[baseOffset + perVertexOffset]); } -void ColladaParser::ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Mesh &pMesh, std::vector &pPerIndexChannels, size_t currentPrimitive, const std::vector &indices) { +void ColladaParser::ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Mesh &pMesh, std::vector &pPerIndexChannels, + size_t currentPrimitive, const std::vector &indices) { if (currentPrimitive % 2 != 0) { //odd tristrip triangles need their indices mangled, to preserve winding direction CopyVertex(1, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices); @@ -2470,9 +2693,12 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz // ------------------------------------------------------------------------------------------------ // Reads the library of node hierarchies and scene parts -void ColladaParser::ReadSceneLibrary() { - if (mReader->isEmptyElement()) +void ColladaParser::ReadSceneLibrary(XmlNode &node) { + if (node.empty()) { return; + } + /*if (mReader->isEmptyElement()) + return;*/ while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { @@ -2510,10 +2736,14 @@ void ColladaParser::ReadSceneLibrary() { // ------------------------------------------------------------------------------------------------ // Reads a scene node's contents including children and stores it in the given node -void ColladaParser::ReadSceneNode(Node *pNode) { +void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) { // quit immediately on elements - if (mReader->isEmptyElement()) + if (node.empty()) { return; + } + +/* if (mReader->isEmptyElement()) + return;*/ while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { @@ -2628,9 +2858,12 @@ void ColladaParser::ReadSceneNode(Node *pNode) { // ------------------------------------------------------------------------------------------------ // Reads a node transformation entry of the given type and adds it to the given node's transformation list. -void ColladaParser::ReadNodeTransformation(Node *pNode, TransformType pType) { - if (mReader->isEmptyElement()) +void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, TransformType pType) { + if (node.empty()) { return; + } + /*if (mReader->isEmptyElement()) + return;*/ std::string tagName = mReader->getNodeName(); @@ -2663,7 +2896,7 @@ void ColladaParser::ReadNodeTransformation(Node *pNode, TransformType pType) { // ------------------------------------------------------------------------------------------------ // Processes bind_vertex_input and bind elements -void ColladaParser::ReadMaterialVertexInputBinding(Collada::SemanticMappingTable &tbl) { +void ColladaParser::ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl) { while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { if (IsElement("bind_vertex_input")) { @@ -2714,7 +2947,7 @@ void ColladaParser::ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive) { // ------------------------------------------------------------------------------------------------ // Reads a mesh reference in a node and adds it to the node's mesh list -void ColladaParser::ReadNodeGeometry(Node *pNode) { +void ColladaParser::ReadNodeGeometry(XmlNode &node, Node *pNode) { // referred mesh is given as an attribute of the element int attrUrl = GetAttribute("url"); const char *url = mReader->getAttributeValue(attrUrl); @@ -2760,9 +2993,12 @@ void ColladaParser::ReadNodeGeometry(Node *pNode) { // ------------------------------------------------------------------------------------------------ // Reads the collada scene -void ColladaParser::ReadScene() { - if (mReader->isEmptyElement()) +void ColladaParser::ReadScene(XmlNode &node) { + if (node.empty()) { return; + } + /*if (mReader->isEmptyElement()) + return;*/ while (mReader->read()) { if (mReader->getNodeType() == irr::io::EXN_ELEMENT) { @@ -2813,7 +3049,7 @@ void ColladaParser::ReportWarning(const char *msg, ...) { // ------------------------------------------------------------------------------------------------ // Skips all data until the end node of the current element -void ColladaParser::SkipElement() { +/*void ColladaParser::SkipElement() { // nothing to skip if it's an if (mReader->isEmptyElement()) { return; @@ -2821,11 +3057,11 @@ void ColladaParser::SkipElement() { // reroute SkipElement(mReader->getNodeName()); -} +}*/ // ------------------------------------------------------------------------------------------------ // Skips all data until the end node of the given element -void ColladaParser::SkipElement(const char *pElement) { +/*void ColladaParser::SkipElement(const char *pElement) { // copy the current node's name because it'a pointer to the reader's internal buffer, // which is going to change with the upcoming parsing std::string element = pElement; @@ -2836,11 +3072,11 @@ void ColladaParser::SkipElement(const char *pElement) { } } } -} +}*/ // ------------------------------------------------------------------------------------------------ // Tests for an opening element of the given name, throws an exception if not found -void ColladaParser::TestOpening(const char *pName) { +/*void ColladaParser::TestOpening(const char *pName) { // read element start if (!mReader->read()) { ThrowException(format() << "Unexpected end of file while beginning of <" << pName << "> element."); @@ -2855,11 +3091,11 @@ void ColladaParser::TestOpening(const char *pName) { if (mReader->getNodeType() != irr::io::EXN_ELEMENT || strcmp(mReader->getNodeName(), pName) != 0) { ThrowException(format() << "Expected start of <" << pName << "> element."); } -} +}*/ // ------------------------------------------------------------------------------------------------ // Tests for the closing tag of the given element, throws an exception if not found -void ColladaParser::TestClosing(const char *pName) { +/*void ColladaParser::TestClosing(const char *pName) { // check if we have an empty (self-closing) element if (mReader->isEmptyElement()) { return; @@ -2885,7 +3121,7 @@ void ColladaParser::TestClosing(const char *pName) { if (mReader->getNodeType() != irr::io::EXN_ELEMENT_END || strcmp(mReader->getNodeName(), pName) != 0) { ThrowException(format() << "Expected end of <" << pName << "> element."); } -} +}*/ // ------------------------------------------------------------------------------------------------ // Returns the index of the named attribute or -1 if not found. Does not throw, therefore useful for optional attributes @@ -2940,7 +3176,7 @@ const char *ColladaParser::TestTextContent() { } // ------------------------------------------------------------------------------------------------ -// Calculates the resulting transformation fromm all the given transform steps +// Calculates the resulting transformation from all the given transform steps aiMatrix4x4 ColladaParser::CalculateResultTransform(const std::vector &pTransforms) const { aiMatrix4x4 res; diff --git a/code/AssetLib/Collada/ColladaParser.h b/code/AssetLib/Collada/ColladaParser.h index a84a59354..69e0c9759 100644 --- a/code/AssetLib/Collada/ColladaParser.h +++ b/code/AssetLib/Collada/ColladaParser.h @@ -50,9 +50,10 @@ #include "ColladaHelper.h" #include #include -#include +#include namespace Assimp { + class ZipArchiveIOSystem; // ------------------------------------------------------------------------------------------ @@ -81,25 +82,25 @@ protected: static std::string ReadZaeManifest(ZipArchiveIOSystem &zip_archive); /** Reads the contents of the file */ - void ReadContents(); + void ReadContents(XmlNode &node); /** Reads the structure of the file */ - void ReadStructure(); + void ReadStructure(XmlNode &node); /** Reads asset information such as coordinate system information and legal blah */ - void ReadAssetInfo(); + void ReadAssetInfo(XmlNode &node); /** Reads contributor information such as author and legal blah */ - void ReadContributorInfo(); + void ReadContributorInfo(XmlNode &node); /** Reads generic metadata into provided map and renames keys for Assimp */ - void ReadMetaDataItem(StringMetaData &metadata); + void ReadMetaDataItem(XmlNode &node, StringMetaData &metadata); /** Reads the animation library */ - void ReadAnimationLibrary(); + void ReadAnimationLibrary(XmlNode &node); /** Reads the animation clip library */ - void ReadAnimationClipLibrary(); + void ReadAnimationClipLibrary(XmlNode &node); /** Unwrap controllers dependency hierarchy */ void PostProcessControllers(); @@ -108,103 +109,103 @@ protected: void PostProcessRootAnimations(); /** Reads an animation into the given parent structure */ - void ReadAnimation(Collada::Animation *pParent); + void ReadAnimation(XmlNode &node, Collada::Animation *pParent); /** Reads an animation sampler into the given anim channel */ - void ReadAnimationSampler(Collada::AnimationChannel &pChannel); + void ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel); /** Reads the skeleton controller library */ - void ReadControllerLibrary(); + void ReadControllerLibrary(XmlNode &node); /** Reads a controller into the given mesh structure */ - void ReadController(Collada::Controller &pController); + void ReadController(XmlNode &node, Collada::Controller &pController); /** Reads the joint definitions for the given controller */ - void ReadControllerJoints(Collada::Controller &pController); + void ReadControllerJoints(XmlNode &node, Collada::Controller &pController); /** Reads the joint weights for the given controller */ - void ReadControllerWeights(Collada::Controller &pController); + void ReadControllerWeights(XmlNode &node, Collada::Controller &pController); /** Reads the image library contents */ - void ReadImageLibrary(); + void ReadImageLibrary(XmlNode &node); /** Reads an image entry into the given image */ - void ReadImage(Collada::Image &pImage); + void ReadImage(XmlNode &node, Collada::Image &pImage); /** Reads the material library */ - void ReadMaterialLibrary(); + void ReadMaterialLibrary(XmlNode &node); /** Reads a material entry into the given material */ - void ReadMaterial(Collada::Material &pMaterial); + void ReadMaterial(XmlNode &node, Collada::Material &pMaterial); /** Reads the camera library */ - void ReadCameraLibrary(); + void ReadCameraLibrary(XmlNode &node); /** Reads a camera entry into the given camera */ - void ReadCamera(Collada::Camera &pCamera); + void ReadCamera(XmlNode &node, Collada::Camera &pCamera); /** Reads the light library */ - void ReadLightLibrary(); + void ReadLightLibrary(XmlNode &node); /** Reads a light entry into the given light */ - void ReadLight(Collada::Light &pLight); + void ReadLight(XmlNode &node, Collada::Light &pLight); /** Reads the effect library */ - void ReadEffectLibrary(); + void ReadEffectLibrary(XmlNode &node); /** Reads an effect entry into the given effect*/ - void ReadEffect(Collada::Effect &pEffect); + void ReadEffect(XmlNode &node, Collada::Effect &pEffect); /** Reads an COMMON effect profile */ - void ReadEffectProfileCommon(Collada::Effect &pEffect); + void ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect); /** Read sampler properties */ - void ReadSamplerProperties(Collada::Sampler &pSampler); + void ReadSamplerProperties(XmlNode &node, Collada::Sampler &pSampler); /** Reads an effect entry containing a color or a texture defining that color */ - void ReadEffectColor(aiColor4D &pColor, Collada::Sampler &pSampler); + void ReadEffectColor(XmlNode &node, aiColor4D &pColor, Collada::Sampler &pSampler); /** Reads an effect entry containing a float */ - void ReadEffectFloat(ai_real &pFloat); + void ReadEffectFloat(XmlNode &node, ai_real &pFloat); /** Reads an effect parameter specification of any kind */ - void ReadEffectParam(Collada::EffectParam &pParam); + void ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam); /** Reads the geometry library contents */ - void ReadGeometryLibrary(); + void ReadGeometryLibrary(XmlNode &node); /** Reads a geometry from the geometry library. */ - void ReadGeometry(Collada::Mesh &pMesh); + void ReadGeometry(XmlNode &node, Collada::Mesh &pMesh); /** Reads a mesh from the geometry library */ - void ReadMesh(Collada::Mesh &pMesh); + void ReadMesh(XmlNode &node, Collada::Mesh &pMesh); /** Reads a source element - a combination of raw data and an accessor defining * things that should not be redefinable. Yes, that's another rant. */ - void ReadSource(); + void ReadSource(XmlNode &node); /** Reads a data array holding a number of elements, and stores it in the global library. * Currently supported are array of floats and arrays of strings. */ - void ReadDataArray(); + void ReadDataArray(XmlNode &node); /** Reads an accessor and stores it in the global library under the given ID - * accessors use the ID of the parent element */ - void ReadAccessor(const std::string &pID); + void ReadAccessor(XmlNode &node, const std::string &pID); /** Reads input declarations of per-vertex mesh data into the given mesh */ - void ReadVertexData(Collada::Mesh &pMesh); + void ReadVertexData(XmlNode &node, Collada::Mesh &pMesh); /** Reads input declarations of per-index mesh data into the given mesh */ - void ReadIndexData(Collada::Mesh &pMesh); + void ReadIndexData(XmlNode &node, Collada::Mesh &pMesh); /** Reads a single input channel element and stores it in the given array, if valid */ - void ReadInputChannel(std::vector &poChannels); + void ReadInputChannel(XmlNode &node, std::vector &poChannels); /** Reads a

primitive index list and assembles the mesh data into the given mesh */ - size_t ReadPrimitives(Collada::Mesh &pMesh, std::vector &pPerIndexChannels, + size_t ReadPrimitives(XmlNode &node, Collada::Mesh &pMesh, std::vector &pPerIndexChannels, size_t pNumPrimitives, const std::vector &pVCount, Collada::PrimitiveType pPrimType); /** Copies the data for a single primitive into the mesh, based on the InputChannels */ @@ -220,22 +221,22 @@ protected: void ExtractDataObjectFromChannel(const Collada::InputChannel &pInput, size_t pLocalIndex, Collada::Mesh &pMesh); /** Reads the library of node hierarchies and scene parts */ - void ReadSceneLibrary(); + void ReadSceneLibrary(XmlNode &node); /** Reads a scene node's contents including children and stores it in the given node */ - void ReadSceneNode(Collada::Node *pNode); + void ReadSceneNode(XmlNode &node, Collada::Node *pNode); /** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */ - void ReadNodeTransformation(Collada::Node *pNode, Collada::TransformType pType); + void ReadNodeTransformation(XmlNode &node, Collada::Node *pNode, Collada::TransformType pType); /** Reads a mesh reference in a node and adds it to the node's mesh list */ - void ReadNodeGeometry(Collada::Node *pNode); + void ReadNodeGeometry(XmlNode &node, Collada::Node *pNode); /** Reads the collada scene */ - void ReadScene(); + void ReadScene(XmlNode &node); // Processes bind_vertex_input and bind elements - void ReadMaterialVertexInputBinding(Collada::SemanticMappingTable &tbl); + void ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl); /** Reads embedded textures from a ZAE archive*/ void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive); @@ -246,19 +247,19 @@ protected: void ReportWarning(const char *msg, ...); /** Skips all data until the end node of the current element */ - void SkipElement(); + //void SkipElement(); /** Skips all data until the end node of the given element */ - void SkipElement(const char *pElement); + //void SkipElement(const char *pElement); /** Compares the current xml element name to the given string and returns true if equal */ bool IsElement(const char *pName) const; /** Tests for the opening tag of the given element, throws an exception if not found */ - void TestOpening(const char *pName); + //void TestOpening(const char *pName); /** Tests for the closing tag of the given element, throws an exception if not found */ - void TestClosing(const char *pName); + //void TestClosing(const char *pName); /** Checks the present element for the presence of the attribute, returns its index or throws an exception if not found */ @@ -293,11 +294,12 @@ protected: const Type &ResolveLibraryReference(const std::map &pLibrary, const std::string &pURL) const; protected: - /** Filename, for a verbose error message */ + // Filename, for a verbose error message std::string mFileName; - /** XML reader, member for everyday use */ - irr::io::IrrXMLReader *mReader; + // XML reader, member for everyday use + //irr::io::IrrXMLReader *mReader; + XmlParser mXmlParser; /** All data arrays found in the file by ID. Might be referred to by actually everyone. Collada, you are a steaming pile of indirection. */ diff --git a/code/AssetLib/Irr/IRRMeshLoader.cpp b/code/AssetLib/Irr/IRRMeshLoader.cpp index 6129abf6a..904210d48 100644 --- a/code/AssetLib/Irr/IRRMeshLoader.cpp +++ b/code/AssetLib/Irr/IRRMeshLoader.cpp @@ -73,7 +73,11 @@ static const aiImporterDesc desc = { // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer -IRRMeshImporter::IRRMeshImporter() {} +IRRMeshImporter::IRRMeshImporter() : + BaseImporter(), + IrrlichtBase() { + // empty +} // ------------------------------------------------------------------------------------------------ // Destructor, private as well diff --git a/code/AssetLib/Irr/IRRMeshLoader.h b/code/AssetLib/Irr/IRRMeshLoader.h index f0d249f71..b77033ea2 100644 --- a/code/AssetLib/Irr/IRRMeshLoader.h +++ b/code/AssetLib/Irr/IRRMeshLoader.h @@ -4,7 +4,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2020, assimp team - All rights reserved. Redistribution and use of this software in source and binary forms, @@ -47,12 +46,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_IRRMESHLOADER_H_INCLUDED #define AI_IRRMESHLOADER_H_INCLUDED -#include #include "IRRShared.h" +#include #ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER -namespace Assimp { +namespace Assimp { // --------------------------------------------------------------------------- /** IrrMesh importer class. @@ -61,37 +60,31 @@ namespace Assimp { * irrEdit. As IrrEdit itself is capable of importing quite many file formats, * it might be a good file format for data exchange. */ -class IRRMeshImporter : public BaseImporter, public IrrlichtBase -{ +class IRRMeshImporter : public BaseImporter, public IrrlichtBase { public: IRRMeshImporter(); ~IRRMeshImporter(); - -public: - // ------------------------------------------------------------------- /** Returns whether the class can handle the format of the given file. * See BaseImporter::CanRead() for details. */ - bool CanRead( const std::string& pFile, IOSystem* pIOHandler, - bool checkSig) const; + bool CanRead(const std::string &pFile, IOSystem *pIOHandler, + bool checkSig) const; protected: - // ------------------------------------------------------------------- /** Return importer meta information. * See #BaseImporter::GetInfo for the details */ - const aiImporterDesc* GetInfo () const; + const aiImporterDesc *GetInfo() const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. * See BaseImporter::InternReadFile() for details */ - void InternReadFile( const std::string& pFile, aiScene* pScene, - IOSystem* pIOHandler); - + void InternReadFile(const std::string &pFile, aiScene *pScene, + IOSystem *pIOHandler); }; } // end of namespace Assimp diff --git a/code/AssetLib/Irr/IRRShared.cpp b/code/AssetLib/Irr/IRRShared.cpp index 3488e24ea..a809f7ce6 100644 --- a/code/AssetLib/Irr/IRRShared.cpp +++ b/code/AssetLib/Irr/IRRShared.cpp @@ -43,8 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * @brief Shared utilities for the IRR and IRRMESH loaders */ - - //This section should be excluded only if both the Irrlicht AND the Irrlicht Mesh importers were omitted. #if !(defined(ASSIMP_BUILD_NO_IRR_IMPORTER) && defined(ASSIMP_BUILD_NO_IRRMESH_IMPORTER)) @@ -57,7 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; // Transformation matrix to convert from Assimp to IRR space -static const aiMatrix4x4 Assimp::AI_TO_IRR_MATRIX = aiMatrix4x4 ( +const aiMatrix4x4 Assimp::AI_TO_IRR_MATRIX = aiMatrix4x4 ( 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, @@ -66,7 +64,7 @@ static const aiMatrix4x4 Assimp::AI_TO_IRR_MATRIX = aiMatrix4x4 ( // ------------------------------------------------------------------------------------------------ // read a property in hexadecimal format (i.e. ffffffff) void IrrlichtBase::ReadHexProperty(HexProperty &out ) { - for (pugi::xml_attribute attrib : mNode.attributes()) { + for (pugi::xml_attribute attrib : mNode->attributes()) { if (!ASSIMP_stricmp(attrib.name(), "name")) { out.name = std::string( attrib.value() ); } else if (!ASSIMP_stricmp(attrib.name(),"value")) { @@ -79,7 +77,7 @@ void IrrlichtBase::ReadHexProperty(HexProperty &out ) { // ------------------------------------------------------------------------------------------------ // read a decimal property void IrrlichtBase::ReadIntProperty(IntProperty & out) { - for (pugi::xml_attribute attrib : mNode.attributes()) { + for (pugi::xml_attribute attrib : mNode->attributes()) { if (!ASSIMP_stricmp(attrib.name(), "name")) { out.name = std::string(attrib.value()); } else if (!ASSIMP_stricmp(attrib.value(),"value")) { @@ -91,8 +89,8 @@ void IrrlichtBase::ReadIntProperty(IntProperty & out) { // ------------------------------------------------------------------------------------------------ // read a string property -void IrrlichtBase::ReadStringProperty (StringProperty& out) { - for (pugi::xml_attribute attrib : mNode.attributes()) { +void IrrlichtBase::ReadStringProperty( StringProperty& out) { + for (pugi::xml_attribute attrib : mNode->attributes()) { if (!ASSIMP_stricmp(attrib.name(), "name")) { out.name = std::string(attrib.value()); } else if (!ASSIMP_stricmp(attrib.name(), "value")) { @@ -105,7 +103,7 @@ void IrrlichtBase::ReadStringProperty (StringProperty& out) { // ------------------------------------------------------------------------------------------------ // read a boolean property void IrrlichtBase::ReadBoolProperty(BoolProperty &out) { - for (pugi::xml_attribute attrib : mNode.attributes()) { + for (pugi::xml_attribute attrib : mNode->attributes()) { if (!ASSIMP_stricmp(attrib.name(), "name")){ out.name = std::string(attrib.value()); } else if (!ASSIMP_stricmp(attrib.name(), "value")) { @@ -118,7 +116,7 @@ void IrrlichtBase::ReadBoolProperty(BoolProperty &out) { // ------------------------------------------------------------------------------------------------ // read a float property void IrrlichtBase::ReadFloatProperty(FloatProperty &out) { - for (pugi::xml_attribute attrib : mNode.attributes()) { + for (pugi::xml_attribute attrib : mNode->attributes()) { if (!ASSIMP_stricmp(attrib.name(), "name")) { out.name = std::string(attrib.value()); } else if (!ASSIMP_stricmp(attrib.name(), "value")) { @@ -131,7 +129,7 @@ void IrrlichtBase::ReadFloatProperty(FloatProperty &out) { // ------------------------------------------------------------------------------------------------ // read a vector property void IrrlichtBase::ReadVectorProperty( VectorProperty &out ) { - for (pugi::xml_attribute attrib : mNode.attributes()) { + for (pugi::xml_attribute attrib : mNode->attributes()) { if (!ASSIMP_stricmp(attrib.name(), "name")) { out.name = std::string(attrib.value()); } else if (!ASSIMP_stricmp(attrib.name(), "value")) { @@ -181,7 +179,7 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) { int cnt = 0; // number of used texture channels unsigned int nd = 0; - for (pugi::xml_node child : mNode.children()) { + for (pugi::xml_node child : mNode->children()) { if (!ASSIMP_stricmp(child.name(), "color")) { // Hex properties HexProperty prop; ReadHexProperty(prop); diff --git a/code/AssetLib/Irr/IRRShared.h b/code/AssetLib/Irr/IRRShared.h index 5495793c5..ce8851ebc 100644 --- a/code/AssetLib/Irr/IRRShared.h +++ b/code/AssetLib/Irr/IRRShared.h @@ -7,49 +7,48 @@ #ifndef INCLUDED_AI_IRRSHARED_H #define INCLUDED_AI_IRRSHARED_H -#include #include +#include #include struct aiMaterial; -namespace Assimp { +namespace Assimp { /** @brief Matrix to convert from Assimp to IRR and backwards */ extern const aiMatrix4x4 AI_TO_IRR_MATRIX; - // Default: 0 = solid, one texture -#define AI_IRRMESH_MAT_solid_2layer 0x10000 +#define AI_IRRMESH_MAT_solid_2layer 0x10000 // Transparency flags -#define AI_IRRMESH_MAT_trans_vertex_alpha 0x1 -#define AI_IRRMESH_MAT_trans_add 0x2 +#define AI_IRRMESH_MAT_trans_vertex_alpha 0x1 +#define AI_IRRMESH_MAT_trans_add 0x2 // Lightmapping flags -#define AI_IRRMESH_MAT_lightmap 0x2 -#define AI_IRRMESH_MAT_lightmap_m2 (AI_IRRMESH_MAT_lightmap|0x4) -#define AI_IRRMESH_MAT_lightmap_m4 (AI_IRRMESH_MAT_lightmap|0x8) -#define AI_IRRMESH_MAT_lightmap_light (AI_IRRMESH_MAT_lightmap|0x10) -#define AI_IRRMESH_MAT_lightmap_light_m2 (AI_IRRMESH_MAT_lightmap|0x20) -#define AI_IRRMESH_MAT_lightmap_light_m4 (AI_IRRMESH_MAT_lightmap|0x40) -#define AI_IRRMESH_MAT_lightmap_add (AI_IRRMESH_MAT_lightmap|0x80) +#define AI_IRRMESH_MAT_lightmap 0x2 +#define AI_IRRMESH_MAT_lightmap_m2 (AI_IRRMESH_MAT_lightmap | 0x4) +#define AI_IRRMESH_MAT_lightmap_m4 (AI_IRRMESH_MAT_lightmap | 0x8) +#define AI_IRRMESH_MAT_lightmap_light (AI_IRRMESH_MAT_lightmap | 0x10) +#define AI_IRRMESH_MAT_lightmap_light_m2 (AI_IRRMESH_MAT_lightmap | 0x20) +#define AI_IRRMESH_MAT_lightmap_light_m4 (AI_IRRMESH_MAT_lightmap | 0x40) +#define AI_IRRMESH_MAT_lightmap_add (AI_IRRMESH_MAT_lightmap | 0x80) // Standard NormalMap (or Parallax map, they're treated equally) -#define AI_IRRMESH_MAT_normalmap_solid (0x100) +#define AI_IRRMESH_MAT_normalmap_solid (0x100) // Normal map combined with vertex alpha -#define AI_IRRMESH_MAT_normalmap_tva \ +#define AI_IRRMESH_MAT_normalmap_tva \ (AI_IRRMESH_MAT_normalmap_solid | AI_IRRMESH_MAT_trans_vertex_alpha) // Normal map combined with additive transparency -#define AI_IRRMESH_MAT_normalmap_ta \ +#define AI_IRRMESH_MAT_normalmap_ta \ (AI_IRRMESH_MAT_normalmap_solid | AI_IRRMESH_MAT_trans_add) // Special flag. It indicates a second texture has been found // Its type depends ... either a normal textue or a normal map -#define AI_IRRMESH_EXTRA_2ND_TEXTURE 0x100000 +#define AI_IRRMESH_EXTRA_2ND_TEXTURE 0x100000 // --------------------------------------------------------------------------- /** Base class for the Irr and IrrMesh importers. @@ -57,58 +56,62 @@ extern const aiMatrix4x4 AI_TO_IRR_MATRIX; * Declares some irrlight-related xml parsing utilities and provides tools * to load materials from IRR and IRRMESH files. */ -class IrrlichtBase -{ +class IrrlichtBase { protected: + IrrlichtBase() : + mNode(nullptr) { + // empty + } + + ~IrrlichtBase() { + // empty + } /** @brief Data structure for a simple name-value property */ template - struct Property - { + struct Property { std::string name; T value; }; - typedef Property HexProperty; - typedef Property StringProperty; - typedef Property BoolProperty; - typedef Property FloatProperty; - typedef Property VectorProperty; - typedef Property IntProperty; + typedef Property HexProperty; + typedef Property StringProperty; + typedef Property BoolProperty; + typedef Property FloatProperty; + typedef Property VectorProperty; + typedef Property IntProperty; /// XML reader instance - XmlParser mParser; - pugi::xml_node &mNode; + XmlParser mParser; + pugi::xml_node *mNode; // ------------------------------------------------------------------- /** Parse a material description from the XML * @return The created material * @param matFlags Receives AI_IRRMESH_MAT_XX flags */ - aiMaterial* ParseMaterial(unsigned int& matFlags); + aiMaterial *ParseMaterial(unsigned int &matFlags); // ------------------------------------------------------------------- /** Read a property of the specified type from the current XML element. * @param out Receives output data */ - void ReadHexProperty (HexProperty& out); - void ReadStringProperty (StringProperty& out); - void ReadBoolProperty (BoolProperty& out); - void ReadFloatProperty (FloatProperty& out); - void ReadVectorProperty (VectorProperty& out); - void ReadIntProperty (IntProperty& out); + void ReadHexProperty(HexProperty &out); + void ReadStringProperty(StringProperty &out); + void ReadBoolProperty(BoolProperty &out); + void ReadFloatProperty(FloatProperty &out); + void ReadVectorProperty(VectorProperty &out); + void ReadIntProperty(IntProperty &out); }; - // ------------------------------------------------------------------------------------------------ // Unpack a hex color, e.g. 0xdcdedfff -inline -void ColorFromARGBPacked(uint32_t in, aiColor4D& clr) { +inline void ColorFromARGBPacked(uint32_t in, aiColor4D &clr) { clr.a = ((in >> 24) & 0xff) / 255.f; clr.r = ((in >> 16) & 0xff) / 255.f; - clr.g = ((in >> 8) & 0xff) / 255.f; - clr.b = ((in ) & 0xff) / 255.f; + clr.g = ((in >> 8) & 0xff) / 255.f; + clr.b = ((in)&0xff) / 255.f; } } // end namespace Assimp diff --git a/contrib/pugixml-1.9/src/pugixml.hpp b/contrib/pugixml-1.9/src/pugixml.hpp index 86403be31..8b5e9b92d 100644 --- a/contrib/pugixml-1.9/src/pugixml.hpp +++ b/contrib/pugixml-1.9/src/pugixml.hpp @@ -1251,6 +1251,8 @@ namespace pugi }; #ifndef PUGIXML_NO_EXCEPTIONS +#pragma warning(push) +#pragma warning( disable: 4275 ) // XPath exception class class PUGIXML_CLASS xpath_exception: public std::exception { @@ -1268,7 +1270,7 @@ namespace pugi const xpath_parse_result& result() const; }; #endif - +#pragma warning(pop) // XPath node class (either xml_node or xml_attribute) class PUGIXML_CLASS xpath_node { diff --git a/include/assimp/XmlParser.h b/include/assimp/XmlParser.h index 0bfcae88f..cbf0e4824 100644 --- a/include/assimp/XmlParser.h +++ b/include/assimp/XmlParser.h @@ -109,6 +109,10 @@ public: return &node; } + bool hasNode( const std::string &name ) const { + return nullptr != findNode(name); + } + TNodeType *parse(IOStream *stream) { if (nullptr == stream) { return nullptr;