- [Core] Organize FBXWrapper.

This commit is contained in:
Razmoth
2023-11-20 21:33:22 +04:00
parent 43f3f52be3
commit 2568e4be08
7 changed files with 93 additions and 92 deletions

View File

@@ -91,7 +91,6 @@ namespace AssetStudio.CLI
public readonly Argument<FileInfo> Input; public readonly Argument<FileInfo> Input;
public readonly Argument<DirectoryInfo> Output; public readonly Argument<DirectoryInfo> Output;
public OptionsBinder() public OptionsBinder()
{ {
Silent = new Option<bool>("--silent", "Hide log messages."); Silent = new Option<bool>("--silent", "Hide log messages.");

View File

@@ -367,21 +367,23 @@ namespace AssetStudio.CLI
private static void ExportFbx(IImported convert, string exportPath) private static void ExportFbx(IImported convert, string exportPath)
{ {
var eulerFilter = Properties.Settings.Default.eulerFilter; var exportOptions = new Fbx.ExportOptions()
var filterPrecision = (float)Properties.Settings.Default.filterPrecision; {
var exportAllNodes = Properties.Settings.Default.exportAllNodes; eulerFilter = Properties.Settings.Default.eulerFilter,
var exportSkins = Properties.Settings.Default.exportSkins; filterPrecision = (float)Properties.Settings.Default.filterPrecision,
var exportAnimations = Properties.Settings.Default.exportAnimations; exportAllNodes = Properties.Settings.Default.exportAllNodes,
var exportBlendShape = Properties.Settings.Default.exportBlendShape; exportSkins = Properties.Settings.Default.exportSkins,
var castToBone = Properties.Settings.Default.castToBone; exportAnimations = Properties.Settings.Default.exportAnimations,
var boneSize = (int)Properties.Settings.Default.boneSize; exportBlendShape = Properties.Settings.Default.exportBlendShape,
var exportAllUvsAsDiffuseMaps = Properties.Settings.Default.exportAllUvsAsDiffuseMaps; castToBone = Properties.Settings.Default.castToBone,
var exportUV0UV1 = Properties.Settings.Default.exportUV0UV1; boneSize = (int)Properties.Settings.Default.boneSize,
var scaleFactor = (float)Properties.Settings.Default.scaleFactor; exportAllUvsAsDiffuseMaps = Properties.Settings.Default.exportAllUvsAsDiffuseMaps,
var fbxVersion = Properties.Settings.Default.fbxVersion; exportUV0UV1 = Properties.Settings.Default.exportUV0UV1,
var fbxFormat = Properties.Settings.Default.fbxFormat; scaleFactor = (float)Properties.Settings.Default.scaleFactor,
ModelExporter.ExportFbx(exportPath, convert, eulerFilter, filterPrecision, fbxVersion = Properties.Settings.Default.fbxVersion,
exportAllNodes, exportSkins, exportAnimations, exportBlendShape, castToBone, boneSize, exportAllUvsAsDiffuseMaps, exportUV0UV1, scaleFactor, fbxVersion, fbxFormat == 1); fbxFormat = Properties.Settings.Default.fbxFormat
};
ModelExporter.ExportFbx(exportPath, convert, exportOptions);
} }
public static bool ExportDumpFile(AssetItem item, string exportPath) public static bool ExportDumpFile(AssetItem item, string exportPath)

View File

@@ -1,5 +1,6 @@
using AssetStudio.FbxInterop; using AssetStudio.FbxInterop;
using AssetStudio.PInvoke; using AssetStudio.PInvoke;
using Newtonsoft.Json.Linq;
using System.IO; using System.IO;
namespace AssetStudio namespace AssetStudio
@@ -26,9 +27,7 @@ namespace AssetStudio
public static class Exporter public static class Exporter
{ {
public static void Export(string path, IImported imported, ExportOptions exportOptions)
public static void Export(string path, IImported imported, bool eulerFilter, float filterPrecision,
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, bool exportAllUvsAsDiffuseMaps, bool exportUV0UV1, float scaleFactor, int versionIndex, bool isAscii)
{ {
var file = new FileInfo(path); var file = new FileInfo(path);
var dir = file.Directory; var dir = file.Directory;
@@ -43,16 +42,31 @@ namespace AssetStudio
var name = Path.GetFileName(path); var name = Path.GetFileName(path);
using (var exporter = new FbxExporter(name, imported, allNodes, skins, castToBone, boneSize, exportAllUvsAsDiffuseMaps, exportUV0UV1, scaleFactor, versionIndex, isAscii)) using (var exporter = new FbxExporter(name, imported, exportOptions))
{ {
exporter.Initialize(); exporter.Initialize();
exporter.ExportAll(blendShape, animation, eulerFilter, filterPrecision); exporter.ExportAll();
} }
Directory.SetCurrentDirectory(currentDir); Directory.SetCurrentDirectory(currentDir);
} }
} }
public record ExportOptions
{
public bool eulerFilter;
public float filterPrecision;
public bool exportAllNodes;
public bool exportSkins;
public bool exportAnimations;
public bool exportBlendShape;
public bool castToBone;
public int boneSize;
public bool exportAllUvsAsDiffuseMaps;
public bool exportUV0UV1;
public float scaleFactor;
public int fbxVersion;
public int fbxFormat;
}
} }
} }

View File

@@ -11,31 +11,14 @@ namespace AssetStudio.FbxInterop
private readonly string _fileName; private readonly string _fileName;
private readonly IImported _imported; private readonly IImported _imported;
private readonly bool _allNodes; private readonly Fbx.ExportOptions _exportOptions;
private readonly bool _exportSkins;
private readonly bool _castToBone;
private readonly float _boneSize;
private readonly bool _exportAllUvsAsDiffuseMaps;
private readonly bool _exportUV0UV1;
private readonly float _scaleFactor;
private readonly int _versionIndex;
private readonly bool _isAscii;
internal FbxExporter(string fileName, IImported imported, bool allNodes, bool exportSkins, bool castToBone, float boneSize, bool exportAllUvsAsDiffuseMaps, bool exportUV0UV1, float scaleFactor, int versionIndex, bool isAscii) internal FbxExporter(string fileName, IImported imported, Fbx.ExportOptions exportOptions)
{ {
_context = new FbxExporterContext(); _context = new FbxExporterContext(exportOptions);
_exportOptions = exportOptions;
_fileName = fileName; _fileName = fileName;
_imported = imported; _imported = imported;
_allNodes = allNodes;
_exportSkins = exportSkins;
_castToBone = castToBone;
_boneSize = boneSize;
_exportAllUvsAsDiffuseMaps = exportAllUvsAsDiffuseMaps;
_exportUV0UV1 = exportUV0UV1;
_scaleFactor = scaleFactor;
_versionIndex = versionIndex;
_isAscii = isAscii;
} }
~FbxExporter() ~FbxExporter()
@@ -70,9 +53,9 @@ namespace AssetStudio.FbxInterop
{ {
var is60Fps = _imported.AnimationList.Count > 0 && _imported.AnimationList[0].SampleRate.Equals(60.0f); var is60Fps = _imported.AnimationList.Count > 0 && _imported.AnimationList[0].SampleRate.Equals(60.0f);
_context.Initialize(_fileName, _scaleFactor, _versionIndex, _isAscii, is60Fps); _context.Initialize(_fileName, is60Fps);
if (!_allNodes) if (!_exportOptions.exportAllNodes)
{ {
var framePaths = SearchHierarchy(); var framePaths = SearchHierarchy();
@@ -80,7 +63,7 @@ namespace AssetStudio.FbxInterop
} }
} }
internal void ExportAll(bool blendShape, bool animation, bool eulerFilter, float filterPrecision) internal void ExportAll()
{ {
var meshFrames = new List<ImportedFrame>(); var meshFrames = new List<ImportedFrame>();
@@ -101,14 +84,14 @@ namespace AssetStudio.FbxInterop
if (blendShape) if (_exportOptions.exportBlendShape)
{ {
ExportMorphs(); ExportMorphs();
} }
if (animation) if (_exportOptions.exportAnimations)
{ {
ExportAnimations(eulerFilter, filterPrecision); ExportAnimations();
} }
ExportScene(); ExportScene();
@@ -119,9 +102,9 @@ namespace AssetStudio.FbxInterop
_context.ExportMorphs(_imported.RootFrame, _imported.MorphList); _context.ExportMorphs(_imported.RootFrame, _imported.MorphList);
} }
private void ExportAnimations(bool eulerFilter, float filterPrecision) private void ExportAnimations()
{ {
_context.ExportAnimations(_imported.RootFrame, _imported.AnimationList, eulerFilter, filterPrecision); _context.ExportAnimations(_imported.RootFrame, _imported.AnimationList);
} }
private void ExportRootFrame(List<ImportedFrame> meshFrames) private void ExportRootFrame(List<ImportedFrame> meshFrames)
@@ -136,7 +119,7 @@ namespace AssetStudio.FbxInterop
private void SetJointsFromImportedMeshes() private void SetJointsFromImportedMeshes()
{ {
if (!_exportSkins) if (!_exportOptions.exportSkins)
{ {
return; return;
} }
@@ -158,12 +141,12 @@ namespace AssetStudio.FbxInterop
} }
} }
SetJointsNode(_imported.RootFrame, bonePaths, _castToBone); SetJointsNode(_imported.RootFrame, bonePaths, _exportOptions.castToBone);
} }
private void SetJointsNode(ImportedFrame rootFrame, HashSet<string> bonePaths, bool castToBone) private void SetJointsNode(ImportedFrame rootFrame, HashSet<string> bonePaths, bool castToBone)
{ {
_context.SetJointsNode(rootFrame, bonePaths, castToBone, _boneSize); _context.SetJointsNode(rootFrame, bonePaths, castToBone);
} }
private void PrepareMaterials() private void PrepareMaterials()
@@ -175,7 +158,7 @@ namespace AssetStudio.FbxInterop
{ {
foreach (var meshFrame in meshFrames) foreach (var meshFrame in meshFrames)
{ {
_context.ExportMeshFromFrame(rootFrame, meshFrame, _imported.MeshList, _imported.MaterialList, _imported.TextureList, _exportSkins, _exportAllUvsAsDiffuseMaps, _exportUV0UV1); _context.ExportMeshFromFrame(rootFrame, meshFrame, _imported.MeshList, _imported.MaterialList, _imported.TextureList);
} }
} }

View File

@@ -13,14 +13,16 @@ namespace AssetStudio.FbxInterop
private readonly Dictionary<ImportedFrame, IntPtr> _frameToNode; private readonly Dictionary<ImportedFrame, IntPtr> _frameToNode;
private readonly List<KeyValuePair<string, IntPtr>> _createdMaterials; private readonly List<KeyValuePair<string, IntPtr>> _createdMaterials;
private readonly Dictionary<string, IntPtr> _createdTextures; private readonly Dictionary<string, IntPtr> _createdTextures;
private readonly Fbx.ExportOptions _exportOptions;
public FbxExporterContext() public FbxExporterContext(Fbx.ExportOptions exportOptions)
{ {
Fbx.QuaternionToEuler(Quaternion.Zero); // workaround to init dll Fbx.QuaternionToEuler(Quaternion.Zero); // workaround to init dll
_pContext = AsFbxCreateContext(); _pContext = AsFbxCreateContext();
_frameToNode = new Dictionary<ImportedFrame, IntPtr>(); _frameToNode = new Dictionary<ImportedFrame, IntPtr>();
_createdMaterials = new List<KeyValuePair<string, IntPtr>>(); _createdMaterials = new List<KeyValuePair<string, IntPtr>>();
_createdTextures = new Dictionary<string, IntPtr>(); _createdTextures = new Dictionary<string, IntPtr>();
_exportOptions = exportOptions;
} }
~FbxExporterContext() ~FbxExporterContext()
@@ -60,11 +62,11 @@ namespace AssetStudio.FbxInterop
} }
} }
internal void Initialize(string fileName, float scaleFactor, int versionIndex, bool isAscii, bool is60Fps) internal void Initialize(string fileName, bool is60Fps)
{ {
EnsureNotDisposed(); EnsureNotDisposed();
var b = AsFbxInitializeContext(_pContext, fileName, scaleFactor, versionIndex, isAscii, is60Fps, out var errorMessage); var b = AsFbxInitializeContext(_pContext, fileName, _exportOptions.scaleFactor, _exportOptions.fbxVersion, _exportOptions.fbxFormat == 1, is60Fps, out var errorMessage);
if (!b) if (!b)
{ {
@@ -129,7 +131,7 @@ namespace AssetStudio.FbxInterop
} }
} }
internal void SetJointsNode(ImportedFrame rootFrame, HashSet<string> bonePaths, bool castToBone, float boneSize) internal void SetJointsNode(ImportedFrame rootFrame, HashSet<string> bonePaths, bool castToBone)
{ {
var frameStack = new Stack<ImportedFrame>(); var frameStack = new Stack<ImportedFrame>();
@@ -145,7 +147,7 @@ namespace AssetStudio.FbxInterop
if (castToBone) if (castToBone)
{ {
AsFbxSetJointsNode_CastToBone(_pContext, node, boneSize); AsFbxSetJointsNode_CastToBone(_pContext, node, _exportOptions.boneSize);
} }
else else
{ {
@@ -153,7 +155,7 @@ namespace AssetStudio.FbxInterop
if (bonePaths.Contains(frame.Path)) if (bonePaths.Contains(frame.Path))
{ {
AsFbxSetJointsNode_BoneInPath(_pContext, node, boneSize); AsFbxSetJointsNode_BoneInPath(_pContext, node, _exportOptions.boneSize);
} }
else else
{ {
@@ -174,12 +176,12 @@ namespace AssetStudio.FbxInterop
AsFbxPrepareMaterials(_pContext, materialCount, textureCount); AsFbxPrepareMaterials(_pContext, materialCount, textureCount);
} }
internal void ExportMeshFromFrame(ImportedFrame rootFrame, ImportedFrame meshFrame, List<ImportedMesh> meshList, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, bool exportSkins, bool exportAllUvsAsDiffuseMaps, bool exportUV0UV1) internal void ExportMeshFromFrame(ImportedFrame rootFrame, ImportedFrame meshFrame, List<ImportedMesh> meshList, List<ImportedMaterial> materialList, List<ImportedTexture> textureList)
{ {
var meshNode = _frameToNode[meshFrame]; var meshNode = _frameToNode[meshFrame];
var mesh = ImportedHelpers.FindMesh(meshFrame.Path, meshList); var mesh = ImportedHelpers.FindMesh(meshFrame.Path, meshList);
ExportMesh(rootFrame, materialList, textureList, meshNode, mesh, exportSkins, exportAllUvsAsDiffuseMaps, exportUV0UV1); ExportMesh(rootFrame, materialList, textureList, meshNode, mesh);
} }
private IntPtr ExportTexture(ImportedTexture texture) private IntPtr ExportTexture(ImportedTexture texture)
@@ -208,12 +210,12 @@ namespace AssetStudio.FbxInterop
return pTex; return pTex;
} }
private void ExportMesh(ImportedFrame rootFrame, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, IntPtr frameNode, ImportedMesh importedMesh, bool exportSkins, bool exportAllUvsAsDiffuseMaps, bool exportUV0UV1) private void ExportMesh(ImportedFrame rootFrame, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, IntPtr frameNode, ImportedMesh importedMesh)
{ {
var boneList = importedMesh.BoneList; var boneList = importedMesh.BoneList;
var totalBoneCount = 0; var totalBoneCount = 0;
var hasBones = false; var hasBones = false;
if (exportSkins && boneList?.Count > 0) if (_exportOptions.exportSkins && boneList?.Count > 0)
{ {
totalBoneCount = boneList.Count; totalBoneCount = boneList.Count;
hasBones = true; hasBones = true;
@@ -254,7 +256,7 @@ namespace AssetStudio.FbxInterop
AsFbxMeshCreateElementNormal(mesh); AsFbxMeshCreateElementNormal(mesh);
} }
if (exportUV0UV1) if (_exportOptions.exportUV0UV1)
{ {
if (importedMesh.hasUV[0]) if (importedMesh.hasUV[0])
{ {
@@ -262,7 +264,7 @@ namespace AssetStudio.FbxInterop
} }
if (importedMesh.hasUV[1]) if (importedMesh.hasUV[1])
{ {
if (exportAllUvsAsDiffuseMaps) if (_exportOptions.exportAllUvsAsDiffuseMaps)
{ {
AsFbxMeshCreateDiffuseUV(mesh, 1); AsFbxMeshCreateDiffuseUV(mesh, 1);
} }
@@ -278,7 +280,7 @@ namespace AssetStudio.FbxInterop
{ {
if (!importedMesh.hasUV[i]) { continue; } if (!importedMesh.hasUV[i]) { continue; }
if (i == 1 && !exportAllUvsAsDiffuseMaps) if (i == 1 && !_exportOptions.exportAllUvsAsDiffuseMaps)
{ {
AsFbxMeshCreateNormalMapUV(mesh, 1); AsFbxMeshCreateNormalMapUV(mesh, 1);
} }
@@ -389,7 +391,7 @@ namespace AssetStudio.FbxInterop
AsFbxMeshElementNormalAdd(mesh, 0, normal.X, normal.Y, normal.Z); AsFbxMeshElementNormalAdd(mesh, 0, normal.X, normal.Y, normal.Z);
} }
var uvSize = exportUV0UV1 ? 2 : importedMesh.hasUV.Length; var uvSize = _exportOptions.exportUV0UV1 ? 2 : importedMesh.hasUV.Length;
for (var uvIndex = 0; uvIndex < uvSize; uvIndex += 1) for (var uvIndex = 0; uvIndex < uvSize; uvIndex += 1)
{ {
if (importedMesh.hasUV[uvIndex]) if (importedMesh.hasUV[uvIndex])
@@ -487,7 +489,7 @@ namespace AssetStudio.FbxInterop
return 4 * m + n; return 4 * m + n;
} }
internal void ExportAnimations(ImportedFrame rootFrame, List<ImportedKeyframedAnimation> animationList, bool eulerFilter, float filterPrecision) internal void ExportAnimations(ImportedFrame rootFrame, List<ImportedKeyframedAnimation> animationList)
{ {
if (animationList == null || animationList.Count == 0) if (animationList == null || animationList.Count == 0)
{ {
@@ -498,7 +500,7 @@ namespace AssetStudio.FbxInterop
try try
{ {
pAnimContext = AsFbxAnimCreateContext(eulerFilter); pAnimContext = AsFbxAnimCreateContext(_exportOptions.eulerFilter);
for (int i = 0; i < animationList.Count; i++) for (int i = 0; i < animationList.Count; i++)
{ {
@@ -516,7 +518,7 @@ namespace AssetStudio.FbxInterop
AsFbxAnimPrepareStackAndLayer(_pContext, pAnimContext, takeName); AsFbxAnimPrepareStackAndLayer(_pContext, pAnimContext, takeName);
ExportKeyframedAnimation(rootFrame, importedAnimation, pAnimContext, filterPrecision); ExportKeyframedAnimation(rootFrame, importedAnimation, pAnimContext);
} }
} }
finally finally
@@ -525,7 +527,7 @@ namespace AssetStudio.FbxInterop
} }
} }
private void ExportKeyframedAnimation(ImportedFrame rootFrame, ImportedKeyframedAnimation parser, IntPtr pAnimContext, float filterPrecision) private void ExportKeyframedAnimation(ImportedFrame rootFrame, ImportedKeyframedAnimation parser, IntPtr pAnimContext)
{ {
foreach (var track in parser.TrackList) foreach (var track in parser.TrackList)
{ {
@@ -567,7 +569,7 @@ namespace AssetStudio.FbxInterop
AsFbxAnimEndKeyModify(pAnimContext); AsFbxAnimEndKeyModify(pAnimContext);
AsFbxAnimApplyEulerFilter(pAnimContext, filterPrecision); AsFbxAnimApplyEulerFilter(pAnimContext, _exportOptions.filterPrecision);
var blendShape = track.BlendShape; var blendShape = track.BlendShape;

View File

@@ -373,21 +373,23 @@ namespace AssetStudio.GUI
private static void ExportFbx(IImported convert, string exportPath) private static void ExportFbx(IImported convert, string exportPath)
{ {
var eulerFilter = Properties.Settings.Default.eulerFilter; var exportOptions = new Fbx.ExportOptions()
var filterPrecision = (float)Properties.Settings.Default.filterPrecision; {
var exportAllNodes = Properties.Settings.Default.exportAllNodes; eulerFilter = Properties.Settings.Default.eulerFilter,
var exportSkins = Properties.Settings.Default.exportSkins; filterPrecision = (float)Properties.Settings.Default.filterPrecision,
var exportAnimations = Properties.Settings.Default.exportAnimations; exportAllNodes = Properties.Settings.Default.exportAllNodes,
var exportBlendShape = Properties.Settings.Default.exportBlendShape; exportSkins = Properties.Settings.Default.exportSkins,
var castToBone = Properties.Settings.Default.castToBone; exportAnimations = Properties.Settings.Default.exportAnimations,
var boneSize = (int)Properties.Settings.Default.boneSize; exportBlendShape = Properties.Settings.Default.exportBlendShape,
var exportAllUvsAsDiffuseMaps = Properties.Settings.Default.exportAllUvsAsDiffuseMaps; castToBone = Properties.Settings.Default.castToBone,
var exportUV0UV1 = Properties.Settings.Default.exportUV0UV1; boneSize = (int)Properties.Settings.Default.boneSize,
var scaleFactor = (float)Properties.Settings.Default.scaleFactor; exportAllUvsAsDiffuseMaps = Properties.Settings.Default.exportAllUvsAsDiffuseMaps,
var fbxVersion = Properties.Settings.Default.fbxVersion; exportUV0UV1 = Properties.Settings.Default.exportUV0UV1,
var fbxFormat = Properties.Settings.Default.fbxFormat; scaleFactor = (float)Properties.Settings.Default.scaleFactor,
ModelExporter.ExportFbx(exportPath, convert, eulerFilter, filterPrecision, fbxVersion = Properties.Settings.Default.fbxVersion,
exportAllNodes, exportSkins, exportAnimations, exportBlendShape, castToBone, boneSize, exportAllUvsAsDiffuseMaps, exportUV0UV1, scaleFactor, fbxVersion, fbxFormat == 1); fbxFormat = Properties.Settings.Default.fbxFormat
};
ModelExporter.ExportFbx(exportPath, convert, exportOptions);
} }
public static bool ExportDumpFile(AssetItem item, string exportPath) public static bool ExportDumpFile(AssetItem item, string exportPath)

View File

@@ -2,10 +2,9 @@
{ {
public static class ModelExporter public static class ModelExporter
{ {
public static void ExportFbx(string path, IImported imported, bool eulerFilter, float filterPrecision, public static void ExportFbx(string path, IImported imported, Fbx.ExportOptions exportOptions)
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, bool exportAllUvsAsDiffuseMaps, bool exportUV0UV1, float scaleFactor, int versionIndex, bool isAscii)
{ {
Fbx.Exporter.Export(path, imported, eulerFilter, filterPrecision, allNodes, skins, animation, blendShape, castToBone, boneSize, exportAllUvsAsDiffuseMaps, exportUV0UV1, scaleFactor, versionIndex, isAscii); Fbx.Exporter.Export(path, imported, exportOptions);
} }
} }
} }