Build Assimp from source

This commit is contained in:
Dane Johnson
2021-03-15 13:46:19 -05:00
parent b7a83a2876
commit a41fcbe7f4
2126 changed files with 1385127 additions and 40 deletions

208
thirdparty/assimp/code/MDC/MDCFileData.h vendored Normal file
View File

@@ -0,0 +1,208 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2019, 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 conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file Defines the helper data structures for importing MDC files
**********************************************************************
File format specification:
http://themdcfile.planetwolfenstein.gamespy.com/MDC_File_Format.pdf
**********************************************************************
*/
#ifndef AI_MDCFILEHELPER_H_INC
#define AI_MDCFILEHELPER_H_INC
#include <assimp/types.h>
#include <assimp/mesh.h>
#include <assimp/anim.h>
#include <assimp/Compiler/pushpack1.h>
#include <stdint.h>
namespace Assimp {
namespace MDC {
// to make it easier for us, we test the magic word against both "endianesses"
#define AI_MDC_MAGIC_NUMBER_BE AI_MAKE_MAGIC("CPDI")
#define AI_MDC_MAGIC_NUMBER_LE AI_MAKE_MAGIC("IDPC")
// common limitations
#define AI_MDC_VERSION 2
#define AI_MDC_MAXQPATH 64
#define AI_MDC_MAX_BONES 128
#define AI_MDC_CVERT_BIAS 127.0f
#define AI_MDC_DELTA_SCALING 4.0f
#define AI_MDC_BASE_SCALING (1.0f / 64.0f)
// ---------------------------------------------------------------------------
/** \brief Data structure for a MDC file's main header
*/
struct Header {
uint32_t ulIdent ;
uint32_t ulVersion ;
char ucName [ AI_MDC_MAXQPATH ] ;
uint32_t ulFlags ;
uint32_t ulNumFrames ;
uint32_t ulNumTags ;
uint32_t ulNumSurfaces ;
uint32_t ulNumSkins ;
uint32_t ulOffsetBorderFrames ;
uint32_t ulOffsetTagNames ;
uint32_t ulOffsetTagFrames ;
uint32_t ulOffsetSurfaces ;
uint32_t ulOffsetEnd ;
} PACK_STRUCT ;
// ---------------------------------------------------------------------------
/** \brief Data structure for a MDC file's surface header
*/
struct Surface {
uint32_t ulIdent ;
char ucName [ AI_MDC_MAXQPATH ] ;
uint32_t ulFlags ;
uint32_t ulNumCompFrames ;
uint32_t ulNumBaseFrames ;
uint32_t ulNumShaders ;
uint32_t ulNumVertices ;
uint32_t ulNumTriangles ;
uint32_t ulOffsetTriangles ;
uint32_t ulOffsetShaders ;
uint32_t ulOffsetTexCoords ;
uint32_t ulOffsetBaseVerts ;
uint32_t ulOffsetCompVerts ;
uint32_t ulOffsetFrameBaseFrames ;
uint32_t ulOffsetFrameCompFrames ;
uint32_t ulOffsetEnd;
Surface() AI_NO_EXCEPT
: ulIdent()
, ulFlags()
, ulNumCompFrames()
, ulNumBaseFrames()
, ulNumShaders()
, ulNumVertices()
, ulNumTriangles()
, ulOffsetTriangles()
, ulOffsetShaders()
, ulOffsetTexCoords()
, ulOffsetBaseVerts()
, ulOffsetCompVerts()
, ulOffsetFrameBaseFrames()
, ulOffsetFrameCompFrames()
, ulOffsetEnd() {
ucName[AI_MDC_MAXQPATH-1] = '\0';
}
} PACK_STRUCT;
// ---------------------------------------------------------------------------
/** \brief Data structure for a MDC frame
*/
struct Frame {
//! bounding box minimum coords
aiVector3D bboxMin ;
//! bounding box maximum coords
aiVector3D bboxMax ;
//! local origin of the frame
aiVector3D localOrigin ;
//! radius of the BB
float radius ;
//! Name of the frame
char name [ 16 ] ;
} /*PACK_STRUCT*/;
// ---------------------------------------------------------------------------
/** \brief Data structure for a MDC triangle
*/
struct Triangle {
uint32_t aiIndices[3];
} PACK_STRUCT;
// ---------------------------------------------------------------------------
/** \brief Data structure for a MDC texture coordinate
*/
struct TexturCoord {
float u,v;
} PACK_STRUCT;
// ---------------------------------------------------------------------------
/** \brief Data structure for a MDC base vertex
*/
struct BaseVertex {
int16_t x,y,z;
uint16_t normal;
} PACK_STRUCT;
// ---------------------------------------------------------------------------
/** \brief Data structure for a MDC compressed vertex
*/
struct CompressedVertex {
uint8_t xd,yd,zd,nd;
} PACK_STRUCT;
// ---------------------------------------------------------------------------
/** \brief Data structure for a MDC shader
*/
struct Shader {
char ucName [ AI_MDC_MAXQPATH ] ;
uint32_t ulPath;
} PACK_STRUCT;
#include <assimp/Compiler/poppack1.h>
// ---------------------------------------------------------------------------
/** Build a floating point vertex from the compressed data in MDC files
*/
void BuildVertex(const Frame& frame,
const BaseVertex& bvert,
const CompressedVertex& cvert,
aiVector3D& vXYZOut,
aiVector3D& vNorOut);
}
}
#endif // !! AI_MDCFILEHELPER_H_INC

495
thirdparty/assimp/code/MDC/MDCLoader.cpp vendored Normal file
View File

@@ -0,0 +1,495 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2019, 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
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file Implementation of the MDC importer class */
#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
// internal headers
#include "MDC/MDCLoader.h"
#include "MD3/MD3FileData.h"
#include "MDC/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 <assimp/importerdesc.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"
};
// ------------------------------------------------------------------------------------------------
void MDC::BuildVertex(const Frame& frame,
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];
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
MDCImporter::MDCImporter()
: configFrameID(),
pcHeader(),
mBuffer(),
fileSize()
{
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
MDCImporter::~MDCImporter()
{
}
// ------------------------------------------------------------------------------------------------
// 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 aiImporterDesc* MDCImporter::GetInfo () const
{
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) {
ASSIMP_LOG_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);
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))
{
throw DeadlyImportError("Some of the offset values in the MDC surface header "
"are invalid and point somewhere behind the file.");
}
}
// ------------------------------------------------------------------------------------------------
// 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);
}
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void MDCImporter::InternReadFile(
const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
{
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.
pcMesh->mName.Set(std::string(pcSurface->ucName
, strnlen(pcSurface->ucName, AI_MDC_MAXQPATH - 1)));
// 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,
::strnlen(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 );
}
#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)
{
ASSIMP_LOG_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 = ai_real( 1.0 )-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();
if ( nullptr != pScene->mMeshes[0] ) {
pScene->mRootNode->mName = pScene->mMeshes[0]->mName;
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 = pScene->mMeshes[i]->mName;
pcNode->mNumMeshes = 1;
pcNode->mMeshes = new unsigned int[1];
pcNode->mMeshes[0] = i;
}
}
// 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

130
thirdparty/assimp/code/MDC/MDCLoader.h vendored Normal file
View File

@@ -0,0 +1,130 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2019, 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 conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file MDCLoader.h
* @brief Definition of the MDC importer class.
*/
#ifndef AI_MDCLOADER_H_INCLUDED
#define AI_MDCLOADER_H_INCLUDED
#include <assimp/types.h>
#include <assimp/BaseImporter.h>
#include "MDCFileData.h"
#include <assimp/ByteSwapper.h>
namespace Assimp {
using namespace MDC;
// ---------------------------------------------------------------------------
/** Importer class to load the RtCW MDC file format
*/
class MDCImporter : public BaseImporter
{
public:
MDCImporter();
~MDCImporter();
public:
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
// -------------------------------------------------------------------
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list.
*/
void SetupProperties(const Importer* pImp);
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
*/
const aiImporterDesc* GetInfo () const;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
protected:
// -------------------------------------------------------------------
/** Validate the header of the file
*/
void ValidateHeader();
// -------------------------------------------------------------------
/** Validate the header of a MDC surface
*/
void ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf);
protected:
/** Configuration option: frame to be loaded */
unsigned int configFrameID;
/** Header of the MDC file */
BE_NCONST MDC::Header* pcHeader;
/** Buffer to hold the loaded file */
unsigned char* mBuffer;
/** size of the file, in bytes */
unsigned int fileSize;
};
} // end of namespace Assimp
#endif // AI_3DSIMPORTER_H_INC

View File

@@ -0,0 +1,299 @@
/* -----------------------------------------------------------------------------
PicoModel Library
Copyright (c) 2002, Randy Reddig & seaw0lf
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
Neither the names of the copyright holders nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------- */
#if (!defined MDC_NORMAL_TABLE_INCLUDED)
#define MDC_NORMAL_TABLE_INCLUDED
/* mdc decoding normal table */
float mdcNormals[ 256 ][ 3 ] =
{
{ 1.000000f, 0.000000f, 0.000000f },
{ 0.980785f, 0.195090f, 0.000000f },
{ 0.923880f, 0.382683f, 0.000000f },
{ 0.831470f, 0.555570f, 0.000000f },
{ 0.707107f, 0.707107f, 0.000000f },
{ 0.555570f, 0.831470f, 0.000000f },
{ 0.382683f, 0.923880f, 0.000000f },
{ 0.195090f, 0.980785f, 0.000000f },
{ -0.000000f, 1.000000f, 0.000000f },
{ -0.195090f, 0.980785f, 0.000000f },
{ -0.382683f, 0.923880f, 0.000000f },
{ -0.555570f, 0.831470f, 0.000000f },
{ -0.707107f, 0.707107f, 0.000000f },
{ -0.831470f, 0.555570f, 0.000000f },
{ -0.923880f, 0.382683f, 0.000000f },
{ -0.980785f, 0.195090f, 0.000000f },
{ -1.000000f, -0.000000f, 0.000000f },
{ -0.980785f, -0.195090f, 0.000000f },
{ -0.923880f, -0.382683f, 0.000000f },
{ -0.831470f, -0.555570f, 0.000000f },
{ -0.707107f, -0.707107f, 0.000000f },
{ -0.555570f, -0.831469f, 0.000000f },
{ -0.382684f, -0.923880f, 0.000000f },
{ -0.195090f, -0.980785f, 0.000000f },
{ 0.000000f, -1.000000f, 0.000000f },
{ 0.195090f, -0.980785f, 0.000000f },
{ 0.382684f, -0.923879f, 0.000000f },
{ 0.555570f, -0.831470f, 0.000000f },
{ 0.707107f, -0.707107f, 0.000000f },
{ 0.831470f, -0.555570f, 0.000000f },
{ 0.923880f, -0.382683f, 0.000000f },
{ 0.980785f, -0.195090f, 0.000000f },
{ 0.980785f, 0.000000f, -0.195090f },
{ 0.956195f, 0.218245f, -0.195090f },
{ 0.883657f, 0.425547f, -0.195090f },
{ 0.766809f, 0.611510f, -0.195090f },
{ 0.611510f, 0.766809f, -0.195090f },
{ 0.425547f, 0.883657f, -0.195090f },
{ 0.218245f, 0.956195f, -0.195090f },
{ -0.000000f, 0.980785f, -0.195090f },
{ -0.218245f, 0.956195f, -0.195090f },
{ -0.425547f, 0.883657f, -0.195090f },
{ -0.611510f, 0.766809f, -0.195090f },
{ -0.766809f, 0.611510f, -0.195090f },
{ -0.883657f, 0.425547f, -0.195090f },
{ -0.956195f, 0.218245f, -0.195090f },
{ -0.980785f, -0.000000f, -0.195090f },
{ -0.956195f, -0.218245f, -0.195090f },
{ -0.883657f, -0.425547f, -0.195090f },
{ -0.766809f, -0.611510f, -0.195090f },
{ -0.611510f, -0.766809f, -0.195090f },
{ -0.425547f, -0.883657f, -0.195090f },
{ -0.218245f, -0.956195f, -0.195090f },
{ 0.000000f, -0.980785f, -0.195090f },
{ 0.218245f, -0.956195f, -0.195090f },
{ 0.425547f, -0.883657f, -0.195090f },
{ 0.611510f, -0.766809f, -0.195090f },
{ 0.766809f, -0.611510f, -0.195090f },
{ 0.883657f, -0.425547f, -0.195090f },
{ 0.956195f, -0.218245f, -0.195090f },
{ 0.923880f, 0.000000f, -0.382683f },
{ 0.892399f, 0.239118f, -0.382683f },
{ 0.800103f, 0.461940f, -0.382683f },
{ 0.653281f, 0.653281f, -0.382683f },
{ 0.461940f, 0.800103f, -0.382683f },
{ 0.239118f, 0.892399f, -0.382683f },
{ -0.000000f, 0.923880f, -0.382683f },
{ -0.239118f, 0.892399f, -0.382683f },
{ -0.461940f, 0.800103f, -0.382683f },
{ -0.653281f, 0.653281f, -0.382683f },
{ -0.800103f, 0.461940f, -0.382683f },
{ -0.892399f, 0.239118f, -0.382683f },
{ -0.923880f, -0.000000f, -0.382683f },
{ -0.892399f, -0.239118f, -0.382683f },
{ -0.800103f, -0.461940f, -0.382683f },
{ -0.653282f, -0.653281f, -0.382683f },
{ -0.461940f, -0.800103f, -0.382683f },
{ -0.239118f, -0.892399f, -0.382683f },
{ 0.000000f, -0.923880f, -0.382683f },
{ 0.239118f, -0.892399f, -0.382683f },
{ 0.461940f, -0.800103f, -0.382683f },
{ 0.653281f, -0.653282f, -0.382683f },
{ 0.800103f, -0.461940f, -0.382683f },
{ 0.892399f, -0.239117f, -0.382683f },
{ 0.831470f, 0.000000f, -0.555570f },
{ 0.790775f, 0.256938f, -0.555570f },
{ 0.672673f, 0.488726f, -0.555570f },
{ 0.488726f, 0.672673f, -0.555570f },
{ 0.256938f, 0.790775f, -0.555570f },
{ -0.000000f, 0.831470f, -0.555570f },
{ -0.256938f, 0.790775f, -0.555570f },
{ -0.488726f, 0.672673f, -0.555570f },
{ -0.672673f, 0.488726f, -0.555570f },
{ -0.790775f, 0.256938f, -0.555570f },
{ -0.831470f, -0.000000f, -0.555570f },
{ -0.790775f, -0.256938f, -0.555570f },
{ -0.672673f, -0.488726f, -0.555570f },
{ -0.488725f, -0.672673f, -0.555570f },
{ -0.256938f, -0.790775f, -0.555570f },
{ 0.000000f, -0.831470f, -0.555570f },
{ 0.256938f, -0.790775f, -0.555570f },
{ 0.488725f, -0.672673f, -0.555570f },
{ 0.672673f, -0.488726f, -0.555570f },
{ 0.790775f, -0.256938f, -0.555570f },
{ 0.707107f, 0.000000f, -0.707107f },
{ 0.653281f, 0.270598f, -0.707107f },
{ 0.500000f, 0.500000f, -0.707107f },
{ 0.270598f, 0.653281f, -0.707107f },
{ -0.000000f, 0.707107f, -0.707107f },
{ -0.270598f, 0.653282f, -0.707107f },
{ -0.500000f, 0.500000f, -0.707107f },
{ -0.653281f, 0.270598f, -0.707107f },
{ -0.707107f, -0.000000f, -0.707107f },
{ -0.653281f, -0.270598f, -0.707107f },
{ -0.500000f, -0.500000f, -0.707107f },
{ -0.270598f, -0.653281f, -0.707107f },
{ 0.000000f, -0.707107f, -0.707107f },
{ 0.270598f, -0.653281f, -0.707107f },
{ 0.500000f, -0.500000f, -0.707107f },
{ 0.653282f, -0.270598f, -0.707107f },
{ 0.555570f, 0.000000f, -0.831470f },
{ 0.481138f, 0.277785f, -0.831470f },
{ 0.277785f, 0.481138f, -0.831470f },
{ -0.000000f, 0.555570f, -0.831470f },
{ -0.277785f, 0.481138f, -0.831470f },
{ -0.481138f, 0.277785f, -0.831470f },
{ -0.555570f, -0.000000f, -0.831470f },
{ -0.481138f, -0.277785f, -0.831470f },
{ -0.277785f, -0.481138f, -0.831470f },
{ 0.000000f, -0.555570f, -0.831470f },
{ 0.277785f, -0.481138f, -0.831470f },
{ 0.481138f, -0.277785f, -0.831470f },
{ 0.382683f, 0.000000f, -0.923880f },
{ 0.270598f, 0.270598f, -0.923880f },
{ -0.000000f, 0.382683f, -0.923880f },
{ -0.270598f, 0.270598f, -0.923880f },
{ -0.382683f, -0.000000f, -0.923880f },
{ -0.270598f, -0.270598f, -0.923880f },
{ 0.000000f, -0.382683f, -0.923880f },
{ 0.270598f, -0.270598f, -0.923880f },
{ 0.195090f, 0.000000f, -0.980785f },
{ -0.000000f, 0.195090f, -0.980785f },
{ -0.195090f, -0.000000f, -0.980785f },
{ 0.000000f, -0.195090f, -0.980785f },
{ 0.980785f, 0.000000f, 0.195090f },
{ 0.956195f, 0.218245f, 0.195090f },
{ 0.883657f, 0.425547f, 0.195090f },
{ 0.766809f, 0.611510f, 0.195090f },
{ 0.611510f, 0.766809f, 0.195090f },
{ 0.425547f, 0.883657f, 0.195090f },
{ 0.218245f, 0.956195f, 0.195090f },
{ -0.000000f, 0.980785f, 0.195090f },
{ -0.218245f, 0.956195f, 0.195090f },
{ -0.425547f, 0.883657f, 0.195090f },
{ -0.611510f, 0.766809f, 0.195090f },
{ -0.766809f, 0.611510f, 0.195090f },
{ -0.883657f, 0.425547f, 0.195090f },
{ -0.956195f, 0.218245f, 0.195090f },
{ -0.980785f, -0.000000f, 0.195090f },
{ -0.956195f, -0.218245f, 0.195090f },
{ -0.883657f, -0.425547f, 0.195090f },
{ -0.766809f, -0.611510f, 0.195090f },
{ -0.611510f, -0.766809f, 0.195090f },
{ -0.425547f, -0.883657f, 0.195090f },
{ -0.218245f, -0.956195f, 0.195090f },
{ 0.000000f, -0.980785f, 0.195090f },
{ 0.218245f, -0.956195f, 0.195090f },
{ 0.425547f, -0.883657f, 0.195090f },
{ 0.611510f, -0.766809f, 0.195090f },
{ 0.766809f, -0.611510f, 0.195090f },
{ 0.883657f, -0.425547f, 0.195090f },
{ 0.956195f, -0.218245f, 0.195090f },
{ 0.923880f, 0.000000f, 0.382683f },
{ 0.892399f, 0.239118f, 0.382683f },
{ 0.800103f, 0.461940f, 0.382683f },
{ 0.653281f, 0.653281f, 0.382683f },
{ 0.461940f, 0.800103f, 0.382683f },
{ 0.239118f, 0.892399f, 0.382683f },
{ -0.000000f, 0.923880f, 0.382683f },
{ -0.239118f, 0.892399f, 0.382683f },
{ -0.461940f, 0.800103f, 0.382683f },
{ -0.653281f, 0.653281f, 0.382683f },
{ -0.800103f, 0.461940f, 0.382683f },
{ -0.892399f, 0.239118f, 0.382683f },
{ -0.923880f, -0.000000f, 0.382683f },
{ -0.892399f, -0.239118f, 0.382683f },
{ -0.800103f, -0.461940f, 0.382683f },
{ -0.653282f, -0.653281f, 0.382683f },
{ -0.461940f, -0.800103f, 0.382683f },
{ -0.239118f, -0.892399f, 0.382683f },
{ 0.000000f, -0.923880f, 0.382683f },
{ 0.239118f, -0.892399f, 0.382683f },
{ 0.461940f, -0.800103f, 0.382683f },
{ 0.653281f, -0.653282f, 0.382683f },
{ 0.800103f, -0.461940f, 0.382683f },
{ 0.892399f, -0.239117f, 0.382683f },
{ 0.831470f, 0.000000f, 0.555570f },
{ 0.790775f, 0.256938f, 0.555570f },
{ 0.672673f, 0.488726f, 0.555570f },
{ 0.488726f, 0.672673f, 0.555570f },
{ 0.256938f, 0.790775f, 0.555570f },
{ -0.000000f, 0.831470f, 0.555570f },
{ -0.256938f, 0.790775f, 0.555570f },
{ -0.488726f, 0.672673f, 0.555570f },
{ -0.672673f, 0.488726f, 0.555570f },
{ -0.790775f, 0.256938f, 0.555570f },
{ -0.831470f, -0.000000f, 0.555570f },
{ -0.790775f, -0.256938f, 0.555570f },
{ -0.672673f, -0.488726f, 0.555570f },
{ -0.488725f, -0.672673f, 0.555570f },
{ -0.256938f, -0.790775f, 0.555570f },
{ 0.000000f, -0.831470f, 0.555570f },
{ 0.256938f, -0.790775f, 0.555570f },
{ 0.488725f, -0.672673f, 0.555570f },
{ 0.672673f, -0.488726f, 0.555570f },
{ 0.790775f, -0.256938f, 0.555570f },
{ 0.707107f, 0.000000f, 0.707107f },
{ 0.653281f, 0.270598f, 0.707107f },
{ 0.500000f, 0.500000f, 0.707107f },
{ 0.270598f, 0.653281f, 0.707107f },
{ -0.000000f, 0.707107f, 0.707107f },
{ -0.270598f, 0.653282f, 0.707107f },
{ -0.500000f, 0.500000f, 0.707107f },
{ -0.653281f, 0.270598f, 0.707107f },
{ -0.707107f, -0.000000f, 0.707107f },
{ -0.653281f, -0.270598f, 0.707107f },
{ -0.500000f, -0.500000f, 0.707107f },
{ -0.270598f, -0.653281f, 0.707107f },
{ 0.000000f, -0.707107f, 0.707107f },
{ 0.270598f, -0.653281f, 0.707107f },
{ 0.500000f, -0.500000f, 0.707107f },
{ 0.653282f, -0.270598f, 0.707107f },
{ 0.555570f, 0.000000f, 0.831470f },
{ 0.481138f, 0.277785f, 0.831470f },
{ 0.277785f, 0.481138f, 0.831470f },
{ -0.000000f, 0.555570f, 0.831470f },
{ -0.277785f, 0.481138f, 0.831470f },
{ -0.481138f, 0.277785f, 0.831470f },
{ -0.555570f, -0.000000f, 0.831470f },
{ -0.481138f, -0.277785f, 0.831470f },
{ -0.277785f, -0.481138f, 0.831470f },
{ 0.000000f, -0.555570f, 0.831470f },
{ 0.277785f, -0.481138f, 0.831470f },
{ 0.481138f, -0.277785f, 0.831470f },
{ 0.382683f, 0.000000f, 0.923880f },
{ 0.270598f, 0.270598f, 0.923880f },
{ -0.000000f, 0.382683f, 0.923880f },
{ -0.270598f, 0.270598f, 0.923880f },
{ -0.382683f, -0.000000f, 0.923880f },
{ -0.270598f, -0.270598f, 0.923880f },
{ 0.000000f, -0.382683f, 0.923880f },
{ 0.270598f, -0.270598f, 0.923880f },
{ 0.195090f, 0.000000f, 0.980785f },
{ -0.000000f, 0.195090f, 0.980785f },
{ -0.195090f, -0.000000f, 0.980785f },
{ 0.000000f, -0.195090f, 0.980785f }
};
#endif // !! MDC_NORMAL_TABLE_INCLUDED