summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/assimp/code/MDCLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/assimp/code/MDCLoader.cpp')
-rw-r--r--src/3rdparty/assimp/code/MDCLoader.cpp762
1 files changed, 386 insertions, 376 deletions
diff --git a/src/3rdparty/assimp/code/MDCLoader.cpp b/src/3rdparty/assimp/code/MDCLoader.cpp
index 45574361a..661447acf 100644
--- a/src/3rdparty/assimp/code/MDCLoader.cpp
+++ b/src/3rdparty/assimp/code/MDCLoader.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,168 +25,178 @@ 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 MDC importer class */
-#include "AssimpPCH.h"
+
#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
// internal headers
#include "MDCLoader.h"
#include "MD3FileData.h"
#include "MDCNormalTable.h" // shouldn't be included by other units
+#include <assimp/DefaultLogger.hpp>
+#include <assimp/Importer.hpp>
+#include <assimp/IOSystem.hpp>
+#include <assimp/scene.h>
+#include <memory>
+
using namespace Assimp;
using namespace Assimp::MDC;
static const aiImporterDesc desc = {
- "Return To Castle Wolfenstein Mesh Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "mdc"
+ "Return To Castle Wolfenstein Mesh Importer",
+ "",
+ "",
+ "",
+ aiImporterFlags_SupportBinaryFlavour,
+ 0,
+ 0,
+ 0,
+ 0,
+ "mdc"
};
// ------------------------------------------------------------------------------------------------
void MDC::BuildVertex(const Frame& frame,
- const BaseVertex& bvert,
- const CompressedVertex& cvert,
- aiVector3D& vXYZOut,
- aiVector3D& vNorOut)
+ const BaseVertex& bvert,
+ const CompressedVertex& cvert,
+ aiVector3D& vXYZOut,
+ aiVector3D& vNorOut)
{
- // compute the position
- const float xd = (cvert.xd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
- const float yd = (cvert.yd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
- const float zd = (cvert.zd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
- vXYZOut.x = frame.localOrigin.x + AI_MDC_BASE_SCALING * (bvert.x + xd);
- vXYZOut.y = frame.localOrigin.y + AI_MDC_BASE_SCALING * (bvert.y + yd);
- vXYZOut.z = frame.localOrigin.z + AI_MDC_BASE_SCALING * (bvert.z + zd);
-
- // compute the normal vector .. ehm ... lookup it in the table :-)
- vNorOut.x = mdcNormals[cvert.nd][0];
- vNorOut.y = mdcNormals[cvert.nd][1];
- vNorOut.z = mdcNormals[cvert.nd][2];
+ // compute the position
+ const float xd = (cvert.xd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
+ const float yd = (cvert.yd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
+ const float zd = (cvert.zd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
+ vXYZOut.x = frame.localOrigin.x + AI_MDC_BASE_SCALING * (bvert.x + xd);
+ vXYZOut.y = frame.localOrigin.y + AI_MDC_BASE_SCALING * (bvert.y + yd);
+ vXYZOut.z = frame.localOrigin.z + AI_MDC_BASE_SCALING * (bvert.z + zd);
+
+ // compute the normal vector .. ehm ... lookup it in the table :-)
+ vNorOut.x = mdcNormals[cvert.nd][0];
+ vNorOut.y = mdcNormals[cvert.nd][1];
+ vNorOut.z = mdcNormals[cvert.nd][2];
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
MDCImporter::MDCImporter()
+ : configFrameID(),
+ pcHeader(),
+ mBuffer(),
+ fileSize()
{
}
// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
+// Destructor, private as well
MDCImporter::~MDCImporter()
{
}
// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
+// Returns whether the class can handle the format of the given file.
bool MDCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
- const std::string extension = GetExtension(pFile);
- if (extension == "mdc")
- return true;
-
- // if check for extension is not enough, check for the magic tokens
- if (!extension.length() || checkSig) {
- uint32_t tokens[1];
- tokens[0] = AI_MDC_MAGIC_NUMBER_LE;
- return CheckMagicToken(pIOHandler,pFile,tokens,1);
- }
- return false;
+ const std::string extension = GetExtension(pFile);
+ if (extension == "mdc")
+ return true;
+
+ // if check for extension is not enough, check for the magic tokens
+ if (!extension.length() || checkSig) {
+ uint32_t tokens[1];
+ tokens[0] = AI_MDC_MAGIC_NUMBER_LE;
+ return CheckMagicToken(pIOHandler,pFile,tokens,1);
+ }
+ return false;
}
// ------------------------------------------------------------------------------------------------
const aiImporterDesc* MDCImporter::GetInfo () const
{
- return &desc;
+ return &desc;
}
// ------------------------------------------------------------------------------------------------
// Validate the header of the given MDC file
void MDCImporter::ValidateHeader()
{
- AI_SWAP4( this->pcHeader->ulVersion );
- AI_SWAP4( this->pcHeader->ulFlags );
- AI_SWAP4( this->pcHeader->ulNumFrames );
- AI_SWAP4( this->pcHeader->ulNumTags );
- AI_SWAP4( this->pcHeader->ulNumSurfaces );
- AI_SWAP4( this->pcHeader->ulNumSkins );
- AI_SWAP4( this->pcHeader->ulOffsetBorderFrames );
-
- if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE &&
- pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE)
- {
- char szBuffer[5];
- szBuffer[0] = ((char*)&pcHeader->ulIdent)[0];
- szBuffer[1] = ((char*)&pcHeader->ulIdent)[1];
- szBuffer[2] = ((char*)&pcHeader->ulIdent)[2];
- szBuffer[3] = ((char*)&pcHeader->ulIdent)[3];
- szBuffer[4] = '\0';
-
- throw DeadlyImportError("Invalid MDC magic word: should be IDPC, the "
- "magic word found is " + std::string( szBuffer ));
- }
-
- if (pcHeader->ulVersion != AI_MDC_VERSION)
- DefaultLogger::get()->warn("Unsupported MDC file version (2 (AI_MDC_VERSION) was expected)");
-
- if (pcHeader->ulOffsetBorderFrames + pcHeader->ulNumFrames * sizeof(MDC::Frame) > this->fileSize ||
- pcHeader->ulOffsetSurfaces + pcHeader->ulNumSurfaces * sizeof(MDC::Surface) > this->fileSize)
- {
- throw DeadlyImportError("Some of the offset values in the MDC header are invalid "
- "and point to something behind the file.");
- }
-
- if (this->configFrameID >= this->pcHeader->ulNumFrames)
- throw DeadlyImportError("The requested frame is not available");
+ AI_SWAP4( this->pcHeader->ulVersion );
+ AI_SWAP4( this->pcHeader->ulFlags );
+ AI_SWAP4( this->pcHeader->ulNumFrames );
+ AI_SWAP4( this->pcHeader->ulNumTags );
+ AI_SWAP4( this->pcHeader->ulNumSurfaces );
+ AI_SWAP4( this->pcHeader->ulNumSkins );
+ AI_SWAP4( this->pcHeader->ulOffsetBorderFrames );
+
+ if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE &&
+ pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE)
+ {
+ char szBuffer[5];
+ szBuffer[0] = ((char*)&pcHeader->ulIdent)[0];
+ szBuffer[1] = ((char*)&pcHeader->ulIdent)[1];
+ szBuffer[2] = ((char*)&pcHeader->ulIdent)[2];
+ szBuffer[3] = ((char*)&pcHeader->ulIdent)[3];
+ szBuffer[4] = '\0';
+
+ throw DeadlyImportError("Invalid MDC magic word: should be IDPC, the "
+ "magic word found is " + std::string( szBuffer ));
+ }
+
+ if (pcHeader->ulVersion != AI_MDC_VERSION)
+ DefaultLogger::get()->warn("Unsupported MDC file version (2 (AI_MDC_VERSION) was expected)");
+
+ if (pcHeader->ulOffsetBorderFrames + pcHeader->ulNumFrames * sizeof(MDC::Frame) > this->fileSize ||
+ pcHeader->ulOffsetSurfaces + pcHeader->ulNumSurfaces * sizeof(MDC::Surface) > this->fileSize)
+ {
+ throw DeadlyImportError("Some of the offset values in the MDC header are invalid "
+ "and point to something behind the file.");
+ }
+
+ if (this->configFrameID >= this->pcHeader->ulNumFrames)
+ throw DeadlyImportError("The requested frame is not available");
}
// ------------------------------------------------------------------------------------------------
// Validate the header of a given MDC file surface
void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf)
{
- AI_SWAP4(pcSurf->ulFlags);
- AI_SWAP4(pcSurf->ulNumCompFrames);
- AI_SWAP4(pcSurf->ulNumBaseFrames);
- AI_SWAP4(pcSurf->ulNumShaders);
- AI_SWAP4(pcSurf->ulNumVertices);
- AI_SWAP4(pcSurf->ulNumTriangles);
- AI_SWAP4(pcSurf->ulOffsetTriangles);
- AI_SWAP4(pcSurf->ulOffsetTexCoords);
- AI_SWAP4(pcSurf->ulOffsetBaseVerts);
- AI_SWAP4(pcSurf->ulOffsetCompVerts);
- AI_SWAP4(pcSurf->ulOffsetFrameBaseFrames);
- AI_SWAP4(pcSurf->ulOffsetFrameCompFrames);
- AI_SWAP4(pcSurf->ulOffsetEnd);
+ AI_SWAP4(pcSurf->ulFlags);
+ AI_SWAP4(pcSurf->ulNumCompFrames);
+ AI_SWAP4(pcSurf->ulNumBaseFrames);
+ AI_SWAP4(pcSurf->ulNumShaders);
+ AI_SWAP4(pcSurf->ulNumVertices);
+ AI_SWAP4(pcSurf->ulNumTriangles);
+ AI_SWAP4(pcSurf->ulOffsetTriangles);
+ AI_SWAP4(pcSurf->ulOffsetTexCoords);
+ AI_SWAP4(pcSurf->ulOffsetBaseVerts);
+ AI_SWAP4(pcSurf->ulOffsetCompVerts);
+ AI_SWAP4(pcSurf->ulOffsetFrameBaseFrames);
+ AI_SWAP4(pcSurf->ulOffsetFrameCompFrames);
+ AI_SWAP4(pcSurf->ulOffsetEnd);
const unsigned int iMax = this->fileSize - (unsigned int)((int8_t*)pcSurf-(int8_t*)pcHeader);
- if (pcSurf->ulOffsetBaseVerts + pcSurf->ulNumVertices * sizeof(MDC::BaseVertex) > iMax ||
- (pcSurf->ulNumCompFrames && pcSurf->ulOffsetCompVerts + pcSurf->ulNumVertices * sizeof(MDC::CompressedVertex) > iMax) ||
- pcSurf->ulOffsetTriangles + pcSurf->ulNumTriangles * sizeof(MDC::Triangle) > iMax ||
- pcSurf->ulOffsetTexCoords + pcSurf->ulNumVertices * sizeof(MDC::TexturCoord) > iMax ||
- pcSurf->ulOffsetShaders + pcSurf->ulNumShaders * sizeof(MDC::Shader) > iMax ||
- pcSurf->ulOffsetFrameBaseFrames + pcSurf->ulNumBaseFrames * 2 > iMax ||
- (pcSurf->ulNumCompFrames && pcSurf->ulOffsetFrameCompFrames + pcSurf->ulNumCompFrames * 2 > iMax))
+ if (pcSurf->ulOffsetBaseVerts + pcSurf->ulNumVertices * sizeof(MDC::BaseVertex) > iMax ||
+ (pcSurf->ulNumCompFrames && pcSurf->ulOffsetCompVerts + pcSurf->ulNumVertices * sizeof(MDC::CompressedVertex) > iMax) ||
+ pcSurf->ulOffsetTriangles + pcSurf->ulNumTriangles * sizeof(MDC::Triangle) > iMax ||
+ pcSurf->ulOffsetTexCoords + pcSurf->ulNumVertices * sizeof(MDC::TexturCoord) > iMax ||
+ pcSurf->ulOffsetShaders + pcSurf->ulNumShaders * sizeof(MDC::Shader) > iMax ||
+ pcSurf->ulOffsetFrameBaseFrames + pcSurf->ulNumBaseFrames * 2 > iMax ||
+ (pcSurf->ulNumCompFrames && pcSurf->ulOffsetFrameCompFrames + pcSurf->ulNumCompFrames * 2 > iMax))
{
throw DeadlyImportError("Some of the offset values in the MDC surface header "
"are invalid and point somewhere behind the file.");
@@ -197,286 +207,286 @@ void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf)
// Setup configuration properties
void MDCImporter::SetupProperties(const Importer* pImp)
{
- // The AI_CONFIG_IMPORT_MDC_KEYFRAME option overrides the
- // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
- if(static_cast<unsigned int>(-1) == (configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MDC_KEYFRAME,-1))){
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
- }
+ // The AI_CONFIG_IMPORT_MDC_KEYFRAME option overrides the
+ // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
+ if(static_cast<unsigned int>(-1) == (configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MDC_KEYFRAME,-1))){
+ configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
+ }
}
// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void MDCImporter::InternReadFile(
- const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
+// Imports the given file into the given scene structure.
+void MDCImporter::InternReadFile(
+ const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
{
- boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if( file.get() == NULL)
- throw DeadlyImportError( "Failed to open MDC file " + pFile + ".");
-
- // check whether the mdc file is large enough to contain the file header
- fileSize = (unsigned int)file->FileSize();
- if( fileSize < sizeof(MDC::Header))
- throw DeadlyImportError( "MDC File is too small.");
-
- std::vector<unsigned char> mBuffer2(fileSize);
- file->Read( &mBuffer2[0], 1, fileSize);
- mBuffer = &mBuffer2[0];
-
- // validate the file header
- this->pcHeader = (BE_NCONST MDC::Header*)this->mBuffer;
- this->ValidateHeader();
-
- std::vector<std::string> aszShaders;
-
- // get a pointer to the frame we want to read
- BE_NCONST MDC::Frame* pcFrame = (BE_NCONST MDC::Frame*)(this->mBuffer+
- this->pcHeader->ulOffsetBorderFrames);
-
- // no need to swap the other members, we won't need them
- pcFrame += configFrameID;
- AI_SWAP4( pcFrame->localOrigin[0] );
- AI_SWAP4( pcFrame->localOrigin[1] );
- AI_SWAP4( pcFrame->localOrigin[2] );
-
- // get the number of valid surfaces
- BE_NCONST MDC::Surface* pcSurface, *pcSurface2;
- pcSurface = pcSurface2 = new (mBuffer + pcHeader->ulOffsetSurfaces) MDC::Surface;
- unsigned int iNumShaders = 0;
- for (unsigned int i = 0; i < pcHeader->ulNumSurfaces;++i)
- {
- // validate the surface header
- this->ValidateSurfaceHeader(pcSurface2);
-
- if (pcSurface2->ulNumVertices && pcSurface2->ulNumTriangles)++pScene->mNumMeshes;
- iNumShaders += pcSurface2->ulNumShaders;
- pcSurface2 = new ((int8_t*)pcSurface2 + pcSurface2->ulOffsetEnd) MDC::Surface;
- }
- aszShaders.reserve(iNumShaders);
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
-
- // necessary that we don't crash if an exception occurs
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mMeshes[i] = NULL;
-
- // now read all surfaces
- unsigned int iDefaultMatIndex = UINT_MAX;
- for (unsigned int i = 0, iNum = 0; i < pcHeader->ulNumSurfaces;++i)
- {
- if (!pcSurface->ulNumVertices || !pcSurface->ulNumTriangles)continue;
- aiMesh* pcMesh = pScene->mMeshes[iNum++] = new aiMesh();
-
- pcMesh->mNumFaces = pcSurface->ulNumTriangles;
- pcMesh->mNumVertices = pcMesh->mNumFaces * 3;
-
- // store the name of the surface for use as node name.
- // FIX: make sure there is a 0 termination
- const_cast<char&>(pcSurface->ucName[AI_MDC_MAXQPATH-1]) = '\0';
- pcMesh->mTextureCoords[3] = (aiVector3D*)pcSurface->ucName;
-
- // go to the first shader in the file. ignore the others.
- if (pcSurface->ulNumShaders)
- {
- const MDC::Shader* pcShader = (const MDC::Shader*)((int8_t*)pcSurface + pcSurface->ulOffsetShaders);
- pcMesh->mMaterialIndex = (unsigned int)aszShaders.size();
-
- // create a new shader
- aszShaders.push_back(std::string( pcShader->ucName, std::min(
- ::strlen(pcShader->ucName),sizeof(pcShader->ucName)) ));
- }
- // need to create a default material
- else if (UINT_MAX == iDefaultMatIndex)
- {
- pcMesh->mMaterialIndex = iDefaultMatIndex = (unsigned int)aszShaders.size();
- aszShaders.push_back(std::string());
- }
- // otherwise assign a reference to the default material
- else pcMesh->mMaterialIndex = iDefaultMatIndex;
-
- // allocate output storage for the mesh
- aiVector3D* pcVertCur = pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
- aiVector3D* pcNorCur = pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
- aiVector3D* pcUVCur = pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
- aiFace* pcFaceCur = pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
-
- // create all vertices/faces
- BE_NCONST MDC::Triangle* pcTriangle = (BE_NCONST MDC::Triangle*)
- ((int8_t*)pcSurface+pcSurface->ulOffsetTriangles);
-
- BE_NCONST MDC::TexturCoord* const pcUVs = (BE_NCONST MDC::TexturCoord*)
- ((int8_t*)pcSurface+pcSurface->ulOffsetTexCoords);
-
- // get a pointer to the uncompressed vertices
- int16_t iOfs = *((int16_t*) ((int8_t*) pcSurface +
- pcSurface->ulOffsetFrameBaseFrames) + this->configFrameID);
-
- AI_SWAP2(iOfs);
-
- BE_NCONST MDC::BaseVertex* const pcVerts = (BE_NCONST MDC::BaseVertex*)
- ((int8_t*)pcSurface+pcSurface->ulOffsetBaseVerts) +
- ((int)iOfs * pcSurface->ulNumVertices * 4);
-
- // do the main swapping stuff ...
+ std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
+
+ // Check whether we can read from the file
+ if( file.get() == NULL)
+ throw DeadlyImportError( "Failed to open MDC file " + pFile + ".");
+
+ // check whether the mdc file is large enough to contain the file header
+ fileSize = (unsigned int)file->FileSize();
+ if( fileSize < sizeof(MDC::Header))
+ throw DeadlyImportError( "MDC File is too small.");
+
+ std::vector<unsigned char> mBuffer2(fileSize);
+ file->Read( &mBuffer2[0], 1, fileSize);
+ mBuffer = &mBuffer2[0];
+
+ // validate the file header
+ this->pcHeader = (BE_NCONST MDC::Header*)this->mBuffer;
+ this->ValidateHeader();
+
+ std::vector<std::string> aszShaders;
+
+ // get a pointer to the frame we want to read
+ BE_NCONST MDC::Frame* pcFrame = (BE_NCONST MDC::Frame*)(this->mBuffer+
+ this->pcHeader->ulOffsetBorderFrames);
+
+ // no need to swap the other members, we won't need them
+ pcFrame += configFrameID;
+ AI_SWAP4( pcFrame->localOrigin[0] );
+ AI_SWAP4( pcFrame->localOrigin[1] );
+ AI_SWAP4( pcFrame->localOrigin[2] );
+
+ // get the number of valid surfaces
+ BE_NCONST MDC::Surface* pcSurface, *pcSurface2;
+ pcSurface = pcSurface2 = new (mBuffer + pcHeader->ulOffsetSurfaces) MDC::Surface;
+ unsigned int iNumShaders = 0;
+ for (unsigned int i = 0; i < pcHeader->ulNumSurfaces;++i)
+ {
+ // validate the surface header
+ this->ValidateSurfaceHeader(pcSurface2);
+
+ if (pcSurface2->ulNumVertices && pcSurface2->ulNumTriangles)++pScene->mNumMeshes;
+ iNumShaders += pcSurface2->ulNumShaders;
+ pcSurface2 = new ((int8_t*)pcSurface2 + pcSurface2->ulOffsetEnd) MDC::Surface;
+ }
+ aszShaders.reserve(iNumShaders);
+ pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
+
+ // necessary that we don't crash if an exception occurs
+ for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
+ pScene->mMeshes[i] = NULL;
+
+ // now read all surfaces
+ unsigned int iDefaultMatIndex = UINT_MAX;
+ for (unsigned int i = 0, iNum = 0; i < pcHeader->ulNumSurfaces;++i)
+ {
+ if (!pcSurface->ulNumVertices || !pcSurface->ulNumTriangles)continue;
+ aiMesh* pcMesh = pScene->mMeshes[iNum++] = new aiMesh();
+
+ pcMesh->mNumFaces = pcSurface->ulNumTriangles;
+ pcMesh->mNumVertices = pcMesh->mNumFaces * 3;
+
+ // store the name of the surface for use as node name.
+ // FIX: make sure there is a 0 termination
+ const_cast<char&>(pcSurface->ucName[AI_MDC_MAXQPATH-1]) = '\0';
+ pcMesh->mTextureCoords[3] = (aiVector3D*)pcSurface->ucName;
+
+ // go to the first shader in the file. ignore the others.
+ if (pcSurface->ulNumShaders)
+ {
+ const MDC::Shader* pcShader = (const MDC::Shader*)((int8_t*)pcSurface + pcSurface->ulOffsetShaders);
+ pcMesh->mMaterialIndex = (unsigned int)aszShaders.size();
+
+ // create a new shader
+ aszShaders.push_back(std::string( pcShader->ucName, std::min(
+ ::strlen(pcShader->ucName),sizeof(pcShader->ucName)) ));
+ }
+ // need to create a default material
+ else if (UINT_MAX == iDefaultMatIndex)
+ {
+ pcMesh->mMaterialIndex = iDefaultMatIndex = (unsigned int)aszShaders.size();
+ aszShaders.push_back(std::string());
+ }
+ // otherwise assign a reference to the default material
+ else pcMesh->mMaterialIndex = iDefaultMatIndex;
+
+ // allocate output storage for the mesh
+ aiVector3D* pcVertCur = pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
+ aiVector3D* pcNorCur = pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
+ aiVector3D* pcUVCur = pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
+ aiFace* pcFaceCur = pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
+
+ // create all vertices/faces
+ BE_NCONST MDC::Triangle* pcTriangle = (BE_NCONST MDC::Triangle*)
+ ((int8_t*)pcSurface+pcSurface->ulOffsetTriangles);
+
+ BE_NCONST MDC::TexturCoord* const pcUVs = (BE_NCONST MDC::TexturCoord*)
+ ((int8_t*)pcSurface+pcSurface->ulOffsetTexCoords);
+
+ // get a pointer to the uncompressed vertices
+ int16_t iOfs = *((int16_t*) ((int8_t*) pcSurface +
+ pcSurface->ulOffsetFrameBaseFrames) + this->configFrameID);
+
+ AI_SWAP2(iOfs);
+
+ BE_NCONST MDC::BaseVertex* const pcVerts = (BE_NCONST MDC::BaseVertex*)
+ ((int8_t*)pcSurface+pcSurface->ulOffsetBaseVerts) +
+ ((int)iOfs * pcSurface->ulNumVertices * 4);
+
+ // do the main swapping stuff ...
#if (defined AI_BUILD_BIG_ENDIAN)
- // swap all triangles
- for (unsigned int i = 0; i < pcSurface->ulNumTriangles;++i)
- {
- AI_SWAP4( pcTriangle[i].aiIndices[0] );
- AI_SWAP4( pcTriangle[i].aiIndices[1] );
- AI_SWAP4( pcTriangle[i].aiIndices[2] );
- }
-
- // swap all vertices
- for (unsigned int i = 0; i < pcSurface->ulNumVertices*pcSurface->ulNumBaseFrames;++i)
- {
- AI_SWAP2( pcVerts->normal );
- AI_SWAP2( pcVerts->x );
- AI_SWAP2( pcVerts->y );
- AI_SWAP2( pcVerts->z );
- }
-
- // swap all texture coordinates
- for (unsigned int i = 0; i < pcSurface->ulNumVertices;++i)
- {
- AI_SWAP4( pcUVs->v );
- AI_SWAP4( pcUVs->v );
- }
+ // swap all triangles
+ for (unsigned int i = 0; i < pcSurface->ulNumTriangles;++i)
+ {
+ AI_SWAP4( pcTriangle[i].aiIndices[0] );
+ AI_SWAP4( pcTriangle[i].aiIndices[1] );
+ AI_SWAP4( pcTriangle[i].aiIndices[2] );
+ }
+
+ // swap all vertices
+ for (unsigned int i = 0; i < pcSurface->ulNumVertices*pcSurface->ulNumBaseFrames;++i)
+ {
+ AI_SWAP2( pcVerts->normal );
+ AI_SWAP2( pcVerts->x );
+ AI_SWAP2( pcVerts->y );
+ AI_SWAP2( pcVerts->z );
+ }
+
+ // swap all texture coordinates
+ for (unsigned int i = 0; i < pcSurface->ulNumVertices;++i)
+ {
+ AI_SWAP4( pcUVs->v );
+ AI_SWAP4( pcUVs->v );
+ }
#endif
- const MDC::CompressedVertex* pcCVerts = NULL;
- int16_t* mdcCompVert = NULL;
-
- // access compressed frames for large frame numbers, but never for the first
- if( this->configFrameID && pcSurface->ulNumCompFrames > 0 )
- {
- mdcCompVert = (int16_t*) ((int8_t*)pcSurface+pcSurface->ulOffsetFrameCompFrames) + this->configFrameID;
- AI_SWAP2P(mdcCompVert);
- if( *mdcCompVert >= 0 )
- {
- pcCVerts = (const MDC::CompressedVertex*)((int8_t*)pcSurface +
- pcSurface->ulOffsetCompVerts) + *mdcCompVert * pcSurface->ulNumVertices;
- }
- else mdcCompVert = NULL;
- }
-
- // copy all faces
- for (unsigned int iFace = 0; iFace < pcSurface->ulNumTriangles;++iFace,
- ++pcTriangle,++pcFaceCur)
- {
- const unsigned int iOutIndex = iFace*3;
- pcFaceCur->mNumIndices = 3;
- pcFaceCur->mIndices = new unsigned int[3];
-
- for (unsigned int iIndex = 0; iIndex < 3;++iIndex,
- ++pcVertCur,++pcUVCur,++pcNorCur)
- {
- uint32_t quak = pcTriangle->aiIndices[iIndex];
- if (quak >= pcSurface->ulNumVertices)
- {
- DefaultLogger::get()->error("MDC vertex index is out of range");
- quak = pcSurface->ulNumVertices-1;
- }
-
- // compressed vertices?
- if (mdcCompVert)
- {
- MDC::BuildVertex(*pcFrame,pcVerts[quak],pcCVerts[quak],
- *pcVertCur,*pcNorCur);
- }
- else
- {
- // copy position
- pcVertCur->x = pcVerts[quak].x * AI_MDC_BASE_SCALING;
- pcVertCur->y = pcVerts[quak].y * AI_MDC_BASE_SCALING;
- pcVertCur->z = pcVerts[quak].z * AI_MDC_BASE_SCALING;
-
- // copy normals
- MD3::LatLngNormalToVec3( pcVerts[quak].normal, &pcNorCur->x );
-
- // copy texture coordinates
- pcUVCur->x = pcUVs[quak].u;
- pcUVCur->y = 1.0f-pcUVs[quak].v; // DX to OGL
- }
- pcVertCur->x += pcFrame->localOrigin[0] ;
- pcVertCur->y += pcFrame->localOrigin[1] ;
- pcVertCur->z += pcFrame->localOrigin[2] ;
- }
-
- // swap the face order - DX to OGL
- pcFaceCur->mIndices[0] = iOutIndex + 2;
- pcFaceCur->mIndices[1] = iOutIndex + 1;
- pcFaceCur->mIndices[2] = iOutIndex + 0;
- }
-
- pcSurface = new ((int8_t*)pcSurface + pcSurface->ulOffsetEnd) MDC::Surface;
- }
-
- // create a flat node graph with a root node and one child for each surface
- if (!pScene->mNumMeshes)
- throw DeadlyImportError( "Invalid MDC file: File contains no valid mesh");
- else if (1 == pScene->mNumMeshes)
- {
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set(std::string((const char*)pScene->mMeshes[0]->mTextureCoords[3]));
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
- }
- else
- {
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mNumChildren = pScene->mNumMeshes;
- pScene->mRootNode->mChildren = new aiNode*[pScene->mNumMeshes];
- pScene->mRootNode->mName.Set("<root>");
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- {
- aiNode* pcNode = pScene->mRootNode->mChildren[i] = new aiNode();
- pcNode->mParent = pScene->mRootNode;
- pcNode->mName.Set(std::string((const char*)pScene->mMeshes[i]->mTextureCoords[3]));
- pcNode->mNumMeshes = 1;
- pcNode->mMeshes = new unsigned int[1];
- pcNode->mMeshes[0] = i;
- }
- }
-
- // make sure we invalidate the pointer to the mesh name
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mMeshes[i]->mTextureCoords[3] = NULL;
-
- // create materials
- pScene->mNumMaterials = (unsigned int)aszShaders.size();
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
- {
- aiMaterial* pcMat = new aiMaterial();
- pScene->mMaterials[i] = pcMat;
-
- const std::string& name = aszShaders[i];
-
- int iMode = (int)aiShadingMode_Gouraud;
- pcMat->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- // add a small ambient color value - RtCW seems to have one
- aiColor3D clr;
- clr.b = clr.g = clr.r = 0.05f;
- pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- if (name.length())clr.b = clr.g = clr.r = 1.0f;
- else clr.b = clr.g = clr.r = 0.6f;
-
- pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- if (name.length())
- {
- aiString path;
- path.Set(name);
- pcMat->AddProperty(&path,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- }
+ const MDC::CompressedVertex* pcCVerts = NULL;
+ int16_t* mdcCompVert = NULL;
+
+ // access compressed frames for large frame numbers, but never for the first
+ if( this->configFrameID && pcSurface->ulNumCompFrames > 0 )
+ {
+ mdcCompVert = (int16_t*) ((int8_t*)pcSurface+pcSurface->ulOffsetFrameCompFrames) + this->configFrameID;
+ AI_SWAP2P(mdcCompVert);
+ if( *mdcCompVert >= 0 )
+ {
+ pcCVerts = (const MDC::CompressedVertex*)((int8_t*)pcSurface +
+ pcSurface->ulOffsetCompVerts) + *mdcCompVert * pcSurface->ulNumVertices;
+ }
+ else mdcCompVert = NULL;
+ }
+
+ // copy all faces
+ for (unsigned int iFace = 0; iFace < pcSurface->ulNumTriangles;++iFace,
+ ++pcTriangle,++pcFaceCur)
+ {
+ const unsigned int iOutIndex = iFace*3;
+ pcFaceCur->mNumIndices = 3;
+ pcFaceCur->mIndices = new unsigned int[3];
+
+ for (unsigned int iIndex = 0; iIndex < 3;++iIndex,
+ ++pcVertCur,++pcUVCur,++pcNorCur)
+ {
+ uint32_t quak = pcTriangle->aiIndices[iIndex];
+ if (quak >= pcSurface->ulNumVertices)
+ {
+ DefaultLogger::get()->error("MDC vertex index is out of range");
+ quak = pcSurface->ulNumVertices-1;
+ }
+
+ // compressed vertices?
+ if (mdcCompVert)
+ {
+ MDC::BuildVertex(*pcFrame,pcVerts[quak],pcCVerts[quak],
+ *pcVertCur,*pcNorCur);
+ }
+ else
+ {
+ // copy position
+ pcVertCur->x = pcVerts[quak].x * AI_MDC_BASE_SCALING;
+ pcVertCur->y = pcVerts[quak].y * AI_MDC_BASE_SCALING;
+ pcVertCur->z = pcVerts[quak].z * AI_MDC_BASE_SCALING;
+
+ // copy normals
+ MD3::LatLngNormalToVec3( pcVerts[quak].normal, &pcNorCur->x );
+
+ // copy texture coordinates
+ pcUVCur->x = pcUVs[quak].u;
+ pcUVCur->y = 1.0f-pcUVs[quak].v; // DX to OGL
+ }
+ pcVertCur->x += pcFrame->localOrigin[0] ;
+ pcVertCur->y += pcFrame->localOrigin[1] ;
+ pcVertCur->z += pcFrame->localOrigin[2] ;
+ }
+
+ // swap the face order - DX to OGL
+ pcFaceCur->mIndices[0] = iOutIndex + 2;
+ pcFaceCur->mIndices[1] = iOutIndex + 1;
+ pcFaceCur->mIndices[2] = iOutIndex + 0;
+ }
+
+ pcSurface = new ((int8_t*)pcSurface + pcSurface->ulOffsetEnd) MDC::Surface;
+ }
+
+ // create a flat node graph with a root node and one child for each surface
+ if (!pScene->mNumMeshes)
+ throw DeadlyImportError( "Invalid MDC file: File contains no valid mesh");
+ else if (1 == pScene->mNumMeshes)
+ {
+ pScene->mRootNode = new aiNode();
+ pScene->mRootNode->mName.Set(std::string((const char*)pScene->mMeshes[0]->mTextureCoords[3]));
+ pScene->mRootNode->mNumMeshes = 1;
+ pScene->mRootNode->mMeshes = new unsigned int[1];
+ pScene->mRootNode->mMeshes[0] = 0;
+ }
+ else
+ {
+ pScene->mRootNode = new aiNode();
+ pScene->mRootNode->mNumChildren = pScene->mNumMeshes;
+ pScene->mRootNode->mChildren = new aiNode*[pScene->mNumMeshes];
+ pScene->mRootNode->mName.Set("<root>");
+ for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
+ {
+ aiNode* pcNode = pScene->mRootNode->mChildren[i] = new aiNode();
+ pcNode->mParent = pScene->mRootNode;
+ pcNode->mName.Set(std::string((const char*)pScene->mMeshes[i]->mTextureCoords[3]));
+ pcNode->mNumMeshes = 1;
+ pcNode->mMeshes = new unsigned int[1];
+ pcNode->mMeshes[0] = i;
+ }
+ }
+
+ // make sure we invalidate the pointer to the mesh name
+ for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
+ pScene->mMeshes[i]->mTextureCoords[3] = NULL;
+
+ // create materials
+ pScene->mNumMaterials = (unsigned int)aszShaders.size();
+ pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
+ for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
+ {
+ aiMaterial* pcMat = new aiMaterial();
+ pScene->mMaterials[i] = pcMat;
+
+ const std::string& name = aszShaders[i];
+
+ int iMode = (int)aiShadingMode_Gouraud;
+ pcMat->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
+
+ // add a small ambient color value - RtCW seems to have one
+ aiColor3D clr;
+ clr.b = clr.g = clr.r = 0.05f;
+ pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
+
+ if (name.length())clr.b = clr.g = clr.r = 1.0f;
+ else clr.b = clr.g = clr.r = 0.6f;
+
+ pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
+ pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
+
+ if (name.length())
+ {
+ aiString path;
+ path.Set(name);
+ pcMat->AddProperty(&path,AI_MATKEY_TEXTURE_DIFFUSE(0));
+ }
+ }
}
#endif // !! ASSIMP_BUILD_NO_MDC_IMPORTER