From 3cd55c54dbf66a320438d743fbd223952043cd39 Mon Sep 17 00:00:00 2001 From: Andy Maloney Date: Wed, 7 Dec 2016 19:33:08 -0500 Subject: Update assimp lib to 3.3.1 The currently included assimp lib is v3.0 from 2012. This updates assimp lib to the latest released version (3.3.1). Change-Id: I15a60e3150c0b268422f23137107b34e4c5c4342 Reviewed-by: Sean Harmer --- src/3rdparty/assimp/code/MDLMaterialLoader.cpp | 1438 ++++++++++++------------ 1 file changed, 723 insertions(+), 715 deletions(-) (limited to 'src/3rdparty/assimp/code/MDLMaterialLoader.cpp') diff --git a/src/3rdparty/assimp/code/MDLMaterialLoader.cpp b/src/3rdparty/assimp/code/MDLMaterialLoader.cpp index 3d32420e1..d1502d6fb 100644 --- a/src/3rdparty/assimp/code/MDLMaterialLoader.cpp +++ b/src/3rdparty/assimp/code/MDLMaterialLoader.cpp @@ -3,12 +3,12 @@ Open Asset Import Library (assimp) --------------------------------------------------------------------------- -Copyright (c) 2006-2012, assimp team +Copyright (c) 2006-2016, assimp team All rights reserved. -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following +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 @@ -25,803 +25,811 @@ conditions are met: derived from this software without specific prior written permission of the assimp team. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +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 +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 +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 +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 Implementation of the material part of the MDL importer class */ -#include "AssimpPCH.h" + #ifndef ASSIMP_BUILD_NO_MDL_IMPORTER // internal headers #include "MDLLoader.h" #include "MDLDefaultColorMap.h" +#include "StringUtils.h" +#include +#include +#include +#include +#include "qnan.h" +#include "Defines.h" + using namespace Assimp; static aiTexel* const bad_texel = reinterpret_cast(SIZE_MAX); // ------------------------------------------------------------------------------------------------ -// Find a suitable pallette file or take teh default one +// Find a suitable pallette file or take the default one void MDLImporter::SearchPalette(const unsigned char** pszColorMap) { - // now try to find the color map in the current directory - IOStream* pcStream = pIOHandler->Open(configPalette,"rb"); - - const unsigned char* szColorMap = (const unsigned char*)::g_aclrDefaultColorMap; - if(pcStream) - { - if (pcStream->FileSize() >= 768) - { - unsigned char* colorMap = new unsigned char[256*3]; - szColorMap = colorMap; - pcStream->Read(colorMap,256*3,1); - DefaultLogger::get()->info("Found valid colormap.lmp in directory. " - "It will be used to decode embedded textures in palletized formats."); - } - delete pcStream; - pcStream = NULL; - } - *pszColorMap = szColorMap; + // now try to find the color map in the current directory + IOStream* pcStream = pIOHandler->Open(configPalette,"rb"); + + const unsigned char* szColorMap = (const unsigned char*)::g_aclrDefaultColorMap; + if(pcStream) + { + if (pcStream->FileSize() >= 768) + { + unsigned char* colorMap = new unsigned char[256*3]; + szColorMap = colorMap; + pcStream->Read(colorMap,256*3,1); + DefaultLogger::get()->info("Found valid colormap.lmp in directory. " + "It will be used to decode embedded textures in palletized formats."); + } + delete pcStream; + pcStream = NULL; + } + *pszColorMap = szColorMap; } // ------------------------------------------------------------------------------------------------ // Free the palette again void MDLImporter::FreePalette(const unsigned char* szColorMap) { - if (szColorMap != (const unsigned char*)::g_aclrDefaultColorMap) - delete[] szColorMap; + if (szColorMap != (const unsigned char*)::g_aclrDefaultColorMap) + delete[] szColorMap; } // ------------------------------------------------------------------------------------------------ // Check whether we can replace a texture with a single color aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture* pcTexture) { - ai_assert(NULL != pcTexture); - - aiColor4D clrOut; - clrOut.r = get_qnan(); - if (!pcTexture->mHeight || !pcTexture->mWidth) - return clrOut; - - const unsigned int iNumPixels = pcTexture->mHeight*pcTexture->mWidth; - const aiTexel* pcTexel = pcTexture->pcData+1; - const aiTexel* const pcTexelEnd = &pcTexture->pcData[iNumPixels]; - - while (pcTexel != pcTexelEnd) - { - if (*pcTexel != *(pcTexel-1)) - { - pcTexel = NULL; - break; - } - ++pcTexel; - } - if (pcTexel) - { - clrOut.r = pcTexture->pcData->r / 255.0f; - clrOut.g = pcTexture->pcData->g / 255.0f; - clrOut.b = pcTexture->pcData->b / 255.0f; - clrOut.a = pcTexture->pcData->a / 255.0f; - } - return clrOut; + ai_assert(NULL != pcTexture); + + aiColor4D clrOut; + clrOut.r = get_qnan(); + if (!pcTexture->mHeight || !pcTexture->mWidth) + return clrOut; + + const unsigned int iNumPixels = pcTexture->mHeight*pcTexture->mWidth; + const aiTexel* pcTexel = pcTexture->pcData+1; + const aiTexel* const pcTexelEnd = &pcTexture->pcData[iNumPixels]; + + while (pcTexel != pcTexelEnd) + { + if (*pcTexel != *(pcTexel-1)) + { + pcTexel = NULL; + break; + } + ++pcTexel; + } + if (pcTexel) + { + clrOut.r = pcTexture->pcData->r / 255.0f; + clrOut.g = pcTexture->pcData->g / 255.0f; + clrOut.b = pcTexture->pcData->b / 255.0f; + clrOut.a = pcTexture->pcData->a / 255.0f; + } + return clrOut; } // ------------------------------------------------------------------------------------------------ // Read a texture from a MDL3 file void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData) { - const MDL::Header *pcHeader = (const MDL::Header*)mBuffer; //the endianess is allready corrected in the InternReadFile_3DGS_MDL345 function + const MDL::Header *pcHeader = (const MDL::Header*)mBuffer; //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function - VALIDATE_FILE_SIZE(szData + pcHeader->skinwidth * - pcHeader->skinheight); + VALIDATE_FILE_SIZE(szData + pcHeader->skinwidth * + pcHeader->skinheight); - // allocate a new texture object - aiTexture* pcNew = new aiTexture(); - pcNew->mWidth = pcHeader->skinwidth; - pcNew->mHeight = pcHeader->skinheight; + // allocate a new texture object + aiTexture* pcNew = new aiTexture(); + pcNew->mWidth = pcHeader->skinwidth; + pcNew->mHeight = pcHeader->skinheight; - pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight]; + pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight]; - const unsigned char* szColorMap; - this->SearchPalette(&szColorMap); + const unsigned char* szColorMap; + this->SearchPalette(&szColorMap); - // copy texture data - for (unsigned int i = 0; i < pcNew->mWidth*pcNew->mHeight;++i) - { - const unsigned char val = szData[i]; - const unsigned char* sz = &szColorMap[val*3]; + // copy texture data + for (unsigned int i = 0; i < pcNew->mWidth*pcNew->mHeight;++i) + { + const unsigned char val = szData[i]; + const unsigned char* sz = &szColorMap[val*3]; - pcNew->pcData[i].a = 0xFF; - pcNew->pcData[i].r = *sz++; - pcNew->pcData[i].g = *sz++; - pcNew->pcData[i].b = *sz; - } + pcNew->pcData[i].a = 0xFF; + pcNew->pcData[i].r = *sz++; + pcNew->pcData[i].g = *sz++; + pcNew->pcData[i].b = *sz; + } - FreePalette(szColorMap); + FreePalette(szColorMap); - // store the texture - aiTexture** pc = this->pScene->mTextures; - this->pScene->mTextures = new aiTexture*[pScene->mNumTextures+1]; - for (unsigned int i = 0; i mNumTextures;++i) - pScene->mTextures[i] = pc[i]; + // store the texture + aiTexture** pc = this->pScene->mTextures; + this->pScene->mTextures = new aiTexture*[pScene->mNumTextures+1]; + for (unsigned int i = 0; i mNumTextures;++i) + pScene->mTextures[i] = pc[i]; - pScene->mTextures[this->pScene->mNumTextures] = pcNew; - pScene->mNumTextures++; - delete[] pc; - return; + pScene->mTextures[this->pScene->mNumTextures] = pcNew; + pScene->mNumTextures++; + delete[] pc; + return; } // ------------------------------------------------------------------------------------------------ // Read a texture from a MDL4 file -void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData, - unsigned int iType, - unsigned int* piSkip) +void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData, + unsigned int iType, + unsigned int* piSkip) { - ai_assert(NULL != piSkip); - - const MDL::Header *pcHeader = (const MDL::Header*)mBuffer; //the endianess is allready corrected in the InternReadFile_3DGS_MDL345 function - - if (iType == 1 || iType > 3) - { - DefaultLogger::get()->error("Unsupported texture file format"); - return; - } - - const bool bNoRead = *piSkip == UINT_MAX; - - // allocate a new texture object - aiTexture* pcNew = new aiTexture(); - pcNew->mWidth = pcHeader->skinwidth; - pcNew->mHeight = pcHeader->skinheight; - - if (bNoRead)pcNew->pcData = bad_texel; - ParseTextureColorData(szData,iType,piSkip,pcNew); - - // store the texture - if (!bNoRead) - { - if (!this->pScene->mNumTextures) - { - pScene->mNumTextures = 1; - pScene->mTextures = new aiTexture*[1]; - pScene->mTextures[0] = pcNew; - } - else - { - aiTexture** pc = pScene->mTextures; - pScene->mTextures = new aiTexture*[pScene->mNumTextures+1]; - for (unsigned int i = 0; i < this->pScene->mNumTextures;++i) - pScene->mTextures[i] = pc[i]; - pScene->mTextures[pScene->mNumTextures] = pcNew; - pScene->mNumTextures++; - delete[] pc; - } - } - else { - pcNew->pcData = NULL; - delete pcNew; - } - return; + ai_assert(NULL != piSkip); + + const MDL::Header *pcHeader = (const MDL::Header*)mBuffer; //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function + + if (iType == 1 || iType > 3) + { + DefaultLogger::get()->error("Unsupported texture file format"); + return; + } + + const bool bNoRead = *piSkip == UINT_MAX; + + // allocate a new texture object + aiTexture* pcNew = new aiTexture(); + pcNew->mWidth = pcHeader->skinwidth; + pcNew->mHeight = pcHeader->skinheight; + + if (bNoRead)pcNew->pcData = bad_texel; + ParseTextureColorData(szData,iType,piSkip,pcNew); + + // store the texture + if (!bNoRead) + { + if (!this->pScene->mNumTextures) + { + pScene->mNumTextures = 1; + pScene->mTextures = new aiTexture*[1]; + pScene->mTextures[0] = pcNew; + } + else + { + aiTexture** pc = pScene->mTextures; + pScene->mTextures = new aiTexture*[pScene->mNumTextures+1]; + for (unsigned int i = 0; i < this->pScene->mNumTextures;++i) + pScene->mTextures[i] = pc[i]; + pScene->mTextures[pScene->mNumTextures] = pcNew; + pScene->mNumTextures++; + delete[] pc; + } + } + else { + pcNew->pcData = NULL; + delete pcNew; + } + return; } // ------------------------------------------------------------------------------------------------ // Load color data of a texture and convert it to our output format -void MDLImporter::ParseTextureColorData(const unsigned char* szData, - unsigned int iType, - unsigned int* piSkip, - aiTexture* pcNew) +void MDLImporter::ParseTextureColorData(const unsigned char* szData, + unsigned int iType, + unsigned int* piSkip, + aiTexture* pcNew) { - const bool do_read = bad_texel != pcNew->pcData; - - // allocate storage for the texture image - if (do_read) { - pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight]; - } - - // R5G6B5 format (with or without MIPs) - // **************************************************************** - if (2 == iType || 10 == iType) - { - VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*2); - - // copy texture data - unsigned int i; - if (do_read) - { - for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i) - { - MDL::RGB565 val = ((MDL::RGB565*)szData)[i]; - AI_SWAP2(val); - - pcNew->pcData[i].a = 0xFF; - pcNew->pcData[i].r = (unsigned char)val.b << 3; - pcNew->pcData[i].g = (unsigned char)val.g << 2; - pcNew->pcData[i].b = (unsigned char)val.r << 3; - } - } - else i = pcNew->mWidth*pcNew->mHeight; - *piSkip = i * 2; - - // apply MIP maps - if (10 == iType) - { - *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1; - VALIDATE_FILE_SIZE(szData + *piSkip); - } - } - // ARGB4 format (with or without MIPs) - // **************************************************************** - else if (3 == iType || 11 == iType) - { - VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4); - - // copy texture data - unsigned int i; - if (do_read) - { - for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i) - { - MDL::ARGB4 val = ((MDL::ARGB4*)szData)[i]; - AI_SWAP2(val); - - pcNew->pcData[i].a = (unsigned char)val.a << 4; - pcNew->pcData[i].r = (unsigned char)val.r << 4; - pcNew->pcData[i].g = (unsigned char)val.g << 4; - pcNew->pcData[i].b = (unsigned char)val.b << 4; - } - } - else i = pcNew->mWidth*pcNew->mHeight; - *piSkip = i * 2; - - // apply MIP maps - if (11 == iType) - { - *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1; - VALIDATE_FILE_SIZE(szData + *piSkip); - } - } - // RGB8 format (with or without MIPs) - // **************************************************************** - else if (4 == iType || 12 == iType) - { - VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*3); - - // copy texture data - unsigned int i; - if (do_read) - { - for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i) - { - const unsigned char* _szData = &szData[i*3]; - - pcNew->pcData[i].a = 0xFF; - pcNew->pcData[i].b = *_szData++; - pcNew->pcData[i].g = *_szData++; - pcNew->pcData[i].r = *_szData; - } - } - else i = pcNew->mWidth*pcNew->mHeight; - - - // apply MIP maps - *piSkip = i * 3; - if (12 == iType) - { - *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) *3; - VALIDATE_FILE_SIZE(szData + *piSkip); - } - } - // ARGB8 format (with ir without MIPs) - // **************************************************************** - else if (5 == iType || 13 == iType) - { - VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4); - - // copy texture data - unsigned int i; - if (do_read) - { - for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i) - { - const unsigned char* _szData = &szData[i*4]; - - pcNew->pcData[i].b = *_szData++; - pcNew->pcData[i].g = *_szData++; - pcNew->pcData[i].r = *_szData++; - pcNew->pcData[i].a = *_szData; - } - } - else i = pcNew->mWidth*pcNew->mHeight; - - // apply MIP maps - *piSkip = i << 2; - if (13 == iType) - { - *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 2; - } - } - // palletized 8 bit texture. As for Quake 1 - // **************************************************************** - else if (0 == iType) - { - VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight); - - // copy texture data - unsigned int i; - if (do_read) - { - - const unsigned char* szColorMap; - SearchPalette(&szColorMap); - - for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i) - { - const unsigned char val = szData[i]; - const unsigned char* sz = &szColorMap[val*3]; - - pcNew->pcData[i].a = 0xFF; - pcNew->pcData[i].r = *sz++; - pcNew->pcData[i].g = *sz++; - pcNew->pcData[i].b = *sz; - } - this->FreePalette(szColorMap); - - } - else i = pcNew->mWidth*pcNew->mHeight; - *piSkip = i; - - // FIXME: Also support for MIP maps? - } + const bool do_read = bad_texel != pcNew->pcData; + + // allocate storage for the texture image + if (do_read) { + pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight]; + } + + // R5G6B5 format (with or without MIPs) + // **************************************************************** + if (2 == iType || 10 == iType) + { + VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*2); + + // copy texture data + unsigned int i; + if (do_read) + { + for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i) + { + MDL::RGB565 val = ((MDL::RGB565*)szData)[i]; + AI_SWAP2(val); + + pcNew->pcData[i].a = 0xFF; + pcNew->pcData[i].r = (unsigned char)val.b << 3; + pcNew->pcData[i].g = (unsigned char)val.g << 2; + pcNew->pcData[i].b = (unsigned char)val.r << 3; + } + } + else i = pcNew->mWidth*pcNew->mHeight; + *piSkip = i * 2; + + // apply MIP maps + if (10 == iType) + { + *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1; + VALIDATE_FILE_SIZE(szData + *piSkip); + } + } + // ARGB4 format (with or without MIPs) + // **************************************************************** + else if (3 == iType || 11 == iType) + { + VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4); + + // copy texture data + unsigned int i; + if (do_read) + { + for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i) + { + MDL::ARGB4 val = ((MDL::ARGB4*)szData)[i]; + AI_SWAP2(val); + + pcNew->pcData[i].a = (unsigned char)val.a << 4; + pcNew->pcData[i].r = (unsigned char)val.r << 4; + pcNew->pcData[i].g = (unsigned char)val.g << 4; + pcNew->pcData[i].b = (unsigned char)val.b << 4; + } + } + else i = pcNew->mWidth*pcNew->mHeight; + *piSkip = i * 2; + + // apply MIP maps + if (11 == iType) + { + *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1; + VALIDATE_FILE_SIZE(szData + *piSkip); + } + } + // RGB8 format (with or without MIPs) + // **************************************************************** + else if (4 == iType || 12 == iType) + { + VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*3); + + // copy texture data + unsigned int i; + if (do_read) + { + for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i) + { + const unsigned char* _szData = &szData[i*3]; + + pcNew->pcData[i].a = 0xFF; + pcNew->pcData[i].b = *_szData++; + pcNew->pcData[i].g = *_szData++; + pcNew->pcData[i].r = *_szData; + } + } + else i = pcNew->mWidth*pcNew->mHeight; + + + // apply MIP maps + *piSkip = i * 3; + if (12 == iType) + { + *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) *3; + VALIDATE_FILE_SIZE(szData + *piSkip); + } + } + // ARGB8 format (with ir without MIPs) + // **************************************************************** + else if (5 == iType || 13 == iType) + { + VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4); + + // copy texture data + unsigned int i; + if (do_read) + { + for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i) + { + const unsigned char* _szData = &szData[i*4]; + + pcNew->pcData[i].b = *_szData++; + pcNew->pcData[i].g = *_szData++; + pcNew->pcData[i].r = *_szData++; + pcNew->pcData[i].a = *_szData; + } + } + else i = pcNew->mWidth*pcNew->mHeight; + + // apply MIP maps + *piSkip = i << 2; + if (13 == iType) + { + *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 2; + } + } + // palletized 8 bit texture. As for Quake 1 + // **************************************************************** + else if (0 == iType) + { + VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight); + + // copy texture data + unsigned int i; + if (do_read) + { + + const unsigned char* szColorMap; + SearchPalette(&szColorMap); + + for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i) + { + const unsigned char val = szData[i]; + const unsigned char* sz = &szColorMap[val*3]; + + pcNew->pcData[i].a = 0xFF; + pcNew->pcData[i].r = *sz++; + pcNew->pcData[i].g = *sz++; + pcNew->pcData[i].b = *sz; + } + this->FreePalette(szColorMap); + + } + else i = pcNew->mWidth*pcNew->mHeight; + *piSkip = i; + + // FIXME: Also support for MIP maps? + } } // ------------------------------------------------------------------------------------------------ // Get a texture from a MDL5 file -void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char* szData, - unsigned int iType, - unsigned int* piSkip) +void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char* szData, + unsigned int iType, + unsigned int* piSkip) { - ai_assert(NULL != piSkip); - bool bNoRead = *piSkip == UINT_MAX; - - // allocate a new texture object - aiTexture* pcNew = new aiTexture(); - - VALIDATE_FILE_SIZE(szData+8); - - // first read the size of the texture - pcNew->mWidth = *((uint32_t*)szData); - AI_SWAP4(pcNew->mWidth); - szData += sizeof(uint32_t); - - pcNew->mHeight = *((uint32_t*)szData); - AI_SWAP4(pcNew->mHeight); - szData += sizeof(uint32_t); - - if (bNoRead) { - pcNew->pcData = bad_texel; - } - - // this should not occur - at least the docs say it shouldn't. - // however, one can easily try out what MED does if you have - // a model with a DDS texture and export it to MDL5 ... - // yeah, it embedds the DDS file. - if (6 == iType) - { - // this is a compressed texture in DDS format - *piSkip = pcNew->mWidth; - VALIDATE_FILE_SIZE(szData + *piSkip); - - if (!bNoRead) - { - // place a hint and let the application know that this is a DDS file - pcNew->mHeight = 0; - pcNew->achFormatHint[0] = 'd'; - pcNew->achFormatHint[1] = 'd'; - pcNew->achFormatHint[2] = 's'; - pcNew->achFormatHint[3] = '\0'; - - pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth]; - ::memcpy(pcNew->pcData,szData,pcNew->mWidth); - } - } - else - { - // parse the color data of the texture - ParseTextureColorData(szData,iType,piSkip,pcNew); - } - *piSkip += sizeof(uint32_t) * 2; - - if (!bNoRead) - { - // store the texture - if (!this->pScene->mNumTextures) - { - pScene->mNumTextures = 1; - pScene->mTextures = new aiTexture*[1]; - pScene->mTextures[0] = pcNew; - } - else - { - aiTexture** pc = pScene->mTextures; - pScene->mTextures = new aiTexture*[pScene->mNumTextures+1]; - for (unsigned int i = 0; i < pScene->mNumTextures;++i) - this->pScene->mTextures[i] = pc[i]; - - pScene->mTextures[pScene->mNumTextures] = pcNew; - pScene->mNumTextures++; - delete[] pc; - } - } - else { - pcNew->pcData = NULL; - delete pcNew; - } - return; + ai_assert(NULL != piSkip); + bool bNoRead = *piSkip == UINT_MAX; + + // allocate a new texture object + aiTexture* pcNew = new aiTexture(); + + VALIDATE_FILE_SIZE(szData+8); + + // first read the size of the texture + pcNew->mWidth = *((uint32_t*)szData); + AI_SWAP4(pcNew->mWidth); + szData += sizeof(uint32_t); + + pcNew->mHeight = *((uint32_t*)szData); + AI_SWAP4(pcNew->mHeight); + szData += sizeof(uint32_t); + + if (bNoRead) { + pcNew->pcData = bad_texel; + } + + // this should not occur - at least the docs say it shouldn't. + // however, one can easily try out what MED does if you have + // a model with a DDS texture and export it to MDL5 ... + // yeah, it embedds the DDS file. + if (6 == iType) + { + // this is a compressed texture in DDS format + *piSkip = pcNew->mWidth; + VALIDATE_FILE_SIZE(szData + *piSkip); + + if (!bNoRead) + { + // place a hint and let the application know that this is a DDS file + pcNew->mHeight = 0; + pcNew->achFormatHint[0] = 'd'; + pcNew->achFormatHint[1] = 'd'; + pcNew->achFormatHint[2] = 's'; + pcNew->achFormatHint[3] = '\0'; + + pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth]; + ::memcpy(pcNew->pcData,szData,pcNew->mWidth); + } + } + else + { + // parse the color data of the texture + ParseTextureColorData(szData,iType,piSkip,pcNew); + } + *piSkip += sizeof(uint32_t) * 2; + + if (!bNoRead) + { + // store the texture + if (!this->pScene->mNumTextures) + { + pScene->mNumTextures = 1; + pScene->mTextures = new aiTexture*[1]; + pScene->mTextures[0] = pcNew; + } + else + { + aiTexture** pc = pScene->mTextures; + pScene->mTextures = new aiTexture*[pScene->mNumTextures+1]; + for (unsigned int i = 0; i < pScene->mNumTextures;++i) + this->pScene->mTextures[i] = pc[i]; + + pScene->mTextures[pScene->mNumTextures] = pcNew; + pScene->mNumTextures++; + delete[] pc; + } + } + else { + pcNew->pcData = NULL; + delete pcNew; + } + return; } // ------------------------------------------------------------------------------------------------ // Get a skin from a MDL7 file - more complex than all other subformats void MDLImporter::ParseSkinLump_3DGS_MDL7( - const unsigned char* szCurrent, - const unsigned char** szCurrentOut, - aiMaterial* pcMatOut, - unsigned int iType, - unsigned int iWidth, - unsigned int iHeight) + const unsigned char* szCurrent, + const unsigned char** szCurrentOut, + aiMaterial* pcMatOut, + unsigned int iType, + unsigned int iWidth, + unsigned int iHeight) { - aiTexture* pcNew = NULL; - - // get the type of the skin - unsigned int iMasked = (unsigned int)(iType & 0xF); - - if (0x1 == iMasked) - { - // ***** REFERENCE TO ANOTHER SKIN INDEX ***** - int referrer = (int)iWidth; - pcMatOut->AddProperty(&referrer,1,AI_MDL7_REFERRER_MATERIAL); - } - else if (0x6 == iMasked) - { - // ***** EMBEDDED DDS FILE ***** - if (1 != iHeight) - { - DefaultLogger::get()->warn("Found a reference to an embedded DDS texture, " - "but texture height is not equal to 1, which is not supported by MED"); - } - - pcNew = new aiTexture(); - pcNew->mHeight = 0; - pcNew->mWidth = iWidth; - - // place a proper format hint - pcNew->achFormatHint[0] = 'd'; - pcNew->achFormatHint[1] = 'd'; - pcNew->achFormatHint[2] = 's'; - pcNew->achFormatHint[3] = '\0'; - - pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth]; - memcpy(pcNew->pcData,szCurrent,pcNew->mWidth); - szCurrent += iWidth; - } - if (0x7 == iMasked) - { - // ***** REFERENCE TO EXTERNAL FILE ***** - if (1 != iHeight) - { - DefaultLogger::get()->warn("Found a reference to an external texture, " - "but texture height is not equal to 1, which is not supported by MED"); - } - - aiString szFile; - const size_t iLen = strlen((const char*)szCurrent); - size_t iLen2 = iLen+1; - iLen2 = iLen2 > MAXLEN ? MAXLEN : iLen2; - memcpy(szFile.data,(const char*)szCurrent,iLen2); - szFile.length = iLen; - - szCurrent += iLen2; - - // place this as diffuse texture - pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0)); - } - else if (iMasked || !iType || (iType && iWidth && iHeight)) - { - // ***** STANDARD COLOR TEXTURE ***** - pcNew = new aiTexture(); - if (!iHeight || !iWidth) - { - DefaultLogger::get()->warn("Found embedded texture, but its width " - "an height are both 0. Is this a joke?"); - - // generate an empty chess pattern - pcNew->mWidth = pcNew->mHeight = 8; - pcNew->pcData = new aiTexel[64]; - for (unsigned int x = 0; x < 8;++x) - { - for (unsigned int y = 0; y < 8;++y) - { - const bool bSet = ((0 == x % 2 && 0 != y % 2) || - (0 != x % 2 && 0 == y % 2)); - - aiTexel* pc = &pcNew->pcData[y * 8 + x]; - pc->r = pc->b = pc->g = (bSet?0xFF:0); - pc->a = 0xFF; - } - } - } - else - { - // it is a standard color texture. Fill in width and height - // and call the same function we used for loading MDL5 files - - pcNew->mWidth = iWidth; - pcNew->mHeight = iHeight; - - unsigned int iSkip = 0; - ParseTextureColorData(szCurrent,iMasked,&iSkip,pcNew); - - // skip length of texture data - szCurrent += iSkip; - } - } - - // sometimes there are MDL7 files which have a monochrome - // texture instead of material colors ... posssible they have - // been converted to MDL7 from other formats, such as MDL5 - aiColor4D clrTexture; - if (pcNew)clrTexture = ReplaceTextureWithColor(pcNew); - else clrTexture.r = get_qnan(); - - // check whether a material definition is contained in the skin - if (iType & AI_MDL7_SKINTYPE_MATERIAL) - { - BE_NCONST MDL::Material_MDL7* pcMatIn = (BE_NCONST MDL::Material_MDL7*)szCurrent; - szCurrent = (unsigned char*)(pcMatIn+1); - VALIDATE_FILE_SIZE(szCurrent); - - aiColor3D clrTemp; + aiTexture* pcNew = NULL; + + // get the type of the skin + unsigned int iMasked = (unsigned int)(iType & 0xF); + + if (0x1 == iMasked) + { + // ***** REFERENCE TO ANOTHER SKIN INDEX ***** + int referrer = (int)iWidth; + pcMatOut->AddProperty(&referrer,1,AI_MDL7_REFERRER_MATERIAL); + } + else if (0x6 == iMasked) + { + // ***** EMBEDDED DDS FILE ***** + if (1 != iHeight) + { + DefaultLogger::get()->warn("Found a reference to an embedded DDS texture, " + "but texture height is not equal to 1, which is not supported by MED"); + } + + pcNew = new aiTexture(); + pcNew->mHeight = 0; + pcNew->mWidth = iWidth; + + // place a proper format hint + pcNew->achFormatHint[0] = 'd'; + pcNew->achFormatHint[1] = 'd'; + pcNew->achFormatHint[2] = 's'; + pcNew->achFormatHint[3] = '\0'; + + pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth]; + memcpy(pcNew->pcData,szCurrent,pcNew->mWidth); + szCurrent += iWidth; + } + if (0x7 == iMasked) + { + // ***** REFERENCE TO EXTERNAL FILE ***** + if (1 != iHeight) + { + DefaultLogger::get()->warn("Found a reference to an external texture, " + "but texture height is not equal to 1, which is not supported by MED"); + } + + aiString szFile; + const size_t iLen = strlen((const char*)szCurrent); + size_t iLen2 = iLen+1; + iLen2 = iLen2 > MAXLEN ? MAXLEN : iLen2; + memcpy(szFile.data,(const char*)szCurrent,iLen2); + szFile.length = iLen; + + szCurrent += iLen2; + + // place this as diffuse texture + pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0)); + } + else if (iMasked || !iType || (iType && iWidth && iHeight)) + { + // ***** STANDARD COLOR TEXTURE ***** + pcNew = new aiTexture(); + if (!iHeight || !iWidth) + { + DefaultLogger::get()->warn("Found embedded texture, but its width " + "an height are both 0. Is this a joke?"); + + // generate an empty chess pattern + pcNew->mWidth = pcNew->mHeight = 8; + pcNew->pcData = new aiTexel[64]; + for (unsigned int x = 0; x < 8;++x) + { + for (unsigned int y = 0; y < 8;++y) + { + const bool bSet = ((0 == x % 2 && 0 != y % 2) || + (0 != x % 2 && 0 == y % 2)); + + aiTexel* pc = &pcNew->pcData[y * 8 + x]; + pc->r = pc->b = pc->g = (bSet?0xFF:0); + pc->a = 0xFF; + } + } + } + else + { + // it is a standard color texture. Fill in width and height + // and call the same function we used for loading MDL5 files + + pcNew->mWidth = iWidth; + pcNew->mHeight = iHeight; + + unsigned int iSkip = 0; + ParseTextureColorData(szCurrent,iMasked,&iSkip,pcNew); + + // skip length of texture data + szCurrent += iSkip; + } + } + + // sometimes there are MDL7 files which have a monochrome + // texture instead of material colors ... posssible they have + // been converted to MDL7 from other formats, such as MDL5 + aiColor4D clrTexture; + if (pcNew)clrTexture = ReplaceTextureWithColor(pcNew); + else clrTexture.r = get_qnan(); + + // check whether a material definition is contained in the skin + if (iType & AI_MDL7_SKINTYPE_MATERIAL) + { + BE_NCONST MDL::Material_MDL7* pcMatIn = (BE_NCONST MDL::Material_MDL7*)szCurrent; + szCurrent = (unsigned char*)(pcMatIn+1); + VALIDATE_FILE_SIZE(szCurrent); + + aiColor3D clrTemp; #define COLOR_MULTIPLY_RGB() \ - if (is_not_qnan(clrTexture.r)) \ - { \ - clrTemp.r *= clrTexture.r; \ - clrTemp.g *= clrTexture.g; \ - clrTemp.b *= clrTexture.b; \ - } - - // read diffuse color - clrTemp.r = pcMatIn->Diffuse.r; - AI_SWAP4(clrTemp.r); - clrTemp.g = pcMatIn->Diffuse.g; - AI_SWAP4(clrTemp.g); - clrTemp.b = pcMatIn->Diffuse.b; - AI_SWAP4(clrTemp.b); - COLOR_MULTIPLY_RGB(); - pcMatOut->AddProperty(&clrTemp,1,AI_MATKEY_COLOR_DIFFUSE); - - // read specular color - clrTemp.r = pcMatIn->Specular.r; - AI_SWAP4(clrTemp.r); - clrTemp.g = pcMatIn->Specular.g; - AI_SWAP4(clrTemp.g); - clrTemp.b = pcMatIn->Specular.b; - AI_SWAP4(clrTemp.b); - COLOR_MULTIPLY_RGB(); - pcMatOut->AddProperty(&clrTemp,1,AI_MATKEY_COLOR_SPECULAR); - - // read ambient color - clrTemp.r = pcMatIn->Ambient.r; - AI_SWAP4(clrTemp.r); - clrTemp.g = pcMatIn->Ambient.g; - AI_SWAP4(clrTemp.g); - clrTemp.b = pcMatIn->Ambient.b; - AI_SWAP4(clrTemp.b); - COLOR_MULTIPLY_RGB(); - pcMatOut->AddProperty(&clrTemp,1,AI_MATKEY_COLOR_AMBIENT); - - // read emissive color - clrTemp.r = pcMatIn->Emissive.r; - AI_SWAP4(clrTemp.r); - clrTemp.g = pcMatIn->Emissive.g; - AI_SWAP4(clrTemp.g); - clrTemp.b = pcMatIn->Emissive.b; - AI_SWAP4(clrTemp.b); - pcMatOut->AddProperty(&clrTemp,1,AI_MATKEY_COLOR_EMISSIVE); + if (is_not_qnan(clrTexture.r)) \ + { \ + clrTemp.r *= clrTexture.r; \ + clrTemp.g *= clrTexture.g; \ + clrTemp.b *= clrTexture.b; \ + } + + // read diffuse color + clrTemp.r = pcMatIn->Diffuse.r; + AI_SWAP4(clrTemp.r); + clrTemp.g = pcMatIn->Diffuse.g; + AI_SWAP4(clrTemp.g); + clrTemp.b = pcMatIn->Diffuse.b; + AI_SWAP4(clrTemp.b); + COLOR_MULTIPLY_RGB(); + pcMatOut->AddProperty(&clrTemp,1,AI_MATKEY_COLOR_DIFFUSE); + + // read specular color + clrTemp.r = pcMatIn->Specular.r; + AI_SWAP4(clrTemp.r); + clrTemp.g = pcMatIn->Specular.g; + AI_SWAP4(clrTemp.g); + clrTemp.b = pcMatIn->Specular.b; + AI_SWAP4(clrTemp.b); + COLOR_MULTIPLY_RGB(); + pcMatOut->AddProperty(&clrTemp,1,AI_MATKEY_COLOR_SPECULAR); + + // read ambient color + clrTemp.r = pcMatIn->Ambient.r; + AI_SWAP4(clrTemp.r); + clrTemp.g = pcMatIn->Ambient.g; + AI_SWAP4(clrTemp.g); + clrTemp.b = pcMatIn->Ambient.b; + AI_SWAP4(clrTemp.b); + COLOR_MULTIPLY_RGB(); + pcMatOut->AddProperty(&clrTemp,1,AI_MATKEY_COLOR_AMBIENT); + + // read emissive color + clrTemp.r = pcMatIn->Emissive.r; + AI_SWAP4(clrTemp.r); + clrTemp.g = pcMatIn->Emissive.g; + AI_SWAP4(clrTemp.g); + clrTemp.b = pcMatIn->Emissive.b; + AI_SWAP4(clrTemp.b); + pcMatOut->AddProperty(&clrTemp,1,AI_MATKEY_COLOR_EMISSIVE); #undef COLOR_MULITPLY_RGB - // FIX: Take the opacity from the ambient color. - // The doc say something else, but it is fact that MED exports the - // opacity like this .... oh well. - clrTemp.r = pcMatIn->Ambient.a; - AI_SWAP4(clrTemp.r); - if (is_not_qnan(clrTexture.r)) { - clrTemp.r *= clrTexture.a; - } - pcMatOut->AddProperty(&clrTemp.r,1,AI_MATKEY_OPACITY); - - // read phong power - int iShadingMode = (int)aiShadingMode_Gouraud; - AI_SWAP4(pcMatIn->Power); - if (0.0f != pcMatIn->Power) - { - iShadingMode = (int)aiShadingMode_Phong; - pcMatOut->AddProperty(&pcMatIn->Power,1,AI_MATKEY_SHININESS); - } - pcMatOut->AddProperty(&iShadingMode,1,AI_MATKEY_SHADING_MODEL); - } - else if (is_not_qnan(clrTexture.r)) - { - pcMatOut->AddProperty(&clrTexture,1,AI_MATKEY_COLOR_DIFFUSE); - pcMatOut->AddProperty(&clrTexture,1,AI_MATKEY_COLOR_SPECULAR); - } - // if the texture could be replaced by a single material color - // we don't need the texture anymore - if (is_not_qnan(clrTexture.r)) - { - delete pcNew; - pcNew = NULL; - } - - // If an ASCII effect description (HLSL?) is contained in the file, - // we can simply ignore it ... - if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF) - { - VALIDATE_FILE_SIZE(szCurrent); - int32_t iMe = *((int32_t*)szCurrent); - AI_SWAP4(iMe); - szCurrent += sizeof(char) * iMe + sizeof(int32_t); - VALIDATE_FILE_SIZE(szCurrent); - } - - // If an embedded texture has been loaded setup the corresponding - // data structures in the aiScene instance - if (pcNew && pScene->mNumTextures <= 999) - { - - // place this as diffuse texture - char szCurrent[5]; - ::sprintf(szCurrent,"*%i",this->pScene->mNumTextures); - - aiString szFile; - const size_t iLen = strlen((const char*)szCurrent); - ::memcpy(szFile.data,(const char*)szCurrent,iLen+1); - szFile.length = iLen; - - pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0)); - - // store the texture - if (!pScene->mNumTextures) - { - pScene->mNumTextures = 1; - pScene->mTextures = new aiTexture*[1]; - pScene->mTextures[0] = pcNew; - } - else - { - aiTexture** pc = pScene->mTextures; - pScene->mTextures = new aiTexture*[pScene->mNumTextures+1]; - for (unsigned int i = 0; i < pScene->mNumTextures;++i) { - pScene->mTextures[i] = pc[i]; - } - - pScene->mTextures[pScene->mNumTextures] = pcNew; - pScene->mNumTextures++; - delete[] pc; - } - } - VALIDATE_FILE_SIZE(szCurrent); - *szCurrentOut = szCurrent; + // FIX: Take the opacity from the ambient color. + // The doc say something else, but it is fact that MED exports the + // opacity like this .... oh well. + clrTemp.r = pcMatIn->Ambient.a; + AI_SWAP4(clrTemp.r); + if (is_not_qnan(clrTexture.r)) { + clrTemp.r *= clrTexture.a; + } + pcMatOut->AddProperty(&clrTemp.r,1,AI_MATKEY_OPACITY); + + // read phong power + int iShadingMode = (int)aiShadingMode_Gouraud; + AI_SWAP4(pcMatIn->Power); + if (0.0f != pcMatIn->Power) + { + iShadingMode = (int)aiShadingMode_Phong; + pcMatOut->AddProperty(&pcMatIn->Power,1,AI_MATKEY_SHININESS); + } + pcMatOut->AddProperty(&iShadingMode,1,AI_MATKEY_SHADING_MODEL); + } + else if (is_not_qnan(clrTexture.r)) + { + pcMatOut->AddProperty(&clrTexture,1,AI_MATKEY_COLOR_DIFFUSE); + pcMatOut->AddProperty(&clrTexture,1,AI_MATKEY_COLOR_SPECULAR); + } + // if the texture could be replaced by a single material color + // we don't need the texture anymore + if (is_not_qnan(clrTexture.r)) + { + delete pcNew; + pcNew = NULL; + } + + // If an ASCII effect description (HLSL?) is contained in the file, + // we can simply ignore it ... + if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF) + { + VALIDATE_FILE_SIZE(szCurrent); + int32_t iMe = *((int32_t*)szCurrent); + AI_SWAP4(iMe); + szCurrent += sizeof(char) * iMe + sizeof(int32_t); + VALIDATE_FILE_SIZE(szCurrent); + } + + // If an embedded texture has been loaded setup the corresponding + // data structures in the aiScene instance + if (pcNew && pScene->mNumTextures <= 999) + { + + // place this as diffuse texture + char szCurrent[5]; + ai_snprintf(szCurrent,5,"*%i",this->pScene->mNumTextures); + + aiString szFile; + const size_t iLen = strlen((const char*)szCurrent); + ::memcpy(szFile.data,(const char*)szCurrent,iLen+1); + szFile.length = iLen; + + pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0)); + + // store the texture + if (!pScene->mNumTextures) + { + pScene->mNumTextures = 1; + pScene->mTextures = new aiTexture*[1]; + pScene->mTextures[0] = pcNew; + } + else + { + aiTexture** pc = pScene->mTextures; + pScene->mTextures = new aiTexture*[pScene->mNumTextures+1]; + for (unsigned int i = 0; i < pScene->mNumTextures;++i) { + pScene->mTextures[i] = pc[i]; + } + + pScene->mTextures[pScene->mNumTextures] = pcNew; + pScene->mNumTextures++; + delete[] pc; + } + } + VALIDATE_FILE_SIZE(szCurrent); + *szCurrentOut = szCurrent; } // ------------------------------------------------------------------------------------------------ // Skip a skin lump void MDLImporter::SkipSkinLump_3DGS_MDL7( - const unsigned char* szCurrent, - const unsigned char** szCurrentOut, - unsigned int iType, - unsigned int iWidth, - unsigned int iHeight) + const unsigned char* szCurrent, + const unsigned char** szCurrentOut, + unsigned int iType, + unsigned int iWidth, + unsigned int iHeight) { - // get the type of the skin - const unsigned int iMasked = (unsigned int)(iType & 0xF); - - if (0x6 == iMasked) - { - szCurrent += iWidth; - } - if (0x7 == iMasked) - { - const size_t iLen = ::strlen((const char*)szCurrent); - szCurrent += iLen+1; - } - else if (iMasked || !iType) - { - if (iMasked || !iType || (iType && iWidth && iHeight)) - { - // ParseTextureColorData(..., aiTexture::pcData == bad_texel) will simply - // return the size of the color data in bytes in iSkip - unsigned int iSkip = 0; - - aiTexture tex; - tex.pcData = bad_texel; - tex.mHeight = iHeight; - tex.mWidth = iWidth; - ParseTextureColorData(szCurrent,iMasked,&iSkip,&tex); - - // FIX: Important, otherwise the destructor will crash - tex.pcData = NULL; - - // skip length of texture data - szCurrent += iSkip; - } - } - - // check whether a material definition is contained in the skin - if (iType & AI_MDL7_SKINTYPE_MATERIAL) - { - BE_NCONST MDL::Material_MDL7* pcMatIn = (BE_NCONST MDL::Material_MDL7*)szCurrent; - szCurrent = (unsigned char*)(pcMatIn+1); - } - - // if an ASCII effect description (HLSL?) is contained in the file, - // we can simply ignore it ... - if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF) - { - int32_t iMe = *((int32_t*)szCurrent); - AI_SWAP4(iMe); - szCurrent += sizeof(char) * iMe + sizeof(int32_t); - } - *szCurrentOut = szCurrent; + // get the type of the skin + const unsigned int iMasked = (unsigned int)(iType & 0xF); + + if (0x6 == iMasked) + { + szCurrent += iWidth; + } + if (0x7 == iMasked) + { + const size_t iLen = ::strlen((const char*)szCurrent); + szCurrent += iLen+1; + } + else if (iMasked || !iType) + { + if (iMasked || !iType || (iType && iWidth && iHeight)) + { + // ParseTextureColorData(..., aiTexture::pcData == bad_texel) will simply + // return the size of the color data in bytes in iSkip + unsigned int iSkip = 0; + + aiTexture tex; + tex.pcData = bad_texel; + tex.mHeight = iHeight; + tex.mWidth = iWidth; + ParseTextureColorData(szCurrent,iMasked,&iSkip,&tex); + + // FIX: Important, otherwise the destructor will crash + tex.pcData = NULL; + + // skip length of texture data + szCurrent += iSkip; + } + } + + // check whether a material definition is contained in the skin + if (iType & AI_MDL7_SKINTYPE_MATERIAL) + { + BE_NCONST MDL::Material_MDL7* pcMatIn = (BE_NCONST MDL::Material_MDL7*)szCurrent; + szCurrent = (unsigned char*)(pcMatIn+1); + } + + // if an ASCII effect description (HLSL?) is contained in the file, + // we can simply ignore it ... + if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF) + { + int32_t iMe = *((int32_t*)szCurrent); + AI_SWAP4(iMe); + szCurrent += sizeof(char) * iMe + sizeof(int32_t); + } + *szCurrentOut = szCurrent; } // ------------------------------------------------------------------------------------------------ void MDLImporter::ParseSkinLump_3DGS_MDL7( - const unsigned char* szCurrent, - const unsigned char** szCurrentOut, - std::vector& pcMats) + const unsigned char* szCurrent, + const unsigned char** szCurrentOut, + std::vector& pcMats) { - ai_assert(NULL != szCurrent); - ai_assert(NULL != szCurrentOut); - - *szCurrentOut = szCurrent; - BE_NCONST MDL::Skin_MDL7* pcSkin = (BE_NCONST MDL::Skin_MDL7*)szCurrent; - AI_SWAP4(pcSkin->width); - AI_SWAP4(pcSkin->height); - szCurrent += 12; - - // allocate an output material - aiMaterial* pcMatOut = new aiMaterial(); - pcMats.push_back(pcMatOut); - - // skip length of file name - szCurrent += AI_MDL7_MAX_TEXNAMESIZE; - - ParseSkinLump_3DGS_MDL7(szCurrent,szCurrentOut,pcMatOut, - pcSkin->typ,pcSkin->width,pcSkin->height); - - // place the name of the skin in the material - if (pcSkin->texture_name[0]) - { - // the 0 termination could be there or not - we can't know - aiString szFile; - ::memcpy(szFile.data,pcSkin->texture_name,sizeof(pcSkin->texture_name)); - szFile.data[sizeof(pcSkin->texture_name)] = '\0'; - szFile.length = ::strlen(szFile.data); - - pcMatOut->AddProperty(&szFile,AI_MATKEY_NAME); - } + ai_assert(NULL != szCurrent); + ai_assert(NULL != szCurrentOut); + + *szCurrentOut = szCurrent; + BE_NCONST MDL::Skin_MDL7* pcSkin = (BE_NCONST MDL::Skin_MDL7*)szCurrent; + AI_SWAP4(pcSkin->width); + AI_SWAP4(pcSkin->height); + szCurrent += 12; + + // allocate an output material + aiMaterial* pcMatOut = new aiMaterial(); + pcMats.push_back(pcMatOut); + + // skip length of file name + szCurrent += AI_MDL7_MAX_TEXNAMESIZE; + + ParseSkinLump_3DGS_MDL7(szCurrent,szCurrentOut,pcMatOut, + pcSkin->typ,pcSkin->width,pcSkin->height); + + // place the name of the skin in the material + if (pcSkin->texture_name[0]) + { + // the 0 termination could be there or not - we can't know + aiString szFile; + ::memcpy(szFile.data,pcSkin->texture_name,sizeof(pcSkin->texture_name)); + szFile.data[sizeof(pcSkin->texture_name)] = '\0'; + szFile.length = ::strlen(szFile.data); + + pcMatOut->AddProperty(&szFile,AI_MATKEY_NAME); + } } #endif // !! ASSIMP_BUILD_NO_MDL_IMPORTER -- cgit v1.2.3