From 1e6eac9e653f967f96655ab68ce12f64b225c571 Mon Sep 17 00:00:00 2001 From: follower Date: Fri, 2 Aug 2019 04:44:21 +1200 Subject: [PATCH 01/10] Fix error when building assimp on older Mac OS X version. Prevents this error when building with Mac OS X 10.9 SDK: error: no member named 'atoi' in namespace 'std'; did you mean simply 'atoi'? --- include/assimp/scene.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/assimp/scene.h b/include/assimp/scene.h index e973f6c5b..df5d6f3b5 100644 --- a/include/assimp/scene.h +++ b/include/assimp/scene.h @@ -56,6 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "material.h" #include "anim.h" #include "metadata.h" +#include #ifdef __cplusplus extern "C" { From 0400e0bc7fde9568f55e61735bd7cb03a6a8b524 Mon Sep 17 00:00:00 2001 From: RichardTea <31507749+RichardTea@users.noreply.github.com> Date: Fri, 16 Aug 2019 11:10:30 +0100 Subject: [PATCH 02/10] Multi-Config generators should also set the debug suffix when enabled Issue #2599 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 412628bbe..4f464ba46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -341,7 +341,7 @@ SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE STRING get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG) -IF (INJECT_DEBUG_POSTFIX AND (CMAKE_BUILD_TYPE STREQUAL "Debug")) +IF (INJECT_DEBUG_POSTFIX AND (is_multi_config OR CMAKE_BUILD_TYPE STREQUAL "Debug")) SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfix for lib, samples and tools") ELSE() SET(CMAKE_DEBUG_POSTFIX "" CACHE STRING "Debug Postfix for lib, samples and tools") From f69bf5f7edcb28d644ff5d6d785f9bd70d23453d Mon Sep 17 00:00:00 2001 From: Ghanshyam Bhutra Date: Fri, 16 Aug 2019 17:04:42 -0700 Subject: [PATCH 03/10] fix for div by zero reported by address sanitizer --- code/PostProcessing/CalcTangentsProcess.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/PostProcessing/CalcTangentsProcess.cpp b/code/PostProcessing/CalcTangentsProcess.cpp index b30f39c27..a3f7dd255 100644 --- a/code/PostProcessing/CalcTangentsProcess.cpp +++ b/code/PostProcessing/CalcTangentsProcess.cpp @@ -212,7 +212,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) // project tangent and bitangent into the plane formed by the vertex' normal aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]); aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]); - localTangent.Normalize(); localBitangent.Normalize(); + localTangent.NormalizeSafe(); localBitangent.NormalizeSafe(); // reconstruct tangent/bitangent according to normal and bitangent/tangent when it's infinite or NaN. bool invalid_tangent = is_special_float(localTangent.x) || is_special_float(localTangent.y) || is_special_float(localTangent.z); @@ -220,10 +220,10 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) if (invalid_tangent != invalid_bitangent) { if (invalid_tangent) { localTangent = meshNorm[p] ^ localBitangent; - localTangent.Normalize(); + localTangent.NormalizeSafe(); } else { localBitangent = localTangent ^ meshNorm[p]; - localBitangent.Normalize(); + localBitangent.NormalizeSafe(); } } From 7ee7946dc56d4260affcb56b6322bf440f2fc40f Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sun, 18 Aug 2019 09:40:13 +0200 Subject: [PATCH 04/10] Update scene.h use #include only if the compiler is used to compile c++ code. --- include/assimp/scene.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/assimp/scene.h b/include/assimp/scene.h index df5d6f3b5..2667db85b 100644 --- a/include/assimp/scene.h +++ b/include/assimp/scene.h @@ -56,9 +56,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "material.h" #include "anim.h" #include "metadata.h" -#include #ifdef __cplusplus +# include extern "C" { #endif From e5372fc385559d8223da5b4673fe9d5fdf63c1aa Mon Sep 17 00:00:00 2001 From: anandvsingh Date: Sun, 18 Aug 2019 15:44:38 +0200 Subject: [PATCH 05/10] Update CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f464ba46..9bbf8bb50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,7 +173,7 @@ SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VER SET (ASSIMP_SOVERSION 5) SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" ) - +set(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Ob2") if(NOT HUNTER_ENABLED) # Enable C++11 support globally set_property( GLOBAL PROPERTY CXX_STANDARD 11 ) From 74685477e6276b4301eeaaf5fcc9830d3a1e02ec Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Mon, 19 Aug 2019 17:22:51 +0200 Subject: [PATCH 06/10] Update CMakeLists.txt Put it into the win32 for VS part. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bbf8bb50..3ed9f6b56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,7 +173,6 @@ SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VER SET (ASSIMP_SOVERSION 5) SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" ) -set(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Ob2") if(NOT HUNTER_ENABLED) # Enable C++11 support globally set_property( GLOBAL PROPERTY CXX_STANDARD 11 ) @@ -254,6 +253,7 @@ ELSEIF(MSVC) IF(MSVC12) ADD_COMPILE_OPTIONS(/wd4351) ENDIF() + SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Ob2") ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" ) IF(NOT HUNTER_ENABLED) SET(CMAKE_CXX_FLAGS "-fPIC -std=c++11 ${CMAKE_CXX_FLAGS}") From fbb34b1de159de772a6715acf9759acf11fcf543 Mon Sep 17 00:00:00 2001 From: Gordon MacPherson Date: Mon, 12 Aug 2019 19:17:07 +0100 Subject: [PATCH 07/10] ScaleProcess overhauled to improve compatibility with animations and unit conversion. ./assimp Added arguments --gs to assimp command line option to enable global scaling. No scaling for mScale of 1.0. Co-Authored-By: K. S. Ernest (iFire) Lee --- code/PostProcessing/ScaleProcess.cpp | 116 ++++++++++++++++++++++++--- code/PostProcessing/ScaleProcess.h | 13 ++- test/unit/TestModelFactory.h | 2 +- test/unit/utScaleProcess.cpp | 13 --- tools/assimp_cmd/Main.cpp | 4 + 5 files changed, 121 insertions(+), 27 deletions(-) diff --git a/code/PostProcessing/ScaleProcess.cpp b/code/PostProcessing/ScaleProcess.cpp index 6d458c4b1..36c59ecf5 100644 --- a/code/PostProcessing/ScaleProcess.cpp +++ b/code/PostProcessing/ScaleProcess.cpp @@ -39,19 +39,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ -#ifndef ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS - #include "ScaleProcess.h" #include #include + namespace Assimp { ScaleProcess::ScaleProcess() : BaseProcess() , mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) { - // empty } ScaleProcess::~ScaleProcess() { @@ -71,10 +69,15 @@ bool ScaleProcess::IsActive( unsigned int pFlags ) const { } void ScaleProcess::SetupProperties( const Importer* pImp ) { - mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 0 ); + mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 1.0f ); } void ScaleProcess::Execute( aiScene* pScene ) { + if(mScale == 1.0f) return; // nothing to scale + + ai_assert(mScale != 0); + ai_assert(nullptr != pScene && nullptr != pScene->mRootNode); + if ( nullptr == pScene ) { return; } @@ -82,22 +85,113 @@ void ScaleProcess::Execute( aiScene* pScene ) { if ( nullptr == pScene->mRootNode ) { return; } + + // Process animations and update position transform to new unit system + for( unsigned int animationID = 0; animationID < pScene->mNumAnimations; animationID++ ) + { + aiAnimation* animation = pScene->mAnimations[animationID]; + + for( unsigned int animationChannel = 0; animationChannel < animation->mNumChannels; animationChannel++) + { + aiNodeAnim* anim = animation->mChannels[animationChannel]; + + for( unsigned int posKey = 0; posKey < anim->mNumPositionKeys; posKey++) + { + aiVectorKey& vectorKey = anim->mPositionKeys[posKey]; + vectorKey.mValue *= mScale; + } + } + } + + for( unsigned int meshID = 0; meshID < pScene->mNumMeshes; meshID++) + { + aiMesh *mesh = pScene->mMeshes[meshID]; + + // Reconstruct mesh vertexes to the new unit system + for( unsigned int vertexID = 0; vertexID < mesh->mNumVertices; vertexID++) + { + aiVector3D& vertex = mesh->mVertices[vertexID]; + vertex *= mScale; + } + + + // bone placement / scaling + for( unsigned int boneID = 0; boneID < mesh->mNumBones; boneID++) + { + // Reconstruct matrix by transform rather than by scale + // This prevent scale values being changed which can + // be meaningful in some cases + // like when you want the modeller to see 1:1 compatibility. + aiBone* bone = mesh->mBones[boneID]; + + aiVector3D pos, scale; + aiQuaternion rotation; + + bone->mOffsetMatrix.Decompose( scale, rotation, pos); + + aiMatrix4x4 translation; + aiMatrix4x4::Translation( pos * mScale, translation ); + + aiMatrix4x4 scaling; + aiMatrix4x4::Scaling( aiVector3D(scale), scaling ); + + aiMatrix4x4 RotMatrix = aiMatrix4x4 (rotation.GetMatrix()); + + bone->mOffsetMatrix = translation * RotMatrix * scaling; + } + + + // animation mesh processing + // convert by position rather than scale. + for( unsigned int animMeshID = 0; animMeshID < mesh->mNumAnimMeshes; animMeshID++) + { + aiAnimMesh * animMesh = mesh->mAnimMeshes[animMeshID]; + + for( unsigned int vertexID = 0; vertexID < animMesh->mNumVertices; vertexID++) + { + aiVector3D& vertex = animMesh->mVertices[vertexID]; + vertex *= mScale; + } + } + } traverseNodes( pScene->mRootNode ); } -void ScaleProcess::traverseNodes( aiNode *node ) { +void ScaleProcess::traverseNodes( aiNode *node, unsigned int nested_node_id ) { applyScaling( node ); + + for( size_t i = 0; i < node->mNumChildren; i++) + { + // recurse into the tree until we are done! + traverseNodes( node->mChildren[i], nested_node_id+1 ); + } } void ScaleProcess::applyScaling( aiNode *currentNode ) { if ( nullptr != currentNode ) { - currentNode->mTransformation.a1 = currentNode->mTransformation.a1 * mScale; - currentNode->mTransformation.b2 = currentNode->mTransformation.b2 * mScale; - currentNode->mTransformation.c3 = currentNode->mTransformation.c3 * mScale; + // Reconstruct matrix by transform rather than by scale + // This prevent scale values being changed which can + // be meaningful in some cases + // like when you want the modeller to + // see 1:1 compatibility. + + aiVector3D pos, scale; + aiQuaternion rotation; + currentNode->mTransformation.Decompose( scale, rotation, pos); + + aiMatrix4x4 translation; + aiMatrix4x4::Translation( pos * mScale, translation ); + + aiMatrix4x4 scaling; + + // note: we do not use mScale here, this is on purpose. + aiMatrix4x4::Scaling( scale, scaling ); + + aiMatrix4x4 RotMatrix = aiMatrix4x4 (rotation.GetMatrix()); + + currentNode->mTransformation = translation * RotMatrix * scaling; } } -} // Namespace Assimp - -#endif // !! ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS +} // Namespace Assimp \ No newline at end of file diff --git a/code/PostProcessing/ScaleProcess.h b/code/PostProcessing/ScaleProcess.h index 256737875..468a21673 100644 --- a/code/PostProcessing/ScaleProcess.h +++ b/code/PostProcessing/ScaleProcess.h @@ -39,7 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ -#pragma once +#ifndef SCALE_PROCESS_H_ +#define SCALE_PROCESS_H_ #include "Common/BaseProcess.h" @@ -53,6 +54,11 @@ namespace Assimp { // --------------------------------------------------------------------------- /** ScaleProcess: Class to rescale the whole model. + * Now rescales animations, bones, and blend shapes properly. + * Please note this will not write to 'scale' transform it will rewrite mesh + * and matrixes so that your scale values + * from your model package are preserved, so this is completely intentional + * bugs should be reported as soon as they are found. */ class ASSIMP_API ScaleProcess : public BaseProcess { public: @@ -78,7 +84,7 @@ public: virtual void Execute( aiScene* pScene ); private: - void traverseNodes( aiNode *currentNode ); + void traverseNodes( aiNode *currentNode, unsigned int nested_node_id = 0 ); void applyScaling( aiNode *currentNode ); private: @@ -86,3 +92,6 @@ private: }; } // Namespace Assimp + + +#endif // SCALE_PROCESS_H_ \ No newline at end of file diff --git a/test/unit/TestModelFactory.h b/test/unit/TestModelFactory.h index f1ef1701f..0e48fb744 100644 --- a/test/unit/TestModelFactory.h +++ b/test/unit/TestModelFactory.h @@ -89,7 +89,7 @@ public: scene->mMeshes[ 0 ]->mFaces[ 0 ].mIndices[ 1 ] = 1; scene->mMeshes[ 0 ]->mFaces[ 0 ].mIndices[ 2 ] = 2; - scene->mRootNode = new aiNode; + scene->mRootNode = new aiNode(); scene->mRootNode->mNumMeshes = 1; scene->mRootNode->mMeshes = new unsigned int[1]{ 0 }; diff --git a/test/unit/utScaleProcess.cpp b/test/unit/utScaleProcess.cpp index fe87daa8d..fd2773c24 100644 --- a/test/unit/utScaleProcess.cpp +++ b/test/unit/utScaleProcess.cpp @@ -69,18 +69,5 @@ TEST_F( utScaleProcess, accessScaleTest ) { EXPECT_FLOAT_EQ( 2.0f, process.getScale() ); } -TEST_F( utScaleProcess, rescaleModelTest ) { - float opacity; - aiScene *testScene = TestModelFacttory::createDefaultTestModel( opacity ); - ai_real v1 = testScene->mRootNode->mTransformation.a1; - ScaleProcess process; - process.setScale( 10.0f ); - process.Execute( testScene ); - ai_real v2 = testScene->mRootNode->mTransformation.a1; - const ai_real scale = v2 / v1; - EXPECT_FLOAT_EQ( scale, 10.0f ); - TestModelFacttory::releaseDefaultTestModel( &testScene ); -} - } // Namespace UnitTest } // Namespace Assimp diff --git a/tools/assimp_cmd/Main.cpp b/tools/assimp_cmd/Main.cpp index af372582c..9173a756b 100644 --- a/tools/assimp_cmd/Main.cpp +++ b/tools/assimp_cmd/Main.cpp @@ -384,6 +384,7 @@ int ProcessStandardArguments( // -om --optimize-meshes // -db --debone // -sbc --split-by-bone-count + // -gs --global-scale // // -c --config-file= @@ -472,6 +473,9 @@ int ProcessStandardArguments( else if (!strcmp(param, "-embtex") || ! strcmp(param, "--embed-textures")) { fill.ppFlags |= aiProcess_EmbedTextures; } + else if (!strcmp(param, "-gs") || ! strcmp(param, "--global-scale")) { + fill.ppFlags |= aiProcess_GlobalScale; + } else if (! strncmp( param, "-c",2) || ! strncmp( param, "--config=",9)) { const unsigned int ofs = (params[i][1] == '-' ? 9 : 2); From eb55a6a3cd5030e2c15037505b335fc5a9904ec8 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Mon, 19 Aug 2019 20:24:01 +0200 Subject: [PATCH 08/10] Update ScaleProcess.cpp Fix review findings. --- code/PostProcessing/ScaleProcess.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/code/PostProcessing/ScaleProcess.cpp b/code/PostProcessing/ScaleProcess.cpp index 36c59ecf5..2a605d6bc 100644 --- a/code/PostProcessing/ScaleProcess.cpp +++ b/code/PostProcessing/ScaleProcess.cpp @@ -73,10 +73,13 @@ void ScaleProcess::SetupProperties( const Importer* pImp ) { } void ScaleProcess::Execute( aiScene* pScene ) { - if(mScale == 1.0f) return; // nothing to scale + if(mScale == 1.0f) { + return; // nothing to scale + } - ai_assert(mScale != 0); - ai_assert(nullptr != pScene && nullptr != pScene->mRootNode); + ai_assert( mScale != 0 ); + ai_assert( nullptr != pScene ); + ai_assert( nullptr != pScene->mRootNode ); if ( nullptr == pScene ) { return; @@ -194,4 +197,4 @@ void ScaleProcess::applyScaling( aiNode *currentNode ) { } } -} // Namespace Assimp \ No newline at end of file +} // Namespace Assimp From b8d4ae5a7c01c0967088aee53c7d7ede12deecde Mon Sep 17 00:00:00 2001 From: RichardTea <31507749+RichardTea@users.noreply.github.com> Date: Wed, 21 Aug 2019 15:54:14 +0100 Subject: [PATCH 09/10] Add git commit, original filename to DLL PE header Windows only --- code/res/assimp.rc | 4 ++-- revision.h.in | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/code/res/assimp.rc b/code/res/assimp.rc index 14ffdf4f5..daecf9cf5 100644 --- a/code/res/assimp.rc +++ b/code/res/assimp.rc @@ -52,8 +52,8 @@ BEGIN VALUE "FileDescription", "Open Asset Import Library" VALUE "FileVersion", VER_FILEVERSION VALUE "InternalName", "assimp " - VALUE "LegalCopyright", "Copyright (C) 2006-2010" - VALUE "OriginalFilename", "assimpNN.dll" + VALUE "LegalCopyright", "Copyright (C) 2006-2019" + VALUE "OriginalFilename", VER_ORIGINAL_FILENAME_STR VALUE "ProductName", "Open Asset Import Library" VALUE "ProductVersion", VER_FILEVERSION_STR ,0 diff --git a/revision.h.in b/revision.h.in index 0ad58feb7..2be06c56b 100644 --- a/revision.h.in +++ b/revision.h.in @@ -13,6 +13,16 @@ #define STR(x) STR_HELP(x) #define VER_FILEVERSION VER_MAJOR,VER_MINOR,VER_PATCH,VER_BUILD +#if (GitVersion == 0) #define VER_FILEVERSION_STR STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) "." STR(VER_BUILD) +#else +#define VER_FILEVERSION_STR STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) "." STR(VER_BUILD) " (Commit 0x@GIT_COMMIT_HASH@)" +#endif + +#ifdef NDEBUG +#define VER_ORIGINAL_FILENAME_STR "assimp@LIBRARY_SUFFIX@.dll" +#else +#define VER_ORIGINAL_FILENAME_STR "assimp@LIBRARY_SUFFIX@@CMAKE_DEBUG_POSTFIX@.dll" +#endif // NDEBUG #endif // ASSIMP_REVISION_H_INC From 0f6e95f19db4d981042504991ec924002f23b1c9 Mon Sep 17 00:00:00 2001 From: RichardTea <31507749+RichardTea@users.noreply.github.com> Date: Wed, 21 Aug 2019 16:07:51 +0100 Subject: [PATCH 10/10] Fix typo. githash canonically doesn't start 0x --- revision.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/revision.h.in b/revision.h.in index 2be06c56b..6d09afbc6 100644 --- a/revision.h.in +++ b/revision.h.in @@ -16,7 +16,7 @@ #if (GitVersion == 0) #define VER_FILEVERSION_STR STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) "." STR(VER_BUILD) #else -#define VER_FILEVERSION_STR STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) "." STR(VER_BUILD) " (Commit 0x@GIT_COMMIT_HASH@)" +#define VER_FILEVERSION_STR STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) "." STR(VER_BUILD) " (Commit @GIT_COMMIT_HASH@)" #endif #ifdef NDEBUG