From c6eda6729677ae86217248701cd0b24dead4d728 Mon Sep 17 00:00:00 2001 From: Sebastian Maisch Date: Tue, 29 May 2018 13:01:11 +0200 Subject: [PATCH 1/5] Changed assimp to force regeneration of normals. --- code/GenFaceNormalsProcess.cpp | 14 +++++++++++++- code/GenVertexNormalsProcess.cpp | 6 ++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/code/GenFaceNormalsProcess.cpp b/code/GenFaceNormalsProcess.cpp index be726302c..6c222e154 100644 --- a/code/GenFaceNormalsProcess.cpp +++ b/code/GenFaceNormalsProcess.cpp @@ -106,7 +106,8 @@ void GenFaceNormalsProcess::Execute( aiScene* pScene) bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh) { if (NULL != pMesh->mNormals) { - return false; + // return false; + delete[] pMesh->mNormals; } // If the mesh consists of lines and/or points but not of @@ -135,8 +136,19 @@ 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]]; + + auto pV12 = *pV2 - *pV1; + auto pV31 = *pV3 - *pV1; + const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).Normalize(); + if (std::isnan(vNor.x) || std::isnan(vNor.y) || std::isnan(vNor.z)) { + for (unsigned int i = 0; i < face.mNumIndices; ++i) { + pMesh->mNormals[face.mIndices[i]] = aiVector3D(0.0f, 0.0f, 0.0f); + } + continue; + } + for (unsigned int i = 0;i < face.mNumIndices;++i) { pMesh->mNormals[face.mIndices[i]] = vNor; } diff --git a/code/GenVertexNormalsProcess.cpp b/code/GenVertexNormalsProcess.cpp index f746f3776..e0783b0a2 100644 --- a/code/GenVertexNormalsProcess.cpp +++ b/code/GenVertexNormalsProcess.cpp @@ -112,8 +112,10 @@ void GenVertexNormalsProcess::Execute( aiScene* pScene) // Executes the post processing step on the given imported data. bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int meshIndex) { - if (NULL != pMesh->mNormals) - return false; + if (NULL != pMesh->mNormals) { + delete[] pMesh->mNormals; + } +// return false; // If the mesh consists of lines and/or points but not of // triangles or higher-order polygons the normal vectors From fceeaa72f4a9f4547adc500f45c69202b9e89188 Mon Sep 17 00:00:00 2001 From: Michael Roer Pedersen Date: Thu, 31 May 2018 15:07:00 +0200 Subject: [PATCH 2/5] FBX animation export: Assimp animation time is already in seconds. Just convert to FBX time. --- code/FBXExporter.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/code/FBXExporter.cpp b/code/FBXExporter.cpp index a942e31bc..2403ca845 100644 --- a/code/FBXExporter.cpp +++ b/code/FBXExporter.cpp @@ -980,9 +980,13 @@ aiMatrix4x4 get_world_transform(const aiNode* node, const aiScene* scene) int64_t to_ktime(double ticks, const aiAnimation* anim) { if (anim->mTicksPerSecond <= 0) { - return static_cast(ticks) * FBX::SECOND; + return static_cast(ticks * FBX::SECOND); } - return (static_cast(ticks) / static_cast(anim->mTicksPerSecond)) * FBX::SECOND; + return (static_cast(ticks / anim->mTicksPerSecond * FBX::SECOND)); +} + +int64_t to_ktime(double time) { + return (static_cast(time * FBX::SECOND)); } void FBXExporter::WriteObjects () @@ -2089,7 +2093,7 @@ void FBXExporter::WriteObjects () // position/translation for (size_t ki = 0; ki < na->mNumPositionKeys; ++ki) { const aiVectorKey& k = na->mPositionKeys[ki]; - times.push_back(to_ktime(k.mTime, anim)); + times.push_back(to_ktime(k.mTime)); xval.push_back(k.mValue.x); yval.push_back(k.mValue.y); zval.push_back(k.mValue.z); @@ -2103,7 +2107,7 @@ void FBXExporter::WriteObjects () times.clear(); xval.clear(); yval.clear(); zval.clear(); for (size_t ki = 0; ki < na->mNumRotationKeys; ++ki) { const aiQuatKey& k = na->mRotationKeys[ki]; - times.push_back(to_ktime(k.mTime, anim)); + times.push_back(to_ktime(k.mTime)); // TODO: aiQuaternion method to convert to Euler... aiMatrix4x4 m(k.mValue.GetMatrix()); aiVector3D qs, qr, qt; @@ -2121,7 +2125,7 @@ void FBXExporter::WriteObjects () times.clear(); xval.clear(); yval.clear(); zval.clear(); for (size_t ki = 0; ki < na->mNumScalingKeys; ++ki) { const aiVectorKey& k = na->mScalingKeys[ki]; - times.push_back(to_ktime(k.mTime, anim)); + times.push_back(to_ktime(k.mTime)); xval.push_back(k.mValue.x); yval.push_back(k.mValue.y); zval.push_back(k.mValue.z); From b176513efaa81b396900568dcf67b9f09a1a203e Mon Sep 17 00:00:00 2001 From: Michael Roer Pedersen Date: Fri, 1 Jun 2018 09:24:53 +0200 Subject: [PATCH 3/5] FBX export. to_ktime ticks was ok. --- .gitignore | 3 +++ code/FBXExporter.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 60884061d..d3ec794d5 100644 --- a/.gitignore +++ b/.gitignore @@ -87,3 +87,6 @@ lib64/assimp-vc120-mt.exp xcuserdata cmake-build-debug +/.vs +/code/assimp.vcxproj.user +*.user diff --git a/code/FBXExporter.cpp b/code/FBXExporter.cpp index 2403ca845..037520641 100644 --- a/code/FBXExporter.cpp +++ b/code/FBXExporter.cpp @@ -980,9 +980,9 @@ aiMatrix4x4 get_world_transform(const aiNode* node, const aiScene* scene) int64_t to_ktime(double ticks, const aiAnimation* anim) { if (anim->mTicksPerSecond <= 0) { - return static_cast(ticks * FBX::SECOND); + return static_cast(ticks) * FBX::SECOND; } - return (static_cast(ticks / anim->mTicksPerSecond * FBX::SECOND)); + return (static_cast(ticks) / static_cast(anim->mTicksPerSecond)) * FBX::SECOND; } int64_t to_ktime(double time) { From 4af69dbeb9e528c6f3e4b85ac1147cd68482a35c Mon Sep 17 00:00:00 2001 From: Michael Roer Pedersen Date: Fri, 1 Jun 2018 09:33:28 +0200 Subject: [PATCH 4/5] undo .gitignore --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index d3ec794d5..60884061d 100644 --- a/.gitignore +++ b/.gitignore @@ -87,6 +87,3 @@ lib64/assimp-vc120-mt.exp xcuserdata cmake-build-debug -/.vs -/code/assimp.vcxproj.user -*.user From f15dcf7663782e63334dc1c725b9a3ee4a7af7fa Mon Sep 17 00:00:00 2001 From: Sebastian Maisch Date: Fri, 1 Jun 2018 17:32:02 +0200 Subject: [PATCH 5/5] Added forced generation of normals with extra flag. --- code/GenFaceNormalsProcess.cpp | 5 +++-- code/GenFaceNormalsProcess.h | 3 ++- code/GenVertexNormalsProcess.cpp | 18 +++++++++++++++--- code/GenVertexNormalsProcess.h | 1 + include/assimp/postprocess.h | 5 ++++- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/code/GenFaceNormalsProcess.cpp b/code/GenFaceNormalsProcess.cpp index 6c222e154..30a26b898 100644 --- a/code/GenFaceNormalsProcess.cpp +++ b/code/GenFaceNormalsProcess.cpp @@ -74,6 +74,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; return (pFlags & aiProcess_GenNormals) != 0; } @@ -106,8 +107,8 @@ void GenFaceNormalsProcess::Execute( aiScene* pScene) bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh) { if (NULL != pMesh->mNormals) { - // return false; - delete[] pMesh->mNormals; + if (force_) delete[] pMesh->mNormals; + else return false; } // If the mesh consists of lines and/or points but not of diff --git a/code/GenFaceNormalsProcess.h b/code/GenFaceNormalsProcess.h index 27ae7acac..e2f41e07f 100644 --- a/code/GenFaceNormalsProcess.h +++ b/code/GenFaceNormalsProcess.h @@ -78,7 +78,8 @@ public: private: - bool GenMeshFaceNormals (aiMesh* pcMesh); + bool GenMeshFaceNormals(aiMesh* pcMesh); + mutable bool force_ = false; }; } // end of namespace Assimp diff --git a/code/GenVertexNormalsProcess.cpp b/code/GenVertexNormalsProcess.cpp index e0783b0a2..74139a646 100644 --- a/code/GenVertexNormalsProcess.cpp +++ b/code/GenVertexNormalsProcess.cpp @@ -72,6 +72,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; return (pFlags & aiProcess_GenSmoothNormals) != 0; } @@ -113,9 +114,9 @@ void GenVertexNormalsProcess::Execute( aiScene* pScene) bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int meshIndex) { if (NULL != pMesh->mNormals) { - delete[] pMesh->mNormals; + if (force_) delete[] pMesh->mNormals; + else return false; } -// return false; // If the mesh consists of lines and/or points but not of // triangles or higher-order polygons the normal vectors @@ -147,7 +148,18 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int 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]]; - const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)); + + auto pV12 = *pV2 - *pV1; + auto pV31 = *pV3 - *pV1; + + const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).Normalize(); + + if (std::isnan(vNor.x) || std::isnan(vNor.y) || std::isnan(vNor.z)) { + for (unsigned int i = 0; i < face.mNumIndices; ++i) { + pMesh->mNormals[face.mIndices[i]] = aiVector3D(0.0f, 0.0f, 0.0f); + } + continue; + } for (unsigned int i = 0;i < face.mNumIndices;++i) { pMesh->mNormals[face.mIndices[i]] = vNor; diff --git a/code/GenVertexNormalsProcess.h b/code/GenVertexNormalsProcess.h index 5ab9eb6f5..2efafa302 100644 --- a/code/GenVertexNormalsProcess.h +++ b/code/GenVertexNormalsProcess.h @@ -107,6 +107,7 @@ private: /** Configuration option: maximum smoothing angle, in radians*/ ai_real configMaxAngle; + mutable bool force_ = false; }; } // end of namespace Assimp diff --git a/include/assimp/postprocess.h b/include/assimp/postprocess.h index f6c0833ee..1cb9c72f8 100644 --- a/include/assimp/postprocess.h +++ b/include/assimp/postprocess.h @@ -555,10 +555,13 @@ enum aiPostProcessSteps * of the imported model. And if so, it uses that. */ aiProcess_EmbedTextures = 0x10000000, - + // aiProcess_GenEntityMeshes = 0x100000, // aiProcess_OptimizeAnimations = 0x200000 // aiProcess_FixTexturePaths = 0x200000 + + + aiProcess_ForceGenNormals = 0x20000000, };