- WIP Asset Browser.

- fix for some modes without textures [`SR`]
- AssetMap new mode (Minimal/Full).
This commit is contained in:
Razmoth
2023-05-07 19:56:55 +04:00
parent 8e0f97ce2d
commit 2376a8669e
23 changed files with 498 additions and 180 deletions

View File

@@ -1,11 +0,0 @@
namespace AssetStudio
{
public class AssetEntry
{
public string Name { get; set; }
public string Container { get; set; }
public string Source { get; set; }
public long PathID { get; set; }
public ClassIDType Type { get; set; }
}
}

38
AssetStudio/AssetIndex.cs Normal file
View File

@@ -0,0 +1,38 @@
using System.Collections.Generic;
namespace AssetStudio
{
public record AssetIndex
{
public Dictionary<string, string> Types { get; set; }
public record SubAssetInfo
{
public string Name { get; set; }
public byte PathHashPre { get; set; }
public uint PathHashLast { get; set; }
}
public Dictionary<int, List<SubAssetInfo>> SubAssets { get; set; }
public Dictionary<int, List<int>> Dependencies { get; set; }
public List<uint> PreloadBlocks { get; set; }
public List<uint> PreloadShaderBlocks { get; set; }
public record BlockInfo
{
public byte Language { get; set; }
public uint Id { get; set; }
public uint Offset { get; set; }
}
public Dictionary<int, BlockInfo> Assets { get; set; }
public List<uint> SortList { get; set; }
public AssetIndex()
{
Types = new Dictionary<string, string>();
SubAssets = new Dictionary<int, List<SubAssetInfo>>();
Dependencies = new Dictionary<int, List<int>>();
PreloadBlocks = new List<uint>();
PreloadShaderBlocks = new List<uint>();
Assets = new Dictionary<int, BlockInfo>();
SortList = new List<uint>();
}
}
}

35
AssetStudio/AssetMap.cs Normal file
View File

@@ -0,0 +1,35 @@
using MessagePack;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace AssetStudio
{
[MessagePackObject]
public record AssetMap
{
[Key(0)]
public GameType GameType { get; set; }
[Key(1)]
public AssetEntry[] AssetEntries { get; set; }
}
[MessagePackObject]
public record AssetEntry
{
[Key(0)]
public string Name { get; set; }
[Key(1)]
public string Container { get; set; }
[Key(2)]
public string Source { get; set; }
[Key(3)]
public long PathID { get; set; }
[Key(4)]
public ClassIDType Type { get; set; }
public bool Matches(Regex regex) => regex.IsMatch(Name)
|| regex.IsMatch(Container)
|| regex.IsMatch(Source)
|| regex.IsMatch(PathID.ToString())
|| regex.IsMatch(Type.ToString());
}
}

View File

@@ -11,6 +11,7 @@
<ItemGroup>
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.4-beta" />
<PackageReference Include="MessagePack" Version="2.5.108" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
</ItemGroup>

View File

@@ -9,6 +9,7 @@ using Newtonsoft.Json;
using System.Text.RegularExpressions;
using System.Xml;
using System.Text;
using MessagePack;
namespace AssetStudio
{
@@ -16,6 +17,7 @@ namespace AssetStudio
{
public const string MapName = "Maps";
public static bool Minimal = true;
public static CancellationTokenSource tokenSource = new CancellationTokenSource();
private static string BaseFolder = "";
@@ -34,7 +36,7 @@ namespace AssetStudio
{
Directory.CreateDirectory(MapName);
var files = Directory.GetFiles(MapName, "*.bin", SearchOption.TopDirectoryOnly);
return files.Select(x => Path.GetFileNameWithoutExtension(x)).ToArray();
return files.Select(Path.GetFileNameWithoutExtension).ToArray();
}
public static void Clear()
@@ -132,12 +134,11 @@ namespace AssetStudio
Logger.Info("Building CABMap has been cancelled !!");
return;
}
var dependencies = assetsFile.m_Externals.Select(x => x.fileName).ToArray();
var entry = new Entry()
{
Path = relativePath,
Offset = assetsFile.offset,
Dependencies = dependencies
Dependencies = assetsFile.m_Externals.Select(x => x.fileName).ToArray()
};
if (CABMap.ContainsKey(assetsFile.fileName))
@@ -192,17 +193,16 @@ namespace AssetStudio
var path = reader.ReadString();
var offset = reader.ReadInt64();
var depCount = reader.ReadInt32();
var dependencies = new List<string>();
var dependencies = new string[depCount];
for (int j = 0; j < depCount; j++)
{
var dependancy = reader.ReadString();
dependencies.Add(dependancy);
dependencies[j] = reader.ReadString();
}
var entry = new Entry()
{
Path = path,
Offset = offset,
Dependencies = dependencies.ToArray()
Dependencies = dependencies
};
CABMap.Add(cab, entry);
}
@@ -230,7 +230,7 @@ namespace AssetStudio
UpdateContainers(assets, game);
ExportAssetsMap(assets.ToArray(), mapName, savePath, exportListType, resetEvent);
ExportAssetsMap(assets.ToArray(), game, mapName, savePath, exportListType, resetEvent);
}
catch(Exception e)
{
@@ -283,13 +283,13 @@ namespace AssetStudio
}
obj = null;
asset.Name = assetBundle.m_Name;
exportable = false;
exportable = !Minimal;
break;
case ClassIDType.GameObject:
var gameObject = new GameObject(objectReader);
obj = gameObject;
asset.Name = gameObject.m_Name;
exportable = false;
exportable = !Minimal;
break;
case ClassIDType.Shader when Shader.Parsable:
asset.Name = objectReader.ReadAlignedString();
@@ -306,7 +306,6 @@ namespace AssetStudio
case ClassIDType.MiHoYoBinData:
var MiHoYoBinData = new MiHoYoBinData(objectReader);
obj = MiHoYoBinData;
exportable = true;
break;
case ClassIDType.IndexObject:
var indexObject = new IndexObject(objectReader);
@@ -316,6 +315,7 @@ namespace AssetStudio
mihoyoBinDataNames.Add((index.Value.Object, index.Key));
}
asset.Name = "IndexObject";
exportable = !Minimal;
break;
case ClassIDType.Font:
case ClassIDType.Material:
@@ -329,7 +329,8 @@ namespace AssetStudio
asset.Name = objectReader.ReadAlignedString();
break;
default:
exportable = false;
asset.Name = objectReader.type.ToString();
exportable = !Minimal;
break;
}
}
@@ -428,7 +429,7 @@ namespace AssetStudio
}
}
private static void ExportAssetsMap(AssetEntry[] toExportAssets, string name, string savePath, ExportListType exportListType, ManualResetEvent resetEvent = null)
private static void ExportAssetsMap(AssetEntry[] toExportAssets, Game game, string name, string savePath, ExportListType exportListType, ManualResetEvent resetEvent = null)
{
ThreadPool.QueueUserWorkItem(state =>
{
@@ -436,13 +437,12 @@ namespace AssetStudio
Progress.Reset();
string filename;
string filename = Path.Combine(savePath, $"{name}{exportListType.GetExtension()}");
switch (exportListType)
{
case ExportListType.XML:
filename = Path.Combine(savePath, $"{name}.xml");
var settings = new XmlWriterSettings() { Indent = true };
using (XmlWriter writer = XmlWriter.Create(filename, settings))
var xmlSettings = new XmlWriterSettings() { Indent = true };
using (XmlWriter writer = XmlWriter.Create(filename, xmlSettings))
{
writer.WriteStartDocument();
writer.WriteStartElement("Assets");
@@ -466,7 +466,6 @@ namespace AssetStudio
}
break;
case ExportListType.JSON:
filename = Path.Combine(savePath, $"{name}.json");
using (StreamWriter file = File.CreateText(filename))
{
var serializer = new JsonSerializer() { Formatting = Newtonsoft.Json.Formatting.Indented };
@@ -474,10 +473,20 @@ namespace AssetStudio
serializer.Serialize(file, toExportAssets);
}
break;
case ExportListType.MessagePack:
using (var file = File.Create(filename))
{
var assetMap = new AssetMap
{
GameType = game.Type,
AssetEntries = toExportAssets
};
MessagePackSerializer.Serialize(file, assetMap, MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray));
}
break;
}
Logger.Info($"Finished exporting asset list with {toExportAssets.Length} items.");
Logger.Info($"AssetMap build successfully !!");
Logger.Info($"Finished buidling AssetMap with {toExportAssets.Length} assets.");
resetEvent?.Set();
});
@@ -501,7 +510,7 @@ namespace AssetStudio
DumpCABMap(mapName);
Logger.Info($"Map build successfully !! {collision} collisions found");
ExportAssetsMap(assets.ToArray(), mapName, savePath, exportListType, resetEvent);
ExportAssetsMap(assets.ToArray(), game, mapName, savePath, exportListType, resetEvent);
}
}
}

View File

@@ -3,7 +3,8 @@
public enum ExportListType
{
XML,
JSON
JSON,
MessagePack
}
public static class ExportListTypeExtensions
@@ -12,6 +13,7 @@
{
ExportListType.XML => ".xml",
ExportListType.JSON => ".json",
ExportListType.MessagePack => ".map",
_ => throw new System.NotImplementedException(),
};
}

View File

@@ -2,7 +2,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace AssetStudio
@@ -86,38 +85,4 @@ namespace AssetStudio
return string.Empty;
}
}
public record AssetIndex
{
public Dictionary<string, string> Types { get; set; }
public record SubAssetInfo
{
public string Name { get; set; }
public byte PathHashPre { get; set; }
public uint PathHashLast { get; set; }
}
public Dictionary<int, List<SubAssetInfo>> SubAssets { get; set; }
public Dictionary<int, List<int>> Dependencies { get; set; }
public List<uint> PreloadBlocks { get; set; }
public List<uint> PreloadShaderBlocks { get; set; }
public record BlockInfo
{
public byte Language { get; set; }
public uint Id { get; set; }
public uint Offset { get; set; }
}
public Dictionary<int, BlockInfo> Assets { get; set; }
public List<uint> SortList { get; set; }
public AssetIndex()
{
Types = new Dictionary<string, string>();
SubAssets = new Dictionary<int, List<SubAssetInfo>>();
Dependencies = new Dictionary<int, List<int>>();
PreloadBlocks = new List<uint>();
PreloadShaderBlocks = new List<uint>();
Assets = new Dictionary<int, BlockInfo>();
SortList = new List<uint>();
}
}
}

View File

@@ -0,0 +1,37 @@
using MessagePack;
using System;
using System.IO;
namespace AssetStudio
{
public static class ResourceMap
{
private static AssetMap Instance;
public static AssetEntry[] GetEntries() => Instance.AssetEntries;
public static void FromFile(string path)
{
if (!string.IsNullOrEmpty(path))
{
Logger.Info(string.Format("Parsing...."));
try
{
using var stream = File.OpenRead(path);
Instance = MessagePackSerializer.Deserialize<AssetMap>(stream, MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray));
}
catch (Exception e)
{
Logger.Error("AssetMap was not loaded");
Console.WriteLine(e.ToString());
return;
}
Logger.Info("Loaded !!");
}
}
public static void Clear()
{
Instance.GameType = GameType.Normal;
Instance.AssetEntries = null;
}
}
}

View File

@@ -22,5 +22,6 @@
<add key="exportAllUvsAsDiffuseMaps" value="False" />
<add key="disableShader" value="False" />
<add key="disableRenderer" value="False" />
<add key="minimalAssetMap" value="True" />
</appSettings>
</configuration>

View File

@@ -27,6 +27,7 @@ namespace AssetStudioCLI
Studio.Game = game;
Logger.Default = new ConsoleLogger();
AssetsHelper.Minimal = Settings.Default.minimalAssetMap;
Shader.Parsable = !Settings.Default.disableShader;
Renderer.Parsable = !Settings.Default.disableRenderer;
assetsManager.Silent = o.Silent;

View File

@@ -69,6 +69,7 @@ namespace AssetStudioCLI.Properties {
public bool exportMiHoYoBinData => AppSettings.Get("exportMiHoYoBinData", true);
public bool disableShader => AppSettings.Get("disableShader", false);
public bool disableRenderer => AppSettings.Get("disableRenderer", false);
public bool minimalAssetMap => AppSettings.Get("minimalAssetMap", true);
}
}

View File

@@ -100,6 +100,9 @@
<setting name="disableRenderer" serializeAs="String">
<value>False</value>
</setting>
<setting name="minimalAssetMap" serializeAs="String">
<value>True</value>
</setting>
</AssetStudioGUI.Properties.Settings>
</userSettings>
</configuration>

117
AssetStudioGUI/AssetBrowser.Designer.cs generated Normal file
View File

@@ -0,0 +1,117 @@
namespace AssetStudioGUI
{
partial class AssetBrowser
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
assetListView = new System.Windows.Forms.DataGridView();
fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
loadAssetMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
clearToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
searchTextBox = new System.Windows.Forms.ToolStripTextBox();
menuStrip1 = new System.Windows.Forms.MenuStrip();
((System.ComponentModel.ISupportInitialize)assetListView).BeginInit();
menuStrip1.SuspendLayout();
SuspendLayout();
//
// assetListView
//
assetListView.AllowUserToAddRows = false;
assetListView.AllowUserToDeleteRows = false;
assetListView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
assetListView.Location = new System.Drawing.Point(12, 27);
assetListView.Name = "assetListView";
assetListView.ReadOnly = true;
assetListView.RowTemplate.Height = 25;
assetListView.Size = new System.Drawing.Size(524, 268);
assetListView.TabIndex = 2;
assetListView.RowHeaderMouseDoubleClick += assetListView_RowHeaderMouseDoubleClick;
//
// fileToolStripMenuItem
//
fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { loadAssetMapToolStripMenuItem, clearToolStripMenuItem });
fileToolStripMenuItem.Name = "fileToolStripMenuItem";
fileToolStripMenuItem.Size = new System.Drawing.Size(37, 23);
fileToolStripMenuItem.Text = "File";
//
// loadAssetMapToolStripMenuItem
//
loadAssetMapToolStripMenuItem.Name = "loadAssetMapToolStripMenuItem";
loadAssetMapToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
loadAssetMapToolStripMenuItem.Text = "Load AssetMap";
loadAssetMapToolStripMenuItem.Click += loadAssetMapToolStripMenuItem_Click;
//
// clearToolStripMenuItem
//
clearToolStripMenuItem.Name = "clearToolStripMenuItem";
clearToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
clearToolStripMenuItem.Text = "Clear";
clearToolStripMenuItem.Click += clearToolStripMenuItem_Click;
//
// searchTextBox
//
searchTextBox.Name = "searchTextBox";
searchTextBox.Size = new System.Drawing.Size(500, 23);
searchTextBox.KeyPress += toolStripTextBox1_KeyPress;
//
// menuStrip1
//
menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { fileToolStripMenuItem, searchTextBox });
menuStrip1.Location = new System.Drawing.Point(0, 0);
menuStrip1.Name = "menuStrip1";
menuStrip1.Size = new System.Drawing.Size(548, 27);
menuStrip1.TabIndex = 1;
menuStrip1.Text = "menuStrip1";
//
// AssetBrowser
//
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
ClientSize = new System.Drawing.Size(548, 307);
Controls.Add(assetListView);
Controls.Add(menuStrip1);
MainMenuStrip = menuStrip1;
Name = "AssetBrowser";
ShowIcon = false;
StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
Text = "Asset Browser";
((System.ComponentModel.ISupportInitialize)assetListView).EndInit();
menuStrip1.ResumeLayout(false);
menuStrip1.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private System.Windows.Forms.DataGridView assetListView;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem loadAssetMapToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem clearToolStripMenuItem;
private System.Windows.Forms.ToolStripTextBox searchTextBox;
private System.Windows.Forms.MenuStrip menuStrip1;
}
}

View File

@@ -0,0 +1,79 @@
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using AssetStudio;
namespace AssetStudioGUI
{
partial class AssetBrowser : Form
{
private readonly AssetStudioGUIForm _parent;
public AssetBrowser(AssetStudioGUIForm form)
{
InitializeComponent();
_parent = form;
}
private async void loadAssetMapToolStripMenuItem_Click(object sender, EventArgs e)
{
fileToolStripMenuItem.DropDown.Visible = false;
var openFileDialog = new OpenFileDialog() { Multiselect = false, Filter = "AssetMap File|*.map" };
if (openFileDialog.ShowDialog(this) == DialogResult.OK)
{
var path = openFileDialog.FileName;
Logger.Info($"Loading AssetMap...");
InvokeUpdate(loadAssetMapToolStripMenuItem, false);
await Task.Run(() => ResourceMap.FromFile(path));
assetListView.DataSource = ResourceMap.GetEntries();
InvokeUpdate(loadAssetMapToolStripMenuItem, true);
}
}
private void clearToolStripMenuItem_Click(object sender, EventArgs e)
{
ResourceMap.Clear();
assetListView.DataSource = null;
Logger.Info($"Cleared !!");
}
private async void assetListView_RowHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
var entry = assetListView.CurrentRow.DataBoundItem as AssetEntry;
if (!string.IsNullOrEmpty(entry.Source))
{
Logger.Info("Loading...");
_parent.Invoke(() => _parent.LoadPaths(entry.Source));
}
}
private void InvokeUpdate(ToolStripItem item, bool value)
{
if (InvokeRequired)
{
BeginInvoke(new Action(() => { item.Enabled = value; }));
}
else
{
item.Enabled = value;
}
}
private void toolStripTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
var value = searchTextBox.Text;
if (!string.IsNullOrEmpty(value))
{
var regex = new Regex(value);
assetListView.DataSource = Array.FindAll(ResourceMap.GetEntries(), x => x.Matches(regex));
}
else
{
assetListView.DataSource = ResourceMap.GetEntries();
}
}
}
}
}

View File

@@ -0,0 +1,63 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>142, 17</value>
</metadata>
</root>

View File

@@ -93,6 +93,7 @@ namespace AssetStudioGUI
clearConsoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
miscToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
MapNameComboBox = new System.Windows.Forms.ToolStripComboBox();
buildMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
buildBothToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
clearMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator();
@@ -101,6 +102,7 @@ namespace AssetStudioGUI
assetMapTypeComboBox = new System.Windows.Forms.ToolStripComboBox();
toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator();
loadAIToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
assetBrowserToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
assetHelpersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
MapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
assetMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -155,7 +157,6 @@ namespace AssetStudioGUI
exportAnimatorwithselectedAnimationClipMenuItem = new System.Windows.Forms.ToolStripMenuItem();
goToSceneHierarchyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
showOriginalFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
buildMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
menuStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
splitContainer1.Panel1.SuspendLayout();
@@ -600,7 +601,7 @@ namespace AssetStudioGUI
//
// miscToolStripMenuItem
//
miscToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { MapNameComboBox, buildMapToolStripMenuItem, buildBothToolStripMenuItem, clearMapToolStripMenuItem, toolStripSeparator7, assetMapNameTextBox, buildAssetMapToolStripMenuItem, assetMapTypeComboBox, toolStripSeparator8, loadAIToolStripMenuItem });
miscToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { MapNameComboBox, buildMapToolStripMenuItem, buildBothToolStripMenuItem, clearMapToolStripMenuItem, toolStripSeparator7, assetMapNameTextBox, buildAssetMapToolStripMenuItem, assetMapTypeComboBox, toolStripSeparator8, loadAIToolStripMenuItem, assetBrowserToolStripMenuItem });
miscToolStripMenuItem.Name = "miscToolStripMenuItem";
miscToolStripMenuItem.Size = new System.Drawing.Size(47, 20);
miscToolStripMenuItem.Text = "Misc.";
@@ -670,6 +671,13 @@ namespace AssetStudioGUI
loadAIToolStripMenuItem.Text = "Load AI";
loadAIToolStripMenuItem.Click += loadAIToolStripMenuItem_Click;
//
// assetBrowserToolStripMenuItem
//
assetBrowserToolStripMenuItem.Name = "assetBrowserToolStripMenuItem";
assetBrowserToolStripMenuItem.Size = new System.Drawing.Size(181, 22);
assetBrowserToolStripMenuItem.Text = "Asset Browser";
assetBrowserToolStripMenuItem.Click += loadAssetMapToolStripMenuItem_Click;
//
// assetHelpersToolStripMenuItem
//
assetHelpersToolStripMenuItem.Name = "assetHelpersToolStripMenuItem";
@@ -1391,6 +1399,7 @@ namespace AssetStudioGUI
private System.Windows.Forms.ToolStripSeparator toolStripSeparator7;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator8;
private System.Windows.Forms.ToolStripMenuItem buildMapToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem assetBrowserToolStripMenuItem;
}
}

View File

@@ -110,6 +110,7 @@ namespace AssetStudioGUI
assetsManager.ResolveDependencies = Properties.Settings.Default.enableResolveDependencies;
MiHoYoBinData.Encrypted = Properties.Settings.Default.encrypted;
MiHoYoBinData.Key = Properties.Settings.Default.key;
AssetsHelper.Minimal = Properties.Settings.Default.minimalAssetMap;
Renderer.Parsable = !Properties.Settings.Default.disableRenderer;
Shader.Parsable = !Properties.Settings.Default.disableShader;
}
@@ -163,6 +164,12 @@ namespace AssetStudioGUI
{
var paths = (string[])e.Data.GetData(DataFormats.FileDrop);
if (paths.Length > 0)
{
LoadPaths(paths);
}
}
public async void LoadPaths(params string[] paths)
{
ResetForm();
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
@@ -181,7 +188,6 @@ namespace AssetStudioGUI
}
BuildAssetStructures();
}
}
private async void loadFile_Click(object sender, EventArgs e)
{
@@ -1233,84 +1239,16 @@ namespace AssetStudioGUI
private void PreviewGameObject(GameObject m_GameObject)
{
var model = new ModelConverter(m_GameObject, Properties.Settings.Default.convertType, Studio.Game, false, Array.Empty<AnimationClip>());
if (model.MeshList.Count > 0)
{
viewMatrixData = Matrix4.CreateRotationY(-(float)Math.PI / 4) * Matrix4.CreateRotationX(-(float)Math.PI / 6);
#region Vertices
vertexData = model.MeshList.SelectMany(x => x.VertexList).Select(x => new Vector3(x.Vertex.X, x.Vertex.Y, x.Vertex.Z)).ToArray();
// Calculate Bounding
Vector3 min = vertexData.Aggregate(Vector3.ComponentMin);
Vector3 max = vertexData.Aggregate(Vector3.ComponentMax);
// Calculate modelMatrix
Vector3 dist = max - min;
Vector3 offset = (max - min) / 2;
float d = Math.Max(1e-5f, dist.Length);
modelMatrixData = Matrix4.CreateTranslation(-offset) * Matrix4.CreateScale(2f / d);
#endregion
#region Indicies
int meshOffset = 0;
var indices = new List<int>();
foreach (var mesh in model.MeshList)
{
foreach (var submesh in mesh.SubmeshList)
{
foreach (var face in submesh.FaceList)
{
foreach (var index in face.VertexIndices)
{
indices.Add(submesh.BaseVertex + index + meshOffset);
}
}
}
meshOffset += mesh.VertexList.Count;
}
indiceData = indices.ToArray();
#endregion
#region Normals
normalData = model.MeshList.SelectMany(x => x.VertexList).Select(x => new Vector3(x.Normal.X, x.Normal.Y, x.Normal.Z)).ToArray();
// calculate normal by ourself
normal2Data = new Vector3[vertexData.Length];
int[] normalCalculatedCount = new int[vertexData.Length];
Array.Fill(normal2Data, Vector3.Zero);
Array.Fill(normalCalculatedCount, 0);
for (int j = 0; j < indiceData.Length; j += 3)
{
Vector3 dir1 = vertexData[indiceData[j + 1]] - vertexData[indiceData[j]];
Vector3 dir2 = vertexData[indiceData[j + 2]] - vertexData[indiceData[j]];
Vector3 normal = Vector3.Cross(dir1, dir2);
normal.Normalize();
for (int k = 0; k < 3; k++)
{
normal2Data[indiceData[j + k]] += normal;
normalCalculatedCount[indiceData[j + k]]++;
}
}
for (int j = 0; j < vertexData.Length; j++)
{
if (normalCalculatedCount[j] == 0)
normal2Data[j] = new Vector3(0, 1, 0);
else
normal2Data[j] /= normalCalculatedCount[j];
}
#endregion
#region Colors
colorData = model.MeshList.SelectMany(x => x.VertexList).Select(x => new Vector4(x.Color.R, x.Color.G, x.Color.B, x.Color.A)).ToArray();
#endregion
glControl.Visible = true;
CreateVAO();
StatusStripUpdate("Using OpenGL Version: " + GL.GetString(StringName.Version) + "\n"
+ "'Mouse Left'=Rotate | 'Mouse Right'=Move | 'Mouse Wheel'=Zoom \n"
+ "'Ctrl W'=Wireframe | 'Ctrl S'=Shade | 'Ctrl N'=ReNormal ");
}
else
{
StatusStripUpdate("Unable to preview this model");
}
PreviewModel(model);
}
private void PreviewAnimator(Animator m_Animator)
{
var model = new ModelConverter(m_Animator, Properties.Settings.Default.convertType, Studio.Game, false, Array.Empty<AnimationClip>());
PreviewModel(model);
}
private void PreviewModel(ModelConverter model)
{
if (model.MeshList.Count > 0)
{
viewMatrixData = Matrix4.CreateRotationY(-(float)Math.PI / 4) * Matrix4.CreateRotationX(-(float)Math.PI / 6);
@@ -2267,6 +2205,12 @@ namespace AssetStudioGUI
InvokeUpdate(miscToolStripMenuItem, true);
}
private void loadAssetMapToolStripMenuItem_Click(object sender, EventArgs e)
{
var assetBrowser = new AssetBrowser(this);
assetBrowser.Show();
}
#region FMOD
private void FMODinit()
{

View File

@@ -71,12 +71,13 @@ namespace AssetStudioGUI
key = new System.Windows.Forms.NumericUpDown();
keyToolTip = new System.Windows.Forms.ToolTip(components);
groupBox4 = new System.Windows.Forms.GroupBox();
disableShader = new System.Windows.Forms.CheckBox();
disableRenderer = new System.Windows.Forms.CheckBox();
skipContainer = new System.Windows.Forms.CheckBox();
enableResolveDependencies = new System.Windows.Forms.CheckBox();
resolveToolTip = new System.Windows.Forms.ToolTip(components);
skipToolTip = new System.Windows.Forms.ToolTip(components);
disableRenderer = new System.Windows.Forms.CheckBox();
disableShader = new System.Windows.Forms.CheckBox();
minimalAssetMap = new System.Windows.Forms.CheckBox();
groupBox1.SuspendLayout();
panel1.SuspendLayout();
groupBox2.SuspendLayout();
@@ -537,6 +538,7 @@ namespace AssetStudioGUI
// groupBox4
//
groupBox4.AutoSize = true;
groupBox4.Controls.Add(minimalAssetMap);
groupBox4.Controls.Add(disableShader);
groupBox4.Controls.Add(disableRenderer);
groupBox4.Controls.Add(skipContainer);
@@ -547,11 +549,35 @@ namespace AssetStudioGUI
groupBox4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
groupBox4.Name = "groupBox4";
groupBox4.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
groupBox4.Size = new System.Drawing.Size(272, 176);
groupBox4.Size = new System.Drawing.Size(272, 187);
groupBox4.TabIndex = 13;
groupBox4.TabStop = false;
groupBox4.Text = "Options";
//
// disableShader
//
disableShader.AutoSize = true;
disableShader.Location = new System.Drawing.Point(8, 121);
disableShader.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
disableShader.Name = "disableShader";
disableShader.Size = new System.Drawing.Size(103, 19);
disableShader.TabIndex = 16;
disableShader.Text = "Disable Shader";
skipToolTip.SetToolTip(disableShader, "Skips the container recovery step.\nImproves loading when dealing with a large number of files.");
disableShader.UseVisualStyleBackColor = true;
//
// disableRenderer
//
disableRenderer.AutoSize = true;
disableRenderer.Location = new System.Drawing.Point(8, 96);
disableRenderer.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
disableRenderer.Name = "disableRenderer";
disableRenderer.Size = new System.Drawing.Size(114, 19);
disableRenderer.TabIndex = 15;
disableRenderer.Text = "Disable Renderer";
skipToolTip.SetToolTip(disableRenderer, "Skips the container recovery step.\nImproves loading when dealing with a large number of files.");
disableRenderer.UseVisualStyleBackColor = true;
//
// skipContainer
//
skipContainer.AutoSize = true;
@@ -580,29 +606,15 @@ namespace AssetStudioGUI
resolveToolTip.SetToolTip(enableResolveDependencies, "Toggle the behaviour of loading assets.\r\nDisable to load file(s) without its dependencies.");
enableResolveDependencies.UseVisualStyleBackColor = true;
//
// disableRenderer
// minimalAssetMap
//
disableRenderer.AutoSize = true;
disableRenderer.Location = new System.Drawing.Point(8, 96);
disableRenderer.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
disableRenderer.Name = "disableRenderer";
disableRenderer.Size = new System.Drawing.Size(114, 19);
disableRenderer.TabIndex = 15;
disableRenderer.Text = "Disable Renderer";
skipToolTip.SetToolTip(disableRenderer, "Skips the container recovery step.\nImproves loading when dealing with a large number of files.");
disableRenderer.UseVisualStyleBackColor = true;
//
// disableShader
//
disableShader.AutoSize = true;
disableShader.Location = new System.Drawing.Point(8, 121);
disableShader.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
disableShader.Name = "disableShader";
disableShader.Size = new System.Drawing.Size(103, 19);
disableShader.TabIndex = 16;
disableShader.Text = "Disable Shader";
skipToolTip.SetToolTip(disableShader, "Skips the container recovery step.\nImproves loading when dealing with a large number of files.");
disableShader.UseVisualStyleBackColor = true;
minimalAssetMap.AutoSize = true;
minimalAssetMap.Location = new System.Drawing.Point(8, 146);
minimalAssetMap.Name = "minimalAssetMap";
minimalAssetMap.Size = new System.Drawing.Size(125, 19);
minimalAssetMap.TabIndex = 17;
minimalAssetMap.Text = "Minimal AssetMap";
minimalAssetMap.UseVisualStyleBackColor = true;
//
// ExportOptions
//
@@ -687,5 +699,6 @@ namespace AssetStudioGUI
private System.Windows.Forms.ToolTip skipToolTip;
private System.Windows.Forms.CheckBox disableShader;
private System.Windows.Forms.CheckBox disableRenderer;
private System.Windows.Forms.CheckBox minimalAssetMap;
}
}

View File

@@ -44,6 +44,7 @@ namespace AssetStudioGUI
key.Value = Properties.Settings.Default.key;
disableRenderer.Checked = Properties.Settings.Default.disableRenderer;
disableShader.Checked = Properties.Settings.Default.disableShader;
minimalAssetMap.Checked = Properties.Settings.Default.minimalAssetMap;
}
private void OKbutton_Click(object sender, EventArgs e)
@@ -79,9 +80,11 @@ namespace AssetStudioGUI
Properties.Settings.Default.key = (byte)key.Value;
Properties.Settings.Default.disableRenderer = disableRenderer.Checked;
Properties.Settings.Default.disableShader = disableShader.Checked;
Properties.Settings.Default.minimalAssetMap = minimalAssetMap.Checked;
Properties.Settings.Default.Save();
MiHoYoBinData.Key = (byte)key.Value;
MiHoYoBinData.Encrypted = encrypted.Checked;
AssetsHelper.Minimal = Properties.Settings.Default.minimalAssetMap;
Renderer.Parsable = !Properties.Settings.Default.disableRenderer;
Shader.Parsable = !Properties.Settings.Default.disableShader;
DialogResult = DialogResult.OK;

View File

@@ -60,12 +60,6 @@
<metadata name="exportUvsTooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="exportUvsTooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="keyToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>162, 17</value>
</metadata>
<metadata name="keyToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>162, 17</value>
</metadata>
@@ -75,9 +69,6 @@
<metadata name="resolveToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>273, 17</value>
</metadata>
<metadata name="resolveToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>273, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>57</value>
</metadata>

View File

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

View File

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

View File

@@ -711,6 +711,8 @@ namespace AssetStudio
dest = 2;
else if (texEnv.Key.Contains("Normal"))
dest = 1;
else if (Game.Type.IsSRGroup() && texEnv.Key.Contains("Pack"))
dest = 0;
texture.Dest = dest;