فهرست منبع

Add option to ignore FBX custom axes (#5754)

AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION
Default false

Co-authored-by: Kim Kulling <[email protected]>
RichardTea 1 سال پیش
والد
کامیت
ed3fccd5db

+ 3 - 1
code/AssetLib/FBX/FBXConverter.cpp

@@ -181,7 +181,9 @@ FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBo
     if (out->mNumMeshes == 0) {
     if (out->mNumMeshes == 0) {
         out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
         out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
     } else {
     } else {
-        correctRootTransform(mSceneOut);
+        // Apply the FBX axis metadata unless requested not to
+        if (!doc.Settings().ignoreUpDirection)
+            correctRootTransform(mSceneOut);
     }
     }
 }
 }
 
 

+ 3 - 0
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
     /** Set to true to perform a conversion from cm to meter after the import
     */
     */
     bool convertToMeters;
     bool convertToMeters;
+
+    // Set to true to ignore the axis configuration in the file
+    bool ignoreUpDirection = false;
 };
 };
 
 
 } // namespace FBX
 } // namespace FBX

+ 1 - 0
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.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
     mSettings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
     mSettings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
     mSettings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false);
     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);
     mSettings.useSkeleton = pImp->GetPropertyBool(AI_CONFIG_FBX_USE_SKELETON_BONE_CONTAINER, false);
 }
 }
 
 

+ 13 - 0
include/assimp/config.h.in

@@ -676,6 +676,19 @@ enum aiComponent
 #define AI_CONFIG_FBX_CONVERT_TO_M \
 #define AI_CONFIG_FBX_CONVERT_TO_M \
     "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.
 /** @brief  Will enable the skeleton struct to store bone data.
  *
  *

+ 31 - 0
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) {
 TEST_F(utFBXImporterExporter, importCubesWithOutOfRangeFloat) {
     Assimp::Importer importer;
     Assimp::Importer importer;
     const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/cubes_with_outofrange_float.fbx", aiProcess_ValidateDataStructure);
     const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/cubes_with_outofrange_float.fbx", aiProcess_ValidateDataStructure);