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-9d2fd5bffc1fpull/1/head
parent
6fe8c867e8
commit
c88ae2a0be
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -760,15 +752,9 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,18 +144,14 @@ 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:
|
// check some values whether they are valid
|
||||||
int32_t offsetSkins;
|
if (0 == this->m_pcHeader->numFrames)
|
||||||
int32_t offsetTexCoords;
|
throw new ImportErrorException( "Invalid md2 file: NUM_FRAMES is 0");
|
||||||
int32_t offsetTriangles;
|
|
||||||
int32_t offsetFrames;
|
if (this->m_pcHeader->offsetEnd > (int32_t)fileSize)
|
||||||
//int32_t offsetGlCommands;
|
throw new ImportErrorException( "Invalid md2 file: File is too small");
|
||||||
int32_t offsetEnd;
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (this->m_pcHeader->offsetSkins + this->m_pcHeader->numSkins * sizeof (MD2::Skin) >= this->fileSize ||
|
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->offsetTexCoords + this->m_pcHeader->numTexCoords * sizeof (MD2::TexCoord) >= this->fileSize ||
|
||||||
|
@ -153,7 +160,6 @@ void MD2Importer::ValidateHeader( )
|
||||||
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(
|
void MD2Importer::InternReadFile( const std::string& pFile,
|
||||||
const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
|
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
|
#ifdef AI_BUILD_BIG_ENDIAN
|
||||||
if (0 == this->m_pcHeader->numFrames)
|
|
||||||
{
|
ByteSwap::Swap4(&m_pcHeader->frameSize);
|
||||||
throw new ImportErrorException( "Invalid md2 file: NUM_FRAMES is 0");
|
ByteSwap::Swap4(&m_pcHeader->magic);
|
||||||
}
|
ByteSwap::Swap4(&m_pcHeader->numFrames);
|
||||||
if (this->m_pcHeader->offsetEnd > (int32_t)fileSize)
|
ByteSwap::Swap4(&m_pcHeader->numGlCommands);
|
||||||
{
|
ByteSwap::Swap4(&m_pcHeader->numSkins);
|
||||||
throw new ImportErrorException( "Invalid md2 file: File is too small");
|
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*) (
|
const MD2::Frame* pcFrame = (const MD2::Frame*) ((uint8_t*)
|
||||||
(unsigned char*)this->m_pcHeader + this->m_pcHeader->offsetFrames);
|
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*) (
|
MD2::Triangle* pcTriangles = (MD2::Triangle*) ((uint8_t*)
|
||||||
(unsigned char*)this->m_pcHeader + this->m_pcHeader->offsetTriangles);
|
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*) (
|
const MD2::TexCoord* pcTexCoords = (const MD2::TexCoord*) ((uint8_t*)
|
||||||
(unsigned char*)this->m_pcHeader + this->m_pcHeader->offsetTexCoords);
|
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];
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
if (!this->m_pcHeader->NUM_FRAMES)
|
||||||
throw new ImportErrorException( "Invalid md3 file: NUM_FRAMES is 0");
|
throw new ImportErrorException( "Invalid MD3 file: NUM_FRAMES is 0");
|
||||||
if (0 == this->m_pcHeader->NUM_SURFACES)
|
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
|
#ifdef AI_BUILD_BIG_ENDIAN
|
||||||
if (this->m_pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_BE &&
|
|
||||||
this->m_pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_LE)
|
ByteSwap::Swap4(&m_pcHeader->VERSION);
|
||||||
{
|
ByteSwap::Swap4(&m_pcHeader->FLAGS);
|
||||||
throw new ImportErrorException( "Invalid md3 file: Magic bytes not found");
|
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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue