2
0
Эх сурвалжийг харах

Add implementation to convert from cm to m.

Kim Kulling 6 жил өмнө
parent
commit
4155f005be

+ 41 - 3
code/FBXConverter.cpp

@@ -91,7 +91,7 @@ namespace Assimp {
         , out(out)
         , doc(doc)
         , mRemoveEmptyBones( removeEmptyBones )
-        , mCurrentUnit( FbxUnit::Undefined ) {
+        , mCurrentUnit(FbxUnit::cm) {
             // animations need to be converted first since this will
             // populate the node_anim_chain_bits map, which is needed
             // to determine which nodes need to be generated.
@@ -119,6 +119,7 @@ namespace Assimp {
 
             ConvertGlobalSettings();
             TransferDataToScene();
+            ConvertToUnitScale(doc.GlobalSettings().UnitScaleFactor());
 
             // if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE
             // to make sure the scene passes assimp's validation. FBX files
@@ -3410,8 +3411,9 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
 
             na->mNumScalingKeys = static_cast<unsigned int>(keys.size());
             na->mScalingKeys = new aiVectorKey[keys.size()];
-            if (keys.size() > 0)
+            if (keys.size() > 0) {
                 InterpolateKeys(na->mScalingKeys, keys, inputs, aiVector3D(1.0f, 1.0f, 1.0f), maxTime, minTime);
+            }
         }
 
         void FBXConverter::ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
@@ -3475,8 +3477,44 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
             out->mMetaData->Set(14, "CustomFrameRate", doc.GlobalSettings().CustomFrameRate());
         }
 
-        void FBXConverter::ConvertToUnitScale(FbxUnit unit) {
+        void FBXConverter::ConvertToUnitScale( FbxUnit unit ) {
+            if (mCurrentUnit == unit) {
+                return;
+            }
+
+            ai_real scale = 1.0;
+            if (mCurrentUnit == FbxUnit::cm) {
+                if (unit == FbxUnit::m) {
+                    scale = (ai_real)0.01;
+                } else if (unit == FbxUnit::km) {
+                    scale = (ai_real)0.00001;
+                }
+            } else if (mCurrentUnit == FbxUnit::m) {
+                if (unit == FbxUnit::cm) {
+                    scale = (ai_real)100.0;
+                } else if (unit == FbxUnit::km) {
+                    scale = (ai_real)0.001;
+                }
+            } else if (mCurrentUnit == FbxUnit::km) {
+                if (unit == FbxUnit::cm) {
+                    scale = (ai_real)100000.0;
+                } else if (unit == FbxUnit::m) {
+                    scale = (ai_real)1000.0;
+                }
+            }
+            
+            for (auto mesh : meshes) {
+                if (nullptr == mesh) {
+                    continue;
+                }
 
+                if (mesh->HasPositions()) {
+                    for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
+                        aiVector3D &pos = mesh->mVertices[i];
+                        pos *= scale;
+                    }
+                }
+            }
         }
 
         void FBXConverter::TransferDataToScene()

+ 2 - 4
code/FBXConverter.h

@@ -419,15 +419,13 @@ private:
         cm = 0,
         m,
         km,
-        inch,
-        foot,
-        mile,
-        yard,
         NumUnits,
 
         Undefined
     };
 
+    // ------------------------------------------------------------------------------------------------
+    //  Will perform the conversion from a given unit to the requested unit.
     void ConvertToUnitScale(FbxUnit unit);
 
     // ------------------------------------------------------------------------------------------------

+ 6 - 1
code/FBXImportSettings.h

@@ -65,7 +65,8 @@ struct ImportSettings
     , preservePivots(true)
     , optimizeEmptyAnimationCurves(true)
     , useLegacyEmbeddedTextureNaming(false)
-    , removeEmptyBones( true ) {
+    , removeEmptyBones( true )
+    , convertToMeters( false ) {
         // empty
     }
 
@@ -149,6 +150,10 @@ struct ImportSettings
     /** Empty bones shall be removed
     */
     bool removeEmptyBones;
+
+    /** Set to true to perform a conversion from cm to meter after the import
+    */
+    bool convertToMeters;
 };
 
 

+ 1 - 0
code/FBXImporter.cpp

@@ -141,6 +141,7 @@ void FBXImporter::SetupProperties(const Importer* pImp)
     settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
     settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
     settings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
+    settings.convertToMeters = pImpl->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false);
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/FBXMeshGeometry.cpp

@@ -576,7 +576,7 @@ void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out,
     const std::string& ReferenceInformationType)
 {
     const char * str = source.Elements().count( "Tangents" ) > 0 ? "Tangents" : "Tangent";
-    const char * strIdx = source.Elements().count( "Tangents" ) > 0 ? TangentsIndexToken.c_str() : TangentIndexToken.c_str();
+    const char * strIdx = source.Elements().count( "Tangents" ) > 0 ? TangentsIndexToken : TangentIndexToken;
     ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType,
         str,
         strIdx,

+ 8 - 1
include/assimp/config.h.in

@@ -659,13 +659,20 @@ enum aiComponent
 	"AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
 
 // ---------------------------------------------------------------------------
-/** @brief  Set wether the FBX importer shall not remove empty bones.
+/** @brief  Set wether the importer shall not remove empty bones.
  *  
  *  Empty bone are often used to define connections for other models.
  */
 #define AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES \
     "AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES"
 
+
+// ---------------------------------------------------------------------------
+/** @brief  Set wether the FBX importer shall convert the unit from cm to m.
+ */
+#define AI_CONFIG_FBX_CONVERT_TO_M \
+    "AI_CONFIG_FBX_CONVERT_TO_M"
+
 // ---------------------------------------------------------------------------
 /** @brief  Set the vertex animation keyframe to be imported
  *