vrshoot

diff libs/assimp/MDCLoader.cpp @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libs/assimp/MDCLoader.cpp	Sat Feb 01 19:58:19 2014 +0200
     1.3 @@ -0,0 +1,482 @@
     1.4 +/*
     1.5 +---------------------------------------------------------------------------
     1.6 +Open Asset Import Library (assimp)
     1.7 +---------------------------------------------------------------------------
     1.8 +
     1.9 +Copyright (c) 2006-2012, assimp team
    1.10 +
    1.11 +All rights reserved.
    1.12 +
    1.13 +Redistribution and use of this software in source and binary forms, 
    1.14 +with or without modification, are permitted provided that the following 
    1.15 +conditions are met:
    1.16 +
    1.17 +* Redistributions of source code must retain the above
    1.18 +  copyright notice, this list of conditions and the
    1.19 +  following disclaimer.
    1.20 +
    1.21 +* Redistributions in binary form must reproduce the above
    1.22 +  copyright notice, this list of conditions and the
    1.23 +  following disclaimer in the documentation and/or other
    1.24 +  materials provided with the distribution.
    1.25 +
    1.26 +* Neither the name of the assimp team, nor the names of its
    1.27 +  contributors may be used to endorse or promote products
    1.28 +  derived from this software without specific prior
    1.29 +  written permission of the assimp team.
    1.30 +
    1.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    1.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    1.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    1.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    1.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
    1.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    1.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    1.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.42 +---------------------------------------------------------------------------
    1.43 +*/
    1.44 +
    1.45 +/** @file Implementation of the MDC importer class */
    1.46 +
    1.47 +#include "AssimpPCH.h"
    1.48 +#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
    1.49 +
    1.50 +// internal headers
    1.51 +#include "MDCLoader.h"
    1.52 +#include "MD3FileData.h"
    1.53 +#include "MDCNormalTable.h" // shouldn't be included by other units
    1.54 +
    1.55 +using namespace Assimp;
    1.56 +using namespace Assimp::MDC;
    1.57 +
    1.58 +static const aiImporterDesc desc = {
    1.59 +	"Return To Castle Wolfenstein Mesh Importer",
    1.60 +	"",
    1.61 +	"",
    1.62 +	"",
    1.63 +	aiImporterFlags_SupportBinaryFlavour,
    1.64 +	0,
    1.65 +	0,
    1.66 +	0,
    1.67 +	0,
    1.68 +	"mdc" 
    1.69 +};
    1.70 +
    1.71 +// ------------------------------------------------------------------------------------------------
    1.72 +void MDC::BuildVertex(const Frame& frame,
    1.73 +	const BaseVertex& bvert,
    1.74 +	const CompressedVertex& cvert,
    1.75 +	aiVector3D& vXYZOut, 
    1.76 +	aiVector3D& vNorOut)
    1.77 +{
    1.78 +	// compute the position
    1.79 +	const float xd = (cvert.xd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
    1.80 +	const float yd = (cvert.yd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
    1.81 +	const float zd = (cvert.zd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
    1.82 +	vXYZOut.x = frame.localOrigin.x + AI_MDC_BASE_SCALING * (bvert.x + xd);
    1.83 +	vXYZOut.y = frame.localOrigin.y + AI_MDC_BASE_SCALING * (bvert.y + yd);
    1.84 +	vXYZOut.z = frame.localOrigin.z + AI_MDC_BASE_SCALING * (bvert.z + zd);
    1.85 +
    1.86 +	// compute the normal vector .. ehm ... lookup it in the table :-)
    1.87 +	vNorOut.x = mdcNormals[cvert.nd][0];
    1.88 +	vNorOut.y = mdcNormals[cvert.nd][1];
    1.89 +	vNorOut.z = mdcNormals[cvert.nd][2];
    1.90 +}
    1.91 +
    1.92 +// ------------------------------------------------------------------------------------------------
    1.93 +// Constructor to be privately used by Importer
    1.94 +MDCImporter::MDCImporter()
    1.95 +{
    1.96 +}
    1.97 +
    1.98 +// ------------------------------------------------------------------------------------------------
    1.99 +// Destructor, private as well 
   1.100 +MDCImporter::~MDCImporter()
   1.101 +{
   1.102 +}
   1.103 +// ------------------------------------------------------------------------------------------------
   1.104 +// Returns whether the class can handle the format of the given file. 
   1.105 +bool MDCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
   1.106 +{
   1.107 +	const std::string extension = GetExtension(pFile);
   1.108 +	if (extension == "mdc")
   1.109 +		return true;
   1.110 +
   1.111 +	// if check for extension is not enough, check for the magic tokens 
   1.112 +	if (!extension.length() || checkSig) {
   1.113 +		uint32_t tokens[1]; 
   1.114 +		tokens[0] = AI_MDC_MAGIC_NUMBER_LE;
   1.115 +		return CheckMagicToken(pIOHandler,pFile,tokens,1);
   1.116 +	}
   1.117 +	return false;
   1.118 +}
   1.119 +
   1.120 +// ------------------------------------------------------------------------------------------------
   1.121 +const aiImporterDesc* MDCImporter::GetInfo () const
   1.122 +{
   1.123 +	return &desc;
   1.124 +}
   1.125 +
   1.126 +// ------------------------------------------------------------------------------------------------
   1.127 +// Validate the header of the given MDC file
   1.128 +void MDCImporter::ValidateHeader()
   1.129 +{
   1.130 +	AI_SWAP4( this->pcHeader->ulVersion );
   1.131 +	AI_SWAP4( this->pcHeader->ulFlags );
   1.132 +	AI_SWAP4( this->pcHeader->ulNumFrames );
   1.133 +	AI_SWAP4( this->pcHeader->ulNumTags );
   1.134 +	AI_SWAP4( this->pcHeader->ulNumSurfaces );
   1.135 +	AI_SWAP4( this->pcHeader->ulNumSkins );
   1.136 +	AI_SWAP4( this->pcHeader->ulOffsetBorderFrames );
   1.137 +
   1.138 +	if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE &&
   1.139 +		pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE)
   1.140 +	{
   1.141 +		char szBuffer[5];
   1.142 +		szBuffer[0] = ((char*)&pcHeader->ulIdent)[0];
   1.143 +		szBuffer[1] = ((char*)&pcHeader->ulIdent)[1];
   1.144 +		szBuffer[2] = ((char*)&pcHeader->ulIdent)[2];
   1.145 +		szBuffer[3] = ((char*)&pcHeader->ulIdent)[3];
   1.146 +		szBuffer[4] = '\0';
   1.147 +
   1.148 +		throw DeadlyImportError("Invalid MDC magic word: should be IDPC, the "
   1.149 +			"magic word found is " + std::string( szBuffer ));
   1.150 +	}
   1.151 +
   1.152 +	if (pcHeader->ulVersion != AI_MDC_VERSION)
   1.153 +		DefaultLogger::get()->warn("Unsupported MDC file version (2 (AI_MDC_VERSION) was expected)");
   1.154 +
   1.155 +	if (pcHeader->ulOffsetBorderFrames + pcHeader->ulNumFrames * sizeof(MDC::Frame) > this->fileSize ||
   1.156 +		pcHeader->ulOffsetSurfaces + pcHeader->ulNumSurfaces * sizeof(MDC::Surface) > this->fileSize)
   1.157 +	{
   1.158 +		throw DeadlyImportError("Some of the offset values in the MDC header are invalid "
   1.159 +			"and point to something behind the file.");
   1.160 +	}
   1.161 +
   1.162 +	if (this->configFrameID >= this->pcHeader->ulNumFrames)
   1.163 +		throw DeadlyImportError("The requested frame is not available");
   1.164 +}
   1.165 +
   1.166 +// ------------------------------------------------------------------------------------------------
   1.167 +// Validate the header of a given MDC file surface
   1.168 +void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf)
   1.169 +{
   1.170 +	AI_SWAP4(pcSurf->ulFlags);
   1.171 +	AI_SWAP4(pcSurf->ulNumCompFrames);
   1.172 +	AI_SWAP4(pcSurf->ulNumBaseFrames);
   1.173 +	AI_SWAP4(pcSurf->ulNumShaders);
   1.174 +	AI_SWAP4(pcSurf->ulNumVertices);
   1.175 +	AI_SWAP4(pcSurf->ulNumTriangles);
   1.176 +	AI_SWAP4(pcSurf->ulOffsetTriangles);
   1.177 +	AI_SWAP4(pcSurf->ulOffsetTexCoords);
   1.178 +	AI_SWAP4(pcSurf->ulOffsetBaseVerts);
   1.179 +	AI_SWAP4(pcSurf->ulOffsetCompVerts);
   1.180 +	AI_SWAP4(pcSurf->ulOffsetFrameBaseFrames);
   1.181 +	AI_SWAP4(pcSurf->ulOffsetFrameCompFrames);
   1.182 +	AI_SWAP4(pcSurf->ulOffsetEnd);
   1.183 +
   1.184 +    const unsigned int iMax = this->fileSize - (unsigned int)((int8_t*)pcSurf-(int8_t*)pcHeader);
   1.185 +
   1.186 +    if (pcSurf->ulOffsetBaseVerts + pcSurf->ulNumVertices * sizeof(MDC::BaseVertex)			> iMax ||
   1.187 +        (pcSurf->ulNumCompFrames && pcSurf->ulOffsetCompVerts + pcSurf->ulNumVertices * sizeof(MDC::CompressedVertex)	> iMax) ||
   1.188 +        pcSurf->ulOffsetTriangles + pcSurf->ulNumTriangles * sizeof(MDC::Triangle)			> iMax ||
   1.189 +        pcSurf->ulOffsetTexCoords + pcSurf->ulNumVertices * sizeof(MDC::TexturCoord)		> iMax ||
   1.190 +        pcSurf->ulOffsetShaders + pcSurf->ulNumShaders * sizeof(MDC::Shader)				> iMax ||
   1.191 +        pcSurf->ulOffsetFrameBaseFrames + pcSurf->ulNumBaseFrames * 2						> iMax ||
   1.192 +        (pcSurf->ulNumCompFrames && pcSurf->ulOffsetFrameCompFrames + pcSurf->ulNumCompFrames * 2	> iMax))
   1.193 +    {
   1.194 +        throw DeadlyImportError("Some of the offset values in the MDC surface header "
   1.195 +            "are invalid and point somewhere behind the file.");
   1.196 +    }
   1.197 +}
   1.198 +
   1.199 +// ------------------------------------------------------------------------------------------------
   1.200 +// Setup configuration properties
   1.201 +void MDCImporter::SetupProperties(const Importer* pImp)
   1.202 +{
   1.203 +	// The AI_CONFIG_IMPORT_MDC_KEYFRAME option overrides the
   1.204 +	// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
   1.205 +	if(static_cast<unsigned int>(-1) == (configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MDC_KEYFRAME,-1))){
   1.206 +		configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
   1.207 +	}
   1.208 +}
   1.209 +
   1.210 +// ------------------------------------------------------------------------------------------------
   1.211 +// Imports the given file into the given scene structure. 
   1.212 +void MDCImporter::InternReadFile( 
   1.213 +	const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
   1.214 +{
   1.215 +	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
   1.216 +
   1.217 +	// Check whether we can read from the file
   1.218 +	if( file.get() == NULL)
   1.219 +		throw DeadlyImportError( "Failed to open MDC file " + pFile + ".");
   1.220 +
   1.221 +	// check whether the mdc file is large enough to contain the file header
   1.222 +	fileSize = (unsigned int)file->FileSize();
   1.223 +	if( fileSize < sizeof(MDC::Header))
   1.224 +		throw DeadlyImportError( "MDC File is too small.");
   1.225 +
   1.226 +	std::vector<unsigned char> mBuffer2(fileSize);
   1.227 +	file->Read( &mBuffer2[0], 1, fileSize);
   1.228 +	mBuffer = &mBuffer2[0];
   1.229 +
   1.230 +	// validate the file header
   1.231 +	this->pcHeader = (BE_NCONST MDC::Header*)this->mBuffer;
   1.232 +	this->ValidateHeader();
   1.233 +
   1.234 +	std::vector<std::string> aszShaders;
   1.235 +
   1.236 +	// get a pointer to the frame we want to read
   1.237 +	BE_NCONST MDC::Frame* pcFrame = (BE_NCONST MDC::Frame*)(this->mBuffer+
   1.238 +		this->pcHeader->ulOffsetBorderFrames);
   1.239 +
   1.240 +	// no need to swap the other members, we won't need them
   1.241 +	pcFrame += configFrameID;
   1.242 +	AI_SWAP4( pcFrame->localOrigin[0] );
   1.243 +	AI_SWAP4( pcFrame->localOrigin[1] );
   1.244 +	AI_SWAP4( pcFrame->localOrigin[2] );
   1.245 +
   1.246 +	// get the number of valid surfaces
   1.247 +	BE_NCONST MDC::Surface* pcSurface, *pcSurface2;
   1.248 +	pcSurface = pcSurface2 = new (mBuffer + pcHeader->ulOffsetSurfaces) MDC::Surface;
   1.249 +	unsigned int iNumShaders = 0;
   1.250 +	for (unsigned int i = 0; i < pcHeader->ulNumSurfaces;++i)
   1.251 +	{
   1.252 +		// validate the surface header
   1.253 +		this->ValidateSurfaceHeader(pcSurface2);
   1.254 +
   1.255 +		if (pcSurface2->ulNumVertices && pcSurface2->ulNumTriangles)++pScene->mNumMeshes;
   1.256 +		iNumShaders += pcSurface2->ulNumShaders;
   1.257 +		pcSurface2 = new ((int8_t*)pcSurface2 + pcSurface2->ulOffsetEnd) MDC::Surface;
   1.258 +	}
   1.259 +	aszShaders.reserve(iNumShaders);
   1.260 +	pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
   1.261 +
   1.262 +	// necessary that we don't crash if an exception occurs
   1.263 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
   1.264 +		pScene->mMeshes[i] = NULL;
   1.265 +
   1.266 +	// now read all surfaces
   1.267 +	unsigned int iDefaultMatIndex = UINT_MAX;
   1.268 +	for (unsigned int i = 0, iNum = 0; i < pcHeader->ulNumSurfaces;++i)
   1.269 +	{
   1.270 +		if (!pcSurface->ulNumVertices || !pcSurface->ulNumTriangles)continue;
   1.271 +		aiMesh* pcMesh = pScene->mMeshes[iNum++] = new aiMesh();
   1.272 +
   1.273 +		pcMesh->mNumFaces = pcSurface->ulNumTriangles;
   1.274 +		pcMesh->mNumVertices = pcMesh->mNumFaces * 3;
   1.275 +
   1.276 +		// store the name of the surface for use as node name.
   1.277 +		// FIX: make sure there is a 0 termination
   1.278 +		const_cast<char&>(pcSurface->ucName[AI_MDC_MAXQPATH-1]) = '\0';
   1.279 +		pcMesh->mTextureCoords[3] = (aiVector3D*)pcSurface->ucName;
   1.280 +
   1.281 +		// go to the first shader in the file. ignore the others.
   1.282 +		if (pcSurface->ulNumShaders)
   1.283 +		{
   1.284 +			const MDC::Shader* pcShader = (const MDC::Shader*)((int8_t*)pcSurface + pcSurface->ulOffsetShaders);
   1.285 +			pcMesh->mMaterialIndex = (unsigned int)aszShaders.size();
   1.286 +			
   1.287 +			// create a new shader
   1.288 +			aszShaders.push_back(std::string( pcShader->ucName, std::min(
   1.289 +				::strlen(pcShader->ucName),sizeof(pcShader->ucName)) ));
   1.290 +		}
   1.291 +		// need to create a default material
   1.292 +		else if (UINT_MAX == iDefaultMatIndex)
   1.293 +		{
   1.294 +			pcMesh->mMaterialIndex = iDefaultMatIndex = (unsigned int)aszShaders.size();
   1.295 +			aszShaders.push_back(std::string());
   1.296 +		}
   1.297 +		// otherwise assign a reference to the default material
   1.298 +		else pcMesh->mMaterialIndex = iDefaultMatIndex;
   1.299 +
   1.300 +		// allocate output storage for the mesh
   1.301 +		aiVector3D* pcVertCur	= pcMesh->mVertices			= new aiVector3D[pcMesh->mNumVertices];
   1.302 +		aiVector3D* pcNorCur	= pcMesh->mNormals			= new aiVector3D[pcMesh->mNumVertices];
   1.303 +		aiVector3D* pcUVCur		= pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
   1.304 +		aiFace* pcFaceCur		= pcMesh->mFaces			= new aiFace[pcMesh->mNumFaces];
   1.305 +
   1.306 +		// create all vertices/faces
   1.307 +		BE_NCONST MDC::Triangle* pcTriangle = (BE_NCONST MDC::Triangle*)
   1.308 +			((int8_t*)pcSurface+pcSurface->ulOffsetTriangles);
   1.309 +
   1.310 +		BE_NCONST MDC::TexturCoord* const pcUVs = (BE_NCONST MDC::TexturCoord*)
   1.311 +			((int8_t*)pcSurface+pcSurface->ulOffsetTexCoords);
   1.312 +
   1.313 +		// get a pointer to the uncompressed vertices
   1.314 +		int16_t iOfs = *((int16_t*) ((int8_t*) pcSurface +
   1.315 +			pcSurface->ulOffsetFrameBaseFrames) +  this->configFrameID);
   1.316 +
   1.317 +		AI_SWAP2(iOfs);
   1.318 +
   1.319 +		BE_NCONST MDC::BaseVertex* const pcVerts = (BE_NCONST MDC::BaseVertex*)
   1.320 +			((int8_t*)pcSurface+pcSurface->ulOffsetBaseVerts) +
   1.321 +			((int)iOfs * pcSurface->ulNumVertices * 4);
   1.322 +
   1.323 +		// do the main swapping stuff ...
   1.324 +#if (defined AI_BUILD_BIG_ENDIAN)
   1.325 +
   1.326 +		// swap all triangles
   1.327 +		for (unsigned int i = 0; i < pcSurface->ulNumTriangles;++i)
   1.328 +		{
   1.329 +			AI_SWAP4( pcTriangle[i].aiIndices[0] );
   1.330 +			AI_SWAP4( pcTriangle[i].aiIndices[1] );
   1.331 +			AI_SWAP4( pcTriangle[i].aiIndices[2] );
   1.332 +		}
   1.333 +
   1.334 +		// swap all vertices
   1.335 +		for (unsigned int i = 0; i < pcSurface->ulNumVertices*pcSurface->ulNumBaseFrames;++i)
   1.336 +		{
   1.337 +			AI_SWAP2( pcVerts->normal );
   1.338 +			AI_SWAP2( pcVerts->x );
   1.339 +			AI_SWAP2( pcVerts->y );
   1.340 +			AI_SWAP2( pcVerts->z );
   1.341 +		}
   1.342 +
   1.343 +		// swap all texture coordinates
   1.344 +		for (unsigned int i = 0; i < pcSurface->ulNumVertices;++i)
   1.345 +		{
   1.346 +			AI_SWAP4( pcUVs->v );
   1.347 +			AI_SWAP4( pcUVs->v );
   1.348 +		}
   1.349 +
   1.350 +#endif
   1.351 +
   1.352 +		const MDC::CompressedVertex* pcCVerts = NULL;
   1.353 +		int16_t* mdcCompVert = NULL;
   1.354 +
   1.355 +		// access compressed frames for large frame numbers, but never for the first
   1.356 +		if( this->configFrameID && pcSurface->ulNumCompFrames > 0 )
   1.357 +		{
   1.358 +			mdcCompVert = (int16_t*) ((int8_t*)pcSurface+pcSurface->ulOffsetFrameCompFrames) + this->configFrameID;
   1.359 +			AI_SWAP2P(mdcCompVert);
   1.360 +			if( *mdcCompVert >= 0 )
   1.361 +			{
   1.362 +				pcCVerts = (const MDC::CompressedVertex*)((int8_t*)pcSurface +
   1.363 +					pcSurface->ulOffsetCompVerts) + *mdcCompVert * pcSurface->ulNumVertices;
   1.364 +			}
   1.365 +			else mdcCompVert = NULL;
   1.366 +		}
   1.367 +
   1.368 +		// copy all faces
   1.369 +		for (unsigned int iFace = 0; iFace < pcSurface->ulNumTriangles;++iFace,
   1.370 +			++pcTriangle,++pcFaceCur)
   1.371 +		{
   1.372 +			const unsigned int iOutIndex = iFace*3;
   1.373 +			pcFaceCur->mNumIndices = 3;
   1.374 +			pcFaceCur->mIndices = new unsigned int[3];
   1.375 +
   1.376 +			for (unsigned int iIndex = 0; iIndex < 3;++iIndex,
   1.377 +				++pcVertCur,++pcUVCur,++pcNorCur)
   1.378 +			{
   1.379 +				uint32_t quak = pcTriangle->aiIndices[iIndex];
   1.380 +				if (quak >= pcSurface->ulNumVertices)
   1.381 +				{
   1.382 +					DefaultLogger::get()->error("MDC vertex index is out of range");
   1.383 +					quak = pcSurface->ulNumVertices-1;
   1.384 +				}
   1.385 +
   1.386 +				// compressed vertices?
   1.387 +				if (mdcCompVert)
   1.388 +				{
   1.389 +					MDC::BuildVertex(*pcFrame,pcVerts[quak],pcCVerts[quak],
   1.390 +						*pcVertCur,*pcNorCur);
   1.391 +				}
   1.392 +				else
   1.393 +				{
   1.394 +					// copy position
   1.395 +					pcVertCur->x = pcVerts[quak].x * AI_MDC_BASE_SCALING;
   1.396 +					pcVertCur->y = pcVerts[quak].y * AI_MDC_BASE_SCALING;
   1.397 +					pcVertCur->z = pcVerts[quak].z * AI_MDC_BASE_SCALING;
   1.398 +
   1.399 +					// copy normals
   1.400 +					MD3::LatLngNormalToVec3( pcVerts[quak].normal, &pcNorCur->x );
   1.401 +
   1.402 +					// copy texture coordinates
   1.403 +					pcUVCur->x = pcUVs[quak].u;
   1.404 +					pcUVCur->y = 1.0f-pcUVs[quak].v; // DX to OGL
   1.405 +				}
   1.406 +				pcVertCur->x += pcFrame->localOrigin[0] ;
   1.407 +				pcVertCur->y += pcFrame->localOrigin[1] ;
   1.408 +				pcVertCur->z += pcFrame->localOrigin[2] ;
   1.409 +			}
   1.410 +
   1.411 +			// swap the face order - DX to OGL
   1.412 +			pcFaceCur->mIndices[0] = iOutIndex + 2;
   1.413 +			pcFaceCur->mIndices[1] = iOutIndex + 1;
   1.414 +			pcFaceCur->mIndices[2] = iOutIndex + 0;
   1.415 +		}
   1.416 +
   1.417 +		pcSurface =  new ((int8_t*)pcSurface + pcSurface->ulOffsetEnd) MDC::Surface;
   1.418 +	}
   1.419 +
   1.420 +	// create a flat node graph with a root node and one child for each surface
   1.421 +	if (!pScene->mNumMeshes)
   1.422 +		throw DeadlyImportError( "Invalid MDC file: File contains no valid mesh");
   1.423 +	else if (1 == pScene->mNumMeshes)
   1.424 +	{
   1.425 +		pScene->mRootNode = new aiNode();
   1.426 +		pScene->mRootNode->mName.Set(std::string((const char*)pScene->mMeshes[0]->mTextureCoords[3]));
   1.427 +		pScene->mRootNode->mNumMeshes = 1;
   1.428 +		pScene->mRootNode->mMeshes = new unsigned int[1];
   1.429 +		pScene->mRootNode->mMeshes[0] = 0;
   1.430 +	}
   1.431 +	else
   1.432 +	{
   1.433 +		pScene->mRootNode = new aiNode();
   1.434 +		pScene->mRootNode->mNumChildren = pScene->mNumMeshes;
   1.435 +		pScene->mRootNode->mChildren = new aiNode*[pScene->mNumMeshes];
   1.436 +		pScene->mRootNode->mName.Set("<root>");
   1.437 +		for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
   1.438 +		{
   1.439 +			aiNode* pcNode = pScene->mRootNode->mChildren[i] = new aiNode();
   1.440 +			pcNode->mParent = pScene->mRootNode;
   1.441 +			pcNode->mName.Set(std::string((const char*)pScene->mMeshes[i]->mTextureCoords[3]));
   1.442 +			pcNode->mNumMeshes = 1;
   1.443 +			pcNode->mMeshes = new unsigned int[1];
   1.444 +			pcNode->mMeshes[0] = i;
   1.445 +		}
   1.446 +	}
   1.447 +
   1.448 +	// make sure we invalidate the pointer to the mesh name
   1.449 +	for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
   1.450 +		pScene->mMeshes[i]->mTextureCoords[3] = NULL;
   1.451 +
   1.452 +	// create materials
   1.453 +	pScene->mNumMaterials = (unsigned int)aszShaders.size();
   1.454 +	pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
   1.455 +	for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
   1.456 +	{
   1.457 +		aiMaterial* pcMat = new aiMaterial();
   1.458 +		pScene->mMaterials[i] = pcMat;
   1.459 +
   1.460 +		const std::string& name = aszShaders[i];
   1.461 +
   1.462 +		int iMode = (int)aiShadingMode_Gouraud;
   1.463 +		pcMat->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
   1.464 +
   1.465 +		// add a small ambient color value - RtCW seems to have one
   1.466 +		aiColor3D clr;
   1.467 +		clr.b = clr.g = clr.r = 0.05f;
   1.468 +		pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
   1.469 +
   1.470 +		if (name.length())clr.b = clr.g = clr.r = 1.0f;
   1.471 +		else clr.b = clr.g = clr.r = 0.6f;
   1.472 +
   1.473 +		pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
   1.474 +		pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
   1.475 +
   1.476 +		if (name.length())
   1.477 +		{
   1.478 +			aiString path;
   1.479 +			path.Set(name);
   1.480 +			pcMat->AddProperty(&path,AI_MATKEY_TEXTURE_DIFFUSE(0));
   1.481 +		}
   1.482 +	}
   1.483 +}
   1.484 +
   1.485 +#endif // !! ASSIMP_BUILD_NO_MDC_IMPORTER