diff --git a/src/geometry/geo_reference.cpp b/src/geometry/geo_reference.cpp index 8c04eba3..81479fd4 100644 --- a/src/geometry/geo_reference.cpp +++ b/src/geometry/geo_reference.cpp @@ -86,7 +86,7 @@ namespace plateau::geometry { // WUN → ENU の式は 逆変換 ENU → WUN と同じです。 return { -vertex.x, vertex.z, vertex.y }; case CoordinateSystem::ESU: - // EUN → ESU の式は 逆変換 ESU → EUN と同じです。 + // ENU → ESU の式は 逆変換 ESU → ENU と同じです。 return { vertex.x, -vertex.y, vertex.z }; case CoordinateSystem::EUN: // EUN → ENU の式は 逆変換 ENU → EUN と同じです。 diff --git a/src/mesh_writer/fbx_writer.cpp b/src/mesh_writer/fbx_writer.cpp index 70eabbbe..856ff927 100644 --- a/src/mesh_writer/fbx_writer.cpp +++ b/src/mesh_writer/fbx_writer.cpp @@ -45,6 +45,42 @@ namespace plateau::meshWriter { ios->SetBoolProp(EXP_ASCIIFBX, options.file_format == FbxFileFormat::ASCII); const auto fbx_scene = FbxScene::Create(manager_, ""); + FbxAxisSystem axis_system; + // FBXのデファクトは右手座標系です。 + // 左手座標系ではUnityやUEで正しく読み込めないことがあるため非推奨です。 + switch (options.coordinate_system) { + case geometry::CoordinateSystem::ENU: + axis_system = FbxAxisSystem( + FbxAxisSystem::EUpVector::eZAxis, + FbxAxisSystem::EFrontVector::eParityOdd, // X,Y,ZからUp軸を除いて、残った2軸のうち前者ならParityEven, 後者ならParityOdd + FbxAxisSystem::eRightHanded); // フレミングの法則の要領で中指を折ったとき、親指がX、人差し指がY、中指がZ。左右どちらの手に合うか。 + break; + case geometry::CoordinateSystem::ESU: + axis_system = FbxAxisSystem( + FbxAxisSystem::EUpVector::eZAxis, + FbxAxisSystem::EFrontVector::eParityOdd, + FbxAxisSystem::eLeftHanded); + break; + case geometry::CoordinateSystem::WUN: + axis_system = FbxAxisSystem( + FbxAxisSystem::EUpVector::eYAxis, + FbxAxisSystem::EFrontVector::eParityOdd, + FbxAxisSystem::eRightHanded); + break; + case geometry::CoordinateSystem::EUN: + axis_system = FbxAxisSystem( + FbxAxisSystem::EUpVector::eYAxis, + FbxAxisSystem::EFrontVector::eParityOdd, + FbxAxisSystem::eLeftHanded); + break; + } + // 座標軸の向きをFBXファイルに書き込みます。 + // これを確認するには、FBXをASCIIフォーマットで出力してテキストエディタで開き、 + // GlobalSettingsのPropertiesのAxis系プロパティを確認します。 + // これにより、どの座標軸で書き出したとしてもアプリケーションにFBXをインポートするときに向き補正が働き、 + // 同じ向きに読み込めるはずです(非推奨の左手座標系は除く)。 + fbx_scene->GetGlobalSettings().SetAxisSystem(axis_system); + // create scene info FbxDocumentInfo* SceneInfo = FbxDocumentInfo::Create(manager_, "SceneInfo"); fbx_scene->SetSceneInfo(SceneInfo); diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/MeshWriter/FbxWriterTest.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/MeshWriter/FbxWriterTest.cs index d0b7672b..3a5b52cd 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/MeshWriter/FbxWriterTest.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU.Test/MeshWriter/FbxWriterTest.cs @@ -1,5 +1,6 @@ using System.IO; using Microsoft.VisualStudio.TestTools.UnitTesting; +using PLATEAU.Geometries; using PLATEAU.MeshWriter; using PLATEAU.Test.CityGML; using PLATEAU.Test.GeometryModel; @@ -19,7 +20,7 @@ public void WriteGenerateFbxFile() string gmlPath = TestUtil.GetGmlPath(TestUtil.GmlFileCase.Simple); string fbxFileName = Path.GetFileNameWithoutExtension(gmlPath) + ".fbx"; string fbxPath = Path.Combine(testDir, fbxFileName); - var option = new FbxWriteOptions(FbxFileFormat.Binary); + var option = new FbxWriteOptions(FbxFileFormat.Binary, CoordinateSystem.ENU); bool isSucceed = FbxWriter.Write(fbxPath, model, option); diff --git a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/MeshWriter/FbxWriter.cs b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/MeshWriter/FbxWriter.cs index d024e37c..8d1728e2 100644 --- a/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/MeshWriter/FbxWriter.cs +++ b/wrappers/csharp/LibPLATEAU.NET/CSharpPLATEAU/MeshWriter/FbxWriter.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.InteropServices; +using PLATEAU.Geometries; using PLATEAU.Interop; using PLATEAU.PolygonMesh; @@ -9,10 +10,12 @@ namespace PLATEAU.MeshWriter public struct FbxWriteOptions { public FbxFileFormat FileFormat; + public CoordinateSystem CoordinateSystem; - public FbxWriteOptions(FbxFileFormat fileFormat) + public FbxWriteOptions(FbxFileFormat fileFormat, CoordinateSystem coordinateSystem) { this.FileFormat = fileFormat; + this.CoordinateSystem = coordinateSystem; } }