apply custom assimp fixes

This commit is contained in:
Garux 2021-05-07 14:49:50 +03:00
parent 75c7c09903
commit c58749c72a
17 changed files with 113 additions and 40 deletions

View File

@ -981,9 +981,9 @@ void Discreet3DSImporter::ParseMeshChunk() {
mMesh.mMat.a3 = stream->GetF4(); mMesh.mMat.a3 = stream->GetF4();
mMesh.mMat.b3 = stream->GetF4(); mMesh.mMat.b3 = stream->GetF4();
mMesh.mMat.c3 = stream->GetF4(); mMesh.mMat.c3 = stream->GetF4();
mMesh.mMat.d1 = stream->GetF4(); mMesh.mMat.a4 = stream->GetF4();
mMesh.mMat.d2 = stream->GetF4(); mMesh.mMat.b4 = stream->GetF4();
mMesh.mMat.d3 = stream->GetF4(); mMesh.mMat.c4 = stream->GetF4();
} break; } break;
case Discreet3DS::CHUNK_MAPLIST: { case Discreet3DS::CHUNK_MAPLIST: {

View File

@ -498,6 +498,12 @@ void Parser::ParseLV1MaterialListBlock() {
ParseLV2MaterialBlock(sMat); ParseLV2MaterialBlock(sMat);
continue; 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(); AI_ASE_HANDLE_TOP_LEVEL_SECTION();
} }

View File

@ -433,10 +433,6 @@ void MD2Importer::InternReadFile( const std::string& pFile,
aiVector3D& vNormal = pcMesh->mNormals[iCurrent]; aiVector3D& vNormal = pcMesh->mNormals[iCurrent];
LookupNormalIndex(pcVerts[iIndex].lightNormalIndex,vNormal); 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) { if (m_pcHeader->numTexCoords) {
// validate texture coordinates // validate texture coordinates
iIndex = pcTriangles[i].textureIndices[c]; iIndex = pcTriangles[i].textureIndices[c];
@ -454,7 +450,15 @@ void MD2Importer::InternReadFile( const std::string& pFile,
} }
pScene->mMeshes[0]->mFaces[i].mIndices[c] = iCurrent; 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 #endif // !! ASSIMP_BUILD_NO_MD2_IMPORTER

View File

@ -196,11 +196,11 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
// 'cull' specifies culling behaviour for the model // 'cull' specifies culling behaviour for the model
else if (TokenMatchI(buff, "cull", 4)) { else if (TokenMatchI(buff, "cull", 4)) {
SkipSpaces(&buff); 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; 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; 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; curData->cull = Q3Shader::CULL_NONE;
} else { } else {
ASSIMP_LOG_ERROR("Q3Shader: Unrecognized cull mode"); ASSIMP_LOG_ERROR("Q3Shader: Unrecognized cull mode");
@ -450,6 +450,9 @@ void MD3Importer::SetupProperties(const Importer *pImp) {
// AI_CONFIG_IMPORT_MD3_SKIN_NAME // AI_CONFIG_IMPORT_MD3_SKIN_NAME
configSkinFile = (pImp->GetPropertyString(AI_CONFIG_IMPORT_MD3_SKIN_NAME, "default")); 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 // AI_CONFIG_IMPORT_MD3_SHADER_SRC
configShaderFile = (pImp->GetPropertyString(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 no specific dir or file is given, use our default search behaviour
if (!configShaderFile.length()) { if (!configShaderFile.length()) {
if (!Q3Shader::LoadShader(fill, path + "..\\..\\..\\scripts\\" + model_file + ".shader", mIOHandler)) { const char sep = mIOHandler->getOsSeparator();
Q3Shader::LoadShader(fill, path + "..\\..\\..\\scripts\\" + filename + ".shader", mIOHandler); 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 { } else {
// If the given string specifies a file, load this file. // 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 // And check whether we can locate a shader file for this model
Q3Shader::ShaderData shaders; Q3Shader::ShaderData shaders;
if (configLoadShaders){
ReadShader(shaders); ReadShader(shaders);
}
// Adjust all texture paths in the shader // Adjust all texture paths in the shader
const char *header_name = pcHeader->NAME; const char *header_name = pcHeader->NAME;
@ -862,8 +868,13 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
std::string convertedPath; std::string convertedPath;
if (texture_name) { if (texture_name) {
if (configLoadShaders){
ConvertPath(texture_name, header_name, convertedPath); ConvertPath(texture_name, header_name, convertedPath);
} }
else{
convertedPath = texture_name;
}
}
const Q3Shader::ShaderDataBlock *shader = nullptr; 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].x = pcUVs[index].U;
pcMesh->mTextureCoords[0][iCurrent].y = 1.0f - pcUVs[index].V; pcMesh->mTextureCoords[0][iCurrent].y = 1.0f - pcUVs[index].V;
} }
// Flip face order if necessary // Flip face order normally, unless shader is backfacing
if (!shader || shader->cull == Q3Shader::CULL_CW) { if (!(shader && shader->cull == Q3Shader::CULL_CCW)) {
std::swap(pcMesh->mFaces[i].mIndices[2], pcMesh->mFaces[i].mIndices[1]); std::swap(pcMesh->mFaces[i].mIndices[2], pcMesh->mFaces[i].mIndices[1]);
} }
++pcTriangles; ++pcTriangles;

View File

@ -297,6 +297,9 @@ protected:
/** Configuration option: name of skin file to be read */ /** Configuration option: name of skin file to be read */
std::string configSkinFile; std::string configSkinFile;
/** Configuration option: whether to load shaders */
bool configLoadShaders;
/** Configuration option: name or path of shader */ /** Configuration option: name or path of shader */
std::string configShaderFile; std::string configShaderFile;

View File

@ -250,7 +250,7 @@ void MDCImporter::InternReadFile(
// get the number of valid surfaces // get the number of valid surfaces
BE_NCONST MDC::Surface *pcSurface, *pcSurface2; BE_NCONST MDC::Surface *pcSurface, *pcSurface2;
pcSurface = pcSurface2 = new (mBuffer + pcHeader->ulOffsetSurfaces) MDC::Surface; pcSurface = pcSurface2 = reinterpret_cast<BE_NCONST MDC::Surface *>(mBuffer + pcHeader->ulOffsetSurfaces);
unsigned int iNumShaders = 0; unsigned int iNumShaders = 0;
for (unsigned int i = 0; i < pcHeader->ulNumSurfaces; ++i) { for (unsigned int i = 0; i < pcHeader->ulNumSurfaces; ++i) {
// validate the surface header // validate the surface header
@ -260,7 +260,7 @@ void MDCImporter::InternReadFile(
++pScene->mNumMeshes; ++pScene->mNumMeshes;
} }
iNumShaders += pcSurface2->ulNumShaders; iNumShaders += pcSurface2->ulNumShaders;
pcSurface2 = new ((int8_t *)pcSurface2 + pcSurface2->ulOffsetEnd) MDC::Surface; pcSurface2 = reinterpret_cast<BE_NCONST MDC::Surface *>((BE_NCONST int8_t *)pcSurface2 + pcSurface2->ulOffsetEnd);
} }
aszShaders.reserve(iNumShaders); aszShaders.reserve(iNumShaders);
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes]; pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
@ -405,7 +405,7 @@ void MDCImporter::InternReadFile(
pcFaceCur->mIndices[2] = iOutIndex + 0; pcFaceCur->mIndices[2] = iOutIndex + 0;
} }
pcSurface = new ((int8_t *)pcSurface + pcSurface->ulOffsetEnd) MDC::Surface; 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 // 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)); 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 #endif // !! ASSIMP_BUILD_NO_MDC_IMPORTER

View File

@ -868,7 +868,7 @@ void HL1MDLLoader::read_meshes() {
scene_mesh->mNormals[v] = bind_pose_normals[pTrivert->normindex]; scene_mesh->mNormals[v] = bind_pose_normals[pTrivert->normindex];
scene_mesh->mTextureCoords[0][v] = aiVector3D( scene_mesh->mTextureCoords[0][v] = aiVector3D(
pTrivert->s * texcoords_s_scale, pTrivert->s * texcoords_s_scale,
pTrivert->t * texcoords_t_scale, 0); pTrivert->t * -texcoords_t_scale, 0);
} }
// Add face and indices. // Add face and indices.
@ -879,9 +879,9 @@ void HL1MDLLoader::read_meshes() {
aiFace *face = &scene_mesh->mFaces[f]; aiFace *face = &scene_mesh->mFaces[f];
face->mNumIndices = 3; face->mNumIndices = 3;
face->mIndices = new unsigned int[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[1] = mesh_faces[f].v1;
face->mIndices[2] = mesh_faces[f].v2; face->mIndices[2] = mesh_faces[f].v0;
} }
// Add mesh bones. // Add mesh bones.

View File

@ -696,6 +696,8 @@ struct GroupFrame
//! 0 = simple frame, !0 = group frame //! 0 = simple frame, !0 = group frame
int32_t type; int32_t type;
int32_t numframes;
//! Minimum vertex for all single frames //! Minimum vertex for all single frames
Vertex min; Vertex min;
@ -703,7 +705,7 @@ struct GroupFrame
Vertex max; Vertex max;
//! Time for all single frames //! Time for all single frames
float *time; float time; // float[numframes]
//! List of single frames //! List of single frames
SimpleFrame *frames; SimpleFrame *frames;

View File

@ -199,6 +199,7 @@ void MDLImporter::InternReadFile(const std::string &pFile,
const uint32_t iMagicWord = *((uint32_t *)mBuffer); const uint32_t iMagicWord = *((uint32_t *)mBuffer);
// Determine the file subtype and call the appropriate member function // Determine the file subtype and call the appropriate member function
bool is_half_life = false;
// Original Quake1 format // Original Quake1 format
if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord) { 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 || 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) { AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord) {
iGSFileVersion = 0; iGSFileVersion = 0;
is_half_life = true;
HalfLife::HalfLifeMDLBaseHeader *pHeader = (HalfLife::HalfLifeMDLBaseHeader *)mBuffer; HalfLife::HalfLifeMDLBaseHeader *pHeader = (HalfLife::HalfLifeMDLBaseHeader *)mBuffer;
if (pHeader->version == AI_MDL_HL1_VERSION) { 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"); ". Magic word (", std::string((char *)&iMagicWord, 4), ") is not known");
} }
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 // 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, 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); 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(); DeleteBufferAndCleanup();
} catch (...) { } catch (...) {
@ -428,7 +440,7 @@ void MDLImporter::InternReadFile_Quake1() {
} else { } else {
// get the first frame in the group // get the first frame in the group
BE_NCONST MDL::GroupFrame *pcFrames2 = (BE_NCONST MDL::GroupFrame *)pcFrames; 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)); BE_NCONST MDL::Vertex *pcVertices = (BE_NCONST MDL::Vertex *)((pcFirstFrame->name) + sizeof(pcFirstFrame->name));
VALIDATE_FILE_SIZE((const unsigned char *)(pcVertices + pcHeader->num_verts)); 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 // read the normal vector from the precalculated normal table
MD2::LookupNormalIndex(pcVertices[iIndex].normalIndex, pcMesh->mNormals[iCurrent]); MD2::LookupNormalIndex(pcVertices[iIndex].normalIndex, pcMesh->mNormals[iCurrent]);
pcMesh->mNormals[iCurrent] *= -1;
// pcMesh->mNormals[iCurrent].y *= -1.0f; // pcMesh->mNormals[iCurrent].y *= -1.0f;
// read texture coordinates // read texture coordinates
@ -763,6 +776,7 @@ void MDLImporter::InternReadFile_3DGS_MDL345() {
// read the normal vector from the precalculated normal table // read the normal vector from the precalculated normal table
MD2::LookupNormalIndex(pcVertices[iIndex].normalIndex, pcMesh->mNormals[iCurrent]); MD2::LookupNormalIndex(pcVertices[iIndex].normalIndex, pcMesh->mNormals[iCurrent]);
pcMesh->mNormals[iCurrent] *= -1;
// pcMesh->mNormals[iCurrent].y *= -1.0f; // pcMesh->mNormals[iCurrent].y *= -1.0f;
// read texture coordinates // read texture coordinates
@ -1844,7 +1858,7 @@ void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
for (unsigned int c = 0; c < 3; ++c) { for (unsigned int c = 0; c < 3; ++c) {
const uint32_t iIndex = oldFace.mIndices[c]; const uint32_t iIndex = oldFace.mIndices[c];
pcMesh->mVertices[iCurrent] = groupData.vPositions[iIndex]; pcMesh->mVertices[iCurrent] = groupData.vPositions[iIndex];
pcMesh->mNormals[iCurrent] = groupData.vNormals[iIndex]; pcMesh->mNormals[iCurrent] = -groupData.vNormals[iIndex];
if (!groupData.vTextureCoords1.empty()) { if (!groupData.vTextureCoords1.empty()) {

View File

@ -500,7 +500,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
throw DeadlyImportError("MS3D: Encountered invalid triangle index, file is malformed"); 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]; f.mIndices = new unsigned int[f.mNumIndices=3];
for (unsigned int k = 0; k < 3; ++k,++n) { 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"); 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) { for(unsigned int a = 0; a < 4; ++a) {
if (v.bone_id[a] != UINT_MAX) { if (v.bone_id[a] != UINT_MAX) {
if (v.bone_id[a] >= joints.size()) { if (v.bone_id[a] >= joints.size()) {
@ -524,9 +524,9 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
// collect vertex components // collect vertex components
m->mVertices[n] = v.pos; m->mVertices[n] = v.pos;
m->mNormals[n] = t.normals[i]; m->mNormals[n] = t.normals[k];
m->mTextureCoords[0][n] = aiVector3D(t.uv[i].x,1.f-t.uv[i].y,0.0); m->mTextureCoords[0][n] = aiVector3D(t.uv[k].x,1.f-t.uv[k].y,0.0);
f.mIndices[i] = n; f.mIndices[k] = n;
} }
} }

View File

@ -70,6 +70,7 @@ GenFaceNormalsProcess::~GenFaceNormalsProcess() {
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool GenFaceNormalsProcess::IsActive(unsigned int pFlags) const { bool GenFaceNormalsProcess::IsActive(unsigned int pFlags) const {
force_ = (pFlags & aiProcess_ForceGenNormals) != 0; force_ = (pFlags & aiProcess_ForceGenNormals) != 0;
flippedWindingOrder_ = (pFlags & aiProcess_FlipWindingOrder) != 0;
return (pFlags & aiProcess_GenNormals) != 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 *pV1 = &pMesh->mVertices[face.mIndices[0]];
const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]]; const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]];
const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 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(); const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
for (unsigned int i = 0; i < face.mNumIndices; ++i) { for (unsigned int i = 0; i < face.mNumIndices; ++i) {

View File

@ -80,6 +80,7 @@ public:
private: private:
bool GenMeshFaceNormals(aiMesh* pcMesh); bool GenMeshFaceNormals(aiMesh* pcMesh);
mutable bool force_ = false; mutable bool force_ = false;
mutable bool flippedWindingOrder_ = false;
}; };
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -70,6 +70,7 @@ GenVertexNormalsProcess::~GenVertexNormalsProcess() {
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool GenVertexNormalsProcess::IsActive(unsigned int pFlags) const { bool GenVertexNormalsProcess::IsActive(unsigned int pFlags) const {
force_ = (pFlags & aiProcess_ForceGenNormals) != 0; force_ = (pFlags & aiProcess_ForceGenNormals) != 0;
flippedWindingOrder_ = (pFlags & aiProcess_FlipWindingOrder) != 0;
return (pFlags & aiProcess_GenSmoothNormals) != 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 *pV1 = &pMesh->mVertices[face.mIndices[0]];
const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]]; const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]];
const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 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(); const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
for (unsigned int i = 0; i < face.mNumIndices; ++i) { for (unsigned int i = 0; i < face.mNumIndices; ++i) {

View File

@ -104,6 +104,7 @@ private:
/** Configuration option: maximum smoothing angle, in radians*/ /** Configuration option: maximum smoothing angle, in radians*/
ai_real configMaxAngle; ai_real configMaxAngle;
mutable bool force_ = false; mutable bool force_ = false;
mutable bool flippedWindingOrder_ = false;
}; };
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -429,7 +429,7 @@ void PretransformVertices::Execute(aiScene *pScene) {
const unsigned int iOldNodes = CountNodes(pScene->mRootNode); const unsigned int iOldNodes = CountNodes(pScene->mRootNode);
if (configTransform) { if (configTransform) {
pScene->mRootNode->mTransformation = configTransformation; pScene->mRootNode->mTransformation = configTransformation * pScene->mRootNode->mTransformation;
} }
// first compute absolute transformation matrices for all nodes // first compute absolute transformation matrices for all nodes

View File

@ -854,6 +854,15 @@ enum aiComponent
#define AI_CONFIG_IMPORT_MD3_SKIN_NAME \ #define AI_CONFIG_IMPORT_MD3_SKIN_NAME \
"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 /** @brief Specify the Quake 3 shader file to be used for a particular
* MD3 file. This can also be a search path. * MD3 file. This can also be a search path.

View File

@ -854,6 +854,15 @@ enum aiComponent
#define AI_CONFIG_IMPORT_MD3_SKIN_NAME \ #define AI_CONFIG_IMPORT_MD3_SKIN_NAME \
"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 /** @brief Specify the Quake 3 shader file to be used for a particular
* MD3 file. This can also be a search path. * MD3 file. This can also be a search path.