diff --git a/code/ASEParser.cpp b/code/ASEParser.cpp index 854f644bb..aeac3caae 100644 --- a/code/ASEParser.cpp +++ b/code/ASEParser.cpp @@ -110,6 +110,10 @@ using namespace Assimp::ASE; } else bLastWasEndLine = false; \ ++this->m_szFile; +#ifdef _MSC_VER +# define sprintf sprintf_s +#endif + // ------------------------------------------------------------------------------------------------ Parser::Parser (const char* szFile) { @@ -724,32 +728,20 @@ bool Parser::ParseString(std::string& out,const char* szName) { 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 // be prepared that this might occur ... 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); -#endif this->LogWarning(szBuffer); return false; } // there must be " 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 " "to be enclosed in double quotation marks",szName); -#endif this->LogWarning(szBuffer); return false; } @@ -759,16 +751,10 @@ bool Parser::ParseString(std::string& out,const char* szName) { if ('\"' == *sz)break; 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 " "enclosed in double quotation marks but EOF was reached before a closing " "quotation mark was found",szName); -#endif this->LogWarning(szBuffer); return false; } diff --git a/code/MD2Loader.cpp b/code/MD2Loader.cpp index bb5e55770..2a2a353a3 100644 --- a/code/MD2Loader.cpp +++ b/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 */ #include "MD2Loader.h" #include "MaterialSystem.h" +#include "ByteSwap.h" #include "MD2NormalTable.h" // shouldn't be included by other units #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/aiAssert.h" #include "../include/DefaultLogger.h" +#include "../include/assimp.hpp" #include @@ -110,6 +112,18 @@ bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler) const 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 void MD2Importer::ValidateHeader( ) { @@ -117,9 +131,6 @@ void MD2Importer::ValidateHeader( ) if (this->m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE && this->m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE) { - delete[] this->mBuffer; - AI_DEBUG_INVALIDATE_PTR(this->mBuffer); - char szBuffer[5]; szBuffer[0] = ((char*)&this->m_pcHeader->magic)[0]; szBuffer[1] = ((char*)&this->m_pcHeader->magic)[1]; @@ -133,27 +144,22 @@ void MD2Importer::ValidateHeader( ) // check file format version if (this->m_pcHeader->version != 8) - { 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; - */ + // 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->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 || + 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) { 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) @@ -162,27 +168,27 @@ void MD2Importer::ValidateHeader( ) DefaultLogger::get()->warn("The model contains more frames than Quake 2 supports"); if (this->m_pcHeader->numVertices > AI_MD2_MAX_VERTS) 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. -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 file( pIOHandler->Open( pFile)); // Check whether we can read from the file 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 // at least the file header fileSize = (unsigned int)file->FileSize(); if( fileSize < sizeof(MD2::Header)) - { - throw new ImportErrorException( "md2 File is too small."); - } + throw new ImportErrorException( "MD2 File is too small"); try { @@ -191,17 +197,30 @@ void MD2Importer::InternReadFile( file->Read( (void*)mBuffer, 1, fileSize); 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 pScene->mNumMaterials = 1; @@ -216,20 +235,43 @@ void MD2Importer::InternReadFile( aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh(); // 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 - 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 - 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 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->mFaces = new aiFace[this->m_pcHeader->numTriangles]; diff --git a/code/MD2Loader.h b/code/MD2Loader.h index ac78ec778..b0d3e858b 100644 --- a/code/MD2Loader.h +++ b/code/MD2Loader.h @@ -75,6 +75,14 @@ public: * See BaseImporter::CanRead() for details. */ 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: // ------------------------------------------------------------------- @@ -101,6 +109,9 @@ protected: protected: + /** Configuration option: frame to be loaded */ + unsigned int configFrameID; + /** Header of the MD2 file */ const MD2::Header* m_pcHeader; diff --git a/code/MD3Loader.cpp b/code/MD3Loader.cpp index 5eb4e2494..25e4a4e08 100644 --- a/code/MD3Loader.cpp +++ b/code/MD3Loader.cpp @@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "MD3Loader.h" #include "MaterialSystem.h" #include "StringComparison.h" +#include "ByteSwap.h" #include "../include/IOStream.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/aiAssert.h" #include "../include/DefaultLogger.h" +#include "../include/assimp.hpp" #include @@ -90,14 +92,19 @@ bool MD3Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler) const // ------------------------------------------------------------------------------------------------ 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 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 - 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"); 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"); } + + 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) @@ -131,6 +141,18 @@ void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf) 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. void MD3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) @@ -139,17 +161,13 @@ void MD3Importer::InternReadFile( // Check whether we can read from the file 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 // at least the file header fileSize = (unsigned int)file->FileSize(); 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 this->mBuffer = new unsigned char[fileSize]; @@ -160,12 +178,22 @@ void MD3Importer::InternReadFile( 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 this->ValidateHeaderOffsets(); @@ -190,33 +218,71 @@ void MD3Importer::InternReadFile( unsigned int iDefaultMatIndex = 0xFFFFFFFF; 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 this->ValidateSurfaceHeaderOffsets(pcSurfaces); // navigate to the vertex list of the surface 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 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 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 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 (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--; 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 pScene->mMeshes[iNum] = new aiMesh(); aiMesh* pcMesh = pScene->mMeshes[iNum]; @@ -358,7 +424,7 @@ void MD3Importer::InternReadFile( pcHelper->AddProperty(&szName,AI_MATKEY_NAME); pScene->mMaterials[iNumMaterials] = (aiMaterial*)pcHelper; - pcMesh->mMaterialIndex = iNumMaterials++; + iDefaultMatIndex = pcMesh->mMaterialIndex = iNumMaterials++; } } else @@ -384,7 +450,7 @@ void MD3Importer::InternReadFile( pcHelper->AddProperty(&clr, 1,AI_MATKEY_COLOR_AMBIENT); pScene->mMaterials[iNumMaterials] = (aiMaterial*)pcHelper; - pcMesh->mMaterialIndex = iNumMaterials++; + iDefaultMatIndex = pcMesh->mMaterialIndex = iNumMaterials++; } } // go to the next surface diff --git a/code/MD3Loader.h b/code/MD3Loader.h index 36e69ea93..2eb85eada 100644 --- a/code/MD3Loader.h +++ b/code/MD3Loader.h @@ -78,6 +78,14 @@ public: * See BaseImporter::CanRead() for details. */ 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: // ------------------------------------------------------------------- @@ -105,6 +113,9 @@ protected: protected: + /** Configuration option: frame to be loaded */ + unsigned int configFrameID; + /** Header of the MD3 file */ const MD3::Header* m_pcHeader; diff --git a/code/MDCFileData.h b/code/MDCFileData.h new file mode 100644 index 000000000..9e205cc9e --- /dev/null +++ b/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 \ No newline at end of file diff --git a/code/MDRFileData.h b/code/MDRFileData.h new file mode 100644 index 000000000..9ef5da3a6 --- /dev/null +++ b/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 \ No newline at end of file