Improve mesh loading

This commit is contained in:
VaDiM
2025-08-27 05:25:01 +03:00
parent ae3b5169df
commit 963cd6546b
10 changed files with 104 additions and 28 deletions

View File

@@ -16,6 +16,7 @@ namespace AssetStudio
public class AssetsManager public class AssetsManager
{ {
public bool LoadViaTypeTree = true; public bool LoadViaTypeTree = true;
public bool MeshLazyLoad = true;
public ImportOptions Options = new ImportOptions(); public ImportOptions Options = new ImportOptions();
public readonly List<Action<OptionsFile>> OptionLoaders = new List<Action<OptionsFile>>(); public readonly List<Action<OptionsFile>> OptionLoaders = new List<Action<OptionsFile>>();
public readonly List<SerializedFile> AssetsFileList = new List<SerializedFile>(); public readonly List<SerializedFile> AssetsFileList = new List<SerializedFile>();

View File

@@ -542,6 +542,7 @@ namespace AssetStudio
public sealed class Mesh : NamedObject public sealed class Mesh : NamedObject
{ {
private bool isLoaded;
private bool m_Use16BitIndices = true; private bool m_Use16BitIndices = true;
public List<SubMesh> m_SubMeshes; public List<SubMesh> m_SubMeshes;
private uint[] m_IndexBuffer; private uint[] m_IndexBuffer;
@@ -587,6 +588,7 @@ namespace AssetStudio
{ {
indexBufferList.Add(reader.ReadUInt16()); indexBufferList.Add(reader.ReadUInt16());
} }
reader.AlignStream(); reader.AlignStream();
m_IndexBuffer = indexBufferList.ToArray(); m_IndexBuffer = indexBufferList.ToArray();
} }
@@ -656,14 +658,13 @@ namespace AssetStudio
reader.AlignStream(); reader.AlignStream();
_ = new SharedClusterData(reader, rev: 3); _ = new SharedClusterData(reader, rev: 3);
} }
} }
reader.AlignStream(); reader.AlignStream();
//Unity fixed it in 2017.3.1p1 and later versions //Unity fixed it in 2017.3.1p1 and later versions
if (version >= (2017, 4) //2017.4 if (version >= (2017, 4) //2017.4
|| version == (2017, 3, 1) && version.IsPatch //fixed after 2017.3.1px || version == (2017, 3, 1) && version.IsPatch //fixed after 2017.3.1px
|| version == (2017, 3) && m_MeshCompression == 0)//2017.3.xfx with no compression || version == (2017, 3) && m_MeshCompression == 0) //2017.3.xfx with no compression
{ {
var m_IndexFormat = reader.ReadInt32(); var m_IndexFormat = reader.ReadInt32();
m_Use16BitIndices = m_IndexFormat == 0; m_Use16BitIndices = m_IndexFormat == 0;
@@ -677,6 +678,7 @@ namespace AssetStudio
{ {
indexBufferList.Add(reader.ReadUInt16()); indexBufferList.Add(reader.ReadUInt16());
} }
reader.AlignStream(); reader.AlignStream();
m_IndexBuffer = indexBufferList.ToArray(); m_IndexBuffer = indexBufferList.ToArray();
} }
@@ -781,9 +783,12 @@ namespace AssetStudio
if (version >= 5) //5.0 and up if (version >= 5) //5.0 and up
{ {
var m_BakedConvexCollisionMesh = reader.ReadUInt8Array(); var m_BakedConvexCollisionMeshSize = reader.ReadInt32();
reader.Position += m_BakedConvexCollisionMeshSize; //skip byte[] m_BakedConvexCollisionMesh
reader.AlignStream(); reader.AlignStream();
var m_BakedTriangleCollisionMesh = reader.ReadUInt8Array();
var m_BakedTriangleCollisionMeshSize = reader.ReadInt32();
reader.Position += m_BakedTriangleCollisionMeshSize; //skip byte[] m_BakedTriangleCollisionMesh
reader.AlignStream(); reader.AlignStream();
} }
@@ -805,18 +810,25 @@ namespace AssetStudio
var m_GenerateGeometryBuffer = reader.ReadBoolean(); var m_GenerateGeometryBuffer = reader.ReadBoolean();
m_HasVirtualGeometryMesh = reader.ReadBoolean(); m_HasVirtualGeometryMesh = reader.ReadBoolean();
} }
ProcessData(); if (!assetsFile.assetsManager.MeshLazyLoad)
ProcessData();
} }
private void ProcessData() public void ProcessData()
{ {
if (isLoaded)
return;
var isStreamedDataSize = false;
if (!string.IsNullOrEmpty(m_StreamData?.path)) if (!string.IsNullOrEmpty(m_StreamData?.path))
{ {
if (m_VertexData.m_VertexCount > 0) if (m_VertexData.m_VertexCount > 0)
{ {
m_VertexData.m_DataSize = BigArrayPool<byte>.Shared.Rent((int)m_StreamData.size);
var resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size); var resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size);
m_VertexData.m_DataSize = resourceReader.GetData(); resourceReader.GetData(m_VertexData.m_DataSize);
isStreamedDataSize = true;
} }
} }
if (version >= (3, 5)) //3.5 and up if (version >= (3, 5)) //3.5 and up
@@ -829,10 +841,21 @@ namespace AssetStudio
DecompressCompressedMesh(); DecompressCompressedMesh();
} }
if (m_HasVirtualGeometryMesh && m_IndexBuffer.Length == 0) if (m_IndexBuffer.Length == 0)
Logger.Warning($"Unsupported mesh type: Virtual Geometry | PathID: {m_PathID} | Name: \"{m_Name}\""); {
var msg = m_HasVirtualGeometryMesh
? "Unsupported mesh type: Virtual Geometry"
: "Cannot process empty mesh";
Logger.Warning($"{msg} | PathID: {m_PathID} | Name: \"{m_Name}\"");
}
else else
{
GetTriangles(); GetTriangles();
}
isLoaded = true;
if (isStreamedDataSize)
BigArrayPool<byte>.Shared.Return(m_VertexData.m_DataSize, clearArray: true);
} }
private void ReadVertexData() private void ReadVertexData()

View File

@@ -67,6 +67,11 @@ namespace AssetStudio
string str = null; string str = null;
try try
{ {
if (this is Mesh m_Mesh)
{
m_Mesh.ProcessData();
}
str = JsonSerializer.Deserialize<JsonObject>(JsonSerializer.SerializeToUtf8Bytes(this, GetType(), jsonOptions)) str = JsonSerializer.Deserialize<JsonObject>(JsonSerializer.SerializeToUtf8Bytes(this, GetType(), jsonOptions))
.ToJsonString(jsonOptions).Replace(" ", " "); .ToJsonString(jsonOptions).Replace(" ", " ");
} }
@@ -74,6 +79,7 @@ namespace AssetStudio
{ {
//ignore //ignore
} }
return str; return str;
} }
@@ -104,12 +110,19 @@ namespace AssetStudio
{ {
return JsonSerializer.SerializeToDocument(typeDict, jsonOptions); return JsonSerializer.SerializeToDocument(typeDict, jsonOptions);
} }
if (this is Mesh m_Mesh)
{
m_Mesh.ProcessData();
}
return JsonSerializer.SerializeToDocument(this, GetType(), jsonOptions); return JsonSerializer.SerializeToDocument(this, GetType(), jsonOptions);
} }
catch catch
{ {
//ignore //ignore
} }
return null; return null;
} }

View File

@@ -175,15 +175,17 @@ namespace AssetStudioCLI
private static bool ExportMesh(AssetItem item, string exportPath) private static bool ExportMesh(AssetItem item, string exportPath)
{ {
var m_Mesh = (Mesh)item.Asset; var m_Mesh = (Mesh)item.Asset;
m_Mesh.ProcessData();
if (m_Mesh.m_VertexCount <= 0) if (m_Mesh.m_VertexCount <= 0)
return false; return false;
if (!TryExportFile(exportPath, item, ".obj", out var exportFullPath)) if (!TryExportFile(exportPath, item, ".obj", out var exportFullPath))
return false; return false;
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.AppendLine("g " + m_Mesh.m_Name); sb.AppendLine("g " + m_Mesh.m_Name);
#region Vertices #region Vertices
if (m_Mesh.m_Vertices == null || m_Mesh.m_Vertices.Length == 0) if (m_Mesh.m_Vertices == null || m_Mesh.m_Vertices.Length == 0)
{ {
return false; return false;
@@ -199,11 +201,9 @@ namespace AssetStudioCLI
{ {
sb.Append($"v {-m_Mesh.m_Vertices[v * c]} {m_Mesh.m_Vertices[v * c + 1]} {m_Mesh.m_Vertices[v * c + 2]}\r\n"); sb.Append($"v {-m_Mesh.m_Vertices[v * c]} {m_Mesh.m_Vertices[v * c + 1]} {m_Mesh.m_Vertices[v * c + 2]}\r\n");
} }
#endregion #endregion
#region UV #region UV
if (m_Mesh.m_UV0?.Length > 0) if (m_Mesh.m_UV0?.Length > 0)
{ {
c = 4; c = 4;
@@ -221,11 +221,9 @@ namespace AssetStudioCLI
sb.AppendFormat("vt {0} {1}\r\n", m_Mesh.m_UV0[v * c], m_Mesh.m_UV0[v * c + 1]); sb.AppendFormat("vt {0} {1}\r\n", m_Mesh.m_UV0[v * c], m_Mesh.m_UV0[v * c + 1]);
} }
} }
#endregion #endregion
#region Normals #region Normals
if (m_Mesh.m_Normals?.Length > 0) if (m_Mesh.m_Normals?.Length > 0)
{ {
if (m_Mesh.m_Normals.Length == m_Mesh.m_VertexCount * 3) if (m_Mesh.m_Normals.Length == m_Mesh.m_VertexCount * 3)
@@ -242,11 +240,9 @@ namespace AssetStudioCLI
sb.AppendFormat("vn {0} {1} {2}\r\n", -m_Mesh.m_Normals[v * c], m_Mesh.m_Normals[v * c + 1], m_Mesh.m_Normals[v * c + 2]); sb.AppendFormat("vn {0} {1} {2}\r\n", -m_Mesh.m_Normals[v * c], m_Mesh.m_Normals[v * c + 1], m_Mesh.m_Normals[v * c + 2]);
} }
} }
#endregion #endregion
#region Face #region Face
int sum = 0; int sum = 0;
for (var i = 0; i < m_Mesh.m_SubMeshes.Count; i++) for (var i = 0; i < m_Mesh.m_SubMeshes.Count; i++)
{ {
@@ -260,7 +256,6 @@ namespace AssetStudioCLI
sum = end; sum = end;
} }
#endregion #endregion
sb.Replace("NaN", "0"); sb.Replace("NaN", "0");

View File

@@ -40,6 +40,7 @@
this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.displayAll = new System.Windows.Forms.ToolStripMenuItem(); this.displayAll = new System.Windows.Forms.ToolStripMenuItem();
this.useAssetLoadingViaTypetreeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.useAssetLoadingViaTypetreeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.meshLazyLoadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.assetLoadingToolStripSeparator = new System.Windows.Forms.ToolStripSeparator(); this.assetLoadingToolStripSeparator = new System.Windows.Forms.ToolStripSeparator();
this.enablePreview = new System.Windows.Forms.ToolStripMenuItem(); this.enablePreview = new System.Windows.Forms.ToolStripMenuItem();
this.displayInfo = new System.Windows.Forms.ToolStripMenuItem(); this.displayInfo = new System.Windows.Forms.ToolStripMenuItem();
@@ -271,6 +272,7 @@
this.optionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.optionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.displayAll, this.displayAll,
this.useAssetLoadingViaTypetreeToolStripMenuItem, this.useAssetLoadingViaTypetreeToolStripMenuItem,
this.meshLazyLoadToolStripMenuItem,
this.assetLoadingToolStripSeparator, this.assetLoadingToolStripSeparator,
this.enablePreview, this.enablePreview,
this.displayInfo, this.displayInfo,
@@ -287,7 +289,7 @@
// //
this.displayAll.CheckOnClick = true; this.displayAll.CheckOnClick = true;
this.displayAll.Name = "displayAll"; this.displayAll.Name = "displayAll";
this.displayAll.Size = new System.Drawing.Size(241, 22); this.displayAll.Size = new System.Drawing.Size(243, 22);
this.displayAll.Text = "Display all assets"; this.displayAll.Text = "Display all assets";
this.displayAll.ToolTipText = "Check this option will display all types assets. Not extractable assets can expor" + this.displayAll.ToolTipText = "Check this option will display all types assets. Not extractable assets can expor" +
"t the RAW file."; "t the RAW file.";
@@ -299,16 +301,26 @@
this.useAssetLoadingViaTypetreeToolStripMenuItem.CheckOnClick = true; this.useAssetLoadingViaTypetreeToolStripMenuItem.CheckOnClick = true;
this.useAssetLoadingViaTypetreeToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked; this.useAssetLoadingViaTypetreeToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.useAssetLoadingViaTypetreeToolStripMenuItem.Name = "useAssetLoadingViaTypetreeToolStripMenuItem"; this.useAssetLoadingViaTypetreeToolStripMenuItem.Name = "useAssetLoadingViaTypetreeToolStripMenuItem";
this.useAssetLoadingViaTypetreeToolStripMenuItem.Size = new System.Drawing.Size(241, 22); this.useAssetLoadingViaTypetreeToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
this.useAssetLoadingViaTypetreeToolStripMenuItem.Text = "Parse assets using their typetree"; this.useAssetLoadingViaTypetreeToolStripMenuItem.Text = "Parse assets using their typetree";
this.useAssetLoadingViaTypetreeToolStripMenuItem.ToolTipText = "(Applies to assets with typetree included). Slower but can parse non-standard ass" + this.useAssetLoadingViaTypetreeToolStripMenuItem.ToolTipText = "(Applies to assets with typetree included). Slower but can parse non-standard ass" +
"ets. Only for Texture2D, AnimationClip and Material assets for now."; "ets. Only for Texture2D, AnimationClip and Material assets for now.";
this.useAssetLoadingViaTypetreeToolStripMenuItem.CheckedChanged += new System.EventHandler(this.useAssetLoadingViaTypetreeToolStripMenuItem_CheckedChanged); this.useAssetLoadingViaTypetreeToolStripMenuItem.CheckedChanged += new System.EventHandler(this.useAssetLoadingViaTypetreeToolStripMenuItem_CheckedChanged);
// //
// meshLazyLoadToolStripMenuItem
//
this.meshLazyLoadToolStripMenuItem.Checked = true;
this.meshLazyLoadToolStripMenuItem.CheckOnClick = true;
this.meshLazyLoadToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.meshLazyLoadToolStripMenuItem.Name = "meshLazyLoadToolStripMenuItem";
this.meshLazyLoadToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
this.meshLazyLoadToolStripMenuItem.Text = "Use lazy loading for Mesh assets";
this.meshLazyLoadToolStripMenuItem.CheckedChanged += new System.EventHandler(this.meshLazyLoadToolStripMenuItem_CheckedChanged);
//
// assetLoadingToolStripSeparator // assetLoadingToolStripSeparator
// //
this.assetLoadingToolStripSeparator.Name = "assetLoadingToolStripSeparator"; this.assetLoadingToolStripSeparator.Name = "assetLoadingToolStripSeparator";
this.assetLoadingToolStripSeparator.Size = new System.Drawing.Size(238, 6); this.assetLoadingToolStripSeparator.Size = new System.Drawing.Size(240, 6);
// //
// enablePreview // enablePreview
// //
@@ -316,7 +328,7 @@
this.enablePreview.CheckOnClick = true; this.enablePreview.CheckOnClick = true;
this.enablePreview.CheckState = System.Windows.Forms.CheckState.Checked; this.enablePreview.CheckState = System.Windows.Forms.CheckState.Checked;
this.enablePreview.Name = "enablePreview"; this.enablePreview.Name = "enablePreview";
this.enablePreview.Size = new System.Drawing.Size(241, 22); this.enablePreview.Size = new System.Drawing.Size(243, 22);
this.enablePreview.Text = "Enable preview"; this.enablePreview.Text = "Enable preview";
this.enablePreview.ToolTipText = "Toggle the loading and preview of readable assets, such as images, sounds, text, " + this.enablePreview.ToolTipText = "Toggle the loading and preview of readable assets, such as images, sounds, text, " +
"etc.\r\nDisable preview if you have performance or compatibility issues."; "etc.\r\nDisable preview if you have performance or compatibility issues.";
@@ -328,7 +340,7 @@
this.displayInfo.CheckOnClick = true; this.displayInfo.CheckOnClick = true;
this.displayInfo.CheckState = System.Windows.Forms.CheckState.Checked; this.displayInfo.CheckState = System.Windows.Forms.CheckState.Checked;
this.displayInfo.Name = "displayInfo"; this.displayInfo.Name = "displayInfo";
this.displayInfo.Size = new System.Drawing.Size(241, 22); this.displayInfo.Size = new System.Drawing.Size(243, 22);
this.displayInfo.Text = "Display asset information"; this.displayInfo.Text = "Display asset information";
this.displayInfo.ToolTipText = "Toggle the overlay that shows information about each asset, eg. image size, forma" + this.displayInfo.ToolTipText = "Toggle the overlay that shows information about each asset, eg. image size, forma" +
"t, audio bitrate, etc."; "t, audio bitrate, etc.";
@@ -338,7 +350,7 @@
// //
this.autoPlayAudioAssetsToolStripMenuItem.CheckOnClick = true; this.autoPlayAudioAssetsToolStripMenuItem.CheckOnClick = true;
this.autoPlayAudioAssetsToolStripMenuItem.Name = "autoPlayAudioAssetsToolStripMenuItem"; this.autoPlayAudioAssetsToolStripMenuItem.Name = "autoPlayAudioAssetsToolStripMenuItem";
this.autoPlayAudioAssetsToolStripMenuItem.Size = new System.Drawing.Size(241, 22); this.autoPlayAudioAssetsToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
this.autoPlayAudioAssetsToolStripMenuItem.Text = "Autoplay audio assets"; this.autoPlayAudioAssetsToolStripMenuItem.Text = "Autoplay audio assets";
this.autoPlayAudioAssetsToolStripMenuItem.ToolTipText = "Autoplay AudioClip assets when selected"; this.autoPlayAudioAssetsToolStripMenuItem.ToolTipText = "Autoplay AudioClip assets when selected";
this.autoPlayAudioAssetsToolStripMenuItem.CheckedChanged += new System.EventHandler(this.autoPlayAudioAssetsToolStripMenuItem_CheckedChanged); this.autoPlayAudioAssetsToolStripMenuItem.CheckedChanged += new System.EventHandler(this.autoPlayAudioAssetsToolStripMenuItem_CheckedChanged);
@@ -347,7 +359,7 @@
// //
this.useDumpTreeViewToolStripMenuItem.CheckOnClick = true; this.useDumpTreeViewToolStripMenuItem.CheckOnClick = true;
this.useDumpTreeViewToolStripMenuItem.Name = "useDumpTreeViewToolStripMenuItem"; this.useDumpTreeViewToolStripMenuItem.Name = "useDumpTreeViewToolStripMenuItem";
this.useDumpTreeViewToolStripMenuItem.Size = new System.Drawing.Size(241, 22); this.useDumpTreeViewToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
this.useDumpTreeViewToolStripMenuItem.Text = "Use tree view to display dump"; this.useDumpTreeViewToolStripMenuItem.Text = "Use tree view to display dump";
this.useDumpTreeViewToolStripMenuItem.CheckedChanged += new System.EventHandler(this.useDumpTreeViewToolStripMenuItem_CheckedChanged); this.useDumpTreeViewToolStripMenuItem.CheckedChanged += new System.EventHandler(this.useDumpTreeViewToolStripMenuItem_CheckedChanged);
// //
@@ -357,7 +369,7 @@
this.buildTreeStructureToolStripMenuItem.CheckOnClick = true; this.buildTreeStructureToolStripMenuItem.CheckOnClick = true;
this.buildTreeStructureToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked; this.buildTreeStructureToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.buildTreeStructureToolStripMenuItem.Name = "buildTreeStructureToolStripMenuItem"; this.buildTreeStructureToolStripMenuItem.Name = "buildTreeStructureToolStripMenuItem";
this.buildTreeStructureToolStripMenuItem.Size = new System.Drawing.Size(241, 22); this.buildTreeStructureToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
this.buildTreeStructureToolStripMenuItem.Text = "Build tree structure"; this.buildTreeStructureToolStripMenuItem.Text = "Build tree structure";
this.buildTreeStructureToolStripMenuItem.ToolTipText = "You can disable tree structure building if you don\'t use the Scene Hierarchy tab"; this.buildTreeStructureToolStripMenuItem.ToolTipText = "You can disable tree structure building if you don\'t use the Scene Hierarchy tab";
this.buildTreeStructureToolStripMenuItem.CheckedChanged += new System.EventHandler(this.buildTreeStructureToolStripMenuItem_CheckedChanged); this.buildTreeStructureToolStripMenuItem.CheckedChanged += new System.EventHandler(this.buildTreeStructureToolStripMenuItem_CheckedChanged);
@@ -376,7 +388,7 @@
this.importOptionsToolStripSeparator, this.importOptionsToolStripSeparator,
this.saveOptionsToDiskToolStripMenuItem}); this.saveOptionsToDiskToolStripMenuItem});
this.importOptionsToolStripMenuItem.Name = "importOptionsToolStripMenuItem"; this.importOptionsToolStripMenuItem.Name = "importOptionsToolStripMenuItem";
this.importOptionsToolStripMenuItem.Size = new System.Drawing.Size(241, 22); this.importOptionsToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
this.importOptionsToolStripMenuItem.Text = "Import options"; this.importOptionsToolStripMenuItem.Text = "Import options";
this.importOptionsToolStripMenuItem.DropDownClosed += new System.EventHandler(this.importOptions_DropDownClose); this.importOptionsToolStripMenuItem.DropDownClosed += new System.EventHandler(this.importOptions_DropDownClose);
this.importOptionsToolStripMenuItem.DropDownOpened += new System.EventHandler(this.importOptions_DropDownOpened); this.importOptionsToolStripMenuItem.DropDownOpened += new System.EventHandler(this.importOptions_DropDownOpened);
@@ -479,7 +491,7 @@
// showExpOpt // showExpOpt
// //
this.showExpOpt.Name = "showExpOpt"; this.showExpOpt.Name = "showExpOpt";
this.showExpOpt.Size = new System.Drawing.Size(241, 22); this.showExpOpt.Size = new System.Drawing.Size(243, 22);
this.showExpOpt.Text = "Export options"; this.showExpOpt.Text = "Export options";
this.showExpOpt.Click += new System.EventHandler(this.showExpOpt_Click); this.showExpOpt.Click += new System.EventHandler(this.showExpOpt_Click);
// //
@@ -1858,6 +1870,7 @@
private System.Windows.Forms.ToolStripComboBox customBlockCompressionComboBox; private System.Windows.Forms.ToolStripComboBox customBlockCompressionComboBox;
private System.Windows.Forms.ToolStripMenuItem saveOptionsToDiskToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem saveOptionsToDiskToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator importOptionsToolStripSeparator; private System.Windows.Forms.ToolStripSeparator importOptionsToolStripSeparator;
private System.Windows.Forms.ToolStripMenuItem meshLazyLoadToolStripMenuItem;
} }
} }

View File

@@ -145,6 +145,7 @@ namespace AssetStudioGUI
useAssetLoadingViaTypetreeToolStripMenuItem.Checked = Properties.Settings.Default.useTypetreeLoading; useAssetLoadingViaTypetreeToolStripMenuItem.Checked = Properties.Settings.Default.useTypetreeLoading;
useDumpTreeViewToolStripMenuItem.Checked = Properties.Settings.Default.useDumpTreeView; useDumpTreeViewToolStripMenuItem.Checked = Properties.Settings.Default.useDumpTreeView;
autoPlayAudioAssetsToolStripMenuItem.Checked = Properties.Settings.Default.autoplayAudio; autoPlayAudioAssetsToolStripMenuItem.Checked = Properties.Settings.Default.autoplayAudio;
meshLazyLoadToolStripMenuItem.Checked = Properties.Settings.Default.meshLazyLoad;
customBlockCompressionComboBox.SelectedIndex = 0; customBlockCompressionComboBox.SelectedIndex = 0;
customBlockInfoCompressionComboBox.SelectedIndex = 0; customBlockInfoCompressionComboBox.SelectedIndex = 0;
assetsManager.Options.BundleOptions.DecompressToDisk = Properties.Settings.Default.decompressToDisk; assetsManager.Options.BundleOptions.DecompressToDisk = Properties.Settings.Default.decompressToDisk;
@@ -1308,6 +1309,8 @@ namespace AssetStudioGUI
private void PreviewMesh(Mesh m_Mesh) private void PreviewMesh(Mesh m_Mesh)
{ {
m_Mesh.ProcessData();
if (m_Mesh.m_VertexCount > 0) if (m_Mesh.m_VertexCount > 0)
{ {
viewMatrixData = Matrix4.CreateRotationY(-MathF.PI / 4) * Matrix4.CreateRotationX(-MathF.PI / 6); viewMatrixData = Matrix4.CreateRotationY(-MathF.PI / 4) * Matrix4.CreateRotationX(-MathF.PI / 6);
@@ -2652,6 +2655,13 @@ namespace AssetStudioGUI
Properties.Settings.Default.Save(); Properties.Settings.Default.Save();
} }
private void meshLazyLoadToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
{
Properties.Settings.Default.meshLazyLoad = meshLazyLoadToolStripMenuItem.Checked;
assetsManager.MeshLazyLoad = meshLazyLoadToolStripMenuItem.Checked;
Properties.Settings.Default.Save();
}
private static void FbxInitOptions(string base64String) private static void FbxInitOptions(string base64String)
{ {
if (string.IsNullOrEmpty(base64String)) if (string.IsNullOrEmpty(base64String))

View File

@@ -147,12 +147,16 @@ namespace AssetStudioGUI
private static bool ExportMesh(AssetItem item, string exportPath) private static bool ExportMesh(AssetItem item, string exportPath)
{ {
var m_Mesh = (Mesh)item.Asset; var m_Mesh = (Mesh)item.Asset;
m_Mesh.ProcessData();
if (m_Mesh.m_VertexCount <= 0) if (m_Mesh.m_VertexCount <= 0)
return false; return false;
if (!TryExportFile(exportPath, item, ".obj", out var exportFullPath)) if (!TryExportFile(exportPath, item, ".obj", out var exportFullPath))
return false; return false;
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.AppendLine("g " + m_Mesh.m_Name); sb.AppendLine("g " + m_Mesh.m_Name);
#region Vertices #region Vertices
if (m_Mesh.m_Vertices == null || m_Mesh.m_Vertices.Length == 0) if (m_Mesh.m_Vertices == null || m_Mesh.m_Vertices.Length == 0)
{ {

View File

@@ -346,5 +346,17 @@ namespace AssetStudioGUI.Properties {
this["overwriteExistingFiles"] = value; this["overwriteExistingFiles"] = value;
} }
} }
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool meshLazyLoad {
get {
return ((bool)(this["meshLazyLoad"]));
}
set {
this["meshLazyLoad"] = value;
}
}
} }
} }

View File

@@ -83,5 +83,8 @@
<Setting Name="overwriteExistingFiles" Type="System.Boolean" Scope="User"> <Setting Name="overwriteExistingFiles" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value> <Value Profile="(Default)">False</Value>
</Setting> </Setting>
<Setting Name="meshLazyLoad" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
</Settings> </Settings>
</SettingsFile> </SettingsFile>

View File

@@ -256,6 +256,8 @@ namespace AssetStudio
var mesh = GetMesh(meshR); var mesh = GetMesh(meshR);
if (mesh == null) if (mesh == null)
return; return;
mesh.ProcessData();
var iMesh = new ImportedMesh(); var iMesh = new ImportedMesh();
meshR.m_GameObject.TryGet(out var m_GameObject2); meshR.m_GameObject.TryGet(out var m_GameObject2);
iMesh.Path = GetTransformPath(m_GameObject2.m_Transform); iMesh.Path = GetTransformPath(m_GameObject2.m_Transform);