mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-07-18 03:24:15 -04:00
Add option to manually bind UV map types
This commit is contained in:
@ -1,5 +1,7 @@
|
||||
using AssetStudio.FbxInterop;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using AssetStudio.PInvoke;
|
||||
@ -30,9 +32,7 @@ namespace AssetStudio
|
||||
|
||||
public static class Exporter
|
||||
{
|
||||
|
||||
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, float scaleFactor, int versionIndex, bool isAscii)
|
||||
public static void Export(string path, IImported imported, Settings fbxSettings)
|
||||
{
|
||||
var file = new FileInfo(path);
|
||||
var dir = file.Directory;
|
||||
@ -47,16 +47,88 @@ namespace AssetStudio
|
||||
|
||||
var name = Path.GetFileName(path);
|
||||
|
||||
using (var exporter = new FbxExporter(name, imported, allNodes, skins, castToBone, boneSize, exportAllUvsAsDiffuseMaps, scaleFactor, versionIndex, isAscii))
|
||||
using (var exporter = new FbxExporter(name, imported, fbxSettings))
|
||||
{
|
||||
exporter.Initialize();
|
||||
exporter.ExportAll(blendShape, animation, eulerFilter, filterPrecision);
|
||||
exporter.ExportAll();
|
||||
}
|
||||
|
||||
Directory.SetCurrentDirectory(currentDir);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public sealed class Settings
|
||||
{
|
||||
public bool EulerFilter { get; set; }
|
||||
public float FilterPrecision { get; set; }
|
||||
public bool ExportAllNodes { get; set; }
|
||||
public bool ExportSkins { get; set; }
|
||||
public bool ExportAnimations { get; set; }
|
||||
public bool ExportBlendShape { get; set; }
|
||||
public bool CastToBone { get; set; }
|
||||
public float BoneSize { get; set; }
|
||||
public bool ExportAllUvsAsDiffuseMaps { get; set; }
|
||||
public float ScaleFactor { get; set; }
|
||||
public int FbxVersionIndex { get; set; }
|
||||
public int FbxFormat { get; set; }
|
||||
public Dictionary<int,int> UvBindings { get; set; }
|
||||
public bool IsAscii => FbxFormat == 1;
|
||||
|
||||
public Settings()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
public Settings(bool eulerFilter, float filterPrecision, bool exportAllNodes, bool exportSkins, bool exportAnimations, bool exportBlendShape, bool castToBone, float boneSize,
|
||||
bool exportAllUvsAsDiffuseMaps, float scaleFactor, int fbxVersionIndex, int fbxFormat, Dictionary<int, int> uvBindings)
|
||||
{
|
||||
EulerFilter = eulerFilter;
|
||||
FilterPrecision = filterPrecision;
|
||||
ExportAllNodes = exportAllNodes;
|
||||
ExportSkins = exportSkins;
|
||||
ExportAnimations = exportAnimations;
|
||||
ExportBlendShape = exportBlendShape;
|
||||
CastToBone = castToBone;
|
||||
BoneSize = (int)boneSize;
|
||||
ExportAllUvsAsDiffuseMaps = exportAllUvsAsDiffuseMaps;
|
||||
ScaleFactor = scaleFactor;
|
||||
FbxVersionIndex = fbxVersionIndex;
|
||||
FbxFormat = fbxFormat;
|
||||
UvBindings = uvBindings;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
var uvDict = new Dictionary<int, int>();
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
uvDict[i] = i + 1;
|
||||
}
|
||||
|
||||
EulerFilter = true;
|
||||
FilterPrecision = 0.25f;
|
||||
ExportAllNodes = true;
|
||||
ExportSkins = true;
|
||||
ExportAnimations = true;
|
||||
ExportBlendShape = true;
|
||||
CastToBone = false;
|
||||
ExportAllUvsAsDiffuseMaps = false;
|
||||
BoneSize = 10;
|
||||
ScaleFactor = 1.0f;
|
||||
FbxFormat = 0;
|
||||
FbxVersionIndex = 3;
|
||||
UvBindings = uvDict;
|
||||
}
|
||||
|
||||
public static Settings FromBase64(string base64String)
|
||||
{
|
||||
var settingsData = System.Convert.FromBase64String(base64String);
|
||||
return JsonSerializer.Deserialize<Settings>(settingsData);
|
||||
}
|
||||
|
||||
public string ToBase64()
|
||||
{
|
||||
return System.Convert.ToBase64String(JsonSerializer.SerializeToUtf8Bytes(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,29 +11,15 @@ namespace AssetStudio.FbxInterop
|
||||
|
||||
private readonly string _fileName;
|
||||
private readonly IImported _imported;
|
||||
private readonly bool _allNodes;
|
||||
private readonly bool _exportSkins;
|
||||
private readonly bool _castToBone;
|
||||
private readonly float _boneSize;
|
||||
private readonly bool _exportAllUvsAsDiffuseMaps;
|
||||
private readonly float _scaleFactor;
|
||||
private readonly int _versionIndex;
|
||||
private readonly bool _isAscii;
|
||||
private readonly Fbx.Settings _settings;
|
||||
|
||||
internal FbxExporter(string fileName, IImported imported, bool allNodes, bool exportSkins, bool castToBone, float boneSize, bool exportAllUvsAsDiffuseMaps, float scaleFactor, int versionIndex, bool isAscii)
|
||||
internal FbxExporter(string fileName, IImported imported, Fbx.Settings fbxSettings)
|
||||
{
|
||||
_context = new FbxExporterContext();
|
||||
|
||||
_fileName = fileName;
|
||||
_imported = imported;
|
||||
_allNodes = allNodes;
|
||||
_exportSkins = exportSkins;
|
||||
_castToBone = castToBone;
|
||||
_boneSize = boneSize;
|
||||
_exportAllUvsAsDiffuseMaps = exportAllUvsAsDiffuseMaps;
|
||||
_scaleFactor = scaleFactor;
|
||||
_versionIndex = versionIndex;
|
||||
_isAscii = isAscii;
|
||||
_settings = fbxSettings;
|
||||
}
|
||||
|
||||
~FbxExporter()
|
||||
@ -64,13 +50,13 @@ namespace AssetStudio.FbxInterop
|
||||
IsDisposed = true;
|
||||
}
|
||||
|
||||
internal void Initialize()
|
||||
private void Initialize()
|
||||
{
|
||||
var is60Fps = _imported.AnimationList.Count > 0 && _imported.AnimationList[0].SampleRate.Equals(60.0f);
|
||||
|
||||
_context.Initialize(_fileName, _scaleFactor, _versionIndex, _isAscii, is60Fps);
|
||||
_context.Initialize(_fileName, _settings, is60Fps);
|
||||
|
||||
if (!_allNodes)
|
||||
if (!_settings.ExportAllNodes)
|
||||
{
|
||||
var framePaths = SearchHierarchy();
|
||||
|
||||
@ -78,8 +64,10 @@ namespace AssetStudio.FbxInterop
|
||||
}
|
||||
}
|
||||
|
||||
internal void ExportAll(bool blendShape, bool animation, bool eulerFilter, float filterPrecision)
|
||||
internal void ExportAll()
|
||||
{
|
||||
Initialize();
|
||||
|
||||
var meshFrames = new List<ImportedFrame>();
|
||||
|
||||
ExportRootFrame(meshFrames);
|
||||
@ -97,16 +85,14 @@ namespace AssetStudio.FbxInterop
|
||||
SetJointsNode(_imported.RootFrame, null, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (blendShape)
|
||||
if (_settings.ExportBlendShape)
|
||||
{
|
||||
ExportMorphs();
|
||||
}
|
||||
|
||||
if (animation)
|
||||
if (_settings.ExportAnimations)
|
||||
{
|
||||
ExportAnimations(eulerFilter, filterPrecision);
|
||||
ExportAnimations(_settings.EulerFilter, _settings.FilterPrecision);
|
||||
}
|
||||
|
||||
ExportScene();
|
||||
@ -134,7 +120,7 @@ namespace AssetStudio.FbxInterop
|
||||
|
||||
private void SetJointsFromImportedMeshes()
|
||||
{
|
||||
if (!_exportSkins)
|
||||
if (!_settings.ExportSkins)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -156,12 +142,12 @@ namespace AssetStudio.FbxInterop
|
||||
}
|
||||
}
|
||||
|
||||
SetJointsNode(_imported.RootFrame, bonePaths, _castToBone);
|
||||
SetJointsNode(_imported.RootFrame, bonePaths, _settings.CastToBone);
|
||||
}
|
||||
|
||||
private void SetJointsNode(ImportedFrame rootFrame, HashSet<string> bonePaths, bool castToBone)
|
||||
{
|
||||
_context.SetJointsNode(rootFrame, bonePaths, castToBone, _boneSize);
|
||||
_context.SetJointsNode(rootFrame, bonePaths, castToBone, _settings.BoneSize);
|
||||
}
|
||||
|
||||
private void PrepareMaterials()
|
||||
@ -173,7 +159,7 @@ namespace AssetStudio.FbxInterop
|
||||
{
|
||||
foreach (var meshFrame in meshFrames)
|
||||
{
|
||||
_context.ExportMeshFromFrame(rootFrame, meshFrame, _imported.MeshList, _imported.MaterialList, _imported.TextureList, _exportSkins, _exportAllUvsAsDiffuseMaps);
|
||||
_context.ExportMeshFromFrame(rootFrame, meshFrame, _imported.MeshList, _imported.MaterialList, _imported.TextureList, _settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,10 +142,7 @@ namespace AssetStudio.FbxInterop
|
||||
private static extern void AsFbxMeshCreateElementNormal(IntPtr mesh);
|
||||
|
||||
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
|
||||
private static extern void AsFbxMeshCreateDiffuseUV(IntPtr mesh, int uv);
|
||||
|
||||
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
|
||||
private static extern void AsFbxMeshCreateNormalMapUV(IntPtr mesh, int uv);
|
||||
private static extern void AsFbxMeshCreateUVMap(IntPtr mesh, int uvIndex, int uvType);
|
||||
|
||||
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
|
||||
private static extern void AsFbxMeshCreateElementTangent(IntPtr mesh);
|
||||
|
@ -59,11 +59,11 @@ namespace AssetStudio.FbxInterop
|
||||
}
|
||||
}
|
||||
|
||||
internal void Initialize(string fileName, float scaleFactor, int versionIndex, bool isAscii, bool is60Fps)
|
||||
internal void Initialize(string fileName, Fbx.Settings fbxSettings, bool is60Fps)
|
||||
{
|
||||
EnsureNotDisposed();
|
||||
|
||||
var b = AsFbxInitializeContext(_pContext, fileName, scaleFactor, versionIndex, isAscii, is60Fps, out var errorMessage);
|
||||
var b = AsFbxInitializeContext(_pContext, fileName, fbxSettings.ScaleFactor, fbxSettings.FbxVersionIndex, fbxSettings.IsAscii, is60Fps, out var errorMessage);
|
||||
|
||||
if (!b)
|
||||
{
|
||||
@ -173,12 +173,12 @@ namespace AssetStudio.FbxInterop
|
||||
AsFbxPrepareMaterials(_pContext, materialCount, textureCount);
|
||||
}
|
||||
|
||||
internal void ExportMeshFromFrame(ImportedFrame rootFrame, ImportedFrame meshFrame, List<ImportedMesh> meshList, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, bool exportSkins, bool exportAllUvsAsDiffuseMaps)
|
||||
internal void ExportMeshFromFrame(ImportedFrame rootFrame, ImportedFrame meshFrame, List<ImportedMesh> meshList, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, Fbx.Settings fbxSettings)
|
||||
{
|
||||
var meshNode = _frameToNode[meshFrame];
|
||||
var mesh = ImportedHelpers.FindMesh(meshFrame.Path, meshList);
|
||||
|
||||
ExportMesh(rootFrame, materialList, textureList, meshNode, mesh, exportSkins, exportAllUvsAsDiffuseMaps);
|
||||
ExportMesh(rootFrame, materialList, textureList, meshNode, mesh, fbxSettings);
|
||||
}
|
||||
|
||||
private IntPtr ExportTexture(ImportedTexture texture)
|
||||
@ -207,12 +207,12 @@ namespace AssetStudio.FbxInterop
|
||||
return pTex;
|
||||
}
|
||||
|
||||
private void ExportMesh(ImportedFrame rootFrame, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, IntPtr frameNode, ImportedMesh importedMesh, bool exportSkins, bool exportAllUvsAsDiffuseMaps)
|
||||
private void ExportMesh(ImportedFrame rootFrame, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, IntPtr frameNode, ImportedMesh importedMesh, Fbx.Settings fbxSettings)
|
||||
{
|
||||
var boneList = importedMesh.BoneList;
|
||||
var totalBoneCount = 0;
|
||||
var hasBones = false;
|
||||
if (exportSkins && boneList?.Count > 0)
|
||||
if (fbxSettings.ExportSkins && boneList?.Count > 0)
|
||||
{
|
||||
totalBoneCount = boneList.Count;
|
||||
hasBones = true;
|
||||
@ -253,17 +253,18 @@ namespace AssetStudio.FbxInterop
|
||||
AsFbxMeshCreateElementNormal(mesh);
|
||||
}
|
||||
|
||||
for (int i = 0; i < importedMesh.hasUV.Length; i++)
|
||||
for (var i = 0; i < importedMesh.hasUV.Length; i++)
|
||||
{
|
||||
if (!importedMesh.hasUV[i]) { continue; }
|
||||
if (!importedMesh.hasUV[i])
|
||||
continue;
|
||||
|
||||
if (i == 1 && !exportAllUvsAsDiffuseMaps)
|
||||
if (fbxSettings.ExportAllUvsAsDiffuseMaps)
|
||||
{
|
||||
AsFbxMeshCreateNormalMapUV(mesh, 1);
|
||||
AsFbxMeshCreateUVMap(mesh, i, 0);
|
||||
}
|
||||
else
|
||||
else if(fbxSettings.UvBindings[i] > 0) //if checked
|
||||
{
|
||||
AsFbxMeshCreateDiffuseUV(mesh, i);
|
||||
AsFbxMeshCreateUVMap(mesh, i, fbxSettings.UvBindings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user