diff --git a/code/AssetLib/Irr/IRRLoader.cpp b/code/AssetLib/Irr/IRRLoader.cpp index 2bdc3b6c5..c523ca5e5 100644 --- a/code/AssetLib/Irr/IRRLoader.cpp +++ b/code/AssetLib/Irr/IRRLoader.cpp @@ -833,7 +833,7 @@ void IRRImporter::GenerateGraph(Node *root, aiNode *rootOut, aiScene *scene, } // ------------------------------------------------------------------------------------------------ -void setupXmlTree(const std::string &filename, IOSystem *pIOHandler, pugi::xml_node &rootElement) { +void setupXmlTree(const std::string &filename, IOSystem *pIOHandler, XmlParser &xmlParser, pugi::xml_node &rootElement) { std::unique_ptr file(pIOHandler->Open(filename)); // Check whether we can read from the file @@ -842,18 +842,94 @@ void setupXmlTree(const std::string &filename, IOSystem *pIOHandler, pugi::xml_n } // Construct the irrXML parser - XmlParser st; - if (!st.parse(file.get())) { + if (!xmlParser.parse(file.get())) { throw DeadlyImportError("XML parse error while loading IRR file ", filename); } - rootElement = st.getRootNode().child("irr_scene"); + rootElement = xmlParser.getRootNode().child("irr_scene"); } +void IRRImporter::parseIrrNode(pugi::xml_node &node) { + // *********************************************************************** + /* What we're going to do with the node depends + * on its type: + * + * "mesh" - Load a mesh from an external file + * "cube" - Generate a cube + * "skybox" - Generate a skybox + * "light" - A light source + * "sphere" - Generate a sphere mesh + * "animatedMesh" - Load an animated mesh from an external file + * and join its animation channels with ours. + * "empty" - A dummy node + * "camera" - A camera + * "terrain" - a terrain node (data comes from a heightmap) + * "billboard", "" + * + * Each of these nodes can be animated and all can have multiple + * materials assigned (except lights, cameras and dummies, of course). + */ + // *********************************************************************** + pugi::xml_attribute attrib = node.attribute("type"); + Node *nd; + if (!ASSIMP_stricmp(attrib.value(), "mesh") || !ASSIMP_stricmp(attrib.value(), "octTree")) { + // OctTree's and meshes are treated equally + nd = new Node(Node::MESH); + } else if (!ASSIMP_stricmp(attrib.value(), "cube")) { + nd = new Node(Node::CUBE); + ++guessedMeshCnt; + } else if (!ASSIMP_stricmp(attrib.value(), "skybox")) { + nd = new Node(Node::SKYBOX); + guessedMeshCnt += 6; + } else if (!ASSIMP_stricmp(attrib.value(), "camera")) { + nd = new Node(Node::CAMERA); + + // Setup a temporary name for the camera + aiCamera *cam = new aiCamera(); + cam->mName.Set(nd->name); + cameras.push_back(cam); + } else if (!ASSIMP_stricmp(attrib.value(), "light")) { + nd = new Node(Node::LIGHT); + + // Setup a temporary name for the light + aiLight *cam = new aiLight(); + cam->mName.Set(nd->name); + lights.push_back(cam); + } else if (!ASSIMP_stricmp(attrib.value(), "sphere")) { + nd = new Node(Node::SPHERE); + ++guessedMeshCnt; + } else if (!ASSIMP_stricmp(attrib.value(), "animatedMesh")) { + nd = new Node(Node::ANIMMESH); + } else if (!ASSIMP_stricmp(attrib.value(), "empty")) { + nd = new Node(Node::DUMMY); + } else if (!ASSIMP_stricmp(attrib.value(), "terrain")) { + nd = new Node(Node::TERRAIN); + } else if (!ASSIMP_stricmp(attrib.value(), "billBoard")) { + // We don't support billboards, so ignore them + ASSIMP_LOG_ERROR("IRR: Billboards are not supported by Assimp"); + nd = new Node(Node::DUMMY); + } else { + ASSIMP_LOG_WARN("IRR: Found unknown node: ", attrib.value()); + + /* We skip the contents of nodes we don't know. + * We parse the transformation and all animators + * and skip the rest. + */ + nd = new Node(Node::DUMMY); + } + + /* Attach the newly created node to the scene-graph + */ + curNode = nd; + nd->parent = curParent; + curParent->children.push_back(nd); + } + // ------------------------------------------------------------------------------------------------ // Imports the given file into the given scene structure. void IRRImporter::InternReadFile(const std::string &filename, aiScene *pScene, IOSystem *pIOHandler) { pugi::xml_node rootElement; - setupXmlTree(filename, pIOHandler, rootElement); + XmlParser xmlParser; + setupXmlTree(filename, pIOHandler, xmlParser, rootElement); //std::unique_ptr file(pIOHandler->Open(pFile)); // Check whether we can read from the file diff --git a/code/AssetLib/Irr/IRRLoader.h b/code/AssetLib/Irr/IRRLoader.h index b32150a1c..476c8bee4 100644 --- a/code/AssetLib/Irr/IRRLoader.h +++ b/code/AssetLib/Irr/IRRLoader.h @@ -78,6 +78,7 @@ protected: const aiImporterDesc* GetInfo () const override; void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override; void SetupProperties(const Importer* pImp) override; + void parseIrrNode(); private: /** Data structure for a scene-graph node animator diff --git a/code/AssetLib/Irr/IRRMeshLoader.cpp b/code/AssetLib/Irr/IRRMeshLoader.cpp index 52fb82ff9..442ba8fe2 100644 --- a/code/AssetLib/Irr/IRRMeshLoader.cpp +++ b/code/AssetLib/Irr/IRRMeshLoader.cpp @@ -69,14 +69,6 @@ static const aiImporterDesc desc = { "xml irrmesh" }; -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -IRRMeshImporter::IRRMeshImporter() = default; - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -IRRMeshImporter::~IRRMeshImporter() = default; - // ------------------------------------------------------------------------------------------------ // Returns whether the class can handle the format of the given file. bool IRRMeshImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { diff --git a/code/AssetLib/Irr/IRRMeshLoader.h b/code/AssetLib/Irr/IRRMeshLoader.h index 79c1e486b..6dd220e2e 100644 --- a/code/AssetLib/Irr/IRRMeshLoader.h +++ b/code/AssetLib/Irr/IRRMeshLoader.h @@ -62,8 +62,8 @@ namespace Assimp { */ class IRRMeshImporter : public BaseImporter, public IrrlichtBase { public: - IRRMeshImporter(); - ~IRRMeshImporter() override; + IRRMeshImporter() = default; + ~IRRMeshImporter() override = default; // ------------------------------------------------------------------- /** Returns whether the class can handle the format of the given file. diff --git a/code/AssetLib/Irr/IRRShared.cpp b/code/AssetLib/Irr/IRRShared.cpp index 8763b63ae..e2e5c46eb 100644 --- a/code/AssetLib/Irr/IRRShared.cpp +++ b/code/AssetLib/Irr/IRRShared.cpp @@ -55,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 -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, @@ -64,7 +64,7 @@ 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 (const 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")) { @@ -77,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 (const 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")) { @@ -90,7 +90,7 @@ void IrrlichtBase::ReadIntProperty(IntProperty & out) { // ------------------------------------------------------------------------------------------------ // read a string property void IrrlichtBase::ReadStringProperty( StringProperty& out) { - for (pugi::xml_attribute attrib : mNode->attributes()) { + for (const 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")) { @@ -103,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 (const 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")) { @@ -116,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 (const 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")) { @@ -129,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 (const 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")) { @@ -179,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 (const pugi::xml_node &child : mNode->children()) { if (!ASSIMP_stricmp(child.name(), "color")) { // Hex properties HexProperty prop; ReadHexProperty(prop);