瀏覽代碼

Definitios for MDC and MDR added; MD2 loader is ready for BigEndian now, MD3 too. MD2 and MD3 keyframe option added, not yet implemented for MD3.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@101 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
aramis_acg 17 年之前
父節點
當前提交
c88ae2a0be
共有 7 個文件被更改,包括 646 次插入85 次删除
  1. 5 19
      code/ASEParser.cpp
  2. 85 43
      code/MD2Loader.cpp
  3. 11 0
      code/MD2Loader.h
  4. 89 23
      code/MD3Loader.cpp
  5. 11 0
      code/MD3Loader.h
  6. 208 0
      code/MDCFileData.h
  7. 237 0
      code/MDRFileData.h

+ 5 - 19
code/ASEParser.cpp

@@ -110,6 +110,10 @@ using namespace Assimp::ASE;
 	} else bLastWasEndLine = false; \
 	} else bLastWasEndLine = false; \
 	++this->m_szFile; 
 	++this->m_szFile; 
 
 
+#ifdef _MSC_VER
+#	define sprintf sprintf_s
+#endif
+
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 Parser::Parser (const char* szFile)
 Parser::Parser (const char* szFile)
 {
 {
@@ -724,32 +728,20 @@ bool Parser::ParseString(std::string& out,const char* szName)
 {
 {
 	char szBuffer[1024];
 	char szBuffer[1024];
 
 
-#if (!defined _MSC_VER) || ( _MSC_VER < 1400)
-	ai_assert(strlen(szName) < 750);
-#endif
 
 
 	// NOTE: The name could also be the texture in some cases
 	// NOTE: The name could also be the texture in some cases
 	// be prepared that this might occur ...
 	// be prepared that this might occur ...
 	if (!SkipSpaces(this->m_szFile,&this->m_szFile))
 	if (!SkipSpaces(this->m_szFile,&this->m_szFile))
 	{
 	{
-#if _MSC_VER >= 1400
-		sprintf_s(szBuffer,"Unable to parse %s block: Unexpected EOL",szName);
-#else
 		sprintf(szBuffer,"Unable to parse %s block: Unexpected EOL",szName);
 		sprintf(szBuffer,"Unable to parse %s block: Unexpected EOL",szName);
-#endif
 		this->LogWarning(szBuffer);
 		this->LogWarning(szBuffer);
 		return false;
 		return false;
 	}
 	}
 	// there must be "
 	// there must be "
 	if ('\"' != *this->m_szFile)
 	if ('\"' != *this->m_szFile)
 	{
 	{
-#if _MSC_VER >= 1400
-		sprintf_s(szBuffer,"Unable to parse %s block: String is expected "
-			"to be enclosed in double quotation marks",szName);
-#else
 		sprintf(szBuffer,"Unable to parse %s block: String is expected "
 		sprintf(szBuffer,"Unable to parse %s block: String is expected "
 			"to be enclosed in double quotation marks",szName);
 			"to be enclosed in double quotation marks",szName);
-#endif
 		this->LogWarning(szBuffer);
 		this->LogWarning(szBuffer);
 		return false;
 		return false;
 	}
 	}
@@ -759,16 +751,10 @@ bool Parser::ParseString(std::string& out,const char* szName)
 	{
 	{
 		if ('\"' == *sz)break;
 		if ('\"' == *sz)break;
 		else if ('\0' == sz)
 		else if ('\0' == sz)
-		{
-#if _MSC_VER >= 1400
-			sprintf_s(szBuffer,"Unable to parse %s block: String is expected to be "
-				"enclosed in double quotation marks but EOF was reached before a closing "
-				"quotation mark was found",szName);
-#else
+		{			
 			sprintf(szBuffer,"Unable to parse %s block: String is expected to be "
 			sprintf(szBuffer,"Unable to parse %s block: String is expected to be "
 				"enclosed in double quotation marks but EOF was reached before a closing "
 				"enclosed in double quotation marks but EOF was reached before a closing "
 				"quotation mark was found",szName);
 				"quotation mark was found",szName);
-#endif
 			this->LogWarning(szBuffer);
 			this->LogWarning(szBuffer);
 			return false;
 			return false;
 		}
 		}

+ 85 - 43
code/MD2Loader.cpp

@@ -42,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /** @file Implementation of the MD2 importer class */
 /** @file Implementation of the MD2 importer class */
 #include "MD2Loader.h"
 #include "MD2Loader.h"
 #include "MaterialSystem.h"
 #include "MaterialSystem.h"
+#include "ByteSwap.h"
 #include "MD2NormalTable.h" // shouldn't be included by other units
 #include "MD2NormalTable.h" // shouldn't be included by other units
 
 
 #include "../include/IOStream.h"
 #include "../include/IOStream.h"
@@ -50,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "../include/aiScene.h"
 #include "../include/aiScene.h"
 #include "../include/aiAssert.h"
 #include "../include/aiAssert.h"
 #include "../include/DefaultLogger.h"
 #include "../include/DefaultLogger.h"
+#include "../include/assimp.hpp"
 
 
 #include <boost/scoped_ptr.hpp>
 #include <boost/scoped_ptr.hpp>
 
 
@@ -110,6 +112,18 @@ bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
 	return true;
 	return true;
 }
 }
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
+// Setup configuration properties
+void MD2Importer::SetupProperties(const Importer* pImp)
+{
+	// The AI_CONFIG_IMPORT_MD2_KEYFRAME option overrides the
+	// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
+	if(0xffffffff == (this->configFrameID = pImp->GetProperty(
+		AI_CONFIG_IMPORT_MD2_KEYFRAME,0xffffffff)))
+	{
+		this->configFrameID = pImp->GetProperty(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
+	}
+}
+// ------------------------------------------------------------------------------------------------
 // Validate the file header
 // Validate the file header
 void MD2Importer::ValidateHeader( )
 void MD2Importer::ValidateHeader( )
 {
 {
@@ -117,9 +131,6 @@ void MD2Importer::ValidateHeader( )
 	if (this->m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE &&
 	if (this->m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE &&
 		this->m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE)
 		this->m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE)
 	{
 	{
-		delete[] this->mBuffer;
-		AI_DEBUG_INVALIDATE_PTR(this->mBuffer);
-
 		char szBuffer[5];
 		char szBuffer[5];
 		szBuffer[0] = ((char*)&this->m_pcHeader->magic)[0];
 		szBuffer[0] = ((char*)&this->m_pcHeader->magic)[0];
 		szBuffer[1] = ((char*)&this->m_pcHeader->magic)[1];
 		szBuffer[1] = ((char*)&this->m_pcHeader->magic)[1];
@@ -133,27 +144,22 @@ void MD2Importer::ValidateHeader( )
 
 
 	// check file format version
 	// check file format version
 	if (this->m_pcHeader->version != 8)
 	if (this->m_pcHeader->version != 8)
-	{
 		DefaultLogger::get()->warn( "Unsupported md2 file version. Continuing happily ...");
 		DefaultLogger::get()->warn( "Unsupported md2 file version. Continuing happily ...");
-	}
 
 
-	/* to be validated:
-	int32_t offsetSkins; 
-	int32_t offsetTexCoords; 
-	int32_t offsetTriangles; 
-	int32_t offsetFrames; 
-	//int32_t offsetGlCommands; 
-	int32_t offsetEnd; 
-	*/
-
-	if (this->m_pcHeader->offsetSkins	+ this->m_pcHeader->numSkins * sizeof (MD2::Skin)			>= this->fileSize ||
-		this->m_pcHeader->offsetTexCoords + this->m_pcHeader->numTexCoords * sizeof (MD2::TexCoord) >= this->fileSize ||
-		this->m_pcHeader->offsetTriangles + this->m_pcHeader->numTriangles * sizeof (MD2::Triangle) >= this->fileSize ||
-		this->m_pcHeader->offsetFrames	  + this->m_pcHeader->numFrames * sizeof (MD2::Frame)		>= this->fileSize ||
+	// check some values whether they are valid
+	if (0 == this->m_pcHeader->numFrames)
+		throw new ImportErrorException( "Invalid md2 file: NUM_FRAMES is 0");
+
+	if (this->m_pcHeader->offsetEnd > (int32_t)fileSize)
+		throw new ImportErrorException( "Invalid md2 file: File is too small");
+
+	if (this->m_pcHeader->offsetSkins		+ this->m_pcHeader->numSkins * sizeof (MD2::Skin)			>= this->fileSize ||
+		this->m_pcHeader->offsetTexCoords	+ this->m_pcHeader->numTexCoords * sizeof (MD2::TexCoord)	>= this->fileSize ||
+		this->m_pcHeader->offsetTriangles	+ this->m_pcHeader->numTriangles * sizeof (MD2::Triangle)	>= this->fileSize ||
+		this->m_pcHeader->offsetFrames		+ this->m_pcHeader->numFrames * sizeof (MD2::Frame)			>= this->fileSize ||
 		this->m_pcHeader->offsetEnd			> this->fileSize)
 		this->m_pcHeader->offsetEnd			> this->fileSize)
 	{
 	{
 		throw new ImportErrorException("Invalid MD2 header: some offsets are outside the file");
 		throw new ImportErrorException("Invalid MD2 header: some offsets are outside the file");
-		AI_DEBUG_INVALIDATE_PTR(this->mBuffer);
 	}
 	}
 
 
 	if (this->m_pcHeader->numSkins > AI_MD2_MAX_SKINS)
 	if (this->m_pcHeader->numSkins > AI_MD2_MAX_SKINS)
@@ -162,27 +168,27 @@ void MD2Importer::ValidateHeader( )
 		DefaultLogger::get()->warn("The model contains more frames than Quake 2 supports");
 		DefaultLogger::get()->warn("The model contains more frames than Quake 2 supports");
 	if (this->m_pcHeader->numVertices > AI_MD2_MAX_VERTS)
 	if (this->m_pcHeader->numVertices > AI_MD2_MAX_VERTS)
 		DefaultLogger::get()->warn("The model contains more vertices than Quake 2 supports");
 		DefaultLogger::get()->warn("The model contains more vertices than Quake 2 supports");
+
+	if (this->m_pcHeader->numFrames >= this->configFrameID )
+		throw new ImportErrorException("The requested frame is not existing the file");
+
 }
 }
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Imports the given file into the given scene structure. 
 // Imports the given file into the given scene structure. 
-void MD2Importer::InternReadFile( 
-								 const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
+void MD2Importer::InternReadFile( const std::string& pFile, 
+	aiScene* pScene, IOSystem* pIOHandler)
 {
 {
 	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
 	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
 
 
 	// Check whether we can read from the file
 	// Check whether we can read from the file
 	if( file.get() == NULL)
 	if( file.get() == NULL)
-	{
-		throw new ImportErrorException( "Failed to open md2 file " + pFile + ".");
-	}
+		throw new ImportErrorException( "Failed to open MD2 file " + pFile + "");
 
 
 	// check whether the md3 file is large enough to contain
 	// check whether the md3 file is large enough to contain
 	// at least the file header
 	// at least the file header
 	fileSize = (unsigned int)file->FileSize();
 	fileSize = (unsigned int)file->FileSize();
 	if( fileSize < sizeof(MD2::Header))
 	if( fileSize < sizeof(MD2::Header))
-	{
-		throw new ImportErrorException( "md2 File is too small.");
-	}
+		throw new ImportErrorException( "MD2 File is too small");
 
 
 	try
 	try
 	{
 	{
@@ -191,17 +197,30 @@ void MD2Importer::InternReadFile(
 		file->Read( (void*)mBuffer, 1, fileSize);
 		file->Read( (void*)mBuffer, 1, fileSize);
 
 
 		this->m_pcHeader = (const MD2::Header*)this->mBuffer;
 		this->m_pcHeader = (const MD2::Header*)this->mBuffer;
-	this->ValidateHeader();
 
 
-		// check some values whether they are valid
-		if (0 == this->m_pcHeader->numFrames)
-		{
-			throw new ImportErrorException( "Invalid md2 file: NUM_FRAMES is 0");
-		}
-		if (this->m_pcHeader->offsetEnd > (int32_t)fileSize)
-		{
-			throw new ImportErrorException( "Invalid md2 file: File is too small");
-		}
+#ifdef AI_BUILD_BIG_ENDIAN
+
+		ByteSwap::Swap4(&m_pcHeader->frameSize);
+		ByteSwap::Swap4(&m_pcHeader->magic);
+		ByteSwap::Swap4(&m_pcHeader->numFrames);
+		ByteSwap::Swap4(&m_pcHeader->numGlCommands);
+		ByteSwap::Swap4(&m_pcHeader->numSkins);
+		ByteSwap::Swap4(&m_pcHeader->numTexCoords);
+		ByteSwap::Swap4(&m_pcHeader->numTriangles);
+		ByteSwap::Swap4(&m_pcHeader->numVertices);
+		ByteSwap::Swap4(&m_pcHeader->offsetEnd);
+		ByteSwap::Swap4(&m_pcHeader->offsetFrames);
+		ByteSwap::Swap4(&m_pcHeader->offsetGlCommands);
+		ByteSwap::Swap4(&m_pcHeader->offsetSkins);
+		ByteSwap::Swap4(&m_pcHeader->offsetTexCoords);
+		ByteSwap::Swap4(&m_pcHeader->offsetTriangles);
+		ByteSwap::Swap4(&m_pcHeader->skinHeight);
+		ByteSwap::Swap4(&m_pcHeader->skinWidth);
+		ByteSwap::Swap4(&m_pcHeader->version);
+
+#endif
+
+		this->ValidateHeader();
 
 
 		// there won't be more than one mesh inside the file
 		// there won't be more than one mesh inside the file
 		pScene->mNumMaterials = 1;
 		pScene->mNumMaterials = 1;
@@ -216,20 +235,43 @@ void MD2Importer::InternReadFile(
 		aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
 		aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
 
 
 		// navigate to the begin of the frame data
 		// navigate to the begin of the frame data
-		const MD2::Frame* pcFrame = (const MD2::Frame*) (
-			(unsigned char*)this->m_pcHeader + this->m_pcHeader->offsetFrames);
+		const MD2::Frame* pcFrame = (const MD2::Frame*) ((uint8_t*)
+			this->m_pcHeader + this->m_pcHeader->offsetFrames);
+		pcFrame += this->configFrameID;
 
 
 		// navigate to the begin of the triangle data
 		// navigate to the begin of the triangle data
-		MD2::Triangle* pcTriangles = (MD2::Triangle*) (
-			(unsigned char*)this->m_pcHeader + this->m_pcHeader->offsetTriangles);
+		MD2::Triangle* pcTriangles = (MD2::Triangle*) ((uint8_t*)
+			this->m_pcHeader + this->m_pcHeader->offsetTriangles);
 
 
 		// navigate to the begin of the tex coords data
 		// navigate to the begin of the tex coords data
-		const MD2::TexCoord* pcTexCoords = (const MD2::TexCoord*) (
-			(unsigned char*)this->m_pcHeader + this->m_pcHeader->offsetTexCoords);
+		const MD2::TexCoord* pcTexCoords = (const MD2::TexCoord*) ((uint8_t*)
+			this->m_pcHeader + this->m_pcHeader->offsetTexCoords);
 
 
 		// navigate to the begin of the vertex data
 		// navigate to the begin of the vertex data
 		const MD2::Vertex* pcVerts = (const MD2::Vertex*) (pcFrame->vertices);
 		const MD2::Vertex* pcVerts = (const MD2::Vertex*) (pcFrame->vertices);
 
 
+#ifdef AI_BUILD_BIG_ENDIAN
+		for (uint32_t i = 0; i< m_pcHeader->numTriangles)
+		{
+			for (unsigned int p = 0; p < 3;++p)
+			{
+				ByteSwap::Swap2(& pcTriangles[i].textureIndices[p]);
+				ByteSwap::Swap2(& pcTriangles[i].vertexIndices[p]);
+			}
+		}
+		for (uint32_t i = 0; i < m_pcHeader->offsetTexCoords;++i)
+		{
+			ByteSwap::Swap2(& pcTexCoords[i].s);
+			ByteSwap::Swap2(& pcTexCoords[i].t);
+		}
+		ByteSwap::Swap4( & pcFrame->scale[0] );
+		ByteSwap::Swap4( & pcFrame->scale[1] );
+		ByteSwap::Swap4( & pcFrame->scale[2] );
+		ByteSwap::Swap4( & pcFrame->translate[0] );
+		ByteSwap::Swap4( & pcFrame->translate[1] );
+		ByteSwap::Swap4( & pcFrame->translate[2] );
+#endif
+
 		pcMesh->mNumFaces = this->m_pcHeader->numTriangles;
 		pcMesh->mNumFaces = this->m_pcHeader->numTriangles;
 		pcMesh->mFaces = new aiFace[this->m_pcHeader->numTriangles];
 		pcMesh->mFaces = new aiFace[this->m_pcHeader->numTriangles];
 
 

+ 11 - 0
code/MD2Loader.h

@@ -75,6 +75,14 @@ public:
 	* See BaseImporter::CanRead() for details.	*/
 	* See BaseImporter::CanRead() for details.	*/
 	bool CanRead( const std::string& pFile, IOSystem* pIOHandler) const;
 	bool CanRead( const std::string& pFile, IOSystem* pIOHandler) const;
 
 
+
+	// -------------------------------------------------------------------
+	/** Called prior to ReadFile().
+	* The function is a request to the importer to update its configuration
+	* basing on the Importer's configuration property list.
+	*/
+	void SetupProperties(const Importer* pImp);
+
 protected:
 protected:
 
 
 	// -------------------------------------------------------------------
 	// -------------------------------------------------------------------
@@ -101,6 +109,9 @@ protected:
 
 
 protected:
 protected:
 
 
+	/** Configuration option: frame to be loaded */
+	unsigned int configFrameID;
+
 	/** Header of the MD2 file */
 	/** Header of the MD2 file */
 	const MD2::Header* m_pcHeader;
 	const MD2::Header* m_pcHeader;
 
 

+ 89 - 23
code/MD3Loader.cpp

@@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "MD3Loader.h"
 #include "MD3Loader.h"
 #include "MaterialSystem.h"
 #include "MaterialSystem.h"
 #include "StringComparison.h"
 #include "StringComparison.h"
+#include "ByteSwap.h"
 
 
 #include "../include/IOStream.h"
 #include "../include/IOStream.h"
 #include "../include/IOSystem.h"
 #include "../include/IOSystem.h"
@@ -50,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "../include/aiScene.h"
 #include "../include/aiScene.h"
 #include "../include/aiAssert.h"
 #include "../include/aiAssert.h"
 #include "../include/DefaultLogger.h"
 #include "../include/DefaultLogger.h"
+#include "../include/assimp.hpp"
 
 
 #include <boost/scoped_ptr.hpp>
 #include <boost/scoped_ptr.hpp>
 
 
@@ -90,14 +92,19 @@ bool MD3Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 void MD3Importer::ValidateHeaderOffsets()
 void MD3Importer::ValidateHeaderOffsets()
 {
 {
+	// check magic number
+	if (this->m_pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_BE &&
+		this->m_pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_LE)
+			throw new ImportErrorException( "Invalid MD3 file: Magic bytes not found");
+
 	// check file format version
 	// check file format version
 	if (this->m_pcHeader->VERSION > 15)
 	if (this->m_pcHeader->VERSION > 15)
-		DefaultLogger::get()->warn( "Unsupported md3 file version. Continuing happily ...");
+		DefaultLogger::get()->warn( "Unsupported MD3 file version. Continuing happily ...");
 
 
 	// check some values whether they are valid
 	// check some values whether they are valid
-	if (0 == this->m_pcHeader->NUM_FRAMES)
-		throw new ImportErrorException( "Invalid md3 file: NUM_FRAMES is 0");
-	if (0 == this->m_pcHeader->NUM_SURFACES)
+	if (!this->m_pcHeader->NUM_FRAMES)
+		throw new ImportErrorException( "Invalid MD3 file: NUM_FRAMES is 0");
+	if (!this->m_pcHeader->NUM_SURFACES)
 		throw new ImportErrorException( "Invalid md3 file: NUM_SURFACES is 0");
 		throw new ImportErrorException( "Invalid md3 file: NUM_SURFACES is 0");
 
 
 	if (this->m_pcHeader->OFS_FRAMES	>= this->fileSize ||
 	if (this->m_pcHeader->OFS_FRAMES	>= this->fileSize ||
@@ -106,6 +113,9 @@ void MD3Importer::ValidateHeaderOffsets()
 	{
 	{
 		throw new ImportErrorException("Invalid MD3 header: some offsets are outside the file");
 		throw new ImportErrorException("Invalid MD3 header: some offsets are outside the file");
 	}
 	}
+
+	if (this->m_pcHeader->NUM_FRAMES >= this->configFrameID )
+		throw new ImportErrorException("The requested frame is not existing the file");
 }
 }
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf)
 void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf)
@@ -131,6 +141,18 @@ void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf)
 		DefaultLogger::get()->warn("The model contains more frames than Quake 3 supports");
 		DefaultLogger::get()->warn("The model contains more frames than Quake 3 supports");
 }
 }
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
+// Setup configuration properties
+void MD3Importer::SetupProperties(const Importer* pImp)
+{
+	// The AI_CONFIG_IMPORT_MD3_KEYFRAME option overrides the
+	// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
+	if(0xffffffff == (this->configFrameID = pImp->GetProperty(
+		AI_CONFIG_IMPORT_MD3_KEYFRAME,0xffffffff)))
+	{
+		this->configFrameID = pImp->GetProperty(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
+	}
+}
+// ------------------------------------------------------------------------------------------------
 // Imports the given file into the given scene structure. 
 // Imports the given file into the given scene structure. 
 void MD3Importer::InternReadFile( 
 void MD3Importer::InternReadFile( 
 	const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
 	const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
@@ -139,17 +161,13 @@ void MD3Importer::InternReadFile(
 
 
 	// Check whether we can read from the file
 	// Check whether we can read from the file
 	if( file.get() == NULL)
 	if( file.get() == NULL)
-	{
-		throw new ImportErrorException( "Failed to open md3 file " + pFile + ".");
-	}
+		throw new ImportErrorException( "Failed to open MD3 file " + pFile + ".");
 
 
 	// check whether the md3 file is large enough to contain
 	// check whether the md3 file is large enough to contain
 	// at least the file header
 	// at least the file header
 	fileSize = (unsigned int)file->FileSize();
 	fileSize = (unsigned int)file->FileSize();
 	if( fileSize < sizeof(MD3::Header))
 	if( fileSize < sizeof(MD3::Header))
-	{
-		throw new ImportErrorException( ".md3 File is too small.");
-	}
+		throw new ImportErrorException( "MD3 File is too small.");
 
 
 	// allocate storage and copy the contents of the file to a memory buffer
 	// allocate storage and copy the contents of the file to a memory buffer
 	this->mBuffer = new unsigned char[fileSize];
 	this->mBuffer = new unsigned char[fileSize];
@@ -160,12 +178,22 @@ void MD3Importer::InternReadFile(
 
 
 		this->m_pcHeader = (const MD3::Header*)this->mBuffer;
 		this->m_pcHeader = (const MD3::Header*)this->mBuffer;
 
 
-		// check magic number
-		if (this->m_pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_BE &&
-			this->m_pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_LE)
-		{
-			throw new ImportErrorException( "Invalid md3 file: Magic bytes not found");
-		}
+#ifdef AI_BUILD_BIG_ENDIAN
+
+		ByteSwap::Swap4(&m_pcHeader->VERSION);
+		ByteSwap::Swap4(&m_pcHeader->FLAGS);
+		ByteSwap::Swap4(&m_pcHeader->IDENT);
+		ByteSwap::Swap4(&m_pcHeader->NUM_FRAMES);
+		ByteSwap::Swap4(&m_pcHeader->NUM_SKINS);
+		ByteSwap::Swap4(&m_pcHeader->NUM_SURFACES);
+		ByteSwap::Swap4(&m_pcHeader->NUM_TAGS);
+		ByteSwap::Swap4(&m_pcHeader->OFS_EOF);
+		ByteSwap::Swap4(&m_pcHeader->OFS_FRAMES);
+		ByteSwap::Swap4(&m_pcHeader->OFS_SURFACES);
+		ByteSwap::Swap4(&m_pcHeader->OFS_TAGS);
+
+#endif
+
 		// validate the header
 		// validate the header
 		this->ValidateHeaderOffsets();
 		this->ValidateHeaderOffsets();
 
 
@@ -190,33 +218,71 @@ void MD3Importer::InternReadFile(
 		unsigned int iDefaultMatIndex = 0xFFFFFFFF;
 		unsigned int iDefaultMatIndex = 0xFFFFFFFF;
 		while (iNum-- > 0)
 		while (iNum-- > 0)
 		{
 		{
+		
+#ifdef AI_BUILD_BIG_ENDIAN
+
+			ByteSwap::Swap4(pcSurfaces->FLAGS);
+			ByteSwap::Swap4(pcSurfaces->IDENT);
+			ByteSwap::Swap4(pcSurfaces->NUM_FRAMES);
+			ByteSwap::Swap4(pcSurfaces->NUM_SHADER);
+			ByteSwap::Swap4(pcSurfaces->NUM_TRIANGLES);
+			ByteSwap::Swap4(pcSurfaces->NUM_VERTICES);
+			ByteSwap::Swap4(pcSurfaces->OFS_END);
+			ByteSwap::Swap4(pcSurfaces->OFS_SHADERS);
+			ByteSwap::Swap4(pcSurfaces->OFS_ST);
+			ByteSwap::Swap4(pcSurfaces->OFS_TRIANGLES);
+			ByteSwap::Swap4(pcSurfaces->OFS_XYZNORMAL);
+
+#endif
+
 			// validate the surface
 			// validate the surface
 			this->ValidateSurfaceHeaderOffsets(pcSurfaces);
 			this->ValidateSurfaceHeaderOffsets(pcSurfaces);
 
 
 			// navigate to the vertex list of the surface
 			// navigate to the vertex list of the surface
 			const MD3::Vertex* pcVertices = (const MD3::Vertex*)
 			const MD3::Vertex* pcVertices = (const MD3::Vertex*)
-				(((unsigned char*)pcSurfaces) + pcSurfaces->OFS_XYZNORMAL);
+				(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_XYZNORMAL);
 
 
 			// navigate to the triangle list of the surface
 			// navigate to the triangle list of the surface
 			const MD3::Triangle* pcTriangles = (const MD3::Triangle*)
 			const MD3::Triangle* pcTriangles = (const MD3::Triangle*)
-				(((unsigned char*)pcSurfaces) + pcSurfaces->OFS_TRIANGLES);
+				(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_TRIANGLES);
 
 
 			// navigate to the texture coordinate list of the surface
 			// navigate to the texture coordinate list of the surface
 			const MD3::TexCoord* pcUVs = (const MD3::TexCoord*)
 			const MD3::TexCoord* pcUVs = (const MD3::TexCoord*)
-				(((unsigned char*)pcSurfaces) + pcSurfaces->OFS_ST);
+				(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_ST);
 
 
 			// navigate to the shader list of the surface
 			// navigate to the shader list of the surface
 			const MD3::Shader* pcShaders = (const MD3::Shader*)
 			const MD3::Shader* pcShaders = (const MD3::Shader*)
-				(((unsigned char*)pcSurfaces) + pcSurfaces->OFS_SHADERS);
+				(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_SHADERS);
 
 
 			// if the submesh is empty ignore it
 			// if the submesh is empty ignore it
 			if (0 == pcSurfaces->NUM_VERTICES || 0 == pcSurfaces->NUM_TRIANGLES)
 			if (0 == pcSurfaces->NUM_VERTICES || 0 == pcSurfaces->NUM_TRIANGLES)
 			{
 			{
-				pcSurfaces = (const MD3::Surface*)(((unsigned char*)pcSurfaces) + pcSurfaces->OFS_END);
+				pcSurfaces = (const MD3::Surface*)(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_END);
 				pScene->mNumMeshes--;
 				pScene->mNumMeshes--;
 				continue;
 				continue;
 			}
 			}
 
 
+#ifdef AI_BUILD_BIG_ENDIAN
+
+			for (uint32_t i = 0; i < pcSurfaces->NUM_VERTICES;++i)
+			{
+				ByteSwap::Swap2( & pcVertices[i].NORMAL );
+				ByteSwap::Swap2( & pcVertices[i].X );
+				ByteSwap::Swap2( & pcVertices[i].Y );
+				ByteSwap::Swap2( & pcVertices[i].Z );
+
+				ByteSwap::Swap4( & pcUVs[i].U );
+				ByteSwap::Swap4( & pcUVs[i].U );
+			}
+			for (uint32_t i = 0; i < pcSurfaces->NUM_TRIANGLES;++i)
+			{
+				ByteSwap::Swap4(pcTriangles[i].INDEXES[0]);
+				ByteSwap::Swap4(pcTriangles[i].INDEXES[1]);
+				ByteSwap::Swap4(pcTriangles[i].INDEXES[2]);
+			}
+
+#endif
+
 			// allocate the output mesh
 			// allocate the output mesh
 			pScene->mMeshes[iNum] = new aiMesh();
 			pScene->mMeshes[iNum] = new aiMesh();
 			aiMesh* pcMesh = pScene->mMeshes[iNum];
 			aiMesh* pcMesh = pScene->mMeshes[iNum];
@@ -358,7 +424,7 @@ void MD3Importer::InternReadFile(
 					pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
 					pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
 
 
 					pScene->mMaterials[iNumMaterials] = (aiMaterial*)pcHelper;
 					pScene->mMaterials[iNumMaterials] = (aiMaterial*)pcHelper;
-					pcMesh->mMaterialIndex = iNumMaterials++;
+					iDefaultMatIndex = pcMesh->mMaterialIndex = iNumMaterials++;
 				}
 				}
 			}
 			}
 			else
 			else
@@ -384,7 +450,7 @@ void MD3Importer::InternReadFile(
 					pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
 					pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
 
 
 					pScene->mMaterials[iNumMaterials] = (aiMaterial*)pcHelper;
 					pScene->mMaterials[iNumMaterials] = (aiMaterial*)pcHelper;
-					pcMesh->mMaterialIndex = iNumMaterials++;
+					iDefaultMatIndex = pcMesh->mMaterialIndex = iNumMaterials++;
 				}
 				}
 			}
 			}
 			// go to the next surface
 			// go to the next surface

+ 11 - 0
code/MD3Loader.h

@@ -78,6 +78,14 @@ public:
 	* See BaseImporter::CanRead() for details.	*/
 	* See BaseImporter::CanRead() for details.	*/
 	bool CanRead( const std::string& pFile, IOSystem* pIOHandler) const;
 	bool CanRead( const std::string& pFile, IOSystem* pIOHandler) const;
 
 
+
+	// -------------------------------------------------------------------
+	/** Called prior to ReadFile().
+	* The function is a request to the importer to update its configuration
+	* basing on the Importer's configuration property list.
+	*/
+	void SetupProperties(const Importer* pImp);
+
 protected:
 protected:
 
 
 	// -------------------------------------------------------------------
 	// -------------------------------------------------------------------
@@ -105,6 +113,9 @@ protected:
 
 
 protected:
 protected:
 
 
+	/** Configuration option: frame to be loaded */
+	unsigned int configFrameID;
+
 	/** Header of the MD3 file */
 	/** Header of the MD3 file */
 	const MD3::Header* m_pcHeader;
 	const MD3::Header* m_pcHeader;
 
 

+ 208 - 0
code/MDCFileData.h

@@ -0,0 +1,208 @@
+/*
+Open Asset Import Library (ASSIMP)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2008, ASSIMP Development 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 Development 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.
+
+----------------------------------------------------------------------
+*/
+
+/** @file Defines the helper data structures for importing MDC files  
+
+**********************************************************************
+File format specification: 
+http://themdcfile.planetwolfenstein.gamespy.com/MDC_File_Format.pdf
+**********************************************************************
+
+*/
+#ifndef AI_MDCFILEHELPER_H_INC
+#define AI_MDCFILEHELPER_H_INC
+
+#include "../include/aiTypes.h"
+#include "../include/aiMesh.h"
+#include "../include/aiAnim.h"
+
+#if defined(_MSC_VER) ||  defined(__BORLANDC__) ||	defined (__BCPLUSPLUS__)
+#	pragma pack(push,1)
+#	define PACK_STRUCT
+#elif defined( __GNUC__ )
+#	define PACK_STRUCT	__attribute__((packed))
+#else
+#	error Compiler not supported
+#endif
+
+
+namespace Assimp {
+namespace MDC {
+
+#define AI_MDC_MAGIC_NUMBER_BE	'CPDI'
+#define AI_MDC_MAGIC_NUMBER_LE	'IDPC'
+
+// common limitations
+#define AI_MDC_VERSION			2
+#define AI_MDC_MAXQPATH			64
+#define	AI_MDC_MAX_BONES		128
+
+#define AI_MDC_CVERT_BIAS		127.0f
+#define	AI_MDC_DELTA_SCALING	4.0f
+#define	AI_MDC_BASE_SCALING		(1.0f / 64.0f)
+
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a MDC file's main header
+ */
+struct Header
+{
+	uint32_t ulIdent ;
+	uint32_t ulVersion ;
+	char ucName [ AI_MDC_MAXQPATH ] ;
+	uint32_t ulFlags ;
+	uint32_t ulNumFrames ;
+	uint32_t ulNumTags ;
+	uint32_t ulNumSurfaces ;
+	uint32_t ulNumSkins ;
+	uint32_t ulOffsetBorderFrames ;
+	uint32_t ulOffsetTagNames ;
+	uint32_t ulOffsetTagFrames ;
+	uint32_t ulOffsetSurfaces ;
+	uint32_t ulOffsetEnd ;
+} PACK_STRUCT ;
+
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a MDC file's surface header
+ */
+struct Surface
+{
+	uint32_t ulIdent ;
+	char ucName [ AI_MDC_MAXQPATH ] ;
+	uint32_t ulFlags ;
+	uint32_t ulNumCompFrames ;
+	uint32_t ulNumBaseFrames ;
+	uint32_t ulNumShaders ;
+	uint32_t ulNumVertices ;
+	uint32_t ulNumTriangles ;
+	uint32_t ulOffsetTriangles ;
+	uint32_t ulOffsetShaders ;
+	uint32_t ulOffsetTexCoords ;
+	uint32_t ulOffsetBaseVerts ;
+	uint32_t ulOffsetCompVerts ;
+	uint32_t ulOffsetFrameBaseFrames ;
+	uint32_t ulOffsetFrameCompFrames ;
+	uint32_t ulOffsetEnd ;
+} PACK_STRUCT;
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a MDC frame
+ */
+struct Frame
+{
+	//! bounding box minimum coords
+	aiVector3D bboxMin ;
+
+	//! bounding box maximum coords
+	aiVector3D bboxMax ;
+
+	//! local origin of the frame
+	aiVector3D localOrigin ;
+
+	//! radius of the BB
+	float radius ;
+
+	//! Name of the frame
+	char name [ 16 ] ;
+} PACK_STRUCT;
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a MDC triangle
+ */
+struct Triangle
+{
+	uint32_t aiIndices[3];
+} PACK_STRUCT;
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a MDC texture coordinate
+ */
+struct TexturCoord
+{
+	float u,v;
+} PACK_STRUCT;
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a MDC base vertex
+ */
+struct BaseVertex
+{
+	int16_t x,y,z;
+	uint16_t normal;
+} PACK_STRUCT;
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a MDC compressed vertex
+ */
+struct CompressedVertex
+{
+	uint8_t xd,yd,zd,nd;
+} PACK_STRUCT;
+
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a MDC shader
+ */
+struct Shader
+{
+	char ucName [ AI_MDC_MAXQPATH ] ;
+	uint32_t ulPath;
+
+} PACK_STRUCT;
+
+// reset packing to the original value
+#if defined(_MSC_VER) ||  defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
+#	pragma pack( pop )
+#endif
+#undef PACK_STRUCT
+
+
+// ---------------------------------------------------------------------------
+/** Build a floating point vertex from the compressed data in MDC files
+ */
+void BuildVertex(const Frame& frame,
+	const BaseVertex& bvert,
+	const CompressedVertex& cvert,
+	aiVector3D& vXYZOut, 
+	aiVector3D& vNorOut);
+}}
+
+#endif // !! AI_MDCFILEHELPER_H_INC

+ 237 - 0
code/MDRFileData.h

@@ -0,0 +1,237 @@
+/*
+Open Asset Import Library (ASSIMP)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2008, ASSIMP Development 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 Development 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.
+
+----------------------------------------------------------------------
+*/
+
+/** @file Defines the helper data structures for importing MDR files  */
+#ifndef AI_MDRFILEHELPER_H_INC
+#define AI_MDRFILEHELPER_H_INC
+
+#include "../include/aiTypes.h"
+#include "../include/aiMesh.h"
+#include "../include/aiAnim.h"
+
+#if defined(_MSC_VER) ||  defined(__BORLANDC__) ||	defined (__BCPLUSPLUS__)
+#	pragma pack(push,1)
+#	define PACK_STRUCT
+#elif defined( __GNUC__ )
+#	define PACK_STRUCT	__attribute__((packed))
+#else
+#	error Compiler not supported
+#endif
+
+
+namespace Assimp {
+namespace MDR {
+
+#define AI_MDR_MAGIC_NUMBER_BE	'RDM5'
+#define AI_MDR_MAGIC_NUMBER_LE	'5MDR'
+
+// common limitations
+#define AI_MDR_VERSION			2
+#define AI_MDR_MAXQPATH			64
+#define	AI_MDR_MAX_BONES		128
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a vertex weight in a MDR file
+ */
+struct  Weight
+{
+	//! these are indexes into the boneReferences
+	//! not the global per-frame bone list
+	uint32_t	boneIndex;	
+
+	//! weight of this bone
+	float		boneWeight;
+
+	//! offset of this bone
+	aiVector3D	offset;
+} PACK_STRUCT;
+
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a vertex in a MDR file
+ */
+struct Vertex
+{
+	aiVector3D		normal;
+	aiVector2D		texCoords;
+	uint32_t		numWeights;
+	Weight	weights[1];		// variable sized
+} PACK_STRUCT;
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a triangle in a MDR file
+ */
+struct Triangle
+{
+	uint32_t			indexes[3];
+} PACK_STRUCT;
+
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a surface in a MDR file
+ */
+struct Surface
+{
+	uint32_t	ident;
+
+	char		name[AI_MDR_MAXQPATH];	// polyset name
+	char		shader[AI_MDR_MAXQPATH];
+	uint32_t	shaderIndex;	
+
+	int32_t		ofsHeader;	// this will be a negative number
+
+	uint32_t	numVerts;
+	uint32_t	ofsVerts;
+
+	uint32_t	numTriangles;
+	uint32_t	ofsTriangles;
+
+	// Bone references are a set of ints representing all the bones
+	// present in any vertex weights for this surface.  This is
+	// needed because a model may have surfaces that need to be
+	// drawn at different sort times, and we don't want to have
+	// to re-interpolate all the bones for each surface.
+	uint32_t	numBoneReferences;
+	uint32_t	ofsBoneReferences;
+
+	uint32_t	ofsEnd;		// next surface follows
+} PACK_STRUCT;
+
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a bone in a MDR file
+ */
+struct Bone
+{
+	float		matrix[3][4];
+} PACK_STRUCT;
+
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a frame in a MDR file
+ */
+struct Frame {
+	aiVector3D	bounds[2];		// bounds of all surfaces of all LOD's for this frame
+	aiVector3D	localOrigin;	// midpoint of bounds, used for sphere cull
+	float		radius;			// dist from localOrigin to corner
+	char		name[16];
+	Bone	bones[1];			// [numBones]
+} PACK_STRUCT;
+
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a compressed bone in a MDR file
+ */
+struct CompBone
+{
+        unsigned char Comp[24]; // MC_COMP_BYTES is in MatComp.h, but don't want to couple
+} PACK_STRUCT;
+
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a compressed frame in a MDR file
+ */
+struct CompFrame
+{
+        aiVector3D  bounds[2];		// bounds of all surfaces of all LOD's for this frame
+        aiVector3D  localOrigin;		// midpoint of bounds, used for sphere cull
+        float      radius;			// dist from localOrigin to corner
+        CompBone   bones[1];		// [numBones]
+} PACK_STRUCT;
+
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a LOD in a MDR file
+ */
+struct LOD
+{
+	uint32_t			numSurfaces;
+	uint32_t			ofsSurfaces;		// first surface, others follow
+	uint32_t			ofsEnd;				// next lod follows
+} ;
+
+
+// ---------------------------------------------------------------------------
+/** \brief Data structure for a tag (= attachment) in a MDR file
+ */
+struct Tag
+{
+        uint32_t                     boneIndex;
+        char            name[32];
+} PACK_STRUCT;
+
+
+// ---------------------------------------------------------------------------
+/** \brief Header data structure for a MDR file
+ */
+struct Header
+{
+	uint32_t	ident;
+	uint32_t	version;
+
+	char		name[AI_MDR_MAXQPATH];	
+
+	// frames and bones are shared by all levels of detail
+	int32_t		numFrames;
+	uint32_t	numBones;
+	uint32_t	ofsFrames;			
+
+	// each level of detail has completely separate sets of surfaces
+	uint32_t	numLODs;
+	uint32_t	ofsLODs;
+
+    uint32_t    numTags;
+	uint32_t    ofsTags;
+
+	uint32_t	ofsEnd;				
+} PACK_STRUCT;
+
+
+// reset packing to the original value
+#if defined(_MSC_VER) ||  defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
+#	pragma pack( pop )
+#endif
+#undef PACK_STRUCT
+
+
+};
+};
+
+#endif // !! AI_MDRFILEHELPER_H_INC