From 5a81b42ebe606535c210e58b4e10f428ebf844e8 Mon Sep 17 00:00:00 2001 From: aramis_acg Date: Sun, 22 Apr 2012 22:26:26 +0000 Subject: [PATCH] - add mFileExtensions field to aiImporterDesc, BaseImporter::GetExtensionList is now longer virtual since this would be redundant. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1234 67173fc5-114c-0410-ac8e-9d2fd5bffc1f --- code/3DSLoader.cpp | 21 +- code/3DSLoader.h | 6 +- code/ACLoader.cpp | 20 +- code/ACLoader.h | 6 +- code/ASELoader.cpp | 19 +- code/ASELoader.h | 6 +- code/B3DImporter.cpp | 19 +- code/B3DImporter.h | 2 +- code/BVHLoader.cpp | 20 + code/BVHLoader.h | 10 +- code/BaseImporter.cpp | 19 + code/BaseImporter.h | 26 +- code/BlenderLoader.cpp | 5 +- code/COBLoader.cpp | 21 +- code/COBLoader.h | 2 +- code/CSMLoader.cpp | 18 +- code/CSMLoader.h | 2 +- code/ColladaLoader.cpp | 18 +- code/ColladaLoader.h | 6 +- code/DXFLoader.cpp | 18 +- code/DXFLoader.h | 6 +- code/HMPLoader.cpp | 17 +- code/HMPLoader.h | 6 +- code/IFCLoader.cpp | 18 +- code/IFCLoader.h | 2 +- code/IRRLoader.cpp | 17 +- code/IRRLoader.h | 2 +- code/IRRMeshLoader.cpp | 18 +- code/IRRMeshLoader.h | 6 +- code/LWOLoader.cpp | 23 +- code/LWOLoader.h | 10 +- code/LWSLoader.cpp | 18 +- code/LWSLoader.h | 2 +- code/M3Importer.cpp | 19 +- code/M3Importer.h | 2 +- code/MD2Loader.cpp | 17 +- code/MD2Loader.h | 6 +- code/MD3Loader.cpp | 17 +- code/MD3Loader.h | 6 +- code/MD5Loader.cpp | 20 +- code/MD5Loader.h | 6 +- code/MDCLoader.cpp | 16 +- code/MDCLoader.h | 6 +- code/MDLLoader.cpp | 17 +- code/MDLLoader.h | 6 +- code/MS3DLoader.cpp | 17 +- code/MS3DLoader.h | 6 +- code/NDOLoader.cpp | 17 +- code/NDOLoader.h | 2 +- code/NFFLoader.cpp | 18 +- code/NFFLoader.h | 6 +- code/OFFLoader.cpp | 17 +- code/OFFLoader.h | 6 +- code/ObjFileImporter.cpp | 20 + code/ObjFileImporter.h | 9 +- code/OgreImporter.cpp | 17 +- code/OgreImporter.hpp | 4 +- code/OgreMesh.cpp | 1014 ++++++++++++++++----------------- code/OgreSkeleton.cpp | 910 ++++++++++++++--------------- code/PlyLoader.cpp | 17 +- code/PlyLoader.h | 6 +- code/Q3BSPFileImporter.cpp | 22 +- code/Q3BSPFileImporter.h | 2 +- code/Q3DLoader.cpp | 18 +- code/Q3DLoader.h | 6 +- code/RawLoader.cpp | 18 +- code/RawLoader.h | 6 +- code/SMDLoader.cpp | 18 +- code/SMDLoader.h | 6 +- code/STLLoader.cpp | 16 +- code/STLLoader.h | 6 +- code/TerragenLoader.cpp | 17 +- code/TerragenLoader.h | 2 +- code/UnrealLoader.cpp | 19 +- code/UnrealLoader.h | 4 +- code/XFileImporter.cpp | 18 +- code/XFileImporter.h | 6 +- code/XGLLoader.cpp | 18 +- code/XGLLoader.h | 6 +- include/assimp/importerdesc.h | 14 + workspaces/vc9/assimp.vcproj | 2 +- 81 files changed, 1681 insertions(+), 1176 deletions(-) diff --git a/code/3DSLoader.cpp b/code/3DSLoader.cpp index 867182af4..336a1390b 100644 --- a/code/3DSLoader.cpp +++ b/code/3DSLoader.cpp @@ -52,6 +52,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "3DSLoader.h" using namespace Assimp; + +static const aiImporterDesc desc = { + "Discreet 3DS Importer", + "", + "", + "Limited animation support", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "3ds prj" +}; + // ------------------------------------------------------------------------------------------------ // Begins a new parsing block @@ -108,11 +122,10 @@ bool Discreet3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandle } // ------------------------------------------------------------------------------------------------ -// Get list of all extension supported by this loader -void Discreet3DSImporter::GetExtensionList(std::set& extensions) +// Loader registry entry +const aiImporterDesc* Discreet3DSImporter::GetInfo () const { - extensions.insert("3ds"); - extensions.insert("prj"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/3DSLoader.h b/code/3DSLoader.h index 84c17e3d4..5f13f7626 100644 --- a/code/3DSLoader.h +++ b/code/3DSLoader.h @@ -85,10 +85,10 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/ACLoader.cpp b/code/ACLoader.cpp index aa5815856..fdb2c02cb 100644 --- a/code/ACLoader.cpp +++ b/code/ACLoader.cpp @@ -54,6 +54,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "AC3D Importer", + "", + "", + "", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "ac acc ac3d" +}; // ------------------------------------------------------------------------------------------------ // skip to the next token @@ -136,12 +148,10 @@ bool AC3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool } // ------------------------------------------------------------------------------------------------ -// Get list of file extensions handled by this loader -void AC3DImporter::GetExtensionList(std::set& extensions) +// Loader meta information +const aiImporterDesc* AC3DImporter::GetInfo () const { - extensions.insert("ac"); - extensions.insert("acc"); - extensions.insert("ac3d"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/ACLoader.h b/code/ACLoader.h index b0144b766..2724053e4 100644 --- a/code/ACLoader.h +++ b/code/ACLoader.h @@ -183,9 +183,9 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details */ - void GetExtensionList(std::set& extensions); + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/ASELoader.cpp b/code/ASELoader.cpp index 998571089..1f0c49eb9 100644 --- a/code/ASELoader.cpp +++ b/code/ASELoader.cpp @@ -58,6 +58,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; using namespace Assimp::ASE; +static const aiImporterDesc desc = { + "ASE Importer", + "", + "", + "Similar to 3DS but text-encoded", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "ase ask" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer ASEImporter::ASEImporter() @@ -86,10 +99,10 @@ bool ASEImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool } // ------------------------------------------------------------------------------------------------ -void ASEImporter::GetExtensionList(std::set& extensions) +// Loader meta information +const aiImporterDesc* ASEImporter::GetInfo () const { - extensions.insert("ase"); - extensions.insert("ask"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/ASELoader.h b/code/ASELoader.h index a4b67659b..796b395b9 100644 --- a/code/ASELoader.h +++ b/code/ASELoader.h @@ -75,10 +75,10 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- diff --git a/code/B3DImporter.cpp b/code/B3DImporter.cpp index dd24b172a..53c744d54 100644 --- a/code/B3DImporter.cpp +++ b/code/B3DImporter.cpp @@ -54,6 +54,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; using namespace std; +static const aiImporterDesc desc = { + "BlitzBasic 3D Importer", + "", + "", + "http://www.blitzbasic.com/", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "b3d" +}; + // (fixme, Aramis) quick workaround to get rid of all those signed to unsigned warnings #ifdef _MSC_VER # pragma warning (disable: 4018) @@ -74,8 +87,10 @@ bool B3DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, b } // ------------------------------------------------------------------------------------------------ -void B3DImporter::GetExtensionList( std::set& extensions ){ - extensions.insert("b3d"); +// Loader meta information +const aiImporterDesc* B3DImporter::GetInfo () const +{ + return &desc; } #ifdef DEBUG_B3D diff --git a/code/B3DImporter.h b/code/B3DImporter.h index 47b35a74a..e787ec47c 100644 --- a/code/B3DImporter.h +++ b/code/B3DImporter.h @@ -60,7 +60,7 @@ public: protected: - virtual void GetExtensionList(std::set& extensions); + virtual const aiImporterDesc* GetInfo () const; virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); private: diff --git a/code/BVHLoader.cpp b/code/BVHLoader.cpp index 0f8b9db7f..1464e4d7c 100644 --- a/code/BVHLoader.cpp +++ b/code/BVHLoader.cpp @@ -49,6 +49,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "BVH Importer (MoCap)", + "", + "", + "", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "bvh" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer BVHLoader::BVHLoader() @@ -76,6 +89,13 @@ bool BVHLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs return false; } +// ------------------------------------------------------------------------------------------------ +// Loader meta information +const aiImporterDesc* BVHLoader::GetInfo () const +{ + return &desc; +} + // ------------------------------------------------------------------------------------------------ // Imports the given file into the given scene structure. void BVHLoader::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) diff --git a/code/BVHLoader.h b/code/BVHLoader.h index 5f101cebf..7e8237970 100644 --- a/code/BVHLoader.h +++ b/code/BVHLoader.h @@ -94,14 +94,10 @@ public: * See BaseImporter::CanRead() for details. */ bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const; + const aiImporterDesc* GetInfo () const; + protected: - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details - */ - void GetExtensionList(std::set& extensions) - { - extensions.insert("bvh"); - } + /** Imports the given file into the given scene structure. * See BaseImporter::InternReadFile() for details diff --git a/code/BaseImporter.cpp b/code/BaseImporter.cpp index 3c6bdb5ce..6fdb3b3b5 100644 --- a/code/BaseImporter.cpp +++ b/code/BaseImporter.cpp @@ -105,6 +105,25 @@ void BaseImporter::SetupProperties(const Importer* /*pImp*/) // the default implementation does nothing } +// ------------------------------------------------------------------------------------------------ +void BaseImporter::GetExtensionList(std::set& extensions) +{ + const aiImporterDesc* desc = GetInfo(); + ai_assert(desc != NULL); + + const char* ext = desc->mFileExtensions; + ai_assert(ext != NULL); + + const char* last = ext; + do { + if (!*ext || *ext == ' ') { + extensions.insert(std::string(last,ext-last)); + last = ext+1; + } + } + while(*ext++); +} + // ------------------------------------------------------------------------------------------------ /*static*/ bool BaseImporter::SearchFileHeaderForToken(IOSystem* pIOHandler, const std::string& pFile, diff --git a/code/BaseImporter.h b/code/BaseImporter.h index 07b937d79..073a476f3 100644 --- a/code/BaseImporter.h +++ b/code/BaseImporter.h @@ -187,26 +187,22 @@ public: const Importer* pImp ); -protected: - + // ------------------------------------------------------------------- /** Called by #Importer::GetImporterInfo to get a description of - * some loader features. Importer need not provide this structure, - * but it is highly recommended. */ - virtual const aiImporterDesc* GetInfo() { - return NULL; - } + * some loader features. Importers must provide this information. */ + virtual const aiImporterDesc* GetInfo() const = 0; + + // ------------------------------------------------------------------- /** Called by #Importer::GetExtensionList for each loaded importer. - * Implementations are expected to insert() all file extensions - * handled by them into the extension set. A loader capable of - * reading certain files with the extension BLA would place the - * string bla (lower-case!) in the output set. - * @param extensions Output set. */ - virtual void GetExtensionList( - std::set& extensions - ) = 0; + * Take the extension list contained in the structure returned by + * #GetInfo and insert all file extensions into the given set. + * @param extension set to collect file extensions in*/ + void GetExtensionList(std::set& extensions); + +protected: // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. The diff --git a/code/BlenderLoader.cpp b/code/BlenderLoader.cpp index 9d2c3d0fc..4e15727bc 100644 --- a/code/BlenderLoader.cpp +++ b/code/BlenderLoader.cpp @@ -75,12 +75,13 @@ static const aiImporterDesc blenderDesc = { "Blender 3D Importer \nhttp://www.blender3d.org", "", "", - "", + "No animation support yet", aiImporterFlags_SupportBinaryFlavour, 0, 0, 2, - 50 + 50, + "blend" }; diff --git a/code/COBLoader.cpp b/code/COBLoader.cpp index a0db4788e..71b8209b3 100644 --- a/code/COBLoader.cpp +++ b/code/COBLoader.cpp @@ -72,6 +72,20 @@ static const float units[] = { 1.f/1609.344f }; +static const aiImporterDesc desc = { + "TrueSpace Object Importer", + "", + "", + "little-endian files only", + aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "cob scn" +}; + + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer COBImporter::COBImporter() @@ -99,11 +113,10 @@ bool COBImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool } // ------------------------------------------------------------------------------------------------ -// List all extensions handled by this loader -void COBImporter::GetExtensionList(std::set& app) +// Loader meta information +const aiImporterDesc* COBImporter::GetInfo () const { - app.insert("cob"); - app.insert("scn"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/COBLoader.h b/code/COBLoader.h index 7831bec6a..b6f0b045b 100644 --- a/code/COBLoader.h +++ b/code/COBLoader.h @@ -82,7 +82,7 @@ public: protected: // -------------------- - void GetExtensionList(std::set& app); + const aiImporterDesc* GetInfo () const; // -------------------- void SetupProperties(const Importer* pImp); diff --git a/code/CSMLoader.cpp b/code/CSMLoader.cpp index 84730738e..ab50762e4 100644 --- a/code/CSMLoader.cpp +++ b/code/CSMLoader.cpp @@ -54,6 +54,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "CharacterStudio Motion Importer (MoCap)", + "", + "", + "", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "csm" +}; + + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer CSMImporter::CSMImporter() @@ -83,9 +97,9 @@ bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool // ------------------------------------------------------------------------------------------------ // Build a string of all file extensions supported -void CSMImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* CSMImporter::GetInfo () const { - extensions.insert("csm"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/CSMLoader.h b/code/CSMLoader.h index f3511c0d4..15760845c 100644 --- a/code/CSMLoader.h +++ b/code/CSMLoader.h @@ -69,7 +69,7 @@ public: protected: // ------------------------------------------------------------------- - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- void SetupProperties(const Importer* pImp); diff --git a/code/ColladaLoader.cpp b/code/ColladaLoader.cpp index b6e598128..fd5a5be7a 100644 --- a/code/ColladaLoader.cpp +++ b/code/ColladaLoader.cpp @@ -56,6 +56,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "Collada Importer", + "", + "", + "http://collada.org", + aiImporterFlags_SupportTextFlavour, + 1, + 3, + 1, + 5, + "dae" +}; + + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer ColladaLoader::ColladaLoader() @@ -91,9 +105,9 @@ bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo // ------------------------------------------------------------------------------------------------ // Get file extension list -void ColladaLoader::GetExtensionList( std::set& extensions ) +const aiImporterDesc* ColladaLoader::GetInfo () const { - extensions.insert("dae"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/ColladaLoader.h b/code/ColladaLoader.h index 6ac4e72a7..b2b903077 100644 --- a/code/ColladaLoader.h +++ b/code/ColladaLoader.h @@ -89,10 +89,10 @@ public: bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const; protected: - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList( std::set& extensions); + const aiImporterDesc* GetInfo () const; /** Imports the given file into the given scene structure. * See BaseImporter::InternReadFile() for details diff --git a/code/DXFLoader.cpp b/code/DXFLoader.cpp index 274b8ef79..db443a772 100644 --- a/code/DXFLoader.cpp +++ b/code/DXFLoader.cpp @@ -86,6 +86,20 @@ static aiColor4D g_aclrDxfIndexColors[] = #define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0])) #define AI_DXF_ENTITIES_MAGIC_BLOCK "$ASSIMP_ENTITIES_MAGIC" + +static const aiImporterDesc desc = { + "Drawing Interchange Format (DXF) Importer", + "", + "", + "", + aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport, + 0, + 0, + 0, + 0, + "dxf" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer DXFImporter::DXFImporter() @@ -105,9 +119,9 @@ bool DXFImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, b // ------------------------------------------------------------------------------------------------ // Get a list of all supported file extensions -void DXFImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* DXFImporter::GetInfo () const { - extensions.insert("dxf"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/DXFLoader.h b/code/DXFLoader.h index 487986958..f3eb46c1c 100644 --- a/code/DXFLoader.h +++ b/code/DXFLoader.h @@ -82,9 +82,9 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details*/ - void GetExtensionList(std::set& extensions); + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details*/ + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/HMPLoader.cpp b/code/HMPLoader.cpp index c89b37f83..f5eb31bff 100644 --- a/code/HMPLoader.cpp +++ b/code/HMPLoader.cpp @@ -50,6 +50,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "3D GameStudio Heightmap (HMP) Importer", + "", + "", + "", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "hmp" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer HMPImporter::HMPImporter() @@ -85,9 +98,9 @@ bool HMPImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool // ------------------------------------------------------------------------------------------------ // Get list of all file extensions that are handled by this loader -void HMPImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* HMPImporter::GetInfo () const { - extensions.insert("hmp"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/HMPLoader.h b/code/HMPLoader.h index 12f2cb71f..0a5e0183d 100644 --- a/code/HMPLoader.h +++ b/code/HMPLoader.h @@ -80,10 +80,10 @@ protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/IFCLoader.cpp b/code/IFCLoader.cpp index f2a361dea..6b8789be0 100644 --- a/code/IFCLoader.cpp +++ b/code/IFCLoader.cpp @@ -93,6 +93,20 @@ void ConvertUnit(const EXPRESS::DataType& dt,ConversionData& conv); } // anon +static const aiImporterDesc desc = { + "Industry Foundation Classes (IFC) Importer", + "", + "", + "", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "ifc" +}; + + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer IFCImporter::IFCImporter() @@ -125,9 +139,9 @@ bool IFCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool // ------------------------------------------------------------------------------------------------ // List all extensions handled by this loader -void IFCImporter::GetExtensionList(std::set& app) +const aiImporterDesc* IFCImporter::GetInfo () const { - app.insert("ifc"); + return &desc; } diff --git a/code/IFCLoader.h b/code/IFCLoader.h index 097eae3cf..039770155 100644 --- a/code/IFCLoader.h +++ b/code/IFCLoader.h @@ -85,7 +85,7 @@ public: protected: // -------------------- - void GetExtensionList(std::set& app); + const aiImporterDesc* GetInfo () const; // -------------------- void SetupProperties(const Importer* pImp); diff --git a/code/IRRLoader.cpp b/code/IRRLoader.cpp index b41462998..253b333f4 100644 --- a/code/IRRLoader.cpp +++ b/code/IRRLoader.cpp @@ -61,6 +61,18 @@ using namespace Assimp; using namespace irr; using namespace irr::io; +static const aiImporterDesc desc = { + "Irrlicht Scene Reader", + "", + "", + "http://irrlicht.sourceforge.net/", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "irr xml" +}; // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer @@ -98,10 +110,9 @@ bool IRRImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool } // ------------------------------------------------------------------------------------------------ -void IRRImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* IRRImporter::GetInfo () const { - extensions.insert("irr"); - extensions.insert("xml"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/IRRLoader.h b/code/IRRLoader.h index 5f55c33fc..673c83074 100644 --- a/code/IRRLoader.h +++ b/code/IRRLoader.h @@ -80,7 +80,7 @@ protected: // ------------------------------------------------------------------- /** */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** diff --git a/code/IRRMeshLoader.cpp b/code/IRRMeshLoader.cpp index 1ae33bb58..84f7169c7 100644 --- a/code/IRRMeshLoader.cpp +++ b/code/IRRMeshLoader.cpp @@ -51,6 +51,19 @@ using namespace Assimp; using namespace irr; using namespace irr::io; +static const aiImporterDesc desc = { + "Irrlicht Mesh Reader", + "", + "", + "http://irrlicht.sourceforge.net/", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "xml irrmesh" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer IRRMeshImporter::IRRMeshImporter() @@ -88,10 +101,9 @@ bool IRRMeshImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, b // ------------------------------------------------------------------------------------------------ // Get a list of all file extensions which are handled by this class -void IRRMeshImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* IRRMeshImporter::GetInfo () const { - extensions.insert("xml"); - extensions.insert("irrmesh"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/IRRMeshLoader.h b/code/IRRMeshLoader.h index c5ea8f51e..347ee0a70 100644 --- a/code/IRRMeshLoader.h +++ b/code/IRRMeshLoader.h @@ -76,10 +76,10 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/LWOLoader.cpp b/code/LWOLoader.cpp index f490e3cfc..8e848e30e 100644 --- a/code/LWOLoader.cpp +++ b/code/LWOLoader.cpp @@ -56,6 +56,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "LightWave/Modo Object Importer", + "", + "", + "http://www.newtek.com/lightwave.html\nhttp://www.luxology.com/modo/", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "lwo lxo" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer LWOImporter::LWOImporter() @@ -71,8 +84,9 @@ LWOImporter::~LWOImporter() bool LWOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const { const std::string extension = GetExtension(pFile); - if (extension == "lwo" || extension == "lxo") + if (extension == "lwo" || extension == "lxo") { return true; + } // if check for extension is not enough, check for the magic tokens if (!extension.length() || checkSig) { @@ -94,6 +108,13 @@ void LWOImporter::SetupProperties(const Importer* pImp) configLayerName = pImp->GetPropertyString (AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY,""); } +// ------------------------------------------------------------------------------------------------ +// Get list of file extensions +const aiImporterDesc* LWOImporter::GetInfo () const +{ + return &desc; +} + // ------------------------------------------------------------------------------------------------ // Imports the given file into the given scene structure. void LWOImporter::InternReadFile( const std::string& pFile, diff --git a/code/LWOLoader.h b/code/LWOLoader.h index 46a269502..bf93998c1 100644 --- a/code/LWOLoader.h +++ b/code/LWOLoader.h @@ -91,14 +91,8 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details - */ - void GetExtensionList(std::set& extensions) - { - extensions.insert("lxo"); - extensions.insert("lwo"); - } + // Get list of supported extensions + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/LWSLoader.cpp b/code/LWSLoader.cpp index 3d60dbce8..9058f9169 100644 --- a/code/LWSLoader.cpp +++ b/code/LWSLoader.cpp @@ -57,6 +57,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "LightWave Scene Importer", + "", + "", + "http://www.newtek.com/lightwave.html=", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "lws mot" +}; + // ------------------------------------------------------------------------------------------------ // Recursive parsing of LWS files void LWS::Element::Parse (const char*& buffer) @@ -141,10 +154,9 @@ bool LWSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler,bool c // ------------------------------------------------------------------------------------------------ // Get list of file extensions -void LWSImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* LWSImporter::GetInfo () const { - extensions.insert("lws"); - extensions.insert("mot"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/LWSLoader.h b/code/LWSLoader.h index 799c2c906..d3a6d2787 100644 --- a/code/LWSLoader.h +++ b/code/LWSLoader.h @@ -184,7 +184,7 @@ protected: // ------------------------------------------------------------------- // Get list of supported extensions - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- // Import file into given scene data structure diff --git a/code/M3Importer.cpp b/code/M3Importer.cpp index 1f4954e04..f26e7805e 100644 --- a/code/M3Importer.cpp +++ b/code/M3Importer.cpp @@ -47,7 +47,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace Assimp { namespace M3 { -static const std::string M3Extension = "m3"; +static const aiImporterDesc desc = { + "StarCraft M3 Importer", + "", + "", + "", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "m3" +}; // ------------------------------------------------------------------------------------------------ // Constructor. @@ -72,16 +83,16 @@ M3Importer::~M3Importer() bool M3Importer::CanRead( const std::string &rFile, IOSystem* /*pIOHandler*/, bool checkSig ) const { if ( !checkSig ) { - return SimpleExtensionCheck( rFile, M3Extension.c_str() ); + return SimpleExtensionCheck( rFile, "m3" ); } return false; } // ------------------------------------------------------------------------------------------------ -void M3Importer::GetExtensionList(std::set& extensions) +const aiImporterDesc* M3Importer::GetInfo () const { - extensions.insert( M3Extension ); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/M3Importer.h b/code/M3Importer.h index 3780f6598..a61678398 100644 --- a/code/M3Importer.h +++ b/code/M3Importer.h @@ -694,7 +694,7 @@ public: bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const; private: - void GetExtensionList( std::set& extensions ); + const aiImporterDesc* GetInfo () const; void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ); void convertToAssimp( const std::string& pFile, aiScene* pScene, DIV *pViews, Region *pRegions, uint16 *pFaces, const std::vector &vertices, const std::vector &uvCoords, const std::vector &normals ); diff --git a/code/MD2Loader.cpp b/code/MD2Loader.cpp index 3a254b176..434d23f14 100644 --- a/code/MD2Loader.cpp +++ b/code/MD2Loader.cpp @@ -56,6 +56,19 @@ using namespace Assimp::MD2; # define ARRAYSIZE(_array) (int(sizeof(_array) / sizeof(_array[0]))) #endif +static const aiImporterDesc desc = { + "Quake II Mesh Importer", + "", + "", + "", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "md2" +}; + // ------------------------------------------------------------------------------------------------ // Helper function to lookup a normal in Quake 2's precalculated table void MD2::LookupNormalIndex(uint8_t iNormalIndex,aiVector3D& vOut) @@ -98,9 +111,9 @@ bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool // ------------------------------------------------------------------------------------------------ // Get a list of all extensions supported by this loader -void MD2Importer::GetExtensionList(std::set& extensions) +const aiImporterDesc* MD2Importer::GetInfo () const { - extensions.insert("md2"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/MD2Loader.h b/code/MD2Loader.h index 6a29b13e9..f78112056 100644 --- a/code/MD2Loader.h +++ b/code/MD2Loader.h @@ -84,10 +84,10 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/MD3Loader.cpp b/code/MD3Loader.cpp index ef009701d..49cecd1bf 100644 --- a/code/MD3Loader.cpp +++ b/code/MD3Loader.cpp @@ -61,6 +61,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "Quake III Mesh Importer", + "", + "", + "", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "md3" +}; + // ------------------------------------------------------------------------------------------------ // Convert a Q3 shader blend function to the appropriate enum value Q3Shader::BlendFunc StringToBlendFunc(const std::string& m) @@ -420,9 +433,9 @@ void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf) } // ------------------------------------------------------------------------------------------------ -void MD3Importer::GetExtensionList(std::set& extensions) +const aiImporterDesc* MD3Importer::GetInfo () const { - extensions.insert("md3"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/MD3Loader.h b/code/MD3Loader.h index 22559f53c..155c9ce37 100644 --- a/code/MD3Loader.h +++ b/code/MD3Loader.h @@ -235,10 +235,10 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/MD5Loader.cpp b/code/MD5Loader.cpp index 4db1b0339..cd6f6a155 100644 --- a/code/MD5Loader.cpp +++ b/code/MD5Loader.cpp @@ -58,6 +58,20 @@ using namespace Assimp; // Minimum weight value. Weights inside [-n ... n] are ignored #define AI_MD5_WEIGHT_EPSILON 1e-5f + +static const aiImporterDesc desc = { + "Doom 3 / MD5 Mesh Importer", + "", + "", + "", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "md5mesh md5camera md5anim" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer MD5Importer::MD5Importer() @@ -90,11 +104,9 @@ bool MD5Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool // ------------------------------------------------------------------------------------------------ // Get list of all supported extensions -void MD5Importer::GetExtensionList(std::set& extensions) +const aiImporterDesc* MD5Importer::GetInfo () const { - extensions.insert("md5anim"); - extensions.insert("md5mesh"); - extensions.insert("md5camera"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/MD5Loader.h b/code/MD5Loader.h index 55c9ec1db..f7aa63c79 100644 --- a/code/MD5Loader.h +++ b/code/MD5Loader.h @@ -78,10 +78,10 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Called prior to ReadFile(). diff --git a/code/MDCLoader.cpp b/code/MDCLoader.cpp index 2b0ab5b90..f8b0cb8c2 100644 --- a/code/MDCLoader.cpp +++ b/code/MDCLoader.cpp @@ -52,6 +52,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; using namespace Assimp::MDC; +static const aiImporterDesc desc = { + "Return To Castle Wolfenstein Mesh Importer", + "", + "", + "", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "mdc" +}; // ------------------------------------------------------------------------------------------------ void MDC::BuildVertex(const Frame& frame, @@ -103,9 +115,9 @@ bool MDCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool } // ------------------------------------------------------------------------------------------------ -void MDCImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* MDCImporter::GetInfo () const { - extensions.insert("mdc"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/MDCLoader.h b/code/MDCLoader.h index 63c7e67c6..8d1c9878d 100644 --- a/code/MDCLoader.h +++ b/code/MDCLoader.h @@ -81,10 +81,10 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/MDLLoader.cpp b/code/MDLLoader.cpp index 4b46329be..1ce0347ef 100644 --- a/code/MDLLoader.cpp +++ b/code/MDLLoader.cpp @@ -54,6 +54,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "Quake Mesh / 3D GameStudio Mesh Importer", + "", + "", + "", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 7, + 0, + "mdl" +}; + // ------------------------------------------------------------------------------------------------ // Ugly stuff ... nevermind #define _AI_MDL7_ACCESS(_data, _index, _limit, _type) \ @@ -116,9 +129,9 @@ void MDLImporter::SetupProperties(const Importer* pImp) // ------------------------------------------------------------------------------------------------ // Get a list of all supported extensions -void MDLImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* MDLImporter::GetInfo () const { - extensions.insert( "mdl" ); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/MDLLoader.h b/code/MDLLoader.h index c6b7924d6..81706736d 100644 --- a/code/MDLLoader.h +++ b/code/MDLLoader.h @@ -107,10 +107,10 @@ protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/MS3DLoader.cpp b/code/MS3DLoader.cpp index c3964ca46..f24aa1382 100644 --- a/code/MS3DLoader.cpp +++ b/code/MS3DLoader.cpp @@ -52,6 +52,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "StreamReader.h" using namespace Assimp; +static const aiImporterDesc desc = { + "Milkshape 3D Importer", + "", + "", + "http://chumbalum.swissquake.ch/", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "ms3d" +}; + // ASSIMP_BUILD_MS3D_ONE_NODE_PER_MESH // (enable old code path, which generates extra nodes per mesh while // the newer code uses aiMesh::mName to express the name of the @@ -89,9 +102,9 @@ bool MS3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool } // ------------------------------------------------------------------------------------------------ -void MS3DImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* MS3DImporter::GetInfo () const { - extensions.insert("ms3d"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/MS3DLoader.h b/code/MS3DLoader.h index c3e3bdd36..d060808d6 100644 --- a/code/MS3DLoader.h +++ b/code/MS3DLoader.h @@ -70,9 +70,9 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details */ - void GetExtensionList(std::set& extensions); + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- diff --git a/code/NDOLoader.cpp b/code/NDOLoader.cpp index a09497b09..953114053 100644 --- a/code/NDOLoader.cpp +++ b/code/NDOLoader.cpp @@ -50,6 +50,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; #define for_each BOOST_FOREACH +static const aiImporterDesc desc = { + "Nendo Mesh Importer", + "", + "", + "http://www.izware.com/nendo/index.htm", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "ndo" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer NDOImporter::NDOImporter() @@ -79,9 +92,9 @@ bool NDOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool // ------------------------------------------------------------------------------------------------ // Build a string of all file extensions supported -void NDOImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* NDOImporter::GetInfo () const { - extensions.insert("ndo"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/NDOLoader.h b/code/NDOLoader.h index 8b1d4a49f..9922df42d 100644 --- a/code/NDOLoader.h +++ b/code/NDOLoader.h @@ -97,7 +97,7 @@ public: protected: // ------------------------------------------------------------------- - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- void SetupProperties(const Importer* pImp); diff --git a/code/NFFLoader.cpp b/code/NFFLoader.cpp index 5dfc7ebe6..d54339567 100644 --- a/code/NFFLoader.cpp +++ b/code/NFFLoader.cpp @@ -53,6 +53,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "Neutral File Format Importer", + "", + "", + "", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "enff nff" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer NFFImporter::NFFImporter() @@ -72,10 +85,9 @@ bool NFFImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, b // ------------------------------------------------------------------------------------------------ // Get the list of all supported file extensions -void NFFImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* NFFImporter::GetInfo () const { - extensions.insert("enff"); - extensions.insert("nff"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/NFFLoader.h b/code/NFFLoader.h index 74533008f..ecc3d7ab4 100644 --- a/code/NFFLoader.h +++ b/code/NFFLoader.h @@ -77,10 +77,10 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/OFFLoader.cpp b/code/OFFLoader.cpp index d2940ea32..23a1815c3 100644 --- a/code/OFFLoader.cpp +++ b/code/OFFLoader.cpp @@ -54,6 +54,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "OFF Importer", + "", + "", + "", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "off" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer OFFImporter::OFFImporter() @@ -82,9 +95,9 @@ bool OFFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool } // ------------------------------------------------------------------------------------------------ -void OFFImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* OFFImporter::GetInfo () const { - extensions.insert("off"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/OFFLoader.h b/code/OFFLoader.h index 012b716cb..044dc4eca 100644 --- a/code/OFFLoader.h +++ b/code/OFFLoader.h @@ -71,10 +71,10 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index 155c11cc5..eb1d4098f 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -47,6 +47,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ObjFileParser.h" #include "ObjFileData.h" +static const aiImporterDesc desc = { + "Wavefront Object Importer", + "", + "", + "surfaces not supported", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "obj" +}; + + namespace Assimp { using namespace std; @@ -89,6 +103,12 @@ bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler , } } +// ------------------------------------------------------------------------------------------------ +const aiImporterDesc* ObjFileImporter::GetInfo () const +{ + return &desc; +} + // ------------------------------------------------------------------------------------------------ // Obj-file import implementation void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) diff --git a/code/ObjFileImporter.h b/code/ObjFileImporter.h index ba713a8da..9be71cbf5 100644 --- a/code/ObjFileImporter.h +++ b/code/ObjFileImporter.h @@ -78,7 +78,7 @@ public: private: //! \brief Appends the supported extention. - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; //! \brief File import implementation. void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); @@ -119,13 +119,6 @@ private: std::string m_strAbsPath; }; -// ------------------------------------------------------------------------------------------------ -// -inline void ObjFileImporter::GetExtensionList(std::set& extensions) -{ - extensions.insert("obj"); -} - // ------------------------------------------------------------------------------------------------ } // Namespace Assimp diff --git a/code/OgreImporter.cpp b/code/OgreImporter.cpp index 3241b8497..736f200b9 100644 --- a/code/OgreImporter.cpp +++ b/code/OgreImporter.cpp @@ -52,6 +52,19 @@ using namespace std; #include "TinyFormatter.h" #include "irrXMLWrapper.h" +static const aiImporterDesc desc = { + "Ogre XML Mesh Importer", + "", + "", + "", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "mesh.xml" +}; + namespace Assimp { namespace Ogre @@ -222,9 +235,9 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass } -void OgreImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* OgreImporter::GetInfo () const { - extensions.insert("mesh.xml"); + return &desc; } diff --git a/code/OgreImporter.hpp b/code/OgreImporter.hpp index 357bee4eb..d9dd87e7b 100644 --- a/code/OgreImporter.hpp +++ b/code/OgreImporter.hpp @@ -54,8 +54,8 @@ class OgreImporter : public BaseImporter { public: virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const; - virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); - virtual void GetExtensionList(std::set& extensions); + virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); + virtual const aiImporterDesc* GetInfo () const; virtual void SetupProperties(const Importer* pImp); private: diff --git a/code/OgreMesh.cpp b/code/OgreMesh.cpp index 683034279..3035038aa 100644 --- a/code/OgreMesh.cpp +++ b/code/OgreMesh.cpp @@ -1,507 +1,507 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2012, assimp team -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#include "AssimpPCH.h" - -#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER - -#include "OgreImporter.hpp" -#include "TinyFormatter.h" - -using namespace std; - -namespace Assimp -{ -namespace Ogre -{ - - -void OgreImporter::ReadSubMesh(SubMesh &theSubMesh, XmlReader *Reader) -{ - if(Reader->getAttributeValue("usesharedvertices")) - theSubMesh.SharedData=GetAttribute(Reader, "usesharedvertices"); - - XmlRead(Reader); - //TODO: maybe we have alsways just 1 faces and 1 geometry and always in this order. this loop will only work correct, when the order - //of faces and geometry changed, and not if we have more than one of one - while( Reader->getNodeName()==string("faces") - || Reader->getNodeName()==string("geometry") - || Reader->getNodeName()==string("boneassignments")) - { - if(string(Reader->getNodeName())=="faces")//Read the face list - { - //some info logging: - unsigned int NumFaces=GetAttribute(Reader, "count"); - ostringstream ss; ss <<"Submesh has " << NumFaces << " Faces."; - DefaultLogger::get()->debug(ss.str()); - - while(XmlRead(Reader) && Reader->getNodeName()==string("face")) - { - Face NewFace; - NewFace.VertexIndices[0]=GetAttribute(Reader, "v1"); - NewFace.VertexIndices[1]=GetAttribute(Reader, "v2"); - NewFace.VertexIndices[2]=GetAttribute(Reader, "v3"); - if(Reader->getAttributeValue("v4"))//this should be supported in the future - { - DefaultLogger::get()->warn("Submesh has quads, only traingles are supported!"); - //throw DeadlyImportError("Submesh has quads, only traingles are supported!"); - } - theSubMesh.FaceList.push_back(NewFace); - } - - }//end of faces - else if(string(Reader->getNodeName())=="geometry")//Read the vertexdata - { - //some info logging: - unsigned int NumVertices=GetAttribute(Reader, "vertexcount"); - ostringstream ss; ss<<"VertexCount: " << NumVertices; - DefaultLogger::get()->debug(ss.str()); - - //General Informations about vertices - XmlRead(Reader); - while(Reader->getNodeName()==string("vertexbuffer")) - { - ReadVertexBuffer(theSubMesh, Reader, NumVertices); - } - - //some error checking on the loaded data - if(!theSubMesh.HasPositions) - throw DeadlyImportError("No positions could be loaded!"); - - if(theSubMesh.HasNormals && theSubMesh.Normals.size() != NumVertices) - throw DeadlyImportError("Wrong Number of Normals loaded!"); - - if(theSubMesh.HasTangents && theSubMesh.Tangents.size() != NumVertices) - throw DeadlyImportError("Wrong Number of Tangents loaded!"); - - if(theSubMesh.NumUvs==1 && theSubMesh.Uvs.size() != NumVertices) - throw DeadlyImportError("Wrong Number of Uvs loaded!"); - - }//end of "geometry - - - else if(Reader->getNodeName()==string("boneassignments")) - { - ReadBoneWeights(theSubMesh, Reader); - } - } - DefaultLogger::get()->debug((Formatter::format(), - "Positionen: ",theSubMesh.Positions.size(), - " Normale: ",theSubMesh.Normals.size(), - " TexCoords: ",theSubMesh.Uvs.size(), - " Tantents: ",theSubMesh.Tangents.size() - )); - DefaultLogger::get()->warn(Reader->getNodeName()); -} - - -void OgreImporter::ReadVertexBuffer(SubMesh &theSubMesh, XmlReader *Reader, unsigned int NumVertices) -{ - DefaultLogger::get()->debug("new Vertex Buffer"); - - bool ReadPositions=false; - bool ReadNormals=false; - bool ReadTangents=false; - bool ReadUvs=false; - - //-------------------- check, what we need to read: -------------------------------- - if(Reader->getAttributeValue("positions") && GetAttribute(Reader, "positions")) - { - ReadPositions=theSubMesh.HasPositions=true; - theSubMesh.Positions.reserve(NumVertices); - DefaultLogger::get()->debug("reading positions"); - } - if(Reader->getAttributeValue("normals") && GetAttribute(Reader, "normals")) - { - ReadNormals=theSubMesh.HasNormals=true; - theSubMesh.Normals.reserve(NumVertices); - DefaultLogger::get()->debug("reading normals"); - } - if(Reader->getAttributeValue("tangents") && GetAttribute(Reader, "tangents")) - { - ReadTangents=theSubMesh.HasTangents=true; - theSubMesh.Tangents.reserve(NumVertices); - DefaultLogger::get()->debug("reading tangents"); - } - - - //we can have 1 or 0 uv channels, and if the mesh has no uvs, it also doesn't have the attribute - if(!Reader->getAttributeValue("texture_coords")) - theSubMesh.NumUvs=0; - else - { - ReadUvs=!!(theSubMesh.NumUvs=GetAttribute(Reader, "texture_coords")); - theSubMesh.Uvs.reserve(NumVertices); - DefaultLogger::get()->debug("reading texture coords"); - } - if(theSubMesh.NumUvs>1) - { - DefaultLogger::get()->warn("too many texcoords (just 1 supported!), just the first texcoords will be loaded!"); - theSubMesh.NumUvs=1; - } - //___________________________________________________________________ - - - //check if we will load anything - if(!(ReadPositions || ReadNormals || ReadTangents || ReadUvs)) - DefaultLogger::get()->warn("vertexbuffer seams to be empty!"); - - - //read all the vertices: - XmlRead(Reader); - - /*it might happen, that we have more than one attribute per vertex (they are not splitted to different buffers) - so the break condition is a bit tricky (well, IrrXML just sucks :( )*/ - while(Reader->getNodeName()==string("vertex") - ||Reader->getNodeName()==string("position") - ||Reader->getNodeName()==string("normal") - ||Reader->getNodeName()==string("tangent") - ||Reader->getNodeName()==string("texcoord") - ||Reader->getNodeName()==string("colour_diffuse")) - { - if(Reader->getNodeName()==string("vertex")) - XmlRead(Reader);//Read an attribute tag - - //Position - if(ReadPositions && Reader->getNodeName()==string("position")) - { - aiVector3D NewPos; - NewPos.x=GetAttribute(Reader, "x"); - NewPos.y=GetAttribute(Reader, "y"); - NewPos.z=GetAttribute(Reader, "z"); - theSubMesh.Positions.push_back(NewPos); - } - - //Normal - else if(ReadNormals && Reader->getNodeName()==string("normal")) - { - aiVector3D NewNormal; - NewNormal.x=GetAttribute(Reader, "x"); - NewNormal.y=GetAttribute(Reader, "y"); - NewNormal.z=GetAttribute(Reader, "z"); - theSubMesh.Normals.push_back(NewNormal); - } - - //Tangent - else if(ReadTangents && Reader->getNodeName()==string("tangent")) - { - aiVector3D NewTangent; - NewTangent.x=GetAttribute(Reader, "x"); - NewTangent.y=GetAttribute(Reader, "y"); - NewTangent.z=GetAttribute(Reader, "z"); - theSubMesh.Tangents.push_back(NewTangent); - } - - //Uv: - else if(ReadUvs && Reader->getNodeName()==string("texcoord")) - { - aiVector3D NewUv; - NewUv.x=GetAttribute(Reader, "u"); - NewUv.y=GetAttribute(Reader, "v")*(-1)+1;//flip the uv vertikal, blender exports them so! - theSubMesh.Uvs.push_back(NewUv); - - //skip all the following texcoords: - while(Reader->getNodeName()==string("texcoord")) - XmlRead(Reader); - continue;//don't read another line at the end of the loop - } - - //Color: - //TODO: actually save this data! - else if(Reader->getNodeName()==string("colour_diffuse")) - { - //do nothing, because we not yet support them - } - - //Attribute could not be read - else - { - DefaultLogger::get()->warn(string("Attribute was not read: ")+Reader->getNodeName()); - } - - XmlRead(Reader);//Read the Vertex tag - } -} - - -void OgreImporter::ReadBoneWeights(SubMesh &theSubMesh, XmlReader *Reader) -{ - theSubMesh.Weights.resize(theSubMesh.Positions.size()); - while(XmlRead(Reader) && Reader->getNodeName()==string("vertexboneassignment")) - { - Weight NewWeight; - unsigned int VertexId=GetAttribute(Reader, "vertexindex"); - NewWeight.BoneId=GetAttribute(Reader, "boneindex"); - NewWeight.Value=GetAttribute(Reader, "weight"); - //calculate the number of bones used (this is the highest id +1 becuase bone ids start at 0) - theSubMesh.BonesUsed=max(theSubMesh.BonesUsed, NewWeight.BoneId+1); - - theSubMesh.Weights[VertexId].push_back(NewWeight); - } -} - - - -void OgreImporter::ProcessSubMesh(SubMesh &theSubMesh, SubMesh &theSharedGeometry) -{ - //---------------Make all Vertexes unique: (this is required by assimp)----------------------- - vector UniqueFaceList(theSubMesh.FaceList.size()); - unsigned int UniqueVertexCount=theSubMesh.FaceList.size()*3;//*3 because each face consists of 3 vertexes, because we only support triangles^^ - vector UniquePositions(UniqueVertexCount); - vector UniqueNormals(UniqueVertexCount); - vector UniqueTangents(UniqueVertexCount); - vector UniqueUvs(UniqueVertexCount); - vector< vector > UniqueWeights(UniqueVertexCount); - - //Support for shared data: - /*We can use this loop to copy vertex informations from the shared data pool. In order to do so - we just use a reference to a submodel instead of our submodel itself*/ - - SubMesh& VertexSource= theSubMesh.SharedData ? theSharedGeometry : theSubMesh; - if(theSubMesh.SharedData)//copy vertexinformations to our mesh: - { - theSubMesh.HasPositions=theSharedGeometry.HasPositions; - theSubMesh.HasNormals=theSharedGeometry.HasNormals; - theSubMesh.HasTangents=theSharedGeometry.HasTangents; - theSubMesh.NumUvs=theSharedGeometry.NumUvs; - theSubMesh.BonesUsed=theSharedGeometry.BonesUsed; - } - - - if(VertexSource.NumUvs > 0) - { - DefaultLogger::get()->error("Not all Uvs will be made unique!"); - } - - for(unsigned int i=0; i 0) - { - UniqueUvs[3*i+0]=VertexSource.Uvs[Vertex1]; - UniqueUvs[3*i+1]=VertexSource.Uvs[Vertex2]; - UniqueUvs[3*i+2]=VertexSource.Uvs[Vertex3]; - } - - if(VertexSource.Weights.size() > 0) - { - UniqueWeights[3*i+0]=VertexSource.Weights[Vertex1]; - UniqueWeights[3*i+1]=VertexSource.Weights[Vertex2]; - UniqueWeights[3*i+2]=VertexSource.Weights[Vertex3]; - } - - //The indexvalues a just continuous numbers (0, 1, 2, 3, 4, 5, 6...) - UniqueFaceList[i].VertexIndices[0]=3*i+0; - UniqueFaceList[i].VertexIndices[1]=3*i+1; - UniqueFaceList[i].VertexIndices[2]=3*i+2; - } - //_________________________________________________________________________________________ - - //now we have the unique datas, but want them in the SubMesh, so we swap all the containers: - //if we don't have one of them, we just swap empty containers, so everything is ok - theSubMesh.FaceList.swap(UniqueFaceList); - theSubMesh.Positions.swap(UniquePositions); - theSubMesh.Normals.swap(UniqueNormals); - theSubMesh.Tangents.swap(UniqueTangents); - theSubMesh.Uvs.swap(UniqueUvs); - theSubMesh.Weights.swap(UniqueWeights); - - - - //------------- normalize weights ----------------------------- - //The Blender exporter doesn't care about whether the sum of all boneweights for a single vertex equals 1 or not, - //so we have to make this sure: - for(unsigned int VertexId=0; VertexId1.0f+0.05f) - { - //normalize all weights: - for(unsigned int BoneId=0; BoneId& Bones) const -{ - const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene - (void)m_CurrentScene; - - aiMesh* NewAiMesh=new aiMesh(); - - //Positions - NewAiMesh->mVertices=new aiVector3D[theSubMesh.Positions.size()]; - memcpy(NewAiMesh->mVertices, &theSubMesh.Positions[0], theSubMesh.Positions.size()*sizeof(aiVector3D)); - NewAiMesh->mNumVertices=theSubMesh.Positions.size(); - - //Normals - if(theSubMesh.HasNormals) - { - NewAiMesh->mNormals=new aiVector3D[theSubMesh.Normals.size()]; - memcpy(NewAiMesh->mNormals, &theSubMesh.Normals[0], theSubMesh.Normals.size()*sizeof(aiVector3D)); - } - - - //until we have support for bitangents, no tangents will be written - /* - //Tangents - if(theSubMesh.HasTangents) - { - NewAiMesh->mTangents=new aiVector3D[theSubMesh.Tangents.size()]; - memcpy(NewAiMesh->mTangents, &theSubMesh.Tangents[0], theSubMesh.Tangents.size()*sizeof(aiVector3D)); - } - */ - - //Uvs - if(0!=theSubMesh.NumUvs) - { - NewAiMesh->mNumUVComponents[0]=2; - NewAiMesh->mTextureCoords[0]= new aiVector3D[theSubMesh.Uvs.size()]; - memcpy(NewAiMesh->mTextureCoords[0], &theSubMesh.Uvs[0], theSubMesh.Uvs.size()*sizeof(aiVector3D)); - } - - - //---------------------------------------- Bones -------------------------------------------- - - //Copy the weights in in Bone-Vertices Struktur - //(we have them in a Vertex-Bones Structur, this is much easier for making them unique, which is required by assimp - vector< vector > aiWeights(theSubMesh.BonesUsed);//now the outer list are the bones, and the inner vector the vertices - for(unsigned int VertexId=0; VertexId aiBones; - aiBones.reserve(theSubMesh.BonesUsed);//the vector might be smaller, because there might be empty bones (bones that are not attached to any vertex) - - //create all the bones and fill them with informations - for(unsigned int i=0; i0) - { - aiBone* NewBone=new aiBone(); - NewBone->mNumWeights=aiWeights[i].size(); - NewBone->mWeights=new aiVertexWeight[aiWeights[i].size()]; - memcpy(NewBone->mWeights, &(aiWeights[i][0]), sizeof(aiVertexWeight)*aiWeights[i].size()); - NewBone->mName=Bones[i].Name;//The bone list should be sorted after its id's, this was done in LoadSkeleton - NewBone->mOffsetMatrix=Bones[i].BoneToWorldSpace; - - aiBones.push_back(NewBone); - } - } - NewAiMesh->mNumBones=aiBones.size(); - - // mBones must be NULL if mNumBones is non 0 or the validation fails. - if (aiBones.size()) { - NewAiMesh->mBones=new aiBone* [aiBones.size()]; - memcpy(NewAiMesh->mBones, &(aiBones[0]), aiBones.size()*sizeof(aiBone*)); - } - - //______________________________________________________________________________________________________ - - - - //Faces - NewAiMesh->mFaces=new aiFace[theSubMesh.FaceList.size()]; - for(unsigned int i=0; imFaces[i].mNumIndices=3; - NewAiMesh->mFaces[i].mIndices=new unsigned int[3]; - - NewAiMesh->mFaces[i].mIndices[0]=theSubMesh.FaceList[i].VertexIndices[0]; - NewAiMesh->mFaces[i].mIndices[1]=theSubMesh.FaceList[i].VertexIndices[1]; - NewAiMesh->mFaces[i].mIndices[2]=theSubMesh.FaceList[i].VertexIndices[2]; - } - NewAiMesh->mNumFaces=theSubMesh.FaceList.size(); - - //Link the material: - NewAiMesh->mMaterialIndex=theSubMesh.MaterialIndex;//the index is set by the function who called ReadSubMesh - - return NewAiMesh; -} - - -}//namespace Ogre -}//namespace Assimp - -#endif // !! ASSIMP_BUILD_NO_OGRE_IMPORTER +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER + +#include "OgreImporter.hpp" +#include "TinyFormatter.h" + +using namespace std; + +namespace Assimp +{ +namespace Ogre +{ + + +void OgreImporter::ReadSubMesh(SubMesh &theSubMesh, XmlReader *Reader) +{ + if(Reader->getAttributeValue("usesharedvertices")) + theSubMesh.SharedData=GetAttribute(Reader, "usesharedvertices"); + + XmlRead(Reader); + //TODO: maybe we have alsways just 1 faces and 1 geometry and always in this order. this loop will only work correct, when the order + //of faces and geometry changed, and not if we have more than one of one + while( Reader->getNodeName()==string("faces") + || Reader->getNodeName()==string("geometry") + || Reader->getNodeName()==string("boneassignments")) + { + if(string(Reader->getNodeName())=="faces")//Read the face list + { + //some info logging: + unsigned int NumFaces=GetAttribute(Reader, "count"); + ostringstream ss; ss <<"Submesh has " << NumFaces << " Faces."; + DefaultLogger::get()->debug(ss.str()); + + while(XmlRead(Reader) && Reader->getNodeName()==string("face")) + { + Face NewFace; + NewFace.VertexIndices[0]=GetAttribute(Reader, "v1"); + NewFace.VertexIndices[1]=GetAttribute(Reader, "v2"); + NewFace.VertexIndices[2]=GetAttribute(Reader, "v3"); + if(Reader->getAttributeValue("v4"))//this should be supported in the future + { + DefaultLogger::get()->warn("Submesh has quads, only traingles are supported!"); + //throw DeadlyImportError("Submesh has quads, only traingles are supported!"); + } + theSubMesh.FaceList.push_back(NewFace); + } + + }//end of faces + else if(string(Reader->getNodeName())=="geometry")//Read the vertexdata + { + //some info logging: + unsigned int NumVertices=GetAttribute(Reader, "vertexcount"); + ostringstream ss; ss<<"VertexCount: " << NumVertices; + DefaultLogger::get()->debug(ss.str()); + + //General Informations about vertices + XmlRead(Reader); + while(Reader->getNodeName()==string("vertexbuffer")) + { + ReadVertexBuffer(theSubMesh, Reader, NumVertices); + } + + //some error checking on the loaded data + if(!theSubMesh.HasPositions) + throw DeadlyImportError("No positions could be loaded!"); + + if(theSubMesh.HasNormals && theSubMesh.Normals.size() != NumVertices) + throw DeadlyImportError("Wrong Number of Normals loaded!"); + + if(theSubMesh.HasTangents && theSubMesh.Tangents.size() != NumVertices) + throw DeadlyImportError("Wrong Number of Tangents loaded!"); + + if(theSubMesh.NumUvs==1 && theSubMesh.Uvs.size() != NumVertices) + throw DeadlyImportError("Wrong Number of Uvs loaded!"); + + }//end of "geometry + + + else if(Reader->getNodeName()==string("boneassignments")) + { + ReadBoneWeights(theSubMesh, Reader); + } + } + DefaultLogger::get()->debug((Formatter::format(), + "Positionen: ",theSubMesh.Positions.size(), + " Normale: ",theSubMesh.Normals.size(), + " TexCoords: ",theSubMesh.Uvs.size(), + " Tantents: ",theSubMesh.Tangents.size() + )); + DefaultLogger::get()->warn(Reader->getNodeName()); +} + + +void OgreImporter::ReadVertexBuffer(SubMesh &theSubMesh, XmlReader *Reader, unsigned int NumVertices) +{ + DefaultLogger::get()->debug("new Vertex Buffer"); + + bool ReadPositions=false; + bool ReadNormals=false; + bool ReadTangents=false; + bool ReadUvs=false; + + //-------------------- check, what we need to read: -------------------------------- + if(Reader->getAttributeValue("positions") && GetAttribute(Reader, "positions")) + { + ReadPositions=theSubMesh.HasPositions=true; + theSubMesh.Positions.reserve(NumVertices); + DefaultLogger::get()->debug("reading positions"); + } + if(Reader->getAttributeValue("normals") && GetAttribute(Reader, "normals")) + { + ReadNormals=theSubMesh.HasNormals=true; + theSubMesh.Normals.reserve(NumVertices); + DefaultLogger::get()->debug("reading normals"); + } + if(Reader->getAttributeValue("tangents") && GetAttribute(Reader, "tangents")) + { + ReadTangents=theSubMesh.HasTangents=true; + theSubMesh.Tangents.reserve(NumVertices); + DefaultLogger::get()->debug("reading tangents"); + } + + + //we can have 1 or 0 uv channels, and if the mesh has no uvs, it also doesn't have the attribute + if(!Reader->getAttributeValue("texture_coords")) + theSubMesh.NumUvs=0; + else + { + ReadUvs=!!(theSubMesh.NumUvs=GetAttribute(Reader, "texture_coords")); + theSubMesh.Uvs.reserve(NumVertices); + DefaultLogger::get()->debug("reading texture coords"); + } + if(theSubMesh.NumUvs>1) + { + DefaultLogger::get()->warn("too many texcoords (just 1 supported!), just the first texcoords will be loaded!"); + theSubMesh.NumUvs=1; + } + //___________________________________________________________________ + + + //check if we will load anything + if(!(ReadPositions || ReadNormals || ReadTangents || ReadUvs)) + DefaultLogger::get()->warn("vertexbuffer seams to be empty!"); + + + //read all the vertices: + XmlRead(Reader); + + /*it might happen, that we have more than one attribute per vertex (they are not splitted to different buffers) + so the break condition is a bit tricky (well, IrrXML just sucks :( )*/ + while(Reader->getNodeName()==string("vertex") + ||Reader->getNodeName()==string("position") + ||Reader->getNodeName()==string("normal") + ||Reader->getNodeName()==string("tangent") + ||Reader->getNodeName()==string("texcoord") + ||Reader->getNodeName()==string("colour_diffuse")) + { + if(Reader->getNodeName()==string("vertex")) + XmlRead(Reader);//Read an attribute tag + + //Position + if(ReadPositions && Reader->getNodeName()==string("position")) + { + aiVector3D NewPos; + NewPos.x=GetAttribute(Reader, "x"); + NewPos.y=GetAttribute(Reader, "y"); + NewPos.z=GetAttribute(Reader, "z"); + theSubMesh.Positions.push_back(NewPos); + } + + //Normal + else if(ReadNormals && Reader->getNodeName()==string("normal")) + { + aiVector3D NewNormal; + NewNormal.x=GetAttribute(Reader, "x"); + NewNormal.y=GetAttribute(Reader, "y"); + NewNormal.z=GetAttribute(Reader, "z"); + theSubMesh.Normals.push_back(NewNormal); + } + + //Tangent + else if(ReadTangents && Reader->getNodeName()==string("tangent")) + { + aiVector3D NewTangent; + NewTangent.x=GetAttribute(Reader, "x"); + NewTangent.y=GetAttribute(Reader, "y"); + NewTangent.z=GetAttribute(Reader, "z"); + theSubMesh.Tangents.push_back(NewTangent); + } + + //Uv: + else if(ReadUvs && Reader->getNodeName()==string("texcoord")) + { + aiVector3D NewUv; + NewUv.x=GetAttribute(Reader, "u"); + NewUv.y=GetAttribute(Reader, "v")*(-1)+1;//flip the uv vertikal, blender exports them so! + theSubMesh.Uvs.push_back(NewUv); + + //skip all the following texcoords: + while(Reader->getNodeName()==string("texcoord")) + XmlRead(Reader); + continue;//don't read another line at the end of the loop + } + + //Color: + //TODO: actually save this data! + else if(Reader->getNodeName()==string("colour_diffuse")) + { + //do nothing, because we not yet support them + } + + //Attribute could not be read + else + { + DefaultLogger::get()->warn(string("Attribute was not read: ")+Reader->getNodeName()); + } + + XmlRead(Reader);//Read the Vertex tag + } +} + + +void OgreImporter::ReadBoneWeights(SubMesh &theSubMesh, XmlReader *Reader) +{ + theSubMesh.Weights.resize(theSubMesh.Positions.size()); + while(XmlRead(Reader) && Reader->getNodeName()==string("vertexboneassignment")) + { + Weight NewWeight; + unsigned int VertexId=GetAttribute(Reader, "vertexindex"); + NewWeight.BoneId=GetAttribute(Reader, "boneindex"); + NewWeight.Value=GetAttribute(Reader, "weight"); + //calculate the number of bones used (this is the highest id +1 becuase bone ids start at 0) + theSubMesh.BonesUsed=max(theSubMesh.BonesUsed, NewWeight.BoneId+1); + + theSubMesh.Weights[VertexId].push_back(NewWeight); + } +} + + + +void OgreImporter::ProcessSubMesh(SubMesh &theSubMesh, SubMesh &theSharedGeometry) +{ + //---------------Make all Vertexes unique: (this is required by assimp)----------------------- + vector UniqueFaceList(theSubMesh.FaceList.size()); + unsigned int UniqueVertexCount=theSubMesh.FaceList.size()*3;//*3 because each face consists of 3 vertexes, because we only support triangles^^ + vector UniquePositions(UniqueVertexCount); + vector UniqueNormals(UniqueVertexCount); + vector UniqueTangents(UniqueVertexCount); + vector UniqueUvs(UniqueVertexCount); + vector< vector > UniqueWeights(UniqueVertexCount); + + //Support for shared data: + /*We can use this loop to copy vertex informations from the shared data pool. In order to do so + we just use a reference to a submodel instead of our submodel itself*/ + + SubMesh& VertexSource= theSubMesh.SharedData ? theSharedGeometry : theSubMesh; + if(theSubMesh.SharedData)//copy vertexinformations to our mesh: + { + theSubMesh.HasPositions=theSharedGeometry.HasPositions; + theSubMesh.HasNormals=theSharedGeometry.HasNormals; + theSubMesh.HasTangents=theSharedGeometry.HasTangents; + theSubMesh.NumUvs=theSharedGeometry.NumUvs; + theSubMesh.BonesUsed=theSharedGeometry.BonesUsed; + } + + + if(VertexSource.NumUvs > 0) + { + DefaultLogger::get()->error("Not all Uvs will be made unique!"); + } + + for(unsigned int i=0; i 0) + { + UniqueUvs[3*i+0]=VertexSource.Uvs[Vertex1]; + UniqueUvs[3*i+1]=VertexSource.Uvs[Vertex2]; + UniqueUvs[3*i+2]=VertexSource.Uvs[Vertex3]; + } + + if(VertexSource.Weights.size() > 0) + { + UniqueWeights[3*i+0]=VertexSource.Weights[Vertex1]; + UniqueWeights[3*i+1]=VertexSource.Weights[Vertex2]; + UniqueWeights[3*i+2]=VertexSource.Weights[Vertex3]; + } + + //The indexvalues a just continuous numbers (0, 1, 2, 3, 4, 5, 6...) + UniqueFaceList[i].VertexIndices[0]=3*i+0; + UniqueFaceList[i].VertexIndices[1]=3*i+1; + UniqueFaceList[i].VertexIndices[2]=3*i+2; + } + //_________________________________________________________________________________________ + + //now we have the unique datas, but want them in the SubMesh, so we swap all the containers: + //if we don't have one of them, we just swap empty containers, so everything is ok + theSubMesh.FaceList.swap(UniqueFaceList); + theSubMesh.Positions.swap(UniquePositions); + theSubMesh.Normals.swap(UniqueNormals); + theSubMesh.Tangents.swap(UniqueTangents); + theSubMesh.Uvs.swap(UniqueUvs); + theSubMesh.Weights.swap(UniqueWeights); + + + + //------------- normalize weights ----------------------------- + //The Blender exporter doesn't care about whether the sum of all boneweights for a single vertex equals 1 or not, + //so we have to make this sure: + for(unsigned int VertexId=0; VertexId1.0f+0.05f) + { + //normalize all weights: + for(unsigned int BoneId=0; BoneId& Bones) const +{ + const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene + (void)m_CurrentScene; + + aiMesh* NewAiMesh=new aiMesh(); + + //Positions + NewAiMesh->mVertices=new aiVector3D[theSubMesh.Positions.size()]; + memcpy(NewAiMesh->mVertices, &theSubMesh.Positions[0], theSubMesh.Positions.size()*sizeof(aiVector3D)); + NewAiMesh->mNumVertices=theSubMesh.Positions.size(); + + //Normals + if(theSubMesh.HasNormals) + { + NewAiMesh->mNormals=new aiVector3D[theSubMesh.Normals.size()]; + memcpy(NewAiMesh->mNormals, &theSubMesh.Normals[0], theSubMesh.Normals.size()*sizeof(aiVector3D)); + } + + + //until we have support for bitangents, no tangents will be written + /* + //Tangents + if(theSubMesh.HasTangents) + { + NewAiMesh->mTangents=new aiVector3D[theSubMesh.Tangents.size()]; + memcpy(NewAiMesh->mTangents, &theSubMesh.Tangents[0], theSubMesh.Tangents.size()*sizeof(aiVector3D)); + } + */ + + //Uvs + if(0!=theSubMesh.NumUvs) + { + NewAiMesh->mNumUVComponents[0]=2; + NewAiMesh->mTextureCoords[0]= new aiVector3D[theSubMesh.Uvs.size()]; + memcpy(NewAiMesh->mTextureCoords[0], &theSubMesh.Uvs[0], theSubMesh.Uvs.size()*sizeof(aiVector3D)); + } + + + //---------------------------------------- Bones -------------------------------------------- + + //Copy the weights in in Bone-Vertices Struktur + //(we have them in a Vertex-Bones Structur, this is much easier for making them unique, which is required by assimp + vector< vector > aiWeights(theSubMesh.BonesUsed);//now the outer list are the bones, and the inner vector the vertices + for(unsigned int VertexId=0; VertexId aiBones; + aiBones.reserve(theSubMesh.BonesUsed);//the vector might be smaller, because there might be empty bones (bones that are not attached to any vertex) + + //create all the bones and fill them with informations + for(unsigned int i=0; i0) + { + aiBone* NewBone=new aiBone(); + NewBone->mNumWeights=aiWeights[i].size(); + NewBone->mWeights=new aiVertexWeight[aiWeights[i].size()]; + memcpy(NewBone->mWeights, &(aiWeights[i][0]), sizeof(aiVertexWeight)*aiWeights[i].size()); + NewBone->mName=Bones[i].Name;//The bone list should be sorted after its id's, this was done in LoadSkeleton + NewBone->mOffsetMatrix=Bones[i].BoneToWorldSpace; + + aiBones.push_back(NewBone); + } + } + NewAiMesh->mNumBones=aiBones.size(); + + // mBones must be NULL if mNumBones is non 0 or the validation fails. + if (aiBones.size()) { + NewAiMesh->mBones=new aiBone* [aiBones.size()]; + memcpy(NewAiMesh->mBones, &(aiBones[0]), aiBones.size()*sizeof(aiBone*)); + } + + //______________________________________________________________________________________________________ + + + + //Faces + NewAiMesh->mFaces=new aiFace[theSubMesh.FaceList.size()]; + for(unsigned int i=0; imFaces[i].mNumIndices=3; + NewAiMesh->mFaces[i].mIndices=new unsigned int[3]; + + NewAiMesh->mFaces[i].mIndices[0]=theSubMesh.FaceList[i].VertexIndices[0]; + NewAiMesh->mFaces[i].mIndices[1]=theSubMesh.FaceList[i].VertexIndices[1]; + NewAiMesh->mFaces[i].mIndices[2]=theSubMesh.FaceList[i].VertexIndices[2]; + } + NewAiMesh->mNumFaces=theSubMesh.FaceList.size(); + + //Link the material: + NewAiMesh->mMaterialIndex=theSubMesh.MaterialIndex;//the index is set by the function who called ReadSubMesh + + return NewAiMesh; +} + + +}//namespace Ogre +}//namespace Assimp + +#endif // !! ASSIMP_BUILD_NO_OGRE_IMPORTER diff --git a/code/OgreSkeleton.cpp b/code/OgreSkeleton.cpp index e82d88f54..c045b2d4f 100644 --- a/code/OgreSkeleton.cpp +++ b/code/OgreSkeleton.cpp @@ -1,455 +1,455 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2012, assimp team -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -#include "AssimpPCH.h" - -#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER - -#include "OgreImporter.hpp" -#include "TinyFormatter.h" - -using namespace std; - -namespace Assimp -{ -namespace Ogre -{ - - - -void OgreImporter::LoadSkeleton(std::string FileName, vector &Bones, vector &Animations) const -{ - const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene - (void)m_CurrentScene; - - - //most likely the skeleton file will only end with .skeleton - //But this is a xml reader, so we need: .skeleton.xml - FileName+=".xml"; - - DefaultLogger::get()->debug(string("Loading Skeleton: ")+FileName); - - //Open the File: - boost::scoped_ptr File(m_CurrentIOHandler->Open(FileName)); - if(NULL==File.get()) - throw DeadlyImportError("Failed to open skeleton file "+FileName+"."); - - //Read the Mesh File: - boost::scoped_ptr mIOWrapper(new CIrrXML_IOStreamReader(File.get())); - XmlReader* SkeletonFile = irr::io::createIrrXMLReader(mIOWrapper.get()); - if(!SkeletonFile) - throw DeadlyImportError(string("Failed to create XML Reader for ")+FileName); - - //Quick note: Whoever read this should know this one thing: irrXml fucking sucks!!! - - XmlRead(SkeletonFile); - if(string("skeleton")!=SkeletonFile->getNodeName()) - throw DeadlyImportError("No node in SkeletonFile: "+FileName); - - - - //------------------------------------load bones----------------------------------------- - XmlRead(SkeletonFile); - if(string("bones")!=SkeletonFile->getNodeName()) - throw DeadlyImportError("No bones node in skeleton "+FileName); - - XmlRead(SkeletonFile); - - while(string("bone")==SkeletonFile->getNodeName()) - { - //TODO: Maybe we can have bone ids for the errrors, but normaly, they should never appear, so what.... - - //read a new bone: - Bone NewBone; - NewBone.Id=GetAttribute(SkeletonFile, "id"); - NewBone.Name=GetAttribute(SkeletonFile, "name"); - - //load the position: - XmlRead(SkeletonFile); - if(string("position")!=SkeletonFile->getNodeName()) - throw DeadlyImportError("Position is not first node in Bone!"); - NewBone.Position.x=GetAttribute(SkeletonFile, "x"); - NewBone.Position.y=GetAttribute(SkeletonFile, "y"); - NewBone.Position.z=GetAttribute(SkeletonFile, "z"); - - //Rotation: - XmlRead(SkeletonFile); - if(string("rotation")!=SkeletonFile->getNodeName()) - throw DeadlyImportError("Rotation is not the second node in Bone!"); - NewBone.RotationAngle=GetAttribute(SkeletonFile, "angle"); - XmlRead(SkeletonFile); - if(string("axis")!=SkeletonFile->getNodeName()) - throw DeadlyImportError("No axis specified for bone rotation!"); - NewBone.RotationAxis.x=GetAttribute(SkeletonFile, "x"); - NewBone.RotationAxis.y=GetAttribute(SkeletonFile, "y"); - NewBone.RotationAxis.z=GetAttribute(SkeletonFile, "z"); - - //append the newly loaded bone to the bone list - Bones.push_back(NewBone); - - //Proceed to the next bone: - XmlRead(SkeletonFile); - } - //The bones in the file a not neccesarly ordered by there id's so we do it now: - std::sort(Bones.begin(), Bones.end()); - - //now the id of each bone should be equal to its position in the vector: - //so we do a simple check: - { - bool IdsOk=true; - for(int i=0; i(Bones.size()); ++i)//i is signed, because all Id's are also signed! - { - if(Bones[i].Id!=i) - IdsOk=false; - } - if(!IdsOk) - throw DeadlyImportError("Bone Ids are not valid!"+FileName); - } - DefaultLogger::get()->debug((Formatter::format(),"Number of bones: ",Bones.size())); - //________________________________________________________________________________ - - - - - - - //----------------------------load bonehierarchy-------------------------------- - if(string("bonehierarchy")!=SkeletonFile->getNodeName()) - throw DeadlyImportError("no bonehierarchy node in "+FileName); - - DefaultLogger::get()->debug("loading bonehierarchy..."); - XmlRead(SkeletonFile); - while(string("boneparent")==SkeletonFile->getNodeName()) - { - string Child, Parent; - Child=GetAttribute(SkeletonFile, "bone"); - Parent=GetAttribute(SkeletonFile, "parent"); - - unsigned int ChildId, ParentId; - ChildId=find(Bones.begin(), Bones.end(), Child)->Id; - ParentId=find(Bones.begin(), Bones.end(), Parent)->Id; - - Bones[ChildId].ParentId=ParentId; - Bones[ParentId].Children.push_back(ChildId); - - XmlRead(SkeletonFile);//i once forget this line, which led to an endless loop, did i mentioned, that irrxml sucks?? - } - //_____________________________________________________________________________ - - - //--------- Calculate the WorldToBoneSpace Matrix recursivly for all bones: ------------------ - BOOST_FOREACH(Bone &theBone, Bones) - { - if(-1==theBone.ParentId) //the bone is a root bone - { - theBone.CalculateBoneToWorldSpaceMatrix(Bones); - } - } - //_______________________________________________________________________ - - - //---------------------------load animations----------------------------- - if(string("animations")==SkeletonFile->getNodeName())//animations are optional values - { - DefaultLogger::get()->debug("Loading Animations"); - XmlRead(SkeletonFile); - while(string("animation")==SkeletonFile->getNodeName()) - { - Animation NewAnimation; - NewAnimation.Name=GetAttribute(SkeletonFile, "name"); - NewAnimation.Length=GetAttribute(SkeletonFile, "length"); - - //Load all Tracks - XmlRead(SkeletonFile); - if(string("tracks")!=SkeletonFile->getNodeName()) - throw DeadlyImportError("no tracks node in animation"); - XmlRead(SkeletonFile); - while(string("track")==SkeletonFile->getNodeName()) - { - Track NewTrack; - NewTrack.BoneName=GetAttribute(SkeletonFile, "bone"); - - //Load all keyframes; - XmlRead(SkeletonFile); - if(string("keyframes")!=SkeletonFile->getNodeName()) - throw DeadlyImportError("no keyframes node!"); - XmlRead(SkeletonFile); - while(string("keyframe")==SkeletonFile->getNodeName()) - { - Keyframe NewKeyframe; - NewKeyframe.Time=GetAttribute(SkeletonFile, "time"); - - //loop over the attributes: - - while(true) - { - XmlRead(SkeletonFile); - - //If any property doesn't show up, it will keep its initialization value - - //Position: - if(string("translate")==SkeletonFile->getNodeName()) - { - NewKeyframe.Position.x=GetAttribute(SkeletonFile, "x"); - NewKeyframe.Position.y=GetAttribute(SkeletonFile, "y"); - NewKeyframe.Position.z=GetAttribute(SkeletonFile, "z"); - } - - //Rotation: - else if(string("rotate")==SkeletonFile->getNodeName()) - { - float RotationAngle=GetAttribute(SkeletonFile, "angle"); - aiVector3D RotationAxis; - XmlRead(SkeletonFile); - if(string("axis")!=SkeletonFile->getNodeName()) - throw DeadlyImportError("No axis for keyframe rotation!"); - RotationAxis.x=GetAttribute(SkeletonFile, "x"); - RotationAxis.y=GetAttribute(SkeletonFile, "y"); - RotationAxis.z=GetAttribute(SkeletonFile, "z"); - - if(0==RotationAxis.x && 0==RotationAxis.y && 0==RotationAxis.z)//we have an invalid rotation axis - { - RotationAxis.x=1.0f; - if(0!=RotationAngle)//if we don't rotate at all, the axis does not matter - { - DefaultLogger::get()->warn("Invalid Rotation Axis in Keyframe!"); - } - } - NewKeyframe.Rotation=aiQuaternion(RotationAxis, RotationAngle); - } - - //Scaling: - else if(string("scale")==SkeletonFile->getNodeName()) - { - NewKeyframe.Scaling.x=GetAttribute(SkeletonFile, "x"); - NewKeyframe.Scaling.y=GetAttribute(SkeletonFile, "y"); - NewKeyframe.Scaling.z=GetAttribute(SkeletonFile, "z"); - } - - //we suppose, that we read all attributes and this is a new keyframe or the end of the animation - else - break; - } - - - NewTrack.Keyframes.push_back(NewKeyframe); - //XmlRead(SkeletonFile); - } - - - NewAnimation.Tracks.push_back(NewTrack); - } - - Animations.push_back(NewAnimation); - } - } - //_____________________________________________________________________________ - -} - - -void OgreImporter::CreateAssimpSkeleton(const std::vector &Bones, const std::vector &/*Animations*/) -{ - if(!m_CurrentScene->mRootNode) - throw DeadlyImportError("No root node exists!!"); - if(0!=m_CurrentScene->mRootNode->mNumChildren) - throw DeadlyImportError("Root Node already has childnodes!"); - - - //Createt the assimp bone hierarchy - vector RootBoneNodes; - BOOST_FOREACH(Bone theBone, Bones) - { - if(-1==theBone.ParentId) //the bone is a root bone - { - //which will recursily add all other nodes - RootBoneNodes.push_back(CreateAiNodeFromBone(theBone.Id, Bones, m_CurrentScene->mRootNode)); - } - } - - if (RootBoneNodes.size()) { - m_CurrentScene->mRootNode->mNumChildren=RootBoneNodes.size(); - m_CurrentScene->mRootNode->mChildren=new aiNode*[RootBoneNodes.size()]; - memcpy(m_CurrentScene->mRootNode->mChildren, &RootBoneNodes[0], sizeof(aiNode*)*RootBoneNodes.size()); - } -} - - -void OgreImporter::PutAnimationsInScene(const std::vector &Bones, const std::vector &Animations) -{ - //-----------------Create the Assimp Animations -------------------- - if(Animations.size()>0)//Maybe the model had only a skeleton and no animations. (If it also has no skeleton, this function would'nt have been called - { - m_CurrentScene->mNumAnimations=Animations.size(); - m_CurrentScene->mAnimations=new aiAnimation*[Animations.size()]; - for(unsigned int i=0; imName=Animations[i].Name; - NewAnimation->mDuration=Animations[i].Length; - NewAnimation->mTicksPerSecond=1.0f; - - //Create all tracks in this animation - NewAnimation->mNumChannels=Animations[i].Tracks.size(); - NewAnimation->mChannels=new aiNodeAnim*[Animations[i].Tracks.size()]; - for(unsigned int j=0; jmNodeName=Animations[i].Tracks[j].BoneName; - - //we need this, to acces the bones default pose, which we need to make keys absolute to the default bone pose - vector::const_iterator CurBone=find(Bones.begin(), Bones.end(), NewNodeAnim->mNodeName); - aiMatrix4x4 t0, t1; - aiMatrix4x4 DefBonePose=aiMatrix4x4::Translation(CurBone->Position, t1) - * aiMatrix4x4::Rotation(CurBone->RotationAngle, CurBone->RotationAxis, t0); - - - //Create the keyframe arrays... - unsigned int KeyframeCount=Animations[i].Tracks[j].Keyframes.size(); - NewNodeAnim->mNumPositionKeys=KeyframeCount; - NewNodeAnim->mNumRotationKeys=KeyframeCount; - NewNodeAnim->mNumScalingKeys =KeyframeCount; - NewNodeAnim->mPositionKeys=new aiVectorKey[KeyframeCount]; - NewNodeAnim->mRotationKeys=new aiQuatKey[KeyframeCount]; - NewNodeAnim->mScalingKeys =new aiVectorKey[KeyframeCount]; - - //...and fill them - for(unsigned int k=0; kmPositionKeys[k].mTime=Time; - NewNodeAnim->mPositionKeys[k].mValue=Pos; - - NewNodeAnim->mRotationKeys[k].mTime=Time; - NewNodeAnim->mRotationKeys[k].mValue=Rot; - - NewNodeAnim->mScalingKeys[k].mTime=Time; - NewNodeAnim->mScalingKeys[k].mValue=Scale; - } - - NewAnimation->mChannels[j]=NewNodeAnim; - } - - m_CurrentScene->mAnimations[i]=NewAnimation; - } - } -//TODO: Auf nicht vorhandene Animationskeys achten! -//#pragma warning (s.o.) - //__________________________________________________________________ -} - - -aiNode* OgreImporter::CreateAiNodeFromBone(int BoneId, const std::vector &Bones, aiNode* ParentNode) -{ - //----Create the node for this bone and set its values----- - aiNode* NewNode=new aiNode(Bones[BoneId].Name); - NewNode->mParent=ParentNode; - - aiMatrix4x4 t0,t1; - NewNode->mTransformation= - aiMatrix4x4::Translation(Bones[BoneId].Position, t0) - *aiMatrix4x4::Rotation(Bones[BoneId].RotationAngle, Bones[BoneId].RotationAxis, t1) - ; - //__________________________________________________________ - - - //---------- recursivly create all children Nodes: ---------- - NewNode->mNumChildren=Bones[BoneId].Children.size(); - NewNode->mChildren=new aiNode*[Bones[BoneId].Children.size()]; - for(unsigned int i=0; imChildren[i]=CreateAiNodeFromBone(Bones[BoneId].Children[i], Bones, NewNode); - } - //____________________________________________________ - - - return NewNode; -} - - -void Bone::CalculateBoneToWorldSpaceMatrix(vector &Bones) -{ - //Calculate the matrix for this bone: - - aiMatrix4x4 t0,t1; - aiMatrix4x4 Transf= aiMatrix4x4::Rotation(-RotationAngle, RotationAxis, t1) - * aiMatrix4x4::Translation(-Position, t0); - - if(-1==ParentId) - { - BoneToWorldSpace=Transf; - } - else - { - BoneToWorldSpace=Transf*Bones[ParentId].BoneToWorldSpace; - } - - - //and recursivly for all children: - BOOST_FOREACH(int theChildren, Children) - { - Bones[theChildren].CalculateBoneToWorldSpaceMatrix(Bones); - } -} - - -}//namespace Ogre -}//namespace Assimp - -#endif // !! ASSIMP_BUILD_NO_OGRE_IMPORTER +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER + +#include "OgreImporter.hpp" +#include "TinyFormatter.h" + +using namespace std; + +namespace Assimp +{ +namespace Ogre +{ + + + +void OgreImporter::LoadSkeleton(std::string FileName, vector &Bones, vector &Animations) const +{ + const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene + (void)m_CurrentScene; + + + //most likely the skeleton file will only end with .skeleton + //But this is a xml reader, so we need: .skeleton.xml + FileName+=".xml"; + + DefaultLogger::get()->debug(string("Loading Skeleton: ")+FileName); + + //Open the File: + boost::scoped_ptr File(m_CurrentIOHandler->Open(FileName)); + if(NULL==File.get()) + throw DeadlyImportError("Failed to open skeleton file "+FileName+"."); + + //Read the Mesh File: + boost::scoped_ptr mIOWrapper(new CIrrXML_IOStreamReader(File.get())); + XmlReader* SkeletonFile = irr::io::createIrrXMLReader(mIOWrapper.get()); + if(!SkeletonFile) + throw DeadlyImportError(string("Failed to create XML Reader for ")+FileName); + + //Quick note: Whoever read this should know this one thing: irrXml fucking sucks!!! + + XmlRead(SkeletonFile); + if(string("skeleton")!=SkeletonFile->getNodeName()) + throw DeadlyImportError("No node in SkeletonFile: "+FileName); + + + + //------------------------------------load bones----------------------------------------- + XmlRead(SkeletonFile); + if(string("bones")!=SkeletonFile->getNodeName()) + throw DeadlyImportError("No bones node in skeleton "+FileName); + + XmlRead(SkeletonFile); + + while(string("bone")==SkeletonFile->getNodeName()) + { + //TODO: Maybe we can have bone ids for the errrors, but normaly, they should never appear, so what.... + + //read a new bone: + Bone NewBone; + NewBone.Id=GetAttribute(SkeletonFile, "id"); + NewBone.Name=GetAttribute(SkeletonFile, "name"); + + //load the position: + XmlRead(SkeletonFile); + if(string("position")!=SkeletonFile->getNodeName()) + throw DeadlyImportError("Position is not first node in Bone!"); + NewBone.Position.x=GetAttribute(SkeletonFile, "x"); + NewBone.Position.y=GetAttribute(SkeletonFile, "y"); + NewBone.Position.z=GetAttribute(SkeletonFile, "z"); + + //Rotation: + XmlRead(SkeletonFile); + if(string("rotation")!=SkeletonFile->getNodeName()) + throw DeadlyImportError("Rotation is not the second node in Bone!"); + NewBone.RotationAngle=GetAttribute(SkeletonFile, "angle"); + XmlRead(SkeletonFile); + if(string("axis")!=SkeletonFile->getNodeName()) + throw DeadlyImportError("No axis specified for bone rotation!"); + NewBone.RotationAxis.x=GetAttribute(SkeletonFile, "x"); + NewBone.RotationAxis.y=GetAttribute(SkeletonFile, "y"); + NewBone.RotationAxis.z=GetAttribute(SkeletonFile, "z"); + + //append the newly loaded bone to the bone list + Bones.push_back(NewBone); + + //Proceed to the next bone: + XmlRead(SkeletonFile); + } + //The bones in the file a not neccesarly ordered by there id's so we do it now: + std::sort(Bones.begin(), Bones.end()); + + //now the id of each bone should be equal to its position in the vector: + //so we do a simple check: + { + bool IdsOk=true; + for(int i=0; i(Bones.size()); ++i)//i is signed, because all Id's are also signed! + { + if(Bones[i].Id!=i) + IdsOk=false; + } + if(!IdsOk) + throw DeadlyImportError("Bone Ids are not valid!"+FileName); + } + DefaultLogger::get()->debug((Formatter::format(),"Number of bones: ",Bones.size())); + //________________________________________________________________________________ + + + + + + + //----------------------------load bonehierarchy-------------------------------- + if(string("bonehierarchy")!=SkeletonFile->getNodeName()) + throw DeadlyImportError("no bonehierarchy node in "+FileName); + + DefaultLogger::get()->debug("loading bonehierarchy..."); + XmlRead(SkeletonFile); + while(string("boneparent")==SkeletonFile->getNodeName()) + { + string Child, Parent; + Child=GetAttribute(SkeletonFile, "bone"); + Parent=GetAttribute(SkeletonFile, "parent"); + + unsigned int ChildId, ParentId; + ChildId=find(Bones.begin(), Bones.end(), Child)->Id; + ParentId=find(Bones.begin(), Bones.end(), Parent)->Id; + + Bones[ChildId].ParentId=ParentId; + Bones[ParentId].Children.push_back(ChildId); + + XmlRead(SkeletonFile);//i once forget this line, which led to an endless loop, did i mentioned, that irrxml sucks?? + } + //_____________________________________________________________________________ + + + //--------- Calculate the WorldToBoneSpace Matrix recursivly for all bones: ------------------ + BOOST_FOREACH(Bone &theBone, Bones) + { + if(-1==theBone.ParentId) //the bone is a root bone + { + theBone.CalculateBoneToWorldSpaceMatrix(Bones); + } + } + //_______________________________________________________________________ + + + //---------------------------load animations----------------------------- + if(string("animations")==SkeletonFile->getNodeName())//animations are optional values + { + DefaultLogger::get()->debug("Loading Animations"); + XmlRead(SkeletonFile); + while(string("animation")==SkeletonFile->getNodeName()) + { + Animation NewAnimation; + NewAnimation.Name=GetAttribute(SkeletonFile, "name"); + NewAnimation.Length=GetAttribute(SkeletonFile, "length"); + + //Load all Tracks + XmlRead(SkeletonFile); + if(string("tracks")!=SkeletonFile->getNodeName()) + throw DeadlyImportError("no tracks node in animation"); + XmlRead(SkeletonFile); + while(string("track")==SkeletonFile->getNodeName()) + { + Track NewTrack; + NewTrack.BoneName=GetAttribute(SkeletonFile, "bone"); + + //Load all keyframes; + XmlRead(SkeletonFile); + if(string("keyframes")!=SkeletonFile->getNodeName()) + throw DeadlyImportError("no keyframes node!"); + XmlRead(SkeletonFile); + while(string("keyframe")==SkeletonFile->getNodeName()) + { + Keyframe NewKeyframe; + NewKeyframe.Time=GetAttribute(SkeletonFile, "time"); + + //loop over the attributes: + + while(true) + { + XmlRead(SkeletonFile); + + //If any property doesn't show up, it will keep its initialization value + + //Position: + if(string("translate")==SkeletonFile->getNodeName()) + { + NewKeyframe.Position.x=GetAttribute(SkeletonFile, "x"); + NewKeyframe.Position.y=GetAttribute(SkeletonFile, "y"); + NewKeyframe.Position.z=GetAttribute(SkeletonFile, "z"); + } + + //Rotation: + else if(string("rotate")==SkeletonFile->getNodeName()) + { + float RotationAngle=GetAttribute(SkeletonFile, "angle"); + aiVector3D RotationAxis; + XmlRead(SkeletonFile); + if(string("axis")!=SkeletonFile->getNodeName()) + throw DeadlyImportError("No axis for keyframe rotation!"); + RotationAxis.x=GetAttribute(SkeletonFile, "x"); + RotationAxis.y=GetAttribute(SkeletonFile, "y"); + RotationAxis.z=GetAttribute(SkeletonFile, "z"); + + if(0==RotationAxis.x && 0==RotationAxis.y && 0==RotationAxis.z)//we have an invalid rotation axis + { + RotationAxis.x=1.0f; + if(0!=RotationAngle)//if we don't rotate at all, the axis does not matter + { + DefaultLogger::get()->warn("Invalid Rotation Axis in Keyframe!"); + } + } + NewKeyframe.Rotation=aiQuaternion(RotationAxis, RotationAngle); + } + + //Scaling: + else if(string("scale")==SkeletonFile->getNodeName()) + { + NewKeyframe.Scaling.x=GetAttribute(SkeletonFile, "x"); + NewKeyframe.Scaling.y=GetAttribute(SkeletonFile, "y"); + NewKeyframe.Scaling.z=GetAttribute(SkeletonFile, "z"); + } + + //we suppose, that we read all attributes and this is a new keyframe or the end of the animation + else + break; + } + + + NewTrack.Keyframes.push_back(NewKeyframe); + //XmlRead(SkeletonFile); + } + + + NewAnimation.Tracks.push_back(NewTrack); + } + + Animations.push_back(NewAnimation); + } + } + //_____________________________________________________________________________ + +} + + +void OgreImporter::CreateAssimpSkeleton(const std::vector &Bones, const std::vector &/*Animations*/) +{ + if(!m_CurrentScene->mRootNode) + throw DeadlyImportError("No root node exists!!"); + if(0!=m_CurrentScene->mRootNode->mNumChildren) + throw DeadlyImportError("Root Node already has childnodes!"); + + + //Createt the assimp bone hierarchy + vector RootBoneNodes; + BOOST_FOREACH(Bone theBone, Bones) + { + if(-1==theBone.ParentId) //the bone is a root bone + { + //which will recursily add all other nodes + RootBoneNodes.push_back(CreateAiNodeFromBone(theBone.Id, Bones, m_CurrentScene->mRootNode)); + } + } + + if (RootBoneNodes.size()) { + m_CurrentScene->mRootNode->mNumChildren=RootBoneNodes.size(); + m_CurrentScene->mRootNode->mChildren=new aiNode*[RootBoneNodes.size()]; + memcpy(m_CurrentScene->mRootNode->mChildren, &RootBoneNodes[0], sizeof(aiNode*)*RootBoneNodes.size()); + } +} + + +void OgreImporter::PutAnimationsInScene(const std::vector &Bones, const std::vector &Animations) +{ + //-----------------Create the Assimp Animations -------------------- + if(Animations.size()>0)//Maybe the model had only a skeleton and no animations. (If it also has no skeleton, this function would'nt have been called + { + m_CurrentScene->mNumAnimations=Animations.size(); + m_CurrentScene->mAnimations=new aiAnimation*[Animations.size()]; + for(unsigned int i=0; imName=Animations[i].Name; + NewAnimation->mDuration=Animations[i].Length; + NewAnimation->mTicksPerSecond=1.0f; + + //Create all tracks in this animation + NewAnimation->mNumChannels=Animations[i].Tracks.size(); + NewAnimation->mChannels=new aiNodeAnim*[Animations[i].Tracks.size()]; + for(unsigned int j=0; jmNodeName=Animations[i].Tracks[j].BoneName; + + //we need this, to acces the bones default pose, which we need to make keys absolute to the default bone pose + vector::const_iterator CurBone=find(Bones.begin(), Bones.end(), NewNodeAnim->mNodeName); + aiMatrix4x4 t0, t1; + aiMatrix4x4 DefBonePose=aiMatrix4x4::Translation(CurBone->Position, t1) + * aiMatrix4x4::Rotation(CurBone->RotationAngle, CurBone->RotationAxis, t0); + + + //Create the keyframe arrays... + unsigned int KeyframeCount=Animations[i].Tracks[j].Keyframes.size(); + NewNodeAnim->mNumPositionKeys=KeyframeCount; + NewNodeAnim->mNumRotationKeys=KeyframeCount; + NewNodeAnim->mNumScalingKeys =KeyframeCount; + NewNodeAnim->mPositionKeys=new aiVectorKey[KeyframeCount]; + NewNodeAnim->mRotationKeys=new aiQuatKey[KeyframeCount]; + NewNodeAnim->mScalingKeys =new aiVectorKey[KeyframeCount]; + + //...and fill them + for(unsigned int k=0; kmPositionKeys[k].mTime=Time; + NewNodeAnim->mPositionKeys[k].mValue=Pos; + + NewNodeAnim->mRotationKeys[k].mTime=Time; + NewNodeAnim->mRotationKeys[k].mValue=Rot; + + NewNodeAnim->mScalingKeys[k].mTime=Time; + NewNodeAnim->mScalingKeys[k].mValue=Scale; + } + + NewAnimation->mChannels[j]=NewNodeAnim; + } + + m_CurrentScene->mAnimations[i]=NewAnimation; + } + } +//TODO: Auf nicht vorhandene Animationskeys achten! +//#pragma warning (s.o.) + //__________________________________________________________________ +} + + +aiNode* OgreImporter::CreateAiNodeFromBone(int BoneId, const std::vector &Bones, aiNode* ParentNode) +{ + //----Create the node for this bone and set its values----- + aiNode* NewNode=new aiNode(Bones[BoneId].Name); + NewNode->mParent=ParentNode; + + aiMatrix4x4 t0,t1; + NewNode->mTransformation= + aiMatrix4x4::Translation(Bones[BoneId].Position, t0) + *aiMatrix4x4::Rotation(Bones[BoneId].RotationAngle, Bones[BoneId].RotationAxis, t1) + ; + //__________________________________________________________ + + + //---------- recursivly create all children Nodes: ---------- + NewNode->mNumChildren=Bones[BoneId].Children.size(); + NewNode->mChildren=new aiNode*[Bones[BoneId].Children.size()]; + for(unsigned int i=0; imChildren[i]=CreateAiNodeFromBone(Bones[BoneId].Children[i], Bones, NewNode); + } + //____________________________________________________ + + + return NewNode; +} + + +void Bone::CalculateBoneToWorldSpaceMatrix(vector &Bones) +{ + //Calculate the matrix for this bone: + + aiMatrix4x4 t0,t1; + aiMatrix4x4 Transf= aiMatrix4x4::Rotation(-RotationAngle, RotationAxis, t1) + * aiMatrix4x4::Translation(-Position, t0); + + if(-1==ParentId) + { + BoneToWorldSpace=Transf; + } + else + { + BoneToWorldSpace=Transf*Bones[ParentId].BoneToWorldSpace; + } + + + //and recursivly for all children: + BOOST_FOREACH(int theChildren, Children) + { + Bones[theChildren].CalculateBoneToWorldSpaceMatrix(Bones); + } +} + + +}//namespace Ogre +}//namespace Assimp + +#endif // !! ASSIMP_BUILD_NO_OGRE_IMPORTER diff --git a/code/PlyLoader.cpp b/code/PlyLoader.cpp index b785062d0..104e194d9 100644 --- a/code/PlyLoader.cpp +++ b/code/PlyLoader.cpp @@ -51,6 +51,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "Stanford Polygon Library (PLY) Importer", + "", + "", + "", + aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "ply" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer PLYImporter::PLYImporter() @@ -79,9 +92,9 @@ bool PLYImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool } // ------------------------------------------------------------------------------------------------ -void PLYImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* PLYImporter::GetInfo () const { - extensions.insert("ply"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/PlyLoader.h b/code/PlyLoader.h index cdd0c2c79..d00c7926a 100644 --- a/code/PlyLoader.h +++ b/code/PlyLoader.h @@ -78,10 +78,10 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/Q3BSPFileImporter.cpp b/code/Q3BSPFileImporter.cpp index a19ed7c8c..28b04a59b 100644 --- a/code/Q3BSPFileImporter.cpp +++ b/code/Q3BSPFileImporter.cpp @@ -57,13 +57,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../include/assimp/mesh.h" #include + +static const aiImporterDesc desc = { + "Quake III BSP Importer", + "", + "", + "", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "pk3" +}; + namespace Assimp { using namespace Q3BSP; -static const std::string Q3BSPExtension = "pk3"; - // ------------------------------------------------------------------------------------------------ // Local function to create a material key name. static void createKey( int id1, int id2, std::string &rKey ) @@ -161,7 +173,7 @@ Q3BSPFileImporter::~Q3BSPFileImporter() bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* /*pIOHandler*/, bool checkSig ) const { if(!checkSig) { - return SimpleExtensionCheck( rFile, Q3BSPExtension.c_str() ); + return SimpleExtensionCheck( rFile, "pk3" ); } // TODO perhaps add keyword based detection return false; @@ -169,9 +181,9 @@ bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* /*pIOHandle // ------------------------------------------------------------------------------------------------ // Adds extensions. -void Q3BSPFileImporter::GetExtensionList( std::set& extensions ) +const aiImporterDesc* Q3BSPFileImporter::GetInfo () const { - extensions.insert( Q3BSPExtension ); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/Q3BSPFileImporter.h b/code/Q3BSPFileImporter.h index b5a6e6e50..6d0e8287a 100644 --- a/code/Q3BSPFileImporter.h +++ b/code/Q3BSPFileImporter.h @@ -78,7 +78,7 @@ private: typedef std::map* >::iterator FaceMapIt; typedef std::map*>::const_iterator FaceMapConstIt; - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); void separateMapName( const std::string &rImportName, std::string &rArchiveName, std::string &rMapName ); bool findFirstMapInArchive( Q3BSP::Q3BSPZipArchive &rArchive, std::string &rMapName ); diff --git a/code/Q3DLoader.cpp b/code/Q3DLoader.cpp index c0c2874a7..76051feea 100644 --- a/code/Q3DLoader.cpp +++ b/code/Q3DLoader.cpp @@ -53,6 +53,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "Quick3D Importer", + "", + "", + "http://www.quick3d.com/", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "q3o q3s" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer Q3DImporter::Q3DImporter() @@ -81,10 +94,9 @@ bool Q3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool } // ------------------------------------------------------------------------------------------------ -void Q3DImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* Q3DImporter::GetInfo () const { - extensions.insert("q3o"); - extensions.insert("q3s"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/Q3DLoader.h b/code/Q3DLoader.h index 78194233c..55fda7303 100644 --- a/code/Q3DLoader.h +++ b/code/Q3DLoader.h @@ -71,10 +71,10 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/RawLoader.cpp b/code/RawLoader.cpp index f74ae48dd..be6736307 100644 --- a/code/RawLoader.cpp +++ b/code/RawLoader.cpp @@ -53,6 +53,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "Raw Importer", + "", + "", + "", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "raw" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer RAWImporter::RAWImporter() @@ -71,10 +84,9 @@ bool RAWImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, b } // ------------------------------------------------------------------------------------------------ -// Get the list of all supported file extensions -void RAWImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* RAWImporter::GetInfo () const { - extensions.insert("raw"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/RawLoader.h b/code/RawLoader.h index 4654261f8..23d942c8c 100644 --- a/code/RawLoader.h +++ b/code/RawLoader.h @@ -72,10 +72,10 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/SMDLoader.cpp b/code/SMDLoader.cpp index 61485576a..3abe862fe 100644 --- a/code/SMDLoader.cpp +++ b/code/SMDLoader.cpp @@ -53,6 +53,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "Valve SMD Importer", + "", + "", + "", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "smd vta" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer SMDImporter::SMDImporter() @@ -73,10 +86,9 @@ bool SMDImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, b // ------------------------------------------------------------------------------------------------ // Get a list of all supported file extensions -void SMDImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* SMDImporter::GetInfo () const { - extensions.insert("smd"); - extensions.insert("vta"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/SMDLoader.h b/code/SMDLoader.h index ba00c1ae2..ac6b7214b 100644 --- a/code/SMDLoader.h +++ b/code/SMDLoader.h @@ -197,10 +197,10 @@ protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/STLLoader.cpp b/code/STLLoader.cpp index e785e8fbc..e96d38397 100644 --- a/code/STLLoader.cpp +++ b/code/STLLoader.cpp @@ -51,6 +51,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "Stereolithography (STL) Importer", + "", + "", + "", + aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "stl" +}; // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer @@ -80,9 +92,9 @@ bool STLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool } // ------------------------------------------------------------------------------------------------ -void STLImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* STLImporter::GetInfo () const { - extensions.insert("stl"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/STLLoader.h b/code/STLLoader.h index afa634720..43e75f0de 100644 --- a/code/STLLoader.h +++ b/code/STLLoader.h @@ -71,10 +71,10 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/TerragenLoader.cpp b/code/TerragenLoader.cpp index 5f57e19b7..c7755e42e 100644 --- a/code/TerragenLoader.cpp +++ b/code/TerragenLoader.cpp @@ -48,6 +48,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "Terragen Heightmap Importer", + "", + "", + "http://www.planetside.co.uk/", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "ter" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer TerragenImporter::TerragenImporter() @@ -83,9 +96,9 @@ bool TerragenImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, // ------------------------------------------------------------------------------------------------ // Build a string of all file extensions supported -void TerragenImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* TerragenImporter::GetInfo () const { - extensions.insert("ter"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/TerragenLoader.h b/code/TerragenLoader.h index 98065d884..208cf4467 100644 --- a/code/TerragenLoader.h +++ b/code/TerragenLoader.h @@ -83,7 +83,7 @@ public: protected: // ------------------------------------------------------------------- - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- void InternReadFile( const std::string& pFile, aiScene* pScene, diff --git a/code/UnrealLoader.cpp b/code/UnrealLoader.cpp index 509cdee44..599803610 100644 --- a/code/UnrealLoader.cpp +++ b/code/UnrealLoader.cpp @@ -58,6 +58,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "Unreal Mesh Importer", + "", + "", + "", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "3d uc" +}; + + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer UnrealImporter::UnrealImporter() @@ -79,10 +93,9 @@ bool UnrealImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/ // ------------------------------------------------------------------------------------------------ // Build a string of all file extensions supported -void UnrealImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* UnrealImporter::GetInfo () const { - extensions.insert("3d"); - extensions.insert("uc"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/UnrealLoader.h b/code/UnrealLoader.h index 7ec97ee12..1dd4d8823 100644 --- a/code/UnrealLoader.h +++ b/code/UnrealLoader.h @@ -165,9 +165,9 @@ protected: // ------------------------------------------------------------------- /** @brief Called by Importer::GetExtensionList() * - * See BaseImporter::GetExtensionList() for details + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- diff --git a/code/XFileImporter.cpp b/code/XFileImporter.cpp index 26c42ba3c..eaeb28560 100644 --- a/code/XFileImporter.cpp +++ b/code/XFileImporter.cpp @@ -51,6 +51,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +static const aiImporterDesc desc = { + "Collada Importer", + "", + "", + "", + aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour, + 1, + 3, + 1, + 5, + "x" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer XFileImporter::XFileImporter() @@ -78,9 +91,10 @@ bool XFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo } // ------------------------------------------------------------------------------------------------ -void XFileImporter::GetExtensionList(std::set& extensions) +// Get file extension list +const aiImporterDesc* XFileImporter::GetInfo () const { - extensions.insert("x"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/XFileImporter.h b/code/XFileImporter.h index a92d4f8e2..5f1ac9ac6 100644 --- a/code/XFileImporter.h +++ b/code/XFileImporter.h @@ -81,10 +81,10 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ - void GetExtensionList(std::set& extensions); + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/code/XGLLoader.cpp b/code/XGLLoader.cpp index c96471aa7..24d6d8487 100644 --- a/code/XGLLoader.cpp +++ b/code/XGLLoader.cpp @@ -79,6 +79,19 @@ struct free_it template<> const std::string LogFunctions::log_prefix = "XGL: "; +static const aiImporterDesc desc = { + "XGL Importer", + "", + "", + "", + aiImporterFlags_SupportTextFlavour, + 0, + 0, + 0, + 0, + "xgl zgl" +}; + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer @@ -115,10 +128,9 @@ bool XGLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool // ------------------------------------------------------------------------------------------------ // Get a list of all file extensions which are handled by this class -void XGLImporter::GetExtensionList(std::set& extensions) +const aiImporterDesc* XGLImporter::GetInfo () const { - extensions.insert("xgl"); - extensions.insert("zgl"); + return &desc; } // ------------------------------------------------------------------------------------------------ diff --git a/code/XGLLoader.h b/code/XGLLoader.h index 159f0af25..e9675af01 100644 --- a/code/XGLLoader.h +++ b/code/XGLLoader.h @@ -74,9 +74,9 @@ public: protected: // ------------------------------------------------------------------- - /** Called by Importer::GetExtensionList() for each loaded importer. - * See BaseImporter::GetExtensionList() for details */ - void GetExtensionList(std::set& extensions); + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details */ + const aiImporterDesc* GetInfo () const; // ------------------------------------------------------------------- /** Imports the given file into the given scene structure. diff --git a/include/assimp/importerdesc.h b/include/assimp/importerdesc.h index 0588d615d..a1e29b23b 100644 --- a/include/assimp/importerdesc.h +++ b/include/assimp/importerdesc.h @@ -117,6 +117,20 @@ struct aiImporterDesc maximum version.*/ unsigned int mMaxMajor; unsigned int mMaxMinor; + + /** List of file extensions this importer can handle. + List entries are separated by space characters. + All entries are lower case without a leading dot (i.e. + "xml dae" would be a valid value. Note that multiple + importers may respond to the same file extension - + assimp calls all importers in the order in which they + are registered and each importer gets the opportunity + to load the file until one importer "claims" the file. Apart + from file extension checks, importers typically use + other methods to quickly reject files (i.e. magic + words) so this does not mean that common or generic + file extensions such as XML would be tediously slow. */ + const char* mFileExtensions; }; #endif diff --git a/workspaces/vc9/assimp.vcproj b/workspaces/vc9/assimp.vcproj index 3683d1622..8c8e7148f 100644 --- a/workspaces/vc9/assimp.vcproj +++ b/workspaces/vc9/assimp.vcproj @@ -1812,7 +1812,7 @@ >