2
0
Эх сурвалжийг харах

- 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
aramis_acg 13 жил өмнө
parent
commit
5a81b42ebe
81 өөрчлөгдсөн 1681 нэмэгдсэн , 1176 устгасан
  1. 17 4
      code/3DSLoader.cpp
  2. 3 3
      code/3DSLoader.h
  3. 15 5
      code/ACLoader.cpp
  4. 3 3
      code/ACLoader.h
  5. 16 3
      code/ASELoader.cpp
  6. 3 3
      code/ASELoader.h
  7. 17 2
      code/B3DImporter.cpp
  8. 1 1
      code/B3DImporter.h
  9. 20 0
      code/BVHLoader.cpp
  10. 3 7
      code/BVHLoader.h
  11. 19 0
      code/BaseImporter.cpp
  12. 11 15
      code/BaseImporter.h
  13. 3 2
      code/BlenderLoader.cpp
  14. 17 4
      code/COBLoader.cpp
  15. 1 1
      code/COBLoader.h
  16. 16 2
      code/CSMLoader.cpp
  17. 1 1
      code/CSMLoader.h
  18. 16 2
      code/ColladaLoader.cpp
  19. 3 3
      code/ColladaLoader.h
  20. 16 2
      code/DXFLoader.cpp
  21. 3 3
      code/DXFLoader.h
  22. 15 2
      code/HMPLoader.cpp
  23. 3 3
      code/HMPLoader.h
  24. 16 2
      code/IFCLoader.cpp
  25. 1 1
      code/IFCLoader.h
  26. 14 3
      code/IRRLoader.cpp
  27. 1 1
      code/IRRLoader.h
  28. 15 3
      code/IRRMeshLoader.cpp
  29. 3 3
      code/IRRMeshLoader.h
  30. 22 1
      code/LWOLoader.cpp
  31. 2 8
      code/LWOLoader.h
  32. 15 3
      code/LWSLoader.cpp
  33. 1 1
      code/LWSLoader.h
  34. 15 4
      code/M3Importer.cpp
  35. 1 1
      code/M3Importer.h
  36. 15 2
      code/MD2Loader.cpp
  37. 3 3
      code/MD2Loader.h
  38. 15 2
      code/MD3Loader.cpp
  39. 3 3
      code/MD3Loader.h
  40. 16 4
      code/MD5Loader.cpp
  41. 3 3
      code/MD5Loader.h
  42. 14 2
      code/MDCLoader.cpp
  43. 3 3
      code/MDCLoader.h
  44. 15 2
      code/MDLLoader.cpp
  45. 3 3
      code/MDLLoader.h
  46. 15 2
      code/MS3DLoader.cpp
  47. 3 3
      code/MS3DLoader.h
  48. 15 2
      code/NDOLoader.cpp
  49. 1 1
      code/NDOLoader.h
  50. 15 3
      code/NFFLoader.cpp
  51. 3 3
      code/NFFLoader.h
  52. 15 2
      code/OFFLoader.cpp
  53. 3 3
      code/OFFLoader.h
  54. 20 0
      code/ObjFileImporter.cpp
  55. 1 8
      code/ObjFileImporter.h
  56. 15 2
      code/OgreImporter.cpp
  57. 2 2
      code/OgreImporter.hpp
  58. 507 507
      code/OgreMesh.cpp
  59. 455 455
      code/OgreSkeleton.cpp
  60. 15 2
      code/PlyLoader.cpp
  61. 3 3
      code/PlyLoader.h
  62. 17 5
      code/Q3BSPFileImporter.cpp
  63. 1 1
      code/Q3BSPFileImporter.h
  64. 15 3
      code/Q3DLoader.cpp
  65. 3 3
      code/Q3DLoader.h
  66. 15 3
      code/RawLoader.cpp
  67. 3 3
      code/RawLoader.h
  68. 15 3
      code/SMDLoader.cpp
  69. 3 3
      code/SMDLoader.h
  70. 14 2
      code/STLLoader.cpp
  71. 3 3
      code/STLLoader.h
  72. 15 2
      code/TerragenLoader.cpp
  73. 1 1
      code/TerragenLoader.h
  74. 16 3
      code/UnrealLoader.cpp
  75. 2 2
      code/UnrealLoader.h
  76. 16 2
      code/XFileImporter.cpp
  77. 3 3
      code/XFileImporter.h
  78. 15 3
      code/XGLLoader.cpp
  79. 3 3
      code/XGLLoader.h
  80. 14 0
      include/assimp/importerdesc.h
  81. 1 1
      workspaces/vc9/assimp.vcproj

+ 17 - 4
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<std::string>& extensions)
+// Loader registry entry
+const aiImporterDesc* Discreet3DSImporter::GetInfo () const
 {
-	extensions.insert("3ds");
-	extensions.insert("prj");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 15 - 5
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<std::string>& extensions)
+// Loader meta information
+const aiImporterDesc* AC3DImporter::GetInfo () const
 {
-	extensions.insert("ac");
-	extensions.insert("acc");
-	extensions.insert("ac3d");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	/** Return importer meta information.
+	 * See #BaseImporter::GetInfo for the details */
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 16 - 3
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<std::string>& extensions)
+// Loader meta information
+const aiImporterDesc* ASEImporter::GetInfo () const
 {
-	extensions.insert("ase");
-	extensions.insert("ask");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 
 	// -------------------------------------------------------------------

+ 17 - 2
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<std::string>& extensions ){
-	extensions.insert("b3d");
+// Loader meta information
+const aiImporterDesc* B3DImporter::GetInfo () const
+{
+	return &desc;
 }
 
 #ifdef DEBUG_B3D

+ 1 - 1
code/B3DImporter.h

@@ -60,7 +60,7 @@ public:
 
 protected:
 
-	virtual void GetExtensionList(std::set<std::string>& extensions);
+	virtual const aiImporterDesc* GetInfo () const;
 	virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
 
 private:

+ 20 - 0
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)

+ 3 - 7
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<std::string>& extensions)
-	{
-		extensions.insert("bvh");
-	}
+
 
 	/** Imports the given file into the given scene structure. 
 	 * See BaseImporter::InternReadFile() for details

+ 19 - 0
code/BaseImporter.cpp

@@ -105,6 +105,25 @@ void BaseImporter::SetupProperties(const Importer* /*pImp*/)
 	// the default implementation does nothing
 }
 
+// ------------------------------------------------------------------------------------------------
+void BaseImporter::GetExtensionList(std::set<std::string>& 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,

+ 11 - 15
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<std::string>& 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<std::string>& extensions);
+
+protected:
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. The 

+ 3 - 2
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"
 };
 
 

+ 17 - 4
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<std::string>& app)
+// Loader meta information
+const aiImporterDesc* COBImporter::GetInfo () const
 {
-	app.insert("cob");
-	app.insert("scn");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/COBLoader.h

@@ -82,7 +82,7 @@ public:
 protected:
 
 	// --------------------
-	void GetExtensionList(std::set<std::string>& app);
+	const aiImporterDesc* GetInfo () const;
 
 	// --------------------
 	void SetupProperties(const Importer* pImp);

+ 16 - 2
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<std::string>& extensions)
+const aiImporterDesc* CSMImporter::GetInfo () const
 {
-	extensions.insert("csm");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/CSMLoader.h

@@ -69,7 +69,7 @@ public:
 protected:
 
 	// -------------------------------------------------------------------
-	void GetExtensionList(std::set<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	void SetupProperties(const Importer* pImp);

+ 16 - 2
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<std::string>& extensions )
+const aiImporterDesc* ColladaLoader::GetInfo () const
 {
-	extensions.insert("dae");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	/** Imports the given file into the given scene structure. 
 	 * See BaseImporter::InternReadFile() for details

+ 16 - 2
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<std::string>& extensions)
+const aiImporterDesc* DXFImporter::GetInfo () const
 {
-	extensions.insert("dxf");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	/** Return importer meta information.
+	 * See #BaseImporter::GetInfo for the details*/
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 15 - 2
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<std::string>& extensions)
+const aiImporterDesc* HMPImporter::GetInfo () const
 {
-	extensions.insert("hmp");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 16 - 2
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<std::string>& app) 
+const aiImporterDesc* IFCImporter::GetInfo () const
 {
-	app.insert("ifc");
+	return &desc;
 }
 
 

+ 1 - 1
code/IFCLoader.h

@@ -85,7 +85,7 @@ public:
 protected:
 
 	// --------------------
-	void GetExtensionList(std::set<std::string>& app);
+	const aiImporterDesc* GetInfo () const;
 
 	// --------------------
 	void SetupProperties(const Importer* pImp);

+ 14 - 3
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<std::string>& extensions)
+const aiImporterDesc* IRRImporter::GetInfo () const
 {
-	extensions.insert("irr");
-	extensions.insert("xml");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/IRRLoader.h

@@ -80,7 +80,7 @@ protected:
 	// -------------------------------------------------------------------
 	/**
 	 */
-	void GetExtensionList(std::set<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** 

+ 15 - 3
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<std::string>& extensions)
+const aiImporterDesc* IRRMeshImporter::GetInfo () const
 {
-	extensions.insert("xml");
-	extensions.insert("irrmesh");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 22 - 1
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, 

+ 2 - 8
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<std::string>& 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. 

+ 15 - 3
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<std::string>& extensions)
+const aiImporterDesc* LWSImporter::GetInfo () const
 {
-	extensions.insert("lws");
-	extensions.insert("mot");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/LWSLoader.h

@@ -184,7 +184,7 @@ protected:
 
 	// -------------------------------------------------------------------
 	// Get list of supported extensions
-	void GetExtensionList(std::set<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	// Import file into given scene data structure

+ 15 - 4
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<std::string>& extensions)
+const aiImporterDesc* M3Importer::GetInfo () const
 {
-	extensions.insert( M3Extension );
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/M3Importer.h

@@ -694,7 +694,7 @@ public:
 	bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const;
 
 private:
-	void GetExtensionList( std::set<std::string>& 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<aiVector3D> &vertices, const std::vector<aiVector3D> &uvCoords, const std::vector<aiVector3D> &normals );

+ 15 - 2
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<std::string>& extensions)
+const aiImporterDesc* MD2Importer::GetInfo () const
 {
-	extensions.insert("md2");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 15 - 2
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<std::string>& extensions)
+const aiImporterDesc* MD3Importer::GetInfo () const
 {
-	extensions.insert("md3");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 16 - 4
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<std::string>& extensions)
+const aiImporterDesc* MD5Importer::GetInfo () const
 {
-	extensions.insert("md5anim");
-	extensions.insert("md5mesh");
-	extensions.insert("md5camera");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Called prior to ReadFile().

+ 14 - 2
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<std::string>& extensions)
+const aiImporterDesc* MDCImporter::GetInfo () const
 {
-	extensions.insert("mdc");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 15 - 2
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<std::string>& extensions)
+const aiImporterDesc* MDLImporter::GetInfo () const
 {
-	extensions.insert( "mdl" );
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 15 - 2
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<std::string>& extensions)
+const aiImporterDesc* MS3DImporter::GetInfo () const
 {
-	extensions.insert("ms3d");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	/** Return importer meta information.
+	 * See #BaseImporter::GetInfo for the details */
+	const aiImporterDesc* GetInfo () const;
 
 
 	// -------------------------------------------------------------------

+ 15 - 2
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<std::string>& extensions)
+const aiImporterDesc* NDOImporter::GetInfo () const
 {
-	extensions.insert("ndo");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/NDOLoader.h

@@ -97,7 +97,7 @@ public:
 protected:
 
 	// -------------------------------------------------------------------
-	void GetExtensionList(std::set<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	void SetupProperties(const Importer* pImp);

+ 15 - 3
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<std::string>& extensions)
+const aiImporterDesc* NFFImporter::GetInfo () const
 {
-	extensions.insert("enff");
-	extensions.insert("nff");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 15 - 2
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<std::string>& extensions)
+const aiImporterDesc* OFFImporter::GetInfo () const
 {
-	extensions.insert("off");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 20 - 0
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)

+ 1 - 8
code/ObjFileImporter.h

@@ -78,7 +78,7 @@ public:
 private:
 
 	//! \brief	Appends the supported extention.
-	void GetExtensionList(std::set<std::string>& 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<std::string>& extensions)
-{
-	extensions.insert("obj");
-}
-
 // ------------------------------------------------------------------------------------------------
 
 } // Namespace Assimp

+ 15 - 2
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<std::string>& extensions)
+const aiImporterDesc* OgreImporter::GetInfo () const
 {
-	extensions.insert("mesh.xml");
+	return &desc;
 }
 
 

+ 2 - 2
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<std::string>& extensions);
+	virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
+	virtual const aiImporterDesc* GetInfo () const;
 	virtual void SetupProperties(const Importer* pImp);
 private:
 

+ 507 - 507
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<bool>(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<int>(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<int>(Reader, "v1");
-				NewFace.VertexIndices[1]=GetAttribute<int>(Reader, "v2");
-				NewFace.VertexIndices[2]=GetAttribute<int>(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<int>(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<bool>(Reader, "positions"))
-	{
-		ReadPositions=theSubMesh.HasPositions=true;
-		theSubMesh.Positions.reserve(NumVertices);
-		DefaultLogger::get()->debug("reading positions");
-	}
-	if(Reader->getAttributeValue("normals") && GetAttribute<bool>(Reader, "normals"))
-	{
-		ReadNormals=theSubMesh.HasNormals=true;
-		theSubMesh.Normals.reserve(NumVertices);
-		DefaultLogger::get()->debug("reading normals");
-	}
-	if(Reader->getAttributeValue("tangents") && GetAttribute<bool>(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<int>(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<float>(Reader, "x");
-			NewPos.y=GetAttribute<float>(Reader, "y");
-			NewPos.z=GetAttribute<float>(Reader, "z");
-			theSubMesh.Positions.push_back(NewPos);
-		}
-				
-		//Normal
-		else if(ReadNormals && Reader->getNodeName()==string("normal"))
-		{
-			aiVector3D NewNormal;
-			NewNormal.x=GetAttribute<float>(Reader, "x");
-			NewNormal.y=GetAttribute<float>(Reader, "y");
-			NewNormal.z=GetAttribute<float>(Reader, "z");
-			theSubMesh.Normals.push_back(NewNormal);
-		}
-				
-		//Tangent
-		else if(ReadTangents && Reader->getNodeName()==string("tangent"))
-		{
-			aiVector3D NewTangent;
-			NewTangent.x=GetAttribute<float>(Reader, "x");
-			NewTangent.y=GetAttribute<float>(Reader, "y");
-			NewTangent.z=GetAttribute<float>(Reader, "z");
-			theSubMesh.Tangents.push_back(NewTangent);
-		}
-
-		//Uv:
-		else if(ReadUvs && Reader->getNodeName()==string("texcoord"))
-		{
-			aiVector3D NewUv;
-			NewUv.x=GetAttribute<float>(Reader, "u");
-			NewUv.y=GetAttribute<float>(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<int>(Reader, "vertexindex");
-		NewWeight.BoneId=GetAttribute<int>(Reader, "boneindex");
-		NewWeight.Value=GetAttribute<float>(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<Face> 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<aiVector3D> UniquePositions(UniqueVertexCount);
-	vector<aiVector3D> UniqueNormals(UniqueVertexCount);
-	vector<aiVector3D> UniqueTangents(UniqueVertexCount);
-	vector<aiVector3D> UniqueUvs(UniqueVertexCount);
-	vector< vector<Weight> > 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<theSubMesh.FaceList.size(); ++i)
-	{
-		//We precalculate the index vlaues her, because we need them in all vertex attributes
-		unsigned int Vertex1=theSubMesh.FaceList[i].VertexIndices[0];
-		unsigned int Vertex2=theSubMesh.FaceList[i].VertexIndices[1];
-		unsigned int Vertex3=theSubMesh.FaceList[i].VertexIndices[2];
-
-		UniquePositions[3*i+0]=VertexSource.Positions[Vertex1];
-		UniquePositions[3*i+1]=VertexSource.Positions[Vertex2];
-		UniquePositions[3*i+2]=VertexSource.Positions[Vertex3];
-
-		if(VertexSource.HasNormals)
-		{
-			UniqueNormals[3*i+0]=VertexSource.Normals[Vertex1];
-			UniqueNormals[3*i+1]=VertexSource.Normals[Vertex2];
-			UniqueNormals[3*i+2]=VertexSource.Normals[Vertex3];
-		}
-
-		if(VertexSource.HasTangents)
-		{
-			UniqueTangents[3*i+0]=VertexSource.Tangents[Vertex1];
-			UniqueTangents[3*i+1]=VertexSource.Tangents[Vertex2];
-			UniqueTangents[3*i+2]=VertexSource.Tangents[Vertex3];
-		}
-
-		if(VertexSource.NumUvs > 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; VertexId<theSubMesh.Weights.size(); ++VertexId)//iterate over all vertices
-	{
-		float WeightSum=0.0f;
-		for(unsigned int BoneId=0; BoneId<theSubMesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones
-		{
-			WeightSum+=theSubMesh.Weights[VertexId][BoneId].Value;
-		}
-		
-		//check if the sum is too far away from 1
-		if(WeightSum<1.0f-0.05f || WeightSum>1.0f+0.05f)
-		{
-			//normalize all weights:
-			for(unsigned int BoneId=0; BoneId<theSubMesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones
-			{
-				theSubMesh.Weights[VertexId][BoneId].Value/=WeightSum;
-			}
-		}
-	}
-	//_________________________________________________________
-}
-
-
-
-
-aiMesh* OgreImporter::CreateAssimpSubMesh(const SubMesh& theSubMesh, const vector<Bone>& 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<aiVertexWeight> > aiWeights(theSubMesh.BonesUsed);//now the outer list are the bones, and the inner vector the vertices
-	for(unsigned int VertexId=0; VertexId<theSubMesh.Weights.size(); ++VertexId)//iterate over all vertices
-	{
-		for(unsigned int BoneId=0; BoneId<theSubMesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones
-		{
-			aiVertexWeight NewWeight;
-			NewWeight.mVertexId=VertexId;//the current Vertex, we can't use the Id form the submehs weights, because they are bone id's
-			NewWeight.mWeight=theSubMesh.Weights[VertexId][BoneId].Value;
-			aiWeights[theSubMesh.Weights[VertexId][BoneId].BoneId].push_back(NewWeight);
-		}
-	}
-
-	
-
-	vector<aiBone*> 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; i<theSubMesh.BonesUsed; ++i)
-	{
-		if(aiWeights[i].size()>0)
-		{
-			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; i<theSubMesh.FaceList.size(); ++i)
-	{
-		NewAiMesh->mFaces[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<bool>(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<int>(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<int>(Reader, "v1");
+				NewFace.VertexIndices[1]=GetAttribute<int>(Reader, "v2");
+				NewFace.VertexIndices[2]=GetAttribute<int>(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<int>(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<bool>(Reader, "positions"))
+	{
+		ReadPositions=theSubMesh.HasPositions=true;
+		theSubMesh.Positions.reserve(NumVertices);
+		DefaultLogger::get()->debug("reading positions");
+	}
+	if(Reader->getAttributeValue("normals") && GetAttribute<bool>(Reader, "normals"))
+	{
+		ReadNormals=theSubMesh.HasNormals=true;
+		theSubMesh.Normals.reserve(NumVertices);
+		DefaultLogger::get()->debug("reading normals");
+	}
+	if(Reader->getAttributeValue("tangents") && GetAttribute<bool>(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<int>(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<float>(Reader, "x");
+			NewPos.y=GetAttribute<float>(Reader, "y");
+			NewPos.z=GetAttribute<float>(Reader, "z");
+			theSubMesh.Positions.push_back(NewPos);
+		}
+				
+		//Normal
+		else if(ReadNormals && Reader->getNodeName()==string("normal"))
+		{
+			aiVector3D NewNormal;
+			NewNormal.x=GetAttribute<float>(Reader, "x");
+			NewNormal.y=GetAttribute<float>(Reader, "y");
+			NewNormal.z=GetAttribute<float>(Reader, "z");
+			theSubMesh.Normals.push_back(NewNormal);
+		}
+				
+		//Tangent
+		else if(ReadTangents && Reader->getNodeName()==string("tangent"))
+		{
+			aiVector3D NewTangent;
+			NewTangent.x=GetAttribute<float>(Reader, "x");
+			NewTangent.y=GetAttribute<float>(Reader, "y");
+			NewTangent.z=GetAttribute<float>(Reader, "z");
+			theSubMesh.Tangents.push_back(NewTangent);
+		}
+
+		//Uv:
+		else if(ReadUvs && Reader->getNodeName()==string("texcoord"))
+		{
+			aiVector3D NewUv;
+			NewUv.x=GetAttribute<float>(Reader, "u");
+			NewUv.y=GetAttribute<float>(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<int>(Reader, "vertexindex");
+		NewWeight.BoneId=GetAttribute<int>(Reader, "boneindex");
+		NewWeight.Value=GetAttribute<float>(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<Face> 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<aiVector3D> UniquePositions(UniqueVertexCount);
+	vector<aiVector3D> UniqueNormals(UniqueVertexCount);
+	vector<aiVector3D> UniqueTangents(UniqueVertexCount);
+	vector<aiVector3D> UniqueUvs(UniqueVertexCount);
+	vector< vector<Weight> > 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<theSubMesh.FaceList.size(); ++i)
+	{
+		//We precalculate the index vlaues her, because we need them in all vertex attributes
+		unsigned int Vertex1=theSubMesh.FaceList[i].VertexIndices[0];
+		unsigned int Vertex2=theSubMesh.FaceList[i].VertexIndices[1];
+		unsigned int Vertex3=theSubMesh.FaceList[i].VertexIndices[2];
+
+		UniquePositions[3*i+0]=VertexSource.Positions[Vertex1];
+		UniquePositions[3*i+1]=VertexSource.Positions[Vertex2];
+		UniquePositions[3*i+2]=VertexSource.Positions[Vertex3];
+
+		if(VertexSource.HasNormals)
+		{
+			UniqueNormals[3*i+0]=VertexSource.Normals[Vertex1];
+			UniqueNormals[3*i+1]=VertexSource.Normals[Vertex2];
+			UniqueNormals[3*i+2]=VertexSource.Normals[Vertex3];
+		}
+
+		if(VertexSource.HasTangents)
+		{
+			UniqueTangents[3*i+0]=VertexSource.Tangents[Vertex1];
+			UniqueTangents[3*i+1]=VertexSource.Tangents[Vertex2];
+			UniqueTangents[3*i+2]=VertexSource.Tangents[Vertex3];
+		}
+
+		if(VertexSource.NumUvs > 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; VertexId<theSubMesh.Weights.size(); ++VertexId)//iterate over all vertices
+	{
+		float WeightSum=0.0f;
+		for(unsigned int BoneId=0; BoneId<theSubMesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones
+		{
+			WeightSum+=theSubMesh.Weights[VertexId][BoneId].Value;
+		}
+		
+		//check if the sum is too far away from 1
+		if(WeightSum<1.0f-0.05f || WeightSum>1.0f+0.05f)
+		{
+			//normalize all weights:
+			for(unsigned int BoneId=0; BoneId<theSubMesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones
+			{
+				theSubMesh.Weights[VertexId][BoneId].Value/=WeightSum;
+			}
+		}
+	}
+	//_________________________________________________________
+}
+
+
+
+
+aiMesh* OgreImporter::CreateAssimpSubMesh(const SubMesh& theSubMesh, const vector<Bone>& 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<aiVertexWeight> > aiWeights(theSubMesh.BonesUsed);//now the outer list are the bones, and the inner vector the vertices
+	for(unsigned int VertexId=0; VertexId<theSubMesh.Weights.size(); ++VertexId)//iterate over all vertices
+	{
+		for(unsigned int BoneId=0; BoneId<theSubMesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones
+		{
+			aiVertexWeight NewWeight;
+			NewWeight.mVertexId=VertexId;//the current Vertex, we can't use the Id form the submehs weights, because they are bone id's
+			NewWeight.mWeight=theSubMesh.Weights[VertexId][BoneId].Value;
+			aiWeights[theSubMesh.Weights[VertexId][BoneId].BoneId].push_back(NewWeight);
+		}
+	}
+
+	
+
+	vector<aiBone*> 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; i<theSubMesh.BonesUsed; ++i)
+	{
+		if(aiWeights[i].size()>0)
+		{
+			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; i<theSubMesh.FaceList.size(); ++i)
+	{
+		NewAiMesh->mFaces[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

+ 455 - 455
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<Bone> &Bones, vector<Animation> &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<IOStream> File(m_CurrentIOHandler->Open(FileName));
-	if(NULL==File.get())
-		throw DeadlyImportError("Failed to open skeleton file "+FileName+".");
-
-	//Read the Mesh File:
-	boost::scoped_ptr<CIrrXML_IOStreamReader> 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 <skeleton> 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<int>(SkeletonFile, "id");
-		NewBone.Name=GetAttribute<string>(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<float>(SkeletonFile, "x");
-		NewBone.Position.y=GetAttribute<float>(SkeletonFile, "y");
-		NewBone.Position.z=GetAttribute<float>(SkeletonFile, "z");
-
-		//Rotation:
-		XmlRead(SkeletonFile);
-		if(string("rotation")!=SkeletonFile->getNodeName())
-			throw DeadlyImportError("Rotation is not the second node in Bone!");
-		NewBone.RotationAngle=GetAttribute<float>(SkeletonFile, "angle");
-		XmlRead(SkeletonFile);
-		if(string("axis")!=SkeletonFile->getNodeName())
-			throw DeadlyImportError("No axis specified for bone rotation!");
-		NewBone.RotationAxis.x=GetAttribute<float>(SkeletonFile, "x");
-		NewBone.RotationAxis.y=GetAttribute<float>(SkeletonFile, "y");
-		NewBone.RotationAxis.z=GetAttribute<float>(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<static_cast<signed int>(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<string>(SkeletonFile, "bone");
-		Parent=GetAttribute<string>(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<string>(SkeletonFile, "name");
-			NewAnimation.Length=GetAttribute<float>(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<string>(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<float>(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<float>(SkeletonFile, "x");
-							NewKeyframe.Position.y=GetAttribute<float>(SkeletonFile, "y");
-							NewKeyframe.Position.z=GetAttribute<float>(SkeletonFile, "z");
-						}
-
-						//Rotation:
-						else if(string("rotate")==SkeletonFile->getNodeName())
-						{
-							float RotationAngle=GetAttribute<float>(SkeletonFile, "angle");
-							aiVector3D RotationAxis;
-							XmlRead(SkeletonFile);
-							if(string("axis")!=SkeletonFile->getNodeName())
-								throw DeadlyImportError("No axis for keyframe rotation!");
-							RotationAxis.x=GetAttribute<float>(SkeletonFile, "x");
-							RotationAxis.y=GetAttribute<float>(SkeletonFile, "y");
-							RotationAxis.z=GetAttribute<float>(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<float>(SkeletonFile, "x");
-							NewKeyframe.Scaling.y=GetAttribute<float>(SkeletonFile, "y");
-							NewKeyframe.Scaling.z=GetAttribute<float>(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<Bone> &Bones, const std::vector<Animation> &/*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<aiNode*> 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<Bone> &Bones, const std::vector<Animation> &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; i<Animations.size(); ++i)//create all animations
-		{
-			aiAnimation* NewAnimation=new aiAnimation();
-			NewAnimation->mName=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; j<Animations[i].Tracks.size(); ++j)
-			{
-				aiNodeAnim* NewNodeAnim=new aiNodeAnim();
-				NewNodeAnim->mNodeName=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<Bone>::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; k<KeyframeCount; ++k)
-				{
-					aiMatrix4x4 t2, t3;
-
-					//Create a matrix to transfrom a vector from the bones default pose to the bone bones in this animation key
-					aiMatrix4x4 PoseToKey=
-									  aiMatrix4x4::Translation(Animations[i].Tracks[j].Keyframes[k].Position, t3)	//pos
-									* aiMatrix4x4(Animations[i].Tracks[j].Keyframes[k].Rotation.GetMatrix())		//rot
-									* aiMatrix4x4::Scaling(Animations[i].Tracks[j].Keyframes[k].Scaling, t2);	//scale
-									
-
-					//calculate the complete transformation from world space to bone space
-					aiMatrix4x4 CompleteTransform=DefBonePose * PoseToKey;
-					
-					aiVector3D Pos;
-					aiQuaternion Rot;
-					aiVector3D Scale;
-
-					CompleteTransform.Decompose(Scale, Rot, Pos);
-
-					double Time=Animations[i].Tracks[j].Keyframes[k].Time;
-
-					NewNodeAnim->mPositionKeys[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<Bone> &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; i<Bones[BoneId].Children.size(); ++i)
-	{
-		NewNode->mChildren[i]=CreateAiNodeFromBone(Bones[BoneId].Children[i], Bones, NewNode);
-	}
-	//____________________________________________________
-
-
-	return NewNode;
-}
-
-
-void Bone::CalculateBoneToWorldSpaceMatrix(vector<Bone> &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<Bone> &Bones, vector<Animation> &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<IOStream> File(m_CurrentIOHandler->Open(FileName));
+	if(NULL==File.get())
+		throw DeadlyImportError("Failed to open skeleton file "+FileName+".");
+
+	//Read the Mesh File:
+	boost::scoped_ptr<CIrrXML_IOStreamReader> 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 <skeleton> 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<int>(SkeletonFile, "id");
+		NewBone.Name=GetAttribute<string>(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<float>(SkeletonFile, "x");
+		NewBone.Position.y=GetAttribute<float>(SkeletonFile, "y");
+		NewBone.Position.z=GetAttribute<float>(SkeletonFile, "z");
+
+		//Rotation:
+		XmlRead(SkeletonFile);
+		if(string("rotation")!=SkeletonFile->getNodeName())
+			throw DeadlyImportError("Rotation is not the second node in Bone!");
+		NewBone.RotationAngle=GetAttribute<float>(SkeletonFile, "angle");
+		XmlRead(SkeletonFile);
+		if(string("axis")!=SkeletonFile->getNodeName())
+			throw DeadlyImportError("No axis specified for bone rotation!");
+		NewBone.RotationAxis.x=GetAttribute<float>(SkeletonFile, "x");
+		NewBone.RotationAxis.y=GetAttribute<float>(SkeletonFile, "y");
+		NewBone.RotationAxis.z=GetAttribute<float>(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<static_cast<signed int>(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<string>(SkeletonFile, "bone");
+		Parent=GetAttribute<string>(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<string>(SkeletonFile, "name");
+			NewAnimation.Length=GetAttribute<float>(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<string>(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<float>(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<float>(SkeletonFile, "x");
+							NewKeyframe.Position.y=GetAttribute<float>(SkeletonFile, "y");
+							NewKeyframe.Position.z=GetAttribute<float>(SkeletonFile, "z");
+						}
+
+						//Rotation:
+						else if(string("rotate")==SkeletonFile->getNodeName())
+						{
+							float RotationAngle=GetAttribute<float>(SkeletonFile, "angle");
+							aiVector3D RotationAxis;
+							XmlRead(SkeletonFile);
+							if(string("axis")!=SkeletonFile->getNodeName())
+								throw DeadlyImportError("No axis for keyframe rotation!");
+							RotationAxis.x=GetAttribute<float>(SkeletonFile, "x");
+							RotationAxis.y=GetAttribute<float>(SkeletonFile, "y");
+							RotationAxis.z=GetAttribute<float>(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<float>(SkeletonFile, "x");
+							NewKeyframe.Scaling.y=GetAttribute<float>(SkeletonFile, "y");
+							NewKeyframe.Scaling.z=GetAttribute<float>(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<Bone> &Bones, const std::vector<Animation> &/*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<aiNode*> 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<Bone> &Bones, const std::vector<Animation> &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; i<Animations.size(); ++i)//create all animations
+		{
+			aiAnimation* NewAnimation=new aiAnimation();
+			NewAnimation->mName=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; j<Animations[i].Tracks.size(); ++j)
+			{
+				aiNodeAnim* NewNodeAnim=new aiNodeAnim();
+				NewNodeAnim->mNodeName=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<Bone>::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; k<KeyframeCount; ++k)
+				{
+					aiMatrix4x4 t2, t3;
+
+					//Create a matrix to transfrom a vector from the bones default pose to the bone bones in this animation key
+					aiMatrix4x4 PoseToKey=
+									  aiMatrix4x4::Translation(Animations[i].Tracks[j].Keyframes[k].Position, t3)	//pos
+									* aiMatrix4x4(Animations[i].Tracks[j].Keyframes[k].Rotation.GetMatrix())		//rot
+									* aiMatrix4x4::Scaling(Animations[i].Tracks[j].Keyframes[k].Scaling, t2);	//scale
+									
+
+					//calculate the complete transformation from world space to bone space
+					aiMatrix4x4 CompleteTransform=DefBonePose * PoseToKey;
+					
+					aiVector3D Pos;
+					aiQuaternion Rot;
+					aiVector3D Scale;
+
+					CompleteTransform.Decompose(Scale, Rot, Pos);
+
+					double Time=Animations[i].Tracks[j].Keyframes[k].Time;
+
+					NewNodeAnim->mPositionKeys[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<Bone> &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; i<Bones[BoneId].Children.size(); ++i)
+	{
+		NewNode->mChildren[i]=CreateAiNodeFromBone(Bones[BoneId].Children[i], Bones, NewNode);
+	}
+	//____________________________________________________
+
+
+	return NewNode;
+}
+
+
+void Bone::CalculateBoneToWorldSpaceMatrix(vector<Bone> &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

+ 15 - 2
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<std::string>& extensions)
+const aiImporterDesc* PLYImporter::GetInfo () const
 {
-	extensions.insert("ply");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 17 - 5
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 <vector>
 
+
+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<std::string>& extensions )
+const aiImporterDesc* Q3BSPFileImporter::GetInfo () const
 {
-	extensions.insert( Q3BSPExtension  );
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/Q3BSPFileImporter.h

@@ -78,7 +78,7 @@ private:
 	typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>* >::iterator FaceMapIt;
 	typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>*>::const_iterator FaceMapConstIt;
 
-	void GetExtensionList(std::set<std::string>& 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 );

+ 15 - 3
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<std::string>& extensions)
+const aiImporterDesc* Q3DImporter::GetInfo () const
 {
-	extensions.insert("q3o");
-	extensions.insert("q3s");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 15 - 3
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<std::string>& extensions)
+const aiImporterDesc* RAWImporter::GetInfo () const
 {
-	extensions.insert("raw");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 15 - 3
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<std::string>& extensions)
+const aiImporterDesc* SMDImporter::GetInfo () const
 {
-	extensions.insert("smd");
-	extensions.insert("vta");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 14 - 2
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<std::string>& extensions)
+const aiImporterDesc* STLImporter::GetInfo () const
 {
-	extensions.insert("stl");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 15 - 2
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<std::string>& extensions)
+const aiImporterDesc* TerragenImporter::GetInfo () const
 {
-	extensions.insert("ter");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/TerragenLoader.h

@@ -83,7 +83,7 @@ public:
 protected:
 
 	// -------------------------------------------------------------------
-	void GetExtensionList(std::set<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	void InternReadFile( const std::string& pFile, aiScene* pScene, 

+ 16 - 3
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<std::string>& extensions)
+const aiImporterDesc* UnrealImporter::GetInfo () const
 {
-	extensions.insert("3d");
-	extensions.insert("uc");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 2 - 2
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 
 	// -------------------------------------------------------------------

+ 16 - 2
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<std::string>& extensions)
+// Get file extension list
+const aiImporterDesc* XFileImporter::GetInfo () const
 {
-	extensions.insert("x");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 15 - 3
code/XGLLoader.cpp

@@ -79,6 +79,19 @@ struct free_it
 
 template<> const std::string LogFunctions<XGLImporter>::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<std::string>& extensions)
+const aiImporterDesc* XGLImporter::GetInfo () const
 {
-	extensions.insert("xgl");
-	extensions.insert("zgl");
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
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<std::string>& extensions);
+	/** Return importer meta information.
+	 * See #BaseImporter::GetInfo for the details  */
+	const aiImporterDesc* GetInfo () const;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 14 - 0
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 

+ 1 - 1
workspaces/vc9/assimp.vcproj

@@ -1812,7 +1812,7 @@
 						>
 					</File>
 					<File
-						RelativePath="..\..\code\OgreImporter.h"
+						RelativePath="..\..\code\OgreImporter.hpp"
 						>
 					</File>
 					<File