From ed3fccd5db222d91140a1d45af54a1c7379f3a6a Mon Sep 17 00:00:00 2001 From: RichardTea <31507749+RichardTea@users.noreply.github.com> Date: Thu, 5 Sep 2024 20:03:26 +0100 Subject: [PATCH] Add option to ignore FBX custom axes (#5754) AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION Default false Co-authored-by: Kim Kulling --- code/AssetLib/FBX/FBXConverter.cpp | 4 +++- code/AssetLib/FBX/FBXImportSettings.h | 3 +++ code/AssetLib/FBX/FBXImporter.cpp | 1 + include/assimp/config.h.in | 13 +++++++++++ test/unit/utFBXImporterExporter.cpp | 31 +++++++++++++++++++++++++++ 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index d9718685d..6ce00bb85 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -181,7 +181,9 @@ FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBo if (out->mNumMeshes == 0) { out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; } else { - correctRootTransform(mSceneOut); + // Apply the FBX axis metadata unless requested not to + if (!doc.Settings().ignoreUpDirection) + correctRootTransform(mSceneOut); } } diff --git a/code/AssetLib/FBX/FBXImportSettings.h b/code/AssetLib/FBX/FBXImportSettings.h index 74290f7e0..bd355bd34 100644 --- a/code/AssetLib/FBX/FBXImportSettings.h +++ b/code/AssetLib/FBX/FBXImportSettings.h @@ -156,6 +156,9 @@ struct ImportSettings { /** Set to true to perform a conversion from cm to meter after the import */ bool convertToMeters; + + // Set to true to ignore the axis configuration in the file + bool ignoreUpDirection = false; }; } // namespace FBX diff --git a/code/AssetLib/FBX/FBXImporter.cpp b/code/AssetLib/FBX/FBXImporter.cpp index 3a8fb8b8a..491919bdc 100644 --- a/code/AssetLib/FBX/FBXImporter.cpp +++ b/code/AssetLib/FBX/FBXImporter.cpp @@ -117,6 +117,7 @@ void FBXImporter::SetupProperties(const Importer *pImp) { mSettings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false); mSettings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true); mSettings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false); + mSettings.ignoreUpDirection = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION, false); mSettings.useSkeleton = pImp->GetPropertyBool(AI_CONFIG_FBX_USE_SKELETON_BONE_CONTAINER, false); } diff --git a/include/assimp/config.h.in b/include/assimp/config.h.in index 5194a213c..95107f916 100644 --- a/include/assimp/config.h.in +++ b/include/assimp/config.h.in @@ -676,6 +676,19 @@ enum aiComponent #define AI_CONFIG_FBX_CONVERT_TO_M \ "AI_CONFIG_FBX_CONVERT_TO_M" +// --------------------------------------------------------------------------- +/** @brief Set whether the FBX importer shall ignore the provided axis configuration + * + * If this property is set to true, the axis directions provided in the FBX file + * will be ignored and the file will be loaded as is. + * + * Set to true for Assimp 5.3.x and earlier behavior + * Equivalent to AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION + * Property type: Bool. Default value: false. + */ +#define AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION \ + "AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION" + // --------------------------------------------------------------------------- /** @brief Will enable the skeleton struct to store bone data. * diff --git a/test/unit/utFBXImporterExporter.cpp b/test/unit/utFBXImporterExporter.cpp index 5cc40d216..940724670 100644 --- a/test/unit/utFBXImporterExporter.cpp +++ b/test/unit/utFBXImporterExporter.cpp @@ -311,6 +311,37 @@ TEST_F(utFBXImporterExporter, sceneMetadata) { } } +TEST_F(utFBXImporterExporter, importCustomAxes) { + // see https://github.com/assimp/assimp/issues/5494 + Assimp::Importer importer; + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/embedded_ascii/box.FBX", aiProcess_ValidateDataStructure); + EXPECT_NE(nullptr, scene); + + // The ASCII box has customised the Up and Forward axes, verify that the RootNode transform has applied it + ASSERT_FALSE(scene->mRootNode->mTransformation.IsIdentity()) << "Did not apply the custom axis transform"; + + aiVector3D upVec{ 0, 0, 1 }; // Up is +Z + aiVector3D forwardVec{ 0, -1, 0 }; // Forward is -Y + aiVector3D rightVec{ 1, 0, 0 }; // Right is +X + aiMatrix4x4 mat(rightVec.x, rightVec.y, rightVec.z, 0.0f, + upVec.x, upVec.y, upVec.z, 0.0f, + forwardVec.x, forwardVec.y, forwardVec.z, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); + + EXPECT_EQ(mat, scene->mRootNode->mTransformation); +} + +TEST_F(utFBXImporterExporter, importIgnoreCustomAxes) { + // see https://github.com/assimp/assimp/issues/5494 + Assimp::Importer importer; + importer.SetPropertyBool(AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION, true); + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/embedded_ascii/box.FBX", aiProcess_ValidateDataStructure); + EXPECT_NE(nullptr, scene); + + // Verify that the RootNode transform has NOT applied the custom axes + EXPECT_TRUE(scene->mRootNode->mTransformation.IsIdentity()); +} + TEST_F(utFBXImporterExporter, importCubesWithOutOfRangeFloat) { Assimp::Importer importer; const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/cubes_with_outofrange_float.fbx", aiProcess_ValidateDataStructure);