diff options
author | sanine <sanine.not@pm.me> | 2022-04-16 11:55:09 -0500 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2022-04-16 11:55:09 -0500 |
commit | db81b925d776103326128bf629cbdda576a223e7 (patch) | |
tree | 58bea8155c686733310009f6bed7363f91fbeb9d /libs/assimp/code/AssetLib/MDC | |
parent | 55860037b14fb3893ba21cf2654c83d349cc1082 (diff) |
move 3rd-party librarys into libs/ and add built-in honeysuckle
Diffstat (limited to 'libs/assimp/code/AssetLib/MDC')
-rw-r--r-- | libs/assimp/code/AssetLib/MDC/MDCFileData.h | 208 | ||||
-rw-r--r-- | libs/assimp/code/AssetLib/MDC/MDCLoader.cpp | 460 | ||||
-rw-r--r-- | libs/assimp/code/AssetLib/MDC/MDCLoader.h | 120 | ||||
-rw-r--r-- | libs/assimp/code/AssetLib/MDC/MDCNormalTable.h | 299 |
4 files changed, 1087 insertions, 0 deletions
diff --git a/libs/assimp/code/AssetLib/MDC/MDCFileData.h b/libs/assimp/code/AssetLib/MDC/MDCFileData.h new file mode 100644 index 0000000..36c589e --- /dev/null +++ b/libs/assimp/code/AssetLib/MDC/MDCFileData.h @@ -0,0 +1,208 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, 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 diff --git a/libs/assimp/code/AssetLib/MDC/MDCLoader.cpp b/libs/assimp/code/AssetLib/MDC/MDCLoader.cpp new file mode 100644 index 0000000..7810800 --- /dev/null +++ b/libs/assimp/code/AssetLib/MDC/MDCLoader.cpp @@ -0,0 +1,460 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2022, 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 "AssetLib/MDC/MDCLoader.h" +#include "AssetLib/MD3/MD3FileData.h" +#include "AssetLib/MDC/MDCNormalTable.h" // shouldn't be included by other units + +#include <assimp/importerdesc.h> +#include <assimp/scene.h> +#include <assimp/DefaultLogger.hpp> +#include <assimp/IOSystem.hpp> +#include <assimp/Importer.hpp> +#include <assimp/StringUtils.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() { + // empty +} + +// ------------------------------------------------------------------------------------------------ +// Destructor, private as well +MDCImporter::~MDCImporter() { + // empty +} + +// ------------------------------------------------------------------------------------------------ +// Returns whether the class can handle the format of the given file. +bool MDCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { + static const uint32_t tokens[] = { AI_MDC_MAGIC_NUMBER_LE }; + return CheckMagicToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens)); +} + +// ------------------------------------------------------------------------------------------------ +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) { + throw DeadlyImportError("Invalid MDC magic word: expected IDPC, found ", + ai_str_toprintable((char *)&pcHeader->ulIdent, 4)); + } + + 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() == nullptr) { + throw DeadlyImportError("Failed to open MDC file ", pFile, "."); + } + + // check whether the mdc file is large enough to contain the file header + fileSize = static_cast<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 = reinterpret_cast<BE_NCONST MDC::Surface *>(mBuffer + pcHeader->ulOffsetSurfaces); + 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 = reinterpret_cast<BE_NCONST MDC::Surface *>((BE_NCONST int8_t *)pcSurface2 + pcSurface2->ulOffsetEnd); + } + 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] = nullptr; + } + + // 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->u); + AI_SWAP4(pcUVs->v); + } + +#endif + + const MDC::CompressedVertex *pcCVerts = nullptr; + int16_t *mdcCompVert = nullptr; + + // 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 = nullptr; + } + + // 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 = reinterpret_cast<BE_NCONST MDC::Surface *>((BE_NCONST int8_t *)pcSurface + pcSurface->ulOffsetEnd); + } + + // 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)); + } + } + + // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system + pScene->mRootNode->mTransformation = aiMatrix4x4( + 1.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, -1.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 1.f); +} + +#endif // !! ASSIMP_BUILD_NO_MDC_IMPORTER diff --git a/libs/assimp/code/AssetLib/MDC/MDCLoader.h b/libs/assimp/code/AssetLib/MDC/MDCLoader.h new file mode 100644 index 0000000..6e67cd1 --- /dev/null +++ b/libs/assimp/code/AssetLib/MDC/MDCLoader.h @@ -0,0 +1,120 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2022, 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 "MDCFileData.h" +#include <assimp/BaseImporter.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() override; + + // ------------------------------------------------------------------- + /** 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 override; + + // ------------------------------------------------------------------- + /** 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) override; + +protected: + // ------------------------------------------------------------------- + /** Return importer meta information. + * See #BaseImporter::GetInfo for the details + */ + const aiImporterDesc *GetInfo() const override; + + // ------------------------------------------------------------------- + /** Imports the given file into the given scene structure. + * See BaseImporter::InternReadFile() for details + */ + void InternReadFile(const std::string &pFile, aiScene *pScene, + IOSystem *pIOHandler) override; + + // ------------------------------------------------------------------- + /** 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 diff --git a/libs/assimp/code/AssetLib/MDC/MDCNormalTable.h b/libs/assimp/code/AssetLib/MDC/MDCNormalTable.h new file mode 100644 index 0000000..c96eba7 --- /dev/null +++ b/libs/assimp/code/AssetLib/MDC/MDCNormalTable.h @@ -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 */ +const 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 |