diff options
Diffstat (limited to 'libs/assimp/code/AssetLib/MD2')
-rw-r--r-- | libs/assimp/code/AssetLib/MD2/MD2FileData.h | 164 | ||||
-rw-r--r-- | libs/assimp/code/AssetLib/MD2/MD2Loader.cpp | 449 | ||||
-rw-r--r-- | libs/assimp/code/AssetLib/MD2/MD2Loader.h | 116 | ||||
-rw-r--r-- | libs/assimp/code/AssetLib/MD2/MD2NormalTable.h | 219 |
4 files changed, 948 insertions, 0 deletions
diff --git a/libs/assimp/code/AssetLib/MD2/MD2FileData.h b/libs/assimp/code/AssetLib/MD2/MD2FileData.h new file mode 100644 index 0000000..3bce8fe --- /dev/null +++ b/libs/assimp/code/AssetLib/MD2/MD2FileData.h @@ -0,0 +1,164 @@ +/* +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 MD2FileData.h + * @brief Defines helper data structures for importing MD2 files + * http://linux.ucla.edu/~phaethon/q3/formats/md2-schoenblum.html + */ +#ifndef AI_MD2FILEHELPER_H_INC +#define AI_MD2FILEHELPER_H_INC + +#include <assimp/types.h> +#include <stdint.h> + +#include <assimp/Compiler/pushpack1.h> + +namespace Assimp { +namespace MD2 { + +// to make it easier for us, we test the magic word against both "endianesses" +#define AI_MD2_MAGIC_NUMBER_BE AI_MAKE_MAGIC("IDP2") +#define AI_MD2_MAGIC_NUMBER_LE AI_MAKE_MAGIC("2PDI") + +// common limitations +#define AI_MD2_VERSION 15 +#define AI_MD2_MAXQPATH 64 +#define AI_MD2_MAX_FRAMES 512 +#define AI_MD2_MAX_SKINS 32 +#define AI_MD2_MAX_VERTS 2048 +#define AI_MD2_MAX_TRIANGLES 4096 + +// --------------------------------------------------------------------------- +/** \brief Data structure for the MD2 main header + */ +struct Header +{ + uint32_t magic; + uint32_t version; + uint32_t skinWidth; + uint32_t skinHeight; + uint32_t frameSize; + uint32_t numSkins; + uint32_t numVertices; + uint32_t numTexCoords; + uint32_t numTriangles; + uint32_t numGlCommands; + uint32_t numFrames; + uint32_t offsetSkins; + uint32_t offsetTexCoords; + uint32_t offsetTriangles; + uint32_t offsetFrames; + uint32_t offsetGlCommands; + uint32_t offsetEnd; + +} PACK_STRUCT; + +// --------------------------------------------------------------------------- +/** \brief Data structure for a MD2 OpenGl draw command + */ +struct GLCommand +{ + float s, t; + uint32_t vertexIndex; +} PACK_STRUCT; + +// --------------------------------------------------------------------------- +/** \brief Data structure for a MD2 triangle + */ +struct Triangle +{ + uint16_t vertexIndices[3]; + uint16_t textureIndices[3]; +} PACK_STRUCT; + +// --------------------------------------------------------------------------- +/** \brief Data structure for a MD2 vertex + */ +struct Vertex +{ + uint8_t vertex[3]; + uint8_t lightNormalIndex; +} PACK_STRUCT; + +// --------------------------------------------------------------------------- +/** \brief Data structure for a MD2 frame + */ +struct Frame +{ + float scale[3]; + float translate[3]; + char name[16]; + Vertex vertices[1]; +} PACK_STRUCT; + +// --------------------------------------------------------------------------- +/** \brief Data structure for a MD2 texture coordinate + */ +struct TexCoord +{ + uint16_t s; + uint16_t t; +} PACK_STRUCT; + +// --------------------------------------------------------------------------- +/** \brief Data structure for a MD2 skin + */ +struct Skin +{ + char name[AI_MD2_MAXQPATH]; /* texture file name */ +} PACK_STRUCT; + +#include <assimp/Compiler/poppack1.h> + + +// --------------------------------------------------------------------------- +//! Lookup a normal vector from Quake's normal lookup table +//! \param index Input index (0-161) +//! \param vOut Receives the output normal +void LookupNormalIndex(uint8_t index,aiVector3D& vOut); + + +} +} + +#endif // !! include guard + diff --git a/libs/assimp/code/AssetLib/MD2/MD2Loader.cpp b/libs/assimp/code/AssetLib/MD2/MD2Loader.cpp new file mode 100644 index 0000000..99ab3f5 --- /dev/null +++ b/libs/assimp/code/AssetLib/MD2/MD2Loader.cpp @@ -0,0 +1,449 @@ +/* +--------------------------------------------------------------------------- +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. +--------------------------------------------------------------------------- +*/ + + +#ifndef ASSIMP_BUILD_NO_MD2_IMPORTER + +/** @file Implementation of the MD2 importer class */ +#include "MD2Loader.h" +#include <assimp/ByteSwapper.h> +#include "MD2NormalTable.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 <assimp/StringUtils.h> + +#include <memory> + +using namespace Assimp; +using namespace Assimp::MD2; + +// helper macro to determine the size of an array +#if (!defined ARRAYSIZE) +# define ARRAYSIZE(_array) (int(sizeof(_array) / sizeof(_array[0]))) +#endif + +static const aiImporterDesc desc = { + "Quake II Mesh Importer", + "", + "", + "", + aiImporterFlags_SupportBinaryFlavour, + 0, + 0, + 0, + 0, + "md2" +}; + +// ------------------------------------------------------------------------------------------------ +// Helper function to lookup a normal in Quake 2's precalculated table +void MD2::LookupNormalIndex(uint8_t iNormalIndex,aiVector3D& vOut) +{ + // make sure the normal index has a valid value + if (iNormalIndex >= ARRAYSIZE(g_avNormals)) { + ASSIMP_LOG_WARN("Index overflow in Quake II normal vector list"); + iNormalIndex = ARRAYSIZE(g_avNormals) - 1; + } + vOut = *((const aiVector3D*)(&g_avNormals[iNormalIndex])); +} + + +// ------------------------------------------------------------------------------------------------ +// Constructor to be privately used by Importer +MD2Importer::MD2Importer() + : configFrameID(), + m_pcHeader(), + mBuffer(), + fileSize() +{} + +// ------------------------------------------------------------------------------------------------ +// Destructor, private as well +MD2Importer::~MD2Importer() +{} + +// ------------------------------------------------------------------------------------------------ +// Returns whether the class can handle the format of the given file. +bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const +{ + static const uint32_t tokens[] = { AI_MD2_MAGIC_NUMBER_LE }; + return CheckMagicToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens)); +} + +// ------------------------------------------------------------------------------------------------ +// Get a list of all extensions supported by this loader +const aiImporterDesc* MD2Importer::GetInfo () const +{ + return &desc; +} + +// ------------------------------------------------------------------------------------------------ +// Setup configuration properties +void MD2Importer::SetupProperties(const Importer* pImp) +{ + // The + // AI_CONFIG_IMPORT_MD2_KEYFRAME option overrides the + // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option. + configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD2_KEYFRAME,-1); + if(static_cast<unsigned int>(-1) == configFrameID){ + configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0); + } +} +// ------------------------------------------------------------------------------------------------ +// Validate the file header +void MD2Importer::ValidateHeader( ) +{ + // check magic number + if (m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE && + m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE) + { + throw DeadlyImportError("Invalid MD2 magic word: expected IDP2, found ", + ai_str_toprintable((char *)&m_pcHeader->magic, 4)); + } + + // check file format version + if (m_pcHeader->version != 8) + ASSIMP_LOG_WARN( "Unsupported MD2 file version. Continuing happily ..."); + + // check some values whether they are valid + if (0 == m_pcHeader->numFrames) + throw DeadlyImportError( "Invalid MD2 file: NUM_FRAMES is 0"); + + if (m_pcHeader->offsetEnd > (uint32_t)fileSize) + throw DeadlyImportError( "Invalid MD2 file: File is too small"); + + if (m_pcHeader->numSkins > AI_MAX_ALLOC(MD2::Skin)) { + throw DeadlyImportError("Invalid MD2 header: Too many skins, would overflow"); + } + + if (m_pcHeader->numVertices > AI_MAX_ALLOC(MD2::Vertex)) { + throw DeadlyImportError("Invalid MD2 header: Too many vertices, would overflow"); + } + + if (m_pcHeader->numTexCoords > AI_MAX_ALLOC(MD2::TexCoord)) { + throw DeadlyImportError("Invalid MD2 header: Too many texcoords, would overflow"); + } + + if (m_pcHeader->numTriangles > AI_MAX_ALLOC(MD2::Triangle)) { + throw DeadlyImportError("Invalid MD2 header: Too many triangles, would overflow"); + } + + if (m_pcHeader->numFrames > AI_MAX_ALLOC(MD2::Frame)) { + throw DeadlyImportError("Invalid MD2 header: Too many frames, would overflow"); + } + + // -1 because Frame already contains one + unsigned int frameSize = sizeof (MD2::Frame) + (m_pcHeader->numVertices - 1) * sizeof(MD2::Vertex); + + if (m_pcHeader->offsetSkins + m_pcHeader->numSkins * sizeof (MD2::Skin) >= fileSize || + m_pcHeader->offsetTexCoords + m_pcHeader->numTexCoords * sizeof (MD2::TexCoord) >= fileSize || + m_pcHeader->offsetTriangles + m_pcHeader->numTriangles * sizeof (MD2::Triangle) >= fileSize || + m_pcHeader->offsetFrames + m_pcHeader->numFrames * frameSize >= fileSize || + m_pcHeader->offsetEnd > fileSize) + { + throw DeadlyImportError("Invalid MD2 header: Some offsets are outside the file"); + } + + if (m_pcHeader->numSkins > AI_MD2_MAX_SKINS) + ASSIMP_LOG_WARN("The model contains more skins than Quake 2 supports"); + if ( m_pcHeader->numFrames > AI_MD2_MAX_FRAMES) + ASSIMP_LOG_WARN("The model contains more frames than Quake 2 supports"); + if (m_pcHeader->numVertices > AI_MD2_MAX_VERTS) + ASSIMP_LOG_WARN("The model contains more vertices than Quake 2 supports"); + + if (m_pcHeader->numFrames <= configFrameID ) + throw DeadlyImportError("MD2: The requested frame (", configFrameID, ") does not exist in the file"); +} + +// ------------------------------------------------------------------------------------------------ +// Imports the given file into the given scene structure. +void MD2Importer::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 MD2 file ", pFile, ""); + } + + // check whether the md3 file is large enough to contain + // at least the file header + fileSize = (unsigned int)file->FileSize(); + if (fileSize < sizeof(MD2::Header)) { + throw DeadlyImportError("MD2 File is too small"); + } + + std::vector<uint8_t> mBuffer2(fileSize); + file->Read(&mBuffer2[0], 1, fileSize); + mBuffer = &mBuffer2[0]; + + m_pcHeader = (BE_NCONST MD2::Header*)mBuffer; + +#ifdef AI_BUILD_BIG_ENDIAN + + ByteSwap::Swap4(&m_pcHeader->frameSize); + ByteSwap::Swap4(&m_pcHeader->magic); + ByteSwap::Swap4(&m_pcHeader->numFrames); + ByteSwap::Swap4(&m_pcHeader->numGlCommands); + ByteSwap::Swap4(&m_pcHeader->numSkins); + ByteSwap::Swap4(&m_pcHeader->numTexCoords); + ByteSwap::Swap4(&m_pcHeader->numTriangles); + ByteSwap::Swap4(&m_pcHeader->numVertices); + ByteSwap::Swap4(&m_pcHeader->offsetEnd); + ByteSwap::Swap4(&m_pcHeader->offsetFrames); + ByteSwap::Swap4(&m_pcHeader->offsetGlCommands); + ByteSwap::Swap4(&m_pcHeader->offsetSkins); + ByteSwap::Swap4(&m_pcHeader->offsetTexCoords); + ByteSwap::Swap4(&m_pcHeader->offsetTriangles); + ByteSwap::Swap4(&m_pcHeader->skinHeight); + ByteSwap::Swap4(&m_pcHeader->skinWidth); + ByteSwap::Swap4(&m_pcHeader->version); + +#endif + + ValidateHeader(); + + // there won't be more than one mesh inside the file + pScene->mNumMaterials = 1; + pScene->mRootNode = new aiNode(); + pScene->mRootNode->mNumMeshes = 1; + pScene->mRootNode->mMeshes = new unsigned int[1]; + pScene->mRootNode->mMeshes[0] = 0; + pScene->mMaterials = new aiMaterial*[1]; + pScene->mMaterials[0] = new aiMaterial(); + pScene->mNumMeshes = 1; + pScene->mMeshes = new aiMesh*[1]; + + aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh(); + pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; + + // navigate to the begin of the current frame data + BE_NCONST MD2::Frame* pcFrame = (BE_NCONST MD2::Frame*) ((uint8_t*) + m_pcHeader + m_pcHeader->offsetFrames + (m_pcHeader->frameSize * configFrameID)); + + // navigate to the begin of the triangle data + MD2::Triangle* pcTriangles = (MD2::Triangle*) ((uint8_t*) + m_pcHeader + m_pcHeader->offsetTriangles); + + // navigate to the begin of the tex coords data + BE_NCONST MD2::TexCoord* pcTexCoords = (BE_NCONST MD2::TexCoord*) ((uint8_t*) + m_pcHeader + m_pcHeader->offsetTexCoords); + + // navigate to the begin of the vertex data + BE_NCONST MD2::Vertex* pcVerts = (BE_NCONST MD2::Vertex*) (pcFrame->vertices); + +#ifdef AI_BUILD_BIG_ENDIAN + for (uint32_t i = 0; i< m_pcHeader->numTriangles; ++i) + { + for (unsigned int p = 0; p < 3;++p) + { + ByteSwap::Swap2(& pcTriangles[i].textureIndices[p]); + ByteSwap::Swap2(& pcTriangles[i].vertexIndices[p]); + } + } + for (uint32_t i = 0; i < m_pcHeader->offsetTexCoords;++i) + { + ByteSwap::Swap2(& pcTexCoords[i].s); + ByteSwap::Swap2(& pcTexCoords[i].t); + } + ByteSwap::Swap4( & pcFrame->scale[0] ); + ByteSwap::Swap4( & pcFrame->scale[1] ); + ByteSwap::Swap4( & pcFrame->scale[2] ); + ByteSwap::Swap4( & pcFrame->translate[0] ); + ByteSwap::Swap4( & pcFrame->translate[1] ); + ByteSwap::Swap4( & pcFrame->translate[2] ); +#endif + + pcMesh->mNumFaces = m_pcHeader->numTriangles; + pcMesh->mFaces = new aiFace[m_pcHeader->numTriangles]; + + // allocate output storage + pcMesh->mNumVertices = (unsigned int)pcMesh->mNumFaces*3; + pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices]; + pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices]; + + // Not sure whether there are MD2 files without texture coordinates + // NOTE: texture coordinates can be there without a texture, + // but a texture can't be there without a valid UV channel + aiMaterial* pcHelper = (aiMaterial*)pScene->mMaterials[0]; + const int iMode = (int)aiShadingMode_Gouraud; + pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL); + + if (m_pcHeader->numTexCoords && m_pcHeader->numSkins) + { + // navigate to the first texture associated with the mesh + const MD2::Skin* pcSkins = (const MD2::Skin*) ((unsigned char*)m_pcHeader + + m_pcHeader->offsetSkins); + + aiColor3D clr; + clr.b = clr.g = clr.r = 1.0f; + pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE); + pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR); + + clr.b = clr.g = clr.r = 0.05f; + pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT); + + if (pcSkins->name[0]) + { + aiString szString; + const ai_uint32 iLen = (ai_uint32) ::strlen(pcSkins->name); + ::memcpy(szString.data,pcSkins->name,iLen); + szString.data[iLen] = '\0'; + szString.length = iLen; + + pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0)); + } + else{ + ASSIMP_LOG_WARN("Texture file name has zero length. It will be skipped."); + } + } + else { + // apply a default material + aiColor3D clr; + clr.b = clr.g = clr.r = 0.6f; + pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE); + pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR); + + clr.b = clr.g = clr.r = 0.05f; + pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT); + + aiString szName; + szName.Set(AI_DEFAULT_MATERIAL_NAME); + pcHelper->AddProperty(&szName,AI_MATKEY_NAME); + + aiString sz; + + // TODO: Try to guess the name of the texture file from the model file name + + sz.Set("$texture_dummy.bmp"); + pcHelper->AddProperty(&sz,AI_MATKEY_TEXTURE_DIFFUSE(0)); + } + + + // now read all triangles of the first frame, apply scaling and translation + unsigned int iCurrent = 0; + + float fDivisorU = 1.0f,fDivisorV = 1.0f; + if (m_pcHeader->numTexCoords) { + // allocate storage for texture coordinates, too + pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices]; + pcMesh->mNumUVComponents[0] = 2; + + // check whether the skin width or height are zero (this would + // cause a division through zero) + if (!m_pcHeader->skinWidth) { + ASSIMP_LOG_ERROR("MD2: No valid skin width given"); + } + else fDivisorU = (float)m_pcHeader->skinWidth; + if (!m_pcHeader->skinHeight){ + ASSIMP_LOG_ERROR("MD2: No valid skin height given"); + } + else fDivisorV = (float)m_pcHeader->skinHeight; + } + + for (unsigned int i = 0; i < (unsigned int)m_pcHeader->numTriangles;++i) { + // Allocate the face + pScene->mMeshes[0]->mFaces[i].mIndices = new unsigned int[3]; + pScene->mMeshes[0]->mFaces[i].mNumIndices = 3; + + // copy texture coordinates + // check whether they are different from the previous value at this index. + // In this case, create a full separate set of vertices/normals/texcoords + for (unsigned int c = 0; c < 3;++c,++iCurrent) { + + // validate vertex indices + unsigned int iIndex = (unsigned int)pcTriangles[i].vertexIndices[c]; + if (iIndex >= m_pcHeader->numVertices) { + ASSIMP_LOG_ERROR("MD2: Vertex index is outside the allowed range"); + iIndex = m_pcHeader->numVertices-1; + } + + // read x,y, and z component of the vertex + aiVector3D& vec = pcMesh->mVertices[iCurrent]; + + vec.x = (float)pcVerts[iIndex].vertex[0] * pcFrame->scale[0]; + vec.x += pcFrame->translate[0]; + + vec.y = (float)pcVerts[iIndex].vertex[1] * pcFrame->scale[1]; + vec.y += pcFrame->translate[1]; + + vec.z = (float)pcVerts[iIndex].vertex[2] * pcFrame->scale[2]; + vec.z += pcFrame->translate[2]; + + // read the normal vector from the precalculated normal table + aiVector3D& vNormal = pcMesh->mNormals[iCurrent]; + LookupNormalIndex(pcVerts[iIndex].lightNormalIndex,vNormal); + + if (m_pcHeader->numTexCoords) { + // validate texture coordinates + iIndex = pcTriangles[i].textureIndices[c]; + if (iIndex >= m_pcHeader->numTexCoords) { + ASSIMP_LOG_ERROR("MD2: UV index is outside the allowed range"); + iIndex = m_pcHeader->numTexCoords-1; + } + + aiVector3D& pcOut = pcMesh->mTextureCoords[0][iCurrent]; + + // the texture coordinates are absolute values but we + // need relative values between 0 and 1 + pcOut.x = pcTexCoords[iIndex].s / fDivisorU; + pcOut.y = 1.f-pcTexCoords[iIndex].t / fDivisorV; + } + pScene->mMeshes[0]->mFaces[i].mIndices[c] = iCurrent; + } + // flip the face order + std::swap( pScene->mMeshes[0]->mFaces[i].mIndices[0], pScene->mMeshes[0]->mFaces[i].mIndices[2] ); + } + // 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_MD2_IMPORTER diff --git a/libs/assimp/code/AssetLib/MD2/MD2Loader.h b/libs/assimp/code/AssetLib/MD2/MD2Loader.h new file mode 100644 index 0000000..a49ccb2 --- /dev/null +++ b/libs/assimp/code/AssetLib/MD2/MD2Loader.h @@ -0,0 +1,116 @@ +/* +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 MD2Loader.h + * @brief Declaration of the .MD2 importer class. + */ +#pragma once +#ifndef AI_MD2LOADER_H_INCLUDED +#define AI_MD2LOADER_H_INCLUDED + +#include "MD2FileData.h" +#include <assimp/BaseImporter.h> +#include <assimp/ByteSwapper.h> +#include <assimp/types.h> + +struct aiNode; + +namespace Assimp { + +using namespace MD2; + +// --------------------------------------------------------------------------- +/** Importer class for MD2 +*/ +class MD2Importer : public BaseImporter { +public: + MD2Importer(); + ~MD2Importer() 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(); + +protected: + /** Configuration option: frame to be loaded */ + unsigned int configFrameID; + + /** Header of the MD2 file */ + BE_NCONST MD2::Header *m_pcHeader; + + /** Buffer to hold the loaded file */ + BE_NCONST uint8_t *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/MD2/MD2NormalTable.h b/libs/assimp/code/AssetLib/MD2/MD2NormalTable.h new file mode 100644 index 0000000..1837939 --- /dev/null +++ b/libs/assimp/code/AssetLib/MD2/MD2NormalTable.h @@ -0,0 +1,219 @@ +/* +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 Slightly modified version of the anorms.h header file + * released by ID software with the Quake 2 source code. + * + * Table of normals used by MD2 models + */ + +#ifndef AI_MDL_NORMALTABLE_H_INC +#define AI_MDL_NORMALTABLE_H_INC + + +const float g_avNormals[162][3] = { +{ -0.525731f, 0.000000f, 0.850651f }, +{ -0.442863f, 0.238856f, 0.864188f }, +{ -0.295242f, 0.000000f, 0.955423f }, +{ -0.309017f, 0.500000f, 0.809017f }, +{ -0.162460f, 0.262866f, 0.951056f }, +{ 0.000000f, 0.000000f, 1.000000f }, +{ 0.000000f, 0.850651f, 0.525731f }, +{ -0.147621f, 0.716567f, 0.681718f }, +{ 0.147621f, 0.716567f, 0.681718f }, +{ 0.000000f, 0.525731f, 0.850651f }, +{ 0.309017f, 0.500000f, 0.809017f }, +{ 0.525731f, 0.000000f, 0.850651f }, +{ 0.295242f, 0.000000f, 0.955423f }, +{ 0.442863f, 0.238856f, 0.864188f }, +{ 0.162460f, 0.262866f, 0.951056f }, +{ -0.681718f, 0.147621f, 0.716567f }, +{ -0.809017f, 0.309017f, 0.500000f }, +{ -0.587785f, 0.425325f, 0.688191f }, +{ -0.850651f, 0.525731f, 0.000000f }, +{ -0.864188f, 0.442863f, 0.238856f }, +{ -0.716567f, 0.681718f, 0.147621f }, +{ -0.688191f, 0.587785f, 0.425325f }, +{ -0.500000f, 0.809017f, 0.309017f }, +{ -0.238856f, 0.864188f, 0.442863f }, +{ -0.425325f, 0.688191f, 0.587785f }, +{ -0.716567f, 0.681718f, -0.147621f }, +{ -0.500000f, 0.809017f, -0.309017f }, +{ -0.525731f, 0.850651f, 0.000000f }, +{ 0.000000f, 0.850651f, -0.525731f }, +{ -0.238856f, 0.864188f, -0.442863f }, +{ 0.000000f, 0.955423f, -0.295242f }, +{ -0.262866f, 0.951056f, -0.162460f }, +{ 0.000000f, 1.000000f, 0.000000f }, +{ 0.000000f, 0.955423f, 0.295242f }, +{ -0.262866f, 0.951056f, 0.162460f }, +{ 0.238856f, 0.864188f, 0.442863f }, +{ 0.262866f, 0.951056f, 0.162460f }, +{ 0.500000f, 0.809017f, 0.309017f }, +{ 0.238856f, 0.864188f, -0.442863f }, +{ 0.262866f, 0.951056f, -0.162460f }, +{ 0.500000f, 0.809017f, -0.309017f }, +{ 0.850651f, 0.525731f, 0.000000f }, +{ 0.716567f, 0.681718f, 0.147621f }, +{ 0.716567f, 0.681718f, -0.147621f }, +{ 0.525731f, 0.850651f, 0.000000f }, +{ 0.425325f, 0.688191f, 0.587785f }, +{ 0.864188f, 0.442863f, 0.238856f }, +{ 0.688191f, 0.587785f, 0.425325f }, +{ 0.809017f, 0.309017f, 0.500000f }, +{ 0.681718f, 0.147621f, 0.716567f }, +{ 0.587785f, 0.425325f, 0.688191f }, +{ 0.955423f, 0.295242f, 0.000000f }, +{ 1.000000f, 0.000000f, 0.000000f }, +{ 0.951056f, 0.162460f, 0.262866f }, +{ 0.850651f, -0.525731f, 0.000000f }, +{ 0.955423f, -0.295242f, 0.000000f }, +{ 0.864188f, -0.442863f, 0.238856f }, +{ 0.951056f, -0.162460f, 0.262866f }, +{ 0.809017f, -0.309017f, 0.500000f }, +{ 0.681718f, -0.147621f, 0.716567f }, +{ 0.850651f, 0.000000f, 0.525731f }, +{ 0.864188f, 0.442863f, -0.238856f }, +{ 0.809017f, 0.309017f, -0.500000f }, +{ 0.951056f, 0.162460f, -0.262866f }, +{ 0.525731f, 0.000000f, -0.850651f }, +{ 0.681718f, 0.147621f, -0.716567f }, +{ 0.681718f, -0.147621f, -0.716567f }, +{ 0.850651f, 0.000000f, -0.525731f }, +{ 0.809017f, -0.309017f, -0.500000f }, +{ 0.864188f, -0.442863f, -0.238856f }, +{ 0.951056f, -0.162460f, -0.262866f }, +{ 0.147621f, 0.716567f, -0.681718f }, +{ 0.309017f, 0.500000f, -0.809017f }, +{ 0.425325f, 0.688191f, -0.587785f }, +{ 0.442863f, 0.238856f, -0.864188f }, +{ 0.587785f, 0.425325f, -0.688191f }, +{ 0.688191f, 0.587785f, -0.425325f }, +{ -0.147621f, 0.716567f, -0.681718f }, +{ -0.309017f, 0.500000f, -0.809017f }, +{ 0.000000f, 0.525731f, -0.850651f }, +{ -0.525731f, 0.000000f, -0.850651f }, +{ -0.442863f, 0.238856f, -0.864188f }, +{ -0.295242f, 0.000000f, -0.955423f }, +{ -0.162460f, 0.262866f, -0.951056f }, +{ 0.000000f, 0.000000f, -1.000000f }, +{ 0.295242f, 0.000000f, -0.955423f }, +{ 0.162460f, 0.262866f, -0.951056f }, +{ -0.442863f, -0.238856f, -0.864188f }, +{ -0.309017f, -0.500000f, -0.809017f }, +{ -0.162460f, -0.262866f, -0.951056f }, +{ 0.000000f, -0.850651f, -0.525731f }, +{ -0.147621f, -0.716567f, -0.681718f }, +{ 0.147621f, -0.716567f, -0.681718f }, +{ 0.000000f, -0.525731f, -0.850651f }, +{ 0.309017f, -0.500000f, -0.809017f }, +{ 0.442863f, -0.238856f, -0.864188f }, +{ 0.162460f, -0.262866f, -0.951056f }, +{ 0.238856f, -0.864188f, -0.442863f }, +{ 0.500000f, -0.809017f, -0.309017f }, +{ 0.425325f, -0.688191f, -0.587785f }, +{ 0.716567f, -0.681718f, -0.147621f }, +{ 0.688191f, -0.587785f, -0.425325f }, +{ 0.587785f, -0.425325f, -0.688191f }, +{ 0.000000f, -0.955423f, -0.295242f }, +{ 0.000000f, -1.000000f, 0.000000f }, +{ 0.262866f, -0.951056f, -0.162460f }, +{ 0.000000f, -0.850651f, 0.525731f }, +{ 0.000000f, -0.955423f, 0.295242f }, +{ 0.238856f, -0.864188f, 0.442863f }, +{ 0.262866f, -0.951056f, 0.162460f }, +{ 0.500000f, -0.809017f, 0.309017f }, +{ 0.716567f, -0.681718f, 0.147621f }, +{ 0.525731f, -0.850651f, 0.000000f }, +{ -0.238856f, -0.864188f, -0.442863f }, +{ -0.500000f, -0.809017f, -0.309017f }, +{ -0.262866f, -0.951056f, -0.162460f }, +{ -0.850651f, -0.525731f, 0.000000f }, +{ -0.716567f, -0.681718f, -0.147621f }, +{ -0.716567f, -0.681718f, 0.147621f }, +{ -0.525731f, -0.850651f, 0.000000f }, +{ -0.500000f, -0.809017f, 0.309017f }, +{ -0.238856f, -0.864188f, 0.442863f }, +{ -0.262866f, -0.951056f, 0.162460f }, +{ -0.864188f, -0.442863f, 0.238856f }, +{ -0.809017f, -0.309017f, 0.500000f }, +{ -0.688191f, -0.587785f, 0.425325f }, +{ -0.681718f, -0.147621f, 0.716567f }, +{ -0.442863f, -0.238856f, 0.864188f }, +{ -0.587785f, -0.425325f, 0.688191f }, +{ -0.309017f, -0.500000f, 0.809017f }, +{ -0.147621f, -0.716567f, 0.681718f }, +{ -0.425325f, -0.688191f, 0.587785f }, +{ -0.162460f, -0.262866f, 0.951056f }, +{ 0.442863f, -0.238856f, 0.864188f }, +{ 0.162460f, -0.262866f, 0.951056f }, +{ 0.309017f, -0.500000f, 0.809017f }, +{ 0.147621f, -0.716567f, 0.681718f }, +{ 0.000000f, -0.525731f, 0.850651f }, +{ 0.425325f, -0.688191f, 0.587785f }, +{ 0.587785f, -0.425325f, 0.688191f }, +{ 0.688191f, -0.587785f, 0.425325f }, +{ -0.955423f, 0.295242f, 0.000000f }, +{ -0.951056f, 0.162460f, 0.262866f }, +{ -1.000000f, 0.000000f, 0.000000f }, +{ -0.850651f, 0.000000f, 0.525731f }, +{ -0.955423f, -0.295242f, 0.000000f }, +{ -0.951056f, -0.162460f, 0.262866f }, +{ -0.864188f, 0.442863f, -0.238856f }, +{ -0.951056f, 0.162460f, -0.262866f }, +{ -0.809017f, 0.309017f, -0.500000f }, +{ -0.864188f, -0.442863f, -0.238856f }, +{ -0.951056f, -0.162460f, -0.262866f }, +{ -0.809017f, -0.309017f, -0.500000f }, +{ -0.681718f, 0.147621f, -0.716567f }, +{ -0.681718f, -0.147621f, -0.716567f }, +{ -0.850651f, 0.000000f, -0.525731f }, +{ -0.688191f, 0.587785f, -0.425325f }, +{ -0.587785f, 0.425325f, -0.688191f }, +{ -0.425325f, 0.688191f, -0.587785f }, +{ -0.425325f, -0.688191f, -0.587785f }, +{ -0.587785f, -0.425325f, -0.688191f }, +{ -0.688191f, -0.587785f, -0.425325f } +}; + +#endif // !! include guard |