From c58749c72a7129600b693c6f3811837359c9419f Mon Sep 17 00:00:00 2001 From: Garux Date: Fri, 7 May 2021 14:49:50 +0300 Subject: [PATCH] apply custom assimp fixes --- libs/assimp/code/AssetLib/3DS/3DSLoader.cpp | 6 ++-- libs/assimp/code/AssetLib/ASE/ASEParser.cpp | 6 ++++ libs/assimp/code/AssetLib/MD2/MD2Loader.cpp | 12 +++++--- libs/assimp/code/AssetLib/MD3/MD3Loader.cpp | 29 +++++++++++++------ libs/assimp/code/AssetLib/MD3/MD3Loader.h | 3 ++ libs/assimp/code/AssetLib/MDC/MDCLoader.cpp | 13 +++++++-- .../AssetLib/MDL/HalfLife/HL1MDLLoader.cpp | 10 +++---- libs/assimp/code/AssetLib/MDL/MDLFileData.h | 4 ++- libs/assimp/code/AssetLib/MDL/MDLLoader.cpp | 24 +++++++++++---- libs/assimp/code/AssetLib/MS3D/MS3DLoader.cpp | 10 +++---- .../PostProcessing/GenFaceNormalsProcess.cpp | 3 ++ .../PostProcessing/GenFaceNormalsProcess.h | 1 + .../GenVertexNormalsProcess.cpp | 3 ++ .../PostProcessing/GenVertexNormalsProcess.h | 1 + .../PostProcessing/PretransformVertices.cpp | 2 +- libs/assimp/include/assimp/config.h | 13 +++++++-- libs/assimp/include/assimp/config.h.in | 13 +++++++-- 17 files changed, 113 insertions(+), 40 deletions(-) diff --git a/libs/assimp/code/AssetLib/3DS/3DSLoader.cpp b/libs/assimp/code/AssetLib/3DS/3DSLoader.cpp index 0a64f687..3dabf9da 100644 --- a/libs/assimp/code/AssetLib/3DS/3DSLoader.cpp +++ b/libs/assimp/code/AssetLib/3DS/3DSLoader.cpp @@ -981,9 +981,9 @@ void Discreet3DSImporter::ParseMeshChunk() { mMesh.mMat.a3 = stream->GetF4(); mMesh.mMat.b3 = stream->GetF4(); mMesh.mMat.c3 = stream->GetF4(); - mMesh.mMat.d1 = stream->GetF4(); - mMesh.mMat.d2 = stream->GetF4(); - mMesh.mMat.d3 = stream->GetF4(); + mMesh.mMat.a4 = stream->GetF4(); + mMesh.mMat.b4 = stream->GetF4(); + mMesh.mMat.c4 = stream->GetF4(); } break; case Discreet3DS::CHUNK_MAPLIST: { diff --git a/libs/assimp/code/AssetLib/ASE/ASEParser.cpp b/libs/assimp/code/AssetLib/ASE/ASEParser.cpp index 21ec2659..958e3b9a 100644 --- a/libs/assimp/code/AssetLib/ASE/ASEParser.cpp +++ b/libs/assimp/code/AssetLib/ASE/ASEParser.cpp @@ -498,6 +498,12 @@ void Parser::ParseLV1MaterialListBlock() { ParseLV2MaterialBlock(sMat); continue; } + if( iDepth == 1 ){ + // CRUDE HACK: support missing brace after "Ascii Scene Exporter v2.51" + LogWarning("Missing closing brace in material list"); + --filePtr; + return; + } } AI_ASE_HANDLE_TOP_LEVEL_SECTION(); } diff --git a/libs/assimp/code/AssetLib/MD2/MD2Loader.cpp b/libs/assimp/code/AssetLib/MD2/MD2Loader.cpp index 9ccbcdfc..41cec5ab 100644 --- a/libs/assimp/code/AssetLib/MD2/MD2Loader.cpp +++ b/libs/assimp/code/AssetLib/MD2/MD2Loader.cpp @@ -433,10 +433,6 @@ void MD2Importer::InternReadFile( const std::string& pFile, aiVector3D& vNormal = pcMesh->mNormals[iCurrent]; LookupNormalIndex(pcVerts[iIndex].lightNormalIndex,vNormal); - // flip z and y to become right-handed - std::swap((float&)vNormal.z,(float&)vNormal.y); - std::swap((float&)vec.z,(float&)vec.y); - if (m_pcHeader->numTexCoords) { // validate texture coordinates iIndex = pcTriangles[i].textureIndices[c]; @@ -454,7 +450,15 @@ void MD2Importer::InternReadFile( const std::string& pFile, } 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/MD3/MD3Loader.cpp b/libs/assimp/code/AssetLib/MD3/MD3Loader.cpp index e2707976..53a0eea4 100644 --- a/libs/assimp/code/AssetLib/MD3/MD3Loader.cpp +++ b/libs/assimp/code/AssetLib/MD3/MD3Loader.cpp @@ -196,11 +196,11 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem * // 'cull' specifies culling behaviour for the model else if (TokenMatchI(buff, "cull", 4)) { SkipSpaces(&buff); - if (!ASSIMP_strincmp(buff, "back", 4)) { + if (!ASSIMP_strincmp(buff, "back", 4)) { // render face's backside, does not function in Q3 engine (bug) curData->cull = Q3Shader::CULL_CCW; - } else if (!ASSIMP_strincmp(buff, "front", 5)) { + } else if (!ASSIMP_strincmp(buff, "front", 5)) { // is not valid keyword in Q3, but occurs in shaders curData->cull = Q3Shader::CULL_CW; - } else if (!ASSIMP_strincmp(buff, "none", 4) || !ASSIMP_strincmp(buff, "disable", 7)) { + } else if (!ASSIMP_strincmp(buff, "none", 4) || !ASSIMP_strincmp(buff, "twosided", 8) || !ASSIMP_strincmp(buff, "disable", 7)) { curData->cull = Q3Shader::CULL_NONE; } else { ASSIMP_LOG_ERROR("Q3Shader: Unrecognized cull mode"); @@ -450,6 +450,9 @@ void MD3Importer::SetupProperties(const Importer *pImp) { // AI_CONFIG_IMPORT_MD3_SKIN_NAME configSkinFile = (pImp->GetPropertyString(AI_CONFIG_IMPORT_MD3_SKIN_NAME, "default")); + // AI_CONFIG_IMPORT_MD3_LOAD_SHADERS + configLoadShaders = (pImp->GetPropertyBool(AI_CONFIG_IMPORT_MD3_LOAD_SHADERS, true)); + // AI_CONFIG_IMPORT_MD3_SHADER_SRC configShaderFile = (pImp->GetPropertyString(AI_CONFIG_IMPORT_MD3_SHADER_SRC, "")); @@ -483,8 +486,9 @@ void MD3Importer::ReadShader(Q3Shader::ShaderData &fill) const { // If no specific dir or file is given, use our default search behaviour if (!configShaderFile.length()) { - if (!Q3Shader::LoadShader(fill, path + "..\\..\\..\\scripts\\" + model_file + ".shader", mIOHandler)) { - Q3Shader::LoadShader(fill, path + "..\\..\\..\\scripts\\" + filename + ".shader", mIOHandler); + const char sep = mIOHandler->getOsSeparator(); + if (!Q3Shader::LoadShader(fill, path + ".." + sep + ".." + sep + ".." + sep + "scripts" + sep + model_file + ".shader", mIOHandler)) { + Q3Shader::LoadShader(fill, path + ".." + sep + ".." + sep + ".." + sep + "scripts" + sep + filename + ".shader", mIOHandler); } } else { // If the given string specifies a file, load this file. @@ -780,7 +784,9 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy // And check whether we can locate a shader file for this model Q3Shader::ShaderData shaders; - ReadShader(shaders); + if (configLoadShaders){ + ReadShader(shaders); + } // Adjust all texture paths in the shader const char *header_name = pcHeader->NAME; @@ -862,7 +868,12 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy std::string convertedPath; if (texture_name) { - ConvertPath(texture_name, header_name, convertedPath); + if (configLoadShaders){ + ConvertPath(texture_name, header_name, convertedPath); + } + else{ + convertedPath = texture_name; + } } const Q3Shader::ShaderDataBlock *shader = nullptr; @@ -985,8 +996,8 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[index].U; pcMesh->mTextureCoords[0][iCurrent].y = 1.0f - pcUVs[index].V; } - // Flip face order if necessary - if (!shader || shader->cull == Q3Shader::CULL_CW) { + // Flip face order normally, unless shader is backfacing + if (!(shader && shader->cull == Q3Shader::CULL_CCW)) { std::swap(pcMesh->mFaces[i].mIndices[2], pcMesh->mFaces[i].mIndices[1]); } ++pcTriangles; diff --git a/libs/assimp/code/AssetLib/MD3/MD3Loader.h b/libs/assimp/code/AssetLib/MD3/MD3Loader.h index d34df2d7..1a4e5982 100644 --- a/libs/assimp/code/AssetLib/MD3/MD3Loader.h +++ b/libs/assimp/code/AssetLib/MD3/MD3Loader.h @@ -297,6 +297,9 @@ protected: /** Configuration option: name of skin file to be read */ std::string configSkinFile; + /** Configuration option: whether to load shaders */ + bool configLoadShaders; + /** Configuration option: name or path of shader */ std::string configShaderFile; diff --git a/libs/assimp/code/AssetLib/MDC/MDCLoader.cpp b/libs/assimp/code/AssetLib/MDC/MDCLoader.cpp index 90b88f7d..c53c31b7 100644 --- a/libs/assimp/code/AssetLib/MDC/MDCLoader.cpp +++ b/libs/assimp/code/AssetLib/MDC/MDCLoader.cpp @@ -250,7 +250,7 @@ void MDCImporter::InternReadFile( // get the number of valid surfaces BE_NCONST MDC::Surface *pcSurface, *pcSurface2; - pcSurface = pcSurface2 = new (mBuffer + pcHeader->ulOffsetSurfaces) MDC::Surface; + pcSurface = pcSurface2 = reinterpret_cast(mBuffer + pcHeader->ulOffsetSurfaces); unsigned int iNumShaders = 0; for (unsigned int i = 0; i < pcHeader->ulNumSurfaces; ++i) { // validate the surface header @@ -260,7 +260,7 @@ void MDCImporter::InternReadFile( ++pScene->mNumMeshes; } iNumShaders += pcSurface2->ulNumShaders; - pcSurface2 = new ((int8_t *)pcSurface2 + pcSurface2->ulOffsetEnd) MDC::Surface; + pcSurface2 = reinterpret_cast((BE_NCONST int8_t *)pcSurface2 + pcSurface2->ulOffsetEnd); } aszShaders.reserve(iNumShaders); pScene->mMeshes = new aiMesh *[pScene->mNumMeshes]; @@ -405,7 +405,7 @@ void MDCImporter::InternReadFile( pcFaceCur->mIndices[2] = iOutIndex + 0; } - pcSurface = new ((int8_t *)pcSurface + pcSurface->ulOffsetEnd) MDC::Surface; + pcSurface = reinterpret_cast((BE_NCONST int8_t *)pcSurface + pcSurface->ulOffsetEnd); } // create a flat node graph with a root node and one child for each surface @@ -465,6 +465,13 @@ void MDCImporter::InternReadFile( 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/MDL/HalfLife/HL1MDLLoader.cpp b/libs/assimp/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp index 4df0d0d1..13dd802b 100644 --- a/libs/assimp/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp +++ b/libs/assimp/code/AssetLib/MDL/HalfLife/HL1MDLLoader.cpp @@ -628,7 +628,7 @@ void HL1MDLLoader::read_meshes() { +-- bodypart --+-- model -- [mesh index, mesh index, ...] | | | +-- model -- [mesh index, mesh index, ...] - | | + | | | ... | |-- bodypart -- ... @@ -868,7 +868,7 @@ void HL1MDLLoader::read_meshes() { scene_mesh->mNormals[v] = bind_pose_normals[pTrivert->normindex]; scene_mesh->mTextureCoords[0][v] = aiVector3D( pTrivert->s * texcoords_s_scale, - pTrivert->t * texcoords_t_scale, 0); + pTrivert->t * -texcoords_t_scale, 0); } // Add face and indices. @@ -879,9 +879,9 @@ void HL1MDLLoader::read_meshes() { aiFace *face = &scene_mesh->mFaces[f]; face->mNumIndices = 3; face->mIndices = new unsigned int[3]; - face->mIndices[0] = mesh_faces[f].v0; + face->mIndices[0] = mesh_faces[f].v2; face->mIndices[1] = mesh_faces[f].v1; - face->mIndices[2] = mesh_faces[f].v2; + face->mIndices[2] = mesh_faces[f].v0; } // Add mesh bones. @@ -1297,7 +1297,7 @@ void HL1MDLLoader::read_global_info() { * @note The structure of this method is taken from HL2 source code. * Although this is from HL2, it's implementation is almost identical * to code found in HL1 SDK. See HL1 and HL2 SDKs for more info. -* +* * source: * HL1 source code. * file: studio_render.cpp diff --git a/libs/assimp/code/AssetLib/MDL/MDLFileData.h b/libs/assimp/code/AssetLib/MDL/MDLFileData.h index bbb6f772..872cee7f 100644 --- a/libs/assimp/code/AssetLib/MDL/MDLFileData.h +++ b/libs/assimp/code/AssetLib/MDL/MDLFileData.h @@ -696,6 +696,8 @@ struct GroupFrame //! 0 = simple frame, !0 = group frame int32_t type; + int32_t numframes; + //! Minimum vertex for all single frames Vertex min; @@ -703,7 +705,7 @@ struct GroupFrame Vertex max; //! Time for all single frames - float *time; + float time; // float[numframes] //! List of single frames SimpleFrame *frames; diff --git a/libs/assimp/code/AssetLib/MDL/MDLLoader.cpp b/libs/assimp/code/AssetLib/MDL/MDLLoader.cpp index a4286a71..67f56081 100644 --- a/libs/assimp/code/AssetLib/MDL/MDLLoader.cpp +++ b/libs/assimp/code/AssetLib/MDL/MDLLoader.cpp @@ -199,6 +199,7 @@ void MDLImporter::InternReadFile(const std::string &pFile, const uint32_t iMagicWord = *((uint32_t *)mBuffer); // Determine the file subtype and call the appropriate member function + bool is_half_life = false; // Original Quake1 format if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord) { @@ -240,6 +241,7 @@ void MDLImporter::InternReadFile(const std::string &pFile, else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord) { iGSFileVersion = 0; + is_half_life = true; HalfLife::HalfLifeMDLBaseHeader *pHeader = (HalfLife::HalfLifeMDLBaseHeader *)mBuffer; if (pHeader->version == AI_MDL_HL1_VERSION) { @@ -255,9 +257,19 @@ void MDLImporter::InternReadFile(const std::string &pFile, ". Magic word (", std::string((char *)&iMagicWord, 4), ") is not known"); } - // 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); + if (is_half_life){ + // Now rotate the whole scene 90 degrees around the z and x axes to convert to internal coordinate system + pScene->mRootNode->mTransformation = aiMatrix4x4( + 0.f, -1.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + -1.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 1.f); + } + else { + // 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); + } DeleteBufferAndCleanup(); } catch (...) { @@ -428,7 +440,7 @@ void MDLImporter::InternReadFile_Quake1() { } else { // get the first frame in the group BE_NCONST MDL::GroupFrame *pcFrames2 = (BE_NCONST MDL::GroupFrame *)pcFrames; - pcFirstFrame = &(pcFrames2->frames[0]); + pcFirstFrame = (MDL::SimpleFrame *)( &pcFrames2->time + pcFrames2->numframes ); } BE_NCONST MDL::Vertex *pcVertices = (BE_NCONST MDL::Vertex *)((pcFirstFrame->name) + sizeof(pcFirstFrame->name)); VALIDATE_FILE_SIZE((const unsigned char *)(pcVertices + pcHeader->num_verts)); @@ -708,6 +720,7 @@ void MDLImporter::InternReadFile_3DGS_MDL345() { // read the normal vector from the precalculated normal table MD2::LookupNormalIndex(pcVertices[iIndex].normalIndex, pcMesh->mNormals[iCurrent]); + pcMesh->mNormals[iCurrent] *= -1; // pcMesh->mNormals[iCurrent].y *= -1.0f; // read texture coordinates @@ -763,6 +776,7 @@ void MDLImporter::InternReadFile_3DGS_MDL345() { // read the normal vector from the precalculated normal table MD2::LookupNormalIndex(pcVertices[iIndex].normalIndex, pcMesh->mNormals[iCurrent]); + pcMesh->mNormals[iCurrent] *= -1; // pcMesh->mNormals[iCurrent].y *= -1.0f; // read texture coordinates @@ -1844,7 +1858,7 @@ void MDLImporter::GenerateOutputMeshes_3DGS_MDL7( for (unsigned int c = 0; c < 3; ++c) { const uint32_t iIndex = oldFace.mIndices[c]; pcMesh->mVertices[iCurrent] = groupData.vPositions[iIndex]; - pcMesh->mNormals[iCurrent] = groupData.vNormals[iIndex]; + pcMesh->mNormals[iCurrent] = -groupData.vNormals[iIndex]; if (!groupData.vTextureCoords1.empty()) { diff --git a/libs/assimp/code/AssetLib/MS3D/MS3DLoader.cpp b/libs/assimp/code/AssetLib/MS3D/MS3DLoader.cpp index 10bc17ea..192bcbe4 100644 --- a/libs/assimp/code/AssetLib/MS3D/MS3DLoader.cpp +++ b/libs/assimp/code/AssetLib/MS3D/MS3DLoader.cpp @@ -500,7 +500,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile, throw DeadlyImportError("MS3D: Encountered invalid triangle index, file is malformed"); } - TempTriangle& t = triangles[g.triangles[i]]; + TempTriangle& t = triangles[g.triangles[j]]; f.mIndices = new unsigned int[f.mNumIndices=3]; for (unsigned int k = 0; k < 3; ++k,++n) { @@ -508,7 +508,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile, throw DeadlyImportError("MS3D: Encountered invalid vertex index, file is malformed"); } - const TempVertex& v = vertices[t.indices[i]]; + const TempVertex& v = vertices[t.indices[k]]; for(unsigned int a = 0; a < 4; ++a) { if (v.bone_id[a] != UINT_MAX) { if (v.bone_id[a] >= joints.size()) { @@ -524,9 +524,9 @@ void MS3DImporter::InternReadFile( const std::string& pFile, // collect vertex components m->mVertices[n] = v.pos; - m->mNormals[n] = t.normals[i]; - m->mTextureCoords[0][n] = aiVector3D(t.uv[i].x,1.f-t.uv[i].y,0.0); - f.mIndices[i] = n; + m->mNormals[n] = t.normals[k]; + m->mTextureCoords[0][n] = aiVector3D(t.uv[k].x,1.f-t.uv[k].y,0.0); + f.mIndices[k] = n; } } diff --git a/libs/assimp/code/PostProcessing/GenFaceNormalsProcess.cpp b/libs/assimp/code/PostProcessing/GenFaceNormalsProcess.cpp index a73df2b5..3e8612d2 100644 --- a/libs/assimp/code/PostProcessing/GenFaceNormalsProcess.cpp +++ b/libs/assimp/code/PostProcessing/GenFaceNormalsProcess.cpp @@ -70,6 +70,7 @@ GenFaceNormalsProcess::~GenFaceNormalsProcess() { // Returns whether the processing step is present in the given flag field. bool GenFaceNormalsProcess::IsActive(unsigned int pFlags) const { force_ = (pFlags & aiProcess_ForceGenNormals) != 0; + flippedWindingOrder_ = (pFlags & aiProcess_FlipWindingOrder) != 0; return (pFlags & aiProcess_GenNormals) != 0; } @@ -134,6 +135,8 @@ bool GenFaceNormalsProcess::GenMeshFaceNormals(aiMesh *pMesh) { const aiVector3D *pV1 = &pMesh->mVertices[face.mIndices[0]]; const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]]; const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]]; + if (flippedWindingOrder_) + std::swap( pV2, pV3 ); const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe(); for (unsigned int i = 0; i < face.mNumIndices; ++i) { diff --git a/libs/assimp/code/PostProcessing/GenFaceNormalsProcess.h b/libs/assimp/code/PostProcessing/GenFaceNormalsProcess.h index 4b9222af..eefff6c7 100644 --- a/libs/assimp/code/PostProcessing/GenFaceNormalsProcess.h +++ b/libs/assimp/code/PostProcessing/GenFaceNormalsProcess.h @@ -80,6 +80,7 @@ public: private: bool GenMeshFaceNormals(aiMesh* pcMesh); mutable bool force_ = false; + mutable bool flippedWindingOrder_ = false; }; } // end of namespace Assimp diff --git a/libs/assimp/code/PostProcessing/GenVertexNormalsProcess.cpp b/libs/assimp/code/PostProcessing/GenVertexNormalsProcess.cpp index 5c9a6b75..e82bc3e6 100644 --- a/libs/assimp/code/PostProcessing/GenVertexNormalsProcess.cpp +++ b/libs/assimp/code/PostProcessing/GenVertexNormalsProcess.cpp @@ -70,6 +70,7 @@ GenVertexNormalsProcess::~GenVertexNormalsProcess() { // Returns whether the processing step is present in the given flag field. bool GenVertexNormalsProcess::IsActive(unsigned int pFlags) const { force_ = (pFlags & aiProcess_ForceGenNormals) != 0; + flippedWindingOrder_ = (pFlags & aiProcess_FlipWindingOrder) != 0; return (pFlags & aiProcess_GenSmoothNormals) != 0; } @@ -142,6 +143,8 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals(aiMesh *pMesh, unsigned int m const aiVector3D *pV1 = &pMesh->mVertices[face.mIndices[0]]; const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]]; const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]]; + if (flippedWindingOrder_) + std::swap( pV2, pV3 ); const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe(); for (unsigned int i = 0; i < face.mNumIndices; ++i) { diff --git a/libs/assimp/code/PostProcessing/GenVertexNormalsProcess.h b/libs/assimp/code/PostProcessing/GenVertexNormalsProcess.h index 8b98ea8e..8fc301ab 100644 --- a/libs/assimp/code/PostProcessing/GenVertexNormalsProcess.h +++ b/libs/assimp/code/PostProcessing/GenVertexNormalsProcess.h @@ -104,6 +104,7 @@ private: /** Configuration option: maximum smoothing angle, in radians*/ ai_real configMaxAngle; mutable bool force_ = false; + mutable bool flippedWindingOrder_ = false; }; } // end of namespace Assimp diff --git a/libs/assimp/code/PostProcessing/PretransformVertices.cpp b/libs/assimp/code/PostProcessing/PretransformVertices.cpp index d1740f30..2691ed48 100644 --- a/libs/assimp/code/PostProcessing/PretransformVertices.cpp +++ b/libs/assimp/code/PostProcessing/PretransformVertices.cpp @@ -429,7 +429,7 @@ void PretransformVertices::Execute(aiScene *pScene) { const unsigned int iOldNodes = CountNodes(pScene->mRootNode); if (configTransform) { - pScene->mRootNode->mTransformation = configTransformation; + pScene->mRootNode->mTransformation = configTransformation * pScene->mRootNode->mTransformation; } // first compute absolute transformation matrices for all nodes diff --git a/libs/assimp/include/assimp/config.h b/libs/assimp/include/assimp/config.h index 3f816a2f..97e70b32 100644 --- a/libs/assimp/include/assimp/config.h +++ b/libs/assimp/include/assimp/config.h @@ -669,7 +669,7 @@ enum aiComponent // --------------------------------------------------------------------------- /** @brief Set wether the importer shall not remove empty bones. - * + * * Empty bone are often used to define connections for other models. */ #define AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES \ @@ -854,6 +854,15 @@ enum aiComponent #define AI_CONFIG_IMPORT_MD3_SKIN_NAME \ "IMPORT_MD3_SKIN_NAME" +// --------------------------------------------------------------------------- +/** @brief Specify if to try load Quake 3 shader files. This also controls + * original surface name handling: when disabled it will be used unchanged. + * + * Property type: bool. Default value: true. + */ +#define AI_CONFIG_IMPORT_MD3_LOAD_SHADERS \ + "IMPORT_MD3_LOAD_SHADERS" + // --------------------------------------------------------------------------- /** @brief Specify the Quake 3 shader file to be used for a particular * MD3 file. This can also be a search path. @@ -1058,7 +1067,7 @@ enum aiComponent #define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT" /** @brief Specifies whether the assimp export shall be able to export point clouds - * + * * When this flag is not defined the render data has to contain valid faces. * Point clouds are only a collection of vertices which have nor spatial organization * by a face and the validation process will remove them. Enabling this feature will diff --git a/libs/assimp/include/assimp/config.h.in b/libs/assimp/include/assimp/config.h.in index d78568da..016cabba 100644 --- a/libs/assimp/include/assimp/config.h.in +++ b/libs/assimp/include/assimp/config.h.in @@ -669,7 +669,7 @@ enum aiComponent // --------------------------------------------------------------------------- /** @brief Set wether the importer shall not remove empty bones. - * + * * Empty bone are often used to define connections for other models. */ #define AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES \ @@ -854,6 +854,15 @@ enum aiComponent #define AI_CONFIG_IMPORT_MD3_SKIN_NAME \ "IMPORT_MD3_SKIN_NAME" +// --------------------------------------------------------------------------- +/** @brief Specify if to try load Quake 3 shader files. This also controls + * original surface name handling: when disabled it will be used unchanged. + * + * Property type: bool. Default value: true. + */ +#define AI_CONFIG_IMPORT_MD3_LOAD_SHADERS \ + "IMPORT_MD3_LOAD_SHADERS" + // --------------------------------------------------------------------------- /** @brief Specify the Quake 3 shader file to be used for a particular * MD3 file. This can also be a search path. @@ -1058,7 +1067,7 @@ enum aiComponent #define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT" /** @brief Specifies whether the assimp export shall be able to export point clouds - * + * * When this flag is not defined the render data has to contain valid faces. * Point clouds are only a collection of vertices which have nor spatial organization * by a face and the validation process will remove them. Enabling this feature will