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.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: {

View File

@ -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();
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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<BE_NCONST MDC::Surface *>(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 MDC::Surface *>((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 MDC::Surface *>((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

View File

@ -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.

View File

@ -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;

View File

@ -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()) {

View File

@ -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;
}
}

View File

@ -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) {

View File

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

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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.