Add project files.
This commit is contained in:
107
AssetStudioGUI/AssetStudioGUI.csproj
Normal file
107
AssetStudioGUI/AssetStudioGUI.csproj
Normal file
@@ -0,0 +1,107 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFrameworks>net472;net5.0-windows;net6.0-windows</TargetFrameworks>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ApplicationIcon>Resources\as.ico</ApplicationIcon>
|
||||
<Version>0.18.00</Version>
|
||||
<AssemblyVersion>0.18.00</AssemblyVersion>
|
||||
<FileVersion>0.18.00</FileVersion>
|
||||
<Copyright>Copyright © Razmoth 2022; Copyright © Perfare 2018-2022</Copyright>
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AssetStudioUtility\AssetStudioUtility.csproj" />
|
||||
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Update="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ContentWithTargetPath Include="Libraries\x86\fmod.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>x86\fmod.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="Libraries\x64\fmod.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>x64\fmod.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ContentWithTargetPath Include="Libraries\x86\acl.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>x86\acl.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="Libraries\x64\acl.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>x64\acl.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ContentWithTargetPath Include="Libraries\x86\sracl.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>x86\sracl.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="Libraries\x64\sracl.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>x64\sracl.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' != 'net472' ">
|
||||
<PackageReference Include="OpenTK" Version="4.6.7" />
|
||||
<Reference Include="OpenTK.WinForms">
|
||||
<HintPath>Libraries\OpenTK.WinForms.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
|
||||
<PackageReference Include="OpenTK" Version="3.1.0" />
|
||||
<PackageReference Include="OpenTK.GLControl" Version="3.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.9.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="CopyExtraFiles" AfterTargets="AfterBuild">
|
||||
<Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\Win32\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)x86" ContinueOnError="true" />
|
||||
<Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\x64\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)x64" ContinueOnError="true" />
|
||||
<Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\Win32\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)x86" ContinueOnError="true" />
|
||||
<Copy SourceFiles="$(SolutionDir)Texture2DDecoderNative\bin\x64\$(Configuration)\Texture2DDecoderNative.dll" DestinationFolder="$(TargetDir)x64" ContinueOnError="true" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PublishExtraFiles" AfterTargets="Publish">
|
||||
<Copy SourceFiles="$(TargetDir)x86\AssetStudioFBXNative.dll" DestinationFolder="$(PublishDir)x86" ContinueOnError="true" />
|
||||
<Copy SourceFiles="$(TargetDir)x64\AssetStudioFBXNative.dll" DestinationFolder="$(PublishDir)x64" ContinueOnError="true" />
|
||||
<Copy SourceFiles="$(TargetDir)x86\Texture2DDecoderNative.dll" DestinationFolder="$(PublishDir)x86" ContinueOnError="true" />
|
||||
<Copy SourceFiles="$(TargetDir)x64\Texture2DDecoderNative.dll" DestinationFolder="$(PublishDir)x64" ContinueOnError="true" />
|
||||
</Target>
|
||||
</Project>
|
||||
1314
AssetStudioGUI/AssetStudioGUIForm.Designer.cs
generated
Normal file
1314
AssetStudioGUI/AssetStudioGUIForm.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
2317
AssetStudioGUI/AssetStudioGUIForm.cs
Normal file
2317
AssetStudioGUI/AssetStudioGUIForm.cs
Normal file
File diff suppressed because it is too large
Load Diff
156
AssetStudioGUI/AssetStudioGUIForm.resx
Normal file
156
AssetStudioGUI/AssetStudioGUIForm.resx
Normal file
@@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<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>312, 17</value>
|
||||
</metadata>
|
||||
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>432, 17</value>
|
||||
</metadata>
|
||||
<data name="fontPreviewBox.Text" xml:space="preserve">
|
||||
<value>abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWYZ
|
||||
1234567890.:,;'\"(!?)+-*/=
|
||||
|
||||
The quick brown fox jumps over the lazy dog. 1234567890
|
||||
|
||||
The quick brown fox jumps over the lazy dog. 1234567890
|
||||
|
||||
The quick brown fox jumps over the lazy dog. 1234567890
|
||||
|
||||
The quick brown fox jumps over the lazy dog. 1234567890
|
||||
|
||||
The quick brown fox jumps over the lazy dog. 1234567890
|
||||
|
||||
The quick brown fox jumps over the lazy dog. 1234567890
|
||||
|
||||
The quick brown fox jumps over the lazy dog. 1234567890</value>
|
||||
</data>
|
||||
<metadata name="timer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>553, 17</value>
|
||||
</metadata>
|
||||
<metadata name="openFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>636, 17</value>
|
||||
</metadata>
|
||||
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>147, 17</value>
|
||||
</metadata>
|
||||
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>67</value>
|
||||
</metadata>
|
||||
</root>
|
||||
40
AssetStudioGUI/Components/AssetItem.cs
Normal file
40
AssetStudioGUI/Components/AssetItem.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System.Windows.Forms;
|
||||
using AssetStudio;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
public class AssetItem : ListViewItem
|
||||
{
|
||||
public Object Asset;
|
||||
public SerializedFile SourceFile;
|
||||
public string Container = string.Empty;
|
||||
public string TypeString;
|
||||
public long m_PathID;
|
||||
public long FullSize;
|
||||
public ClassIDType Type;
|
||||
public string InfoText;
|
||||
public string UniqueID;
|
||||
public GameObjectTreeNode TreeNode;
|
||||
|
||||
public AssetItem(Object asset)
|
||||
{
|
||||
Asset = asset;
|
||||
SourceFile = asset.assetsFile;
|
||||
Type = asset.type;
|
||||
TypeString = Type.ToString();
|
||||
m_PathID = asset.m_PathID;
|
||||
FullSize = asset.byteSize;
|
||||
}
|
||||
|
||||
public void SetSubItems()
|
||||
{
|
||||
SubItems.AddRange(new[]
|
||||
{
|
||||
Container, //Container
|
||||
TypeString, //Type
|
||||
m_PathID.ToString(), //PathID
|
||||
FullSize.ToString(), //Size
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
17
AssetStudioGUI/Components/GOHierarchy.cs
Normal file
17
AssetStudioGUI/Components/GOHierarchy.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
internal class GOHierarchy : TreeView
|
||||
{
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
// Filter WM_LBUTTONDBLCLK
|
||||
if (m.Msg != 0x203) base.WndProc(ref m);
|
||||
}
|
||||
}
|
||||
}
|
||||
16
AssetStudioGUI/Components/GameObjectTreeNode.cs
Normal file
16
AssetStudioGUI/Components/GameObjectTreeNode.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Windows.Forms;
|
||||
using AssetStudio;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
public class GameObjectTreeNode : TreeNode
|
||||
{
|
||||
public GameObject gameObject;
|
||||
|
||||
public GameObjectTreeNode(GameObject gameObject)
|
||||
{
|
||||
this.gameObject = gameObject;
|
||||
Text = gameObject.m_Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
229
AssetStudioGUI/Components/OpenFolderDialog.cs
Normal file
229
AssetStudioGUI/Components/OpenFolderDialog.cs
Normal file
@@ -0,0 +1,229 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
internal class OpenFolderDialog
|
||||
{
|
||||
public string InitialFolder { get; set; }
|
||||
public string DefaultFolder { get; set; }
|
||||
public string Folder { get; private set; }
|
||||
public string Title { get; set; }
|
||||
|
||||
internal DialogResult ShowDialog(IWin32Window owner = null)
|
||||
{
|
||||
if (Environment.OSVersion.Version.Major >= 6)
|
||||
{
|
||||
return ShowVistaDialog(owner);
|
||||
}
|
||||
return ShowFolderBrowserDialog(owner);
|
||||
}
|
||||
|
||||
private DialogResult ShowVistaDialog(IWin32Window owner)
|
||||
{
|
||||
var frm = (NativeMethods.IFileDialog)(new NativeMethods.FileOpenDialogRCW());
|
||||
frm.GetOptions(out var options);
|
||||
options |= NativeMethods.FOS_PICKFOLDERS | NativeMethods.FOS_FORCEFILESYSTEM | NativeMethods.FOS_NOVALIDATE | NativeMethods.FOS_NOTESTFILECREATE | NativeMethods.FOS_DONTADDTORECENT;
|
||||
frm.SetOptions(options);
|
||||
if (!string.IsNullOrEmpty(Title))
|
||||
{
|
||||
frm.SetTitle(Title);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(InitialFolder))
|
||||
{
|
||||
var riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem
|
||||
if (NativeMethods.SHCreateItemFromParsingName(InitialFolder, IntPtr.Zero, ref riid, out var directoryShellItem) == NativeMethods.S_OK)
|
||||
{
|
||||
frm.SetFolder(directoryShellItem);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(DefaultFolder))
|
||||
{
|
||||
var riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem
|
||||
if (NativeMethods.SHCreateItemFromParsingName(DefaultFolder, IntPtr.Zero, ref riid, out var directoryShellItem) == NativeMethods.S_OK)
|
||||
{
|
||||
frm.SetDefaultFolder(directoryShellItem);
|
||||
}
|
||||
}
|
||||
|
||||
if ((owner == null ? frm.Show() : frm.Show(owner.Handle)) == NativeMethods.S_OK)
|
||||
{
|
||||
if (frm.GetResult(out var shellItem) == NativeMethods.S_OK)
|
||||
{
|
||||
if (shellItem.GetDisplayName(NativeMethods.SIGDN_FILESYSPATH, out var pszString) == NativeMethods.S_OK)
|
||||
{
|
||||
if (pszString != IntPtr.Zero)
|
||||
{
|
||||
try
|
||||
{
|
||||
Folder = Marshal.PtrToStringAuto(pszString);
|
||||
return DialogResult.OK;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeCoTaskMem(pszString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return DialogResult.Cancel;
|
||||
}
|
||||
|
||||
private DialogResult ShowFolderBrowserDialog(IWin32Window owner)
|
||||
{
|
||||
using (var frm = new FolderBrowserDialog())
|
||||
{
|
||||
if (InitialFolder != null)
|
||||
{
|
||||
frm.SelectedPath = InitialFolder;
|
||||
}
|
||||
#if !NETFRAMEWORK
|
||||
if (Title != null)
|
||||
{
|
||||
frm.Description = Title;
|
||||
frm.UseDescriptionForTitle = true;
|
||||
}
|
||||
#endif
|
||||
var result = owner == null ? frm.ShowDialog() : frm.ShowDialog(owner);
|
||||
if (result == DialogResult.OK)
|
||||
{
|
||||
Folder = frm.SelectedPath;
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class NativeMethods
|
||||
{
|
||||
|
||||
#region Constants
|
||||
|
||||
public const uint FOS_PICKFOLDERS = 0x00000020;
|
||||
public const uint FOS_FORCEFILESYSTEM = 0x00000040;
|
||||
public const uint FOS_NOVALIDATE = 0x00000100;
|
||||
public const uint FOS_NOTESTFILECREATE = 0x00010000;
|
||||
public const uint FOS_DONTADDTORECENT = 0x02000000;
|
||||
|
||||
public const uint S_OK = 0x0000;
|
||||
|
||||
public const uint SIGDN_FILESYSPATH = 0x80058000;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region COM
|
||||
|
||||
[ComImport, ClassInterface(ClassInterfaceType.None), TypeLibType(TypeLibTypeFlags.FCanCreate), Guid("DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7")]
|
||||
internal class FileOpenDialogRCW { }
|
||||
|
||||
|
||||
[ComImport(), Guid("42F85136-DB7E-439C-85F1-E4075D135FC8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
internal interface IFileDialog
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
[PreserveSig()]
|
||||
uint Show([In, Optional] IntPtr hwndOwner); //IModalWindow
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint SetFileTypes([In] uint cFileTypes, [In, MarshalAs(UnmanagedType.LPArray)] IntPtr rgFilterSpec);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint SetFileTypeIndex([In] uint iFileType);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint GetFileTypeIndex(out uint piFileType);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint Advise([In, MarshalAs(UnmanagedType.Interface)] IntPtr pfde, out uint pdwCookie);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint Unadvise([In] uint dwCookie);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint SetOptions([In] uint fos);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint GetOptions(out uint fos);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
void SetDefaultFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint GetFolder([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint GetCurrentSelection([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint SetFileName([In, MarshalAs(UnmanagedType.LPWStr)] string pszName);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint SetTitle([In, MarshalAs(UnmanagedType.LPWStr)] string pszTitle);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint SetOkButtonLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszText);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint SetFileNameLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint AddPlace([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, uint fdap);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint SetDefaultExtension([In, MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint Close([MarshalAs(UnmanagedType.Error)] uint hr);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint SetClientGuid([In] ref Guid guid);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint ClearClientData();
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint SetFilter([MarshalAs(UnmanagedType.Interface)] IntPtr pFilter);
|
||||
}
|
||||
|
||||
|
||||
[ComImport, Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
internal interface IShellItem
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint BindToHandler([In] IntPtr pbc, [In] ref Guid rbhid, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IntPtr ppvOut);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint GetParent([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint GetDisplayName([In] uint sigdnName, out IntPtr ppszName);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint GetAttributes([In] uint sfgaoMask, out uint psfgaoAttribs);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
uint Compare([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, [In] uint hint, out int piOrder);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IntPtr pbc, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out IShellItem ppv);
|
||||
}
|
||||
}
|
||||
29
AssetStudioGUI/Components/TypeTreeItem.cs
Normal file
29
AssetStudioGUI/Components/TypeTreeItem.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using AssetStudio;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
internal class TypeTreeItem : ListViewItem
|
||||
{
|
||||
private TypeTree m_Type;
|
||||
|
||||
public TypeTreeItem(int typeID, TypeTree m_Type)
|
||||
{
|
||||
this.m_Type = m_Type;
|
||||
Text = m_Type.m_Nodes[0].m_Type + " " + m_Type.m_Nodes[0].m_Name;
|
||||
SubItems.Add(typeID.ToString());
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var i in m_Type.m_Nodes)
|
||||
{
|
||||
sb.AppendFormat("{0}{1} {2} {3} {4}\r\n", new string('\t', i.m_Level), i.m_Type, i.m_Name, i.m_ByteSize, (i.m_MetaFlag & 0x4000) != 0);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
43
AssetStudioGUI/DirectBitmap.cs
Normal file
43
AssetStudioGUI/DirectBitmap.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
public sealed class DirectBitmap : IDisposable
|
||||
{
|
||||
public DirectBitmap(byte[] buff, int width, int height)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
Bits = buff;
|
||||
m_handle = GCHandle.Alloc(Bits, GCHandleType.Pinned);
|
||||
m_bitmap = new Bitmap(Width, Height, Stride, PixelFormat.Format32bppArgb, m_handle.AddrOfPinnedObject());
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
m_bitmap.Dispose();
|
||||
m_handle.Free();
|
||||
}
|
||||
m_bitmap = null;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
public int Height { get; }
|
||||
public int Width { get; }
|
||||
public int Stride => Width * 4;
|
||||
public byte[] Bits { get; }
|
||||
public Bitmap Bitmap => m_bitmap;
|
||||
|
||||
private Bitmap m_bitmap;
|
||||
private readonly GCHandle m_handle;
|
||||
}
|
||||
}
|
||||
667
AssetStudioGUI/ExportOptions.Designer.cs
generated
Normal file
667
AssetStudioGUI/ExportOptions.Designer.cs
generated
Normal file
@@ -0,0 +1,667 @@
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
partial class ExportOptions
|
||||
{
|
||||
/// <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()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.OKbutton = new System.Windows.Forms.Button();
|
||||
this.Cancel = new System.Windows.Forms.Button();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.disableShader = new System.Windows.Forms.CheckBox();
|
||||
this.ignoreController = new System.Windows.Forms.CheckBox();
|
||||
this.disableRndrr = new System.Windows.Forms.CheckBox();
|
||||
this.exportIndexObject = new System.Windows.Forms.CheckBox();
|
||||
this.exportAssetBundle = new System.Windows.Forms.CheckBox();
|
||||
this.openAfterExport = new System.Windows.Forms.CheckBox();
|
||||
this.restoreExtensionName = new System.Windows.Forms.CheckBox();
|
||||
this.assetGroupOptions = new System.Windows.Forms.ComboBox();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.convertAudio = new System.Windows.Forms.CheckBox();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.totga = new System.Windows.Forms.RadioButton();
|
||||
this.tojpg = new System.Windows.Forms.RadioButton();
|
||||
this.topng = new System.Windows.Forms.RadioButton();
|
||||
this.tobmp = new System.Windows.Forms.RadioButton();
|
||||
this.converttexture = new System.Windows.Forms.CheckBox();
|
||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
this.exportAllUvsAsDiffuseMaps = new System.Windows.Forms.CheckBox();
|
||||
this.exportBlendShape = new System.Windows.Forms.CheckBox();
|
||||
this.exportAnimations = new System.Windows.Forms.CheckBox();
|
||||
this.scaleFactor = new System.Windows.Forms.NumericUpDown();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.fbxFormat = new System.Windows.Forms.ComboBox();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.fbxVersion = new System.Windows.Forms.ComboBox();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.boneSize = new System.Windows.Forms.NumericUpDown();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.exportSkins = new System.Windows.Forms.CheckBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.filterPrecision = new System.Windows.Forms.NumericUpDown();
|
||||
this.castToBone = new System.Windows.Forms.CheckBox();
|
||||
this.exportAllNodes = new System.Windows.Forms.CheckBox();
|
||||
this.eulerFilter = new System.Windows.Forms.CheckBox();
|
||||
this.exportUvsTooltip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.groupBox3 = new System.Windows.Forms.GroupBox();
|
||||
this.enableXor = new System.Windows.Forms.CheckBox();
|
||||
this.key = new System.Windows.Forms.NumericUpDown();
|
||||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.panel1.SuspendLayout();
|
||||
this.groupBox2.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.scaleFactor)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.boneSize)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.filterPrecision)).BeginInit();
|
||||
this.groupBox3.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.key)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// OKbutton
|
||||
//
|
||||
this.OKbutton.Location = new System.Drawing.Point(318, 380);
|
||||
this.OKbutton.Name = "OKbutton";
|
||||
this.OKbutton.Size = new System.Drawing.Size(75, 23);
|
||||
this.OKbutton.TabIndex = 6;
|
||||
this.OKbutton.Text = "OK";
|
||||
this.OKbutton.UseVisualStyleBackColor = true;
|
||||
this.OKbutton.Click += new System.EventHandler(this.OKbutton_Click);
|
||||
//
|
||||
// Cancel
|
||||
//
|
||||
this.Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.Cancel.Location = new System.Drawing.Point(399, 380);
|
||||
this.Cancel.Name = "Cancel";
|
||||
this.Cancel.Size = new System.Drawing.Size(75, 23);
|
||||
this.Cancel.TabIndex = 7;
|
||||
this.Cancel.Text = "Cancel";
|
||||
this.Cancel.UseVisualStyleBackColor = true;
|
||||
this.Cancel.Click += new System.EventHandler(this.Cancel_Click);
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.AutoSize = true;
|
||||
this.groupBox1.Controls.Add(this.disableShader);
|
||||
this.groupBox1.Controls.Add(this.ignoreController);
|
||||
this.groupBox1.Controls.Add(this.disableRndrr);
|
||||
this.groupBox1.Controls.Add(this.exportIndexObject);
|
||||
this.groupBox1.Controls.Add(this.exportAssetBundle);
|
||||
this.groupBox1.Controls.Add(this.openAfterExport);
|
||||
this.groupBox1.Controls.Add(this.restoreExtensionName);
|
||||
this.groupBox1.Controls.Add(this.assetGroupOptions);
|
||||
this.groupBox1.Controls.Add(this.label6);
|
||||
this.groupBox1.Controls.Add(this.convertAudio);
|
||||
this.groupBox1.Controls.Add(this.panel1);
|
||||
this.groupBox1.Controls.Add(this.converttexture);
|
||||
this.groupBox1.Location = new System.Drawing.Point(12, 13);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(232, 277);
|
||||
this.groupBox1.TabIndex = 9;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "Export";
|
||||
//
|
||||
// disableShader
|
||||
//
|
||||
this.disableShader.AutoSize = true;
|
||||
this.disableShader.Location = new System.Drawing.Point(97, 219);
|
||||
this.disableShader.Name = "disableShader";
|
||||
this.disableShader.Size = new System.Drawing.Size(98, 17);
|
||||
this.disableShader.TabIndex = 22;
|
||||
this.disableShader.Text = "Disable Shader";
|
||||
this.disableShader.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// ignoreController
|
||||
//
|
||||
this.ignoreController.AutoSize = true;
|
||||
this.ignoreController.Checked = true;
|
||||
this.ignoreController.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.ignoreController.Location = new System.Drawing.Point(6, 241);
|
||||
this.ignoreController.Name = "ignoreController";
|
||||
this.ignoreController.Size = new System.Drawing.Size(152, 17);
|
||||
this.ignoreController.TabIndex = 21;
|
||||
this.ignoreController.Text = "Ignore Controller Animation";
|
||||
this.ignoreController.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// disableRndrr
|
||||
//
|
||||
this.disableRndrr.AutoSize = true;
|
||||
this.disableRndrr.Location = new System.Drawing.Point(97, 196);
|
||||
this.disableRndrr.Name = "disableRndrr";
|
||||
this.disableRndrr.Size = new System.Drawing.Size(113, 17);
|
||||
this.disableRndrr.TabIndex = 13;
|
||||
this.disableRndrr.Text = "Disable Renderers";
|
||||
this.disableRndrr.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// exportIndexObject
|
||||
//
|
||||
this.exportIndexObject.AutoSize = true;
|
||||
this.exportIndexObject.Checked = true;
|
||||
this.exportIndexObject.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.exportIndexObject.Location = new System.Drawing.Point(6, 219);
|
||||
this.exportIndexObject.Name = "exportIndexObject";
|
||||
this.exportIndexObject.Size = new System.Drawing.Size(83, 17);
|
||||
this.exportIndexObject.TabIndex = 12;
|
||||
this.exportIndexObject.Text = "IndexObject";
|
||||
this.exportIndexObject.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// exportAssetBundle
|
||||
//
|
||||
this.exportAssetBundle.AutoSize = true;
|
||||
this.exportAssetBundle.Checked = true;
|
||||
this.exportAssetBundle.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.exportAssetBundle.Location = new System.Drawing.Point(6, 196);
|
||||
this.exportAssetBundle.Name = "exportAssetBundle";
|
||||
this.exportAssetBundle.Size = new System.Drawing.Size(85, 17);
|
||||
this.exportAssetBundle.TabIndex = 11;
|
||||
this.exportAssetBundle.Text = "AssetBundle";
|
||||
this.exportAssetBundle.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// openAfterExport
|
||||
//
|
||||
this.openAfterExport.AutoSize = true;
|
||||
this.openAfterExport.Checked = true;
|
||||
this.openAfterExport.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.openAfterExport.Location = new System.Drawing.Point(6, 173);
|
||||
this.openAfterExport.Name = "openAfterExport";
|
||||
this.openAfterExport.Size = new System.Drawing.Size(137, 17);
|
||||
this.openAfterExport.TabIndex = 10;
|
||||
this.openAfterExport.Text = "Open folder after export";
|
||||
this.openAfterExport.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// restoreExtensionName
|
||||
//
|
||||
this.restoreExtensionName.AutoSize = true;
|
||||
this.restoreExtensionName.Checked = true;
|
||||
this.restoreExtensionName.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.restoreExtensionName.Location = new System.Drawing.Point(6, 63);
|
||||
this.restoreExtensionName.Name = "restoreExtensionName";
|
||||
this.restoreExtensionName.Size = new System.Drawing.Size(190, 17);
|
||||
this.restoreExtensionName.TabIndex = 9;
|
||||
this.restoreExtensionName.Text = "Restore TextAsset extension name";
|
||||
this.restoreExtensionName.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// assetGroupOptions
|
||||
//
|
||||
this.assetGroupOptions.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.assetGroupOptions.FormattingEnabled = true;
|
||||
this.assetGroupOptions.Items.AddRange(new object[] {
|
||||
"type name",
|
||||
"container path",
|
||||
"source file name",
|
||||
"do not group"});
|
||||
this.assetGroupOptions.Location = new System.Drawing.Point(6, 35);
|
||||
this.assetGroupOptions.Name = "assetGroupOptions";
|
||||
this.assetGroupOptions.Size = new System.Drawing.Size(149, 21);
|
||||
this.assetGroupOptions.TabIndex = 8;
|
||||
//
|
||||
// label6
|
||||
//
|
||||
this.label6.AutoSize = true;
|
||||
this.label6.Location = new System.Drawing.Point(6, 18);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(127, 13);
|
||||
this.label6.TabIndex = 7;
|
||||
this.label6.Text = "Group exported assets by";
|
||||
//
|
||||
// convertAudio
|
||||
//
|
||||
this.convertAudio.AutoSize = true;
|
||||
this.convertAudio.Checked = true;
|
||||
this.convertAudio.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.convertAudio.Location = new System.Drawing.Point(6, 150);
|
||||
this.convertAudio.Name = "convertAudio";
|
||||
this.convertAudio.Size = new System.Drawing.Size(179, 17);
|
||||
this.convertAudio.TabIndex = 6;
|
||||
this.convertAudio.Text = "Convert AudioClip to WAV(PCM)";
|
||||
this.convertAudio.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Controls.Add(this.totga);
|
||||
this.panel1.Controls.Add(this.tojpg);
|
||||
this.panel1.Controls.Add(this.topng);
|
||||
this.panel1.Controls.Add(this.tobmp);
|
||||
this.panel1.Location = new System.Drawing.Point(20, 111);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(202, 32);
|
||||
this.panel1.TabIndex = 5;
|
||||
//
|
||||
// totga
|
||||
//
|
||||
this.totga.AutoSize = true;
|
||||
this.totga.Location = new System.Drawing.Point(150, 6);
|
||||
this.totga.Name = "totga";
|
||||
this.totga.Size = new System.Drawing.Size(44, 17);
|
||||
this.totga.TabIndex = 2;
|
||||
this.totga.Text = "Tga";
|
||||
this.totga.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tojpg
|
||||
//
|
||||
this.tojpg.AutoSize = true;
|
||||
this.tojpg.Location = new System.Drawing.Point(97, 6);
|
||||
this.tojpg.Name = "tojpg";
|
||||
this.tojpg.Size = new System.Drawing.Size(48, 17);
|
||||
this.tojpg.TabIndex = 4;
|
||||
this.tojpg.Text = "Jpeg";
|
||||
this.tojpg.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// topng
|
||||
//
|
||||
this.topng.AutoSize = true;
|
||||
this.topng.Checked = true;
|
||||
this.topng.Location = new System.Drawing.Point(50, 6);
|
||||
this.topng.Name = "topng";
|
||||
this.topng.Size = new System.Drawing.Size(44, 17);
|
||||
this.topng.TabIndex = 3;
|
||||
this.topng.TabStop = true;
|
||||
this.topng.Text = "Png";
|
||||
this.topng.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tobmp
|
||||
//
|
||||
this.tobmp.AutoSize = true;
|
||||
this.tobmp.Location = new System.Drawing.Point(3, 6);
|
||||
this.tobmp.Name = "tobmp";
|
||||
this.tobmp.Size = new System.Drawing.Size(46, 17);
|
||||
this.tobmp.TabIndex = 2;
|
||||
this.tobmp.Text = "Bmp";
|
||||
this.tobmp.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// converttexture
|
||||
//
|
||||
this.converttexture.AutoSize = true;
|
||||
this.converttexture.Checked = true;
|
||||
this.converttexture.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.converttexture.Location = new System.Drawing.Point(6, 87);
|
||||
this.converttexture.Name = "converttexture";
|
||||
this.converttexture.Size = new System.Drawing.Size(116, 17);
|
||||
this.converttexture.TabIndex = 1;
|
||||
this.converttexture.Text = "Convert Texture2D";
|
||||
this.converttexture.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.AutoSize = true;
|
||||
this.groupBox2.Controls.Add(this.exportAllUvsAsDiffuseMaps);
|
||||
this.groupBox2.Controls.Add(this.exportBlendShape);
|
||||
this.groupBox2.Controls.Add(this.exportAnimations);
|
||||
this.groupBox2.Controls.Add(this.scaleFactor);
|
||||
this.groupBox2.Controls.Add(this.label5);
|
||||
this.groupBox2.Controls.Add(this.fbxFormat);
|
||||
this.groupBox2.Controls.Add(this.label4);
|
||||
this.groupBox2.Controls.Add(this.fbxVersion);
|
||||
this.groupBox2.Controls.Add(this.label3);
|
||||
this.groupBox2.Controls.Add(this.boneSize);
|
||||
this.groupBox2.Controls.Add(this.label2);
|
||||
this.groupBox2.Controls.Add(this.exportSkins);
|
||||
this.groupBox2.Controls.Add(this.label1);
|
||||
this.groupBox2.Controls.Add(this.filterPrecision);
|
||||
this.groupBox2.Controls.Add(this.castToBone);
|
||||
this.groupBox2.Controls.Add(this.exportAllNodes);
|
||||
this.groupBox2.Controls.Add(this.eulerFilter);
|
||||
this.groupBox2.Location = new System.Drawing.Point(250, 13);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(224, 362);
|
||||
this.groupBox2.TabIndex = 11;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "Fbx";
|
||||
//
|
||||
// exportAllUvsAsDiffuseMaps
|
||||
//
|
||||
this.exportAllUvsAsDiffuseMaps.AccessibleDescription = "";
|
||||
this.exportAllUvsAsDiffuseMaps.AutoSize = true;
|
||||
this.exportAllUvsAsDiffuseMaps.Location = new System.Drawing.Point(6, 185);
|
||||
this.exportAllUvsAsDiffuseMaps.Name = "exportAllUvsAsDiffuseMaps";
|
||||
this.exportAllUvsAsDiffuseMaps.Size = new System.Drawing.Size(168, 17);
|
||||
this.exportAllUvsAsDiffuseMaps.TabIndex = 23;
|
||||
this.exportAllUvsAsDiffuseMaps.Text = "Export all UVs as diffuse maps";
|
||||
this.exportUvsTooltip.SetToolTip(this.exportAllUvsAsDiffuseMaps, "Unchecked: UV1 exported as normal map. Check this if your export is missing a UV " +
|
||||
"map.");
|
||||
this.exportAllUvsAsDiffuseMaps.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// exportBlendShape
|
||||
//
|
||||
this.exportBlendShape.AutoSize = true;
|
||||
this.exportBlendShape.Checked = true;
|
||||
this.exportBlendShape.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.exportBlendShape.Location = new System.Drawing.Point(6, 138);
|
||||
this.exportBlendShape.Name = "exportBlendShape";
|
||||
this.exportBlendShape.Size = new System.Drawing.Size(114, 17);
|
||||
this.exportBlendShape.TabIndex = 22;
|
||||
this.exportBlendShape.Text = "Export blendshape";
|
||||
this.exportBlendShape.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// exportAnimations
|
||||
//
|
||||
this.exportAnimations.AutoSize = true;
|
||||
this.exportAnimations.Checked = true;
|
||||
this.exportAnimations.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.exportAnimations.Location = new System.Drawing.Point(6, 114);
|
||||
this.exportAnimations.Name = "exportAnimations";
|
||||
this.exportAnimations.Size = new System.Drawing.Size(109, 17);
|
||||
this.exportAnimations.TabIndex = 21;
|
||||
this.exportAnimations.Text = "Export animations";
|
||||
this.exportAnimations.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// scaleFactor
|
||||
//
|
||||
this.scaleFactor.DecimalPlaces = 2;
|
||||
this.scaleFactor.Increment = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
131072});
|
||||
this.scaleFactor.Location = new System.Drawing.Point(83, 243);
|
||||
this.scaleFactor.Name = "scaleFactor";
|
||||
this.scaleFactor.Size = new System.Drawing.Size(60, 20);
|
||||
this.scaleFactor.TabIndex = 20;
|
||||
this.scaleFactor.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
this.scaleFactor.Value = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.Location = new System.Drawing.Point(6, 245);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(64, 13);
|
||||
this.label5.TabIndex = 19;
|
||||
this.label5.Text = "ScaleFactor";
|
||||
//
|
||||
// fbxFormat
|
||||
//
|
||||
this.fbxFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.fbxFormat.FormattingEnabled = true;
|
||||
this.fbxFormat.Items.AddRange(new object[] {
|
||||
"Binary",
|
||||
"Ascii"});
|
||||
this.fbxFormat.Location = new System.Drawing.Point(77, 275);
|
||||
this.fbxFormat.Name = "fbxFormat";
|
||||
this.fbxFormat.Size = new System.Drawing.Size(61, 21);
|
||||
this.fbxFormat.TabIndex = 18;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(6, 280);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(59, 13);
|
||||
this.label4.TabIndex = 17;
|
||||
this.label4.Text = "FBXFormat";
|
||||
//
|
||||
// fbxVersion
|
||||
//
|
||||
this.fbxVersion.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.fbxVersion.FormattingEnabled = true;
|
||||
this.fbxVersion.Items.AddRange(new object[] {
|
||||
"6.1",
|
||||
"7.1",
|
||||
"7.2",
|
||||
"7.3",
|
||||
"7.4",
|
||||
"7.5"});
|
||||
this.fbxVersion.Location = new System.Drawing.Point(77, 308);
|
||||
this.fbxVersion.Name = "fbxVersion";
|
||||
this.fbxVersion.Size = new System.Drawing.Size(47, 21);
|
||||
this.fbxVersion.TabIndex = 16;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(6, 311);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(62, 13);
|
||||
this.label3.TabIndex = 15;
|
||||
this.label3.Text = "FBXVersion";
|
||||
//
|
||||
// boneSize
|
||||
//
|
||||
this.boneSize.Location = new System.Drawing.Point(65, 213);
|
||||
this.boneSize.Name = "boneSize";
|
||||
this.boneSize.Size = new System.Drawing.Size(46, 20);
|
||||
this.boneSize.TabIndex = 11;
|
||||
this.boneSize.Value = new decimal(new int[] {
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(6, 216);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(52, 13);
|
||||
this.label2.TabIndex = 10;
|
||||
this.label2.Text = "BoneSize";
|
||||
//
|
||||
// exportSkins
|
||||
//
|
||||
this.exportSkins.AutoSize = true;
|
||||
this.exportSkins.Checked = true;
|
||||
this.exportSkins.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.exportSkins.Location = new System.Drawing.Point(6, 90);
|
||||
this.exportSkins.Name = "exportSkins";
|
||||
this.exportSkins.Size = new System.Drawing.Size(83, 17);
|
||||
this.exportSkins.TabIndex = 8;
|
||||
this.exportSkins.Text = "Export skins";
|
||||
this.exportSkins.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(26, 42);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(72, 13);
|
||||
this.label1.TabIndex = 7;
|
||||
this.label1.Text = "FilterPrecision";
|
||||
//
|
||||
// filterPrecision
|
||||
//
|
||||
this.filterPrecision.DecimalPlaces = 2;
|
||||
this.filterPrecision.Increment = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
131072});
|
||||
this.filterPrecision.Location = new System.Drawing.Point(127, 40);
|
||||
this.filterPrecision.Name = "filterPrecision";
|
||||
this.filterPrecision.Size = new System.Drawing.Size(51, 20);
|
||||
this.filterPrecision.TabIndex = 6;
|
||||
this.filterPrecision.Value = new decimal(new int[] {
|
||||
25,
|
||||
0,
|
||||
0,
|
||||
131072});
|
||||
//
|
||||
// castToBone
|
||||
//
|
||||
this.castToBone.AutoSize = true;
|
||||
this.castToBone.Location = new System.Drawing.Point(6, 161);
|
||||
this.castToBone.Name = "castToBone";
|
||||
this.castToBone.Size = new System.Drawing.Size(131, 17);
|
||||
this.castToBone.TabIndex = 5;
|
||||
this.castToBone.Text = "All nodes cast to bone";
|
||||
this.castToBone.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// exportAllNodes
|
||||
//
|
||||
this.exportAllNodes.AutoSize = true;
|
||||
this.exportAllNodes.Checked = true;
|
||||
this.exportAllNodes.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.exportAllNodes.Location = new System.Drawing.Point(6, 66);
|
||||
this.exportAllNodes.Name = "exportAllNodes";
|
||||
this.exportAllNodes.Size = new System.Drawing.Size(101, 17);
|
||||
this.exportAllNodes.TabIndex = 4;
|
||||
this.exportAllNodes.Text = "Export all nodes";
|
||||
this.exportAllNodes.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// eulerFilter
|
||||
//
|
||||
this.eulerFilter.AutoSize = true;
|
||||
this.eulerFilter.Checked = true;
|
||||
this.eulerFilter.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.eulerFilter.Location = new System.Drawing.Point(6, 22);
|
||||
this.eulerFilter.Name = "eulerFilter";
|
||||
this.eulerFilter.Size = new System.Drawing.Size(72, 17);
|
||||
this.eulerFilter.TabIndex = 3;
|
||||
this.eulerFilter.Text = "EulerFilter";
|
||||
this.eulerFilter.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// groupBox3
|
||||
//
|
||||
this.groupBox3.AutoSize = true;
|
||||
this.groupBox3.Controls.Add(this.enableXor);
|
||||
this.groupBox3.Controls.Add(this.key);
|
||||
this.groupBox3.Controls.Add(this.label7);
|
||||
this.groupBox3.Location = new System.Drawing.Point(12, 296);
|
||||
this.groupBox3.Name = "groupBox3";
|
||||
this.groupBox3.Size = new System.Drawing.Size(232, 79);
|
||||
this.groupBox3.TabIndex = 11;
|
||||
this.groupBox3.TabStop = false;
|
||||
this.groupBox3.Text = "MiHoYoBinData";
|
||||
//
|
||||
// enableXor
|
||||
//
|
||||
this.enableXor.AutoSize = true;
|
||||
this.enableXor.Checked = true;
|
||||
this.enableXor.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.enableXor.Location = new System.Drawing.Point(9, 24);
|
||||
this.enableXor.Name = "enableXor";
|
||||
this.enableXor.Size = new System.Drawing.Size(85, 17);
|
||||
this.enableXor.TabIndex = 12;
|
||||
this.enableXor.Text = "Enable XOR";
|
||||
this.enableXor.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// key
|
||||
//
|
||||
this.key.Hexadecimal = true;
|
||||
this.key.Location = new System.Drawing.Point(124, 21);
|
||||
this.key.Maximum = new decimal(new int[] {
|
||||
255,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.key.Name = "key";
|
||||
this.key.Size = new System.Drawing.Size(61, 20);
|
||||
this.key.TabIndex = 8;
|
||||
//
|
||||
// label7
|
||||
//
|
||||
this.label7.AutoSize = true;
|
||||
this.label7.Location = new System.Drawing.Point(97, 25);
|
||||
this.label7.Name = "label7";
|
||||
this.label7.Size = new System.Drawing.Size(25, 13);
|
||||
this.label7.TabIndex = 7;
|
||||
this.label7.Text = "Key";
|
||||
//
|
||||
// ExportOptions
|
||||
//
|
||||
this.AcceptButton = this.OKbutton;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.Cancel;
|
||||
this.ClientSize = new System.Drawing.Size(486, 416);
|
||||
this.Controls.Add(this.groupBox3);
|
||||
this.Controls.Add(this.groupBox2);
|
||||
this.Controls.Add(this.groupBox1);
|
||||
this.Controls.Add(this.Cancel);
|
||||
this.Controls.Add(this.OKbutton);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "ExportOptions";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "Export options";
|
||||
this.TopMost = true;
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.groupBox1.PerformLayout();
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.panel1.PerformLayout();
|
||||
this.groupBox2.ResumeLayout(false);
|
||||
this.groupBox2.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.scaleFactor)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.boneSize)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.filterPrecision)).EndInit();
|
||||
this.groupBox3.ResumeLayout(false);
|
||||
this.groupBox3.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.key)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
private System.Windows.Forms.Button OKbutton;
|
||||
private System.Windows.Forms.Button Cancel;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.CheckBox converttexture;
|
||||
private System.Windows.Forms.RadioButton tojpg;
|
||||
private System.Windows.Forms.RadioButton topng;
|
||||
private System.Windows.Forms.RadioButton tobmp;
|
||||
private System.Windows.Forms.RadioButton totga;
|
||||
private System.Windows.Forms.CheckBox convertAudio;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.GroupBox groupBox2;
|
||||
private System.Windows.Forms.NumericUpDown boneSize;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.CheckBox exportSkins;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.NumericUpDown filterPrecision;
|
||||
private System.Windows.Forms.CheckBox castToBone;
|
||||
private System.Windows.Forms.CheckBox exportAllNodes;
|
||||
private System.Windows.Forms.CheckBox eulerFilter;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.ComboBox fbxVersion;
|
||||
private System.Windows.Forms.ComboBox fbxFormat;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.NumericUpDown scaleFactor;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.CheckBox exportBlendShape;
|
||||
private System.Windows.Forms.CheckBox exportAnimations;
|
||||
private System.Windows.Forms.ComboBox assetGroupOptions;
|
||||
private System.Windows.Forms.Label label6;
|
||||
private System.Windows.Forms.CheckBox restoreExtensionName;
|
||||
private System.Windows.Forms.CheckBox openAfterExport;
|
||||
private System.Windows.Forms.CheckBox exportAllUvsAsDiffuseMaps;
|
||||
private System.Windows.Forms.ToolTip exportUvsTooltip;
|
||||
private System.Windows.Forms.CheckBox exportIndexObject;
|
||||
private System.Windows.Forms.CheckBox exportAssetBundle;
|
||||
private System.Windows.Forms.GroupBox groupBox3;
|
||||
private System.Windows.Forms.NumericUpDown key;
|
||||
private System.Windows.Forms.Label label7;
|
||||
private System.Windows.Forms.CheckBox enableXor;
|
||||
private System.Windows.Forms.CheckBox disableRndrr;
|
||||
private System.Windows.Forms.CheckBox ignoreController;
|
||||
private System.Windows.Forms.CheckBox disableShader;
|
||||
}
|
||||
}
|
||||
98
AssetStudioGUI/ExportOptions.cs
Normal file
98
AssetStudioGUI/ExportOptions.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using AssetStudio;
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
public partial class ExportOptions : Form
|
||||
{
|
||||
public ExportOptions()
|
||||
{
|
||||
InitializeComponent();
|
||||
assetGroupOptions.SelectedIndex = Properties.Settings.Default.assetGroupOption;
|
||||
restoreExtensionName.Checked = Properties.Settings.Default.restoreExtensionName;
|
||||
converttexture.Checked = Properties.Settings.Default.convertTexture;
|
||||
convertAudio.Checked = Properties.Settings.Default.convertAudio;
|
||||
var str = Properties.Settings.Default.convertType.ToString();
|
||||
foreach (Control c in panel1.Controls)
|
||||
{
|
||||
if (c.Text == str)
|
||||
{
|
||||
((RadioButton)c).Checked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
openAfterExport.Checked = Properties.Settings.Default.openAfterExport;
|
||||
exportAssetBundle.Checked = Properties.Settings.Default.exportAssetBundle;
|
||||
exportIndexObject.Checked = Properties.Settings.Default.exportIndexObject;
|
||||
disableRndrr.Checked = Properties.Settings.Default.disableRndrr;
|
||||
disableShader.Checked = Properties.Settings.Default.disableShader;
|
||||
key.Value = Properties.Settings.Default.key;
|
||||
enableXor.Checked = Properties.Settings.Default.enableXor;
|
||||
ignoreController.Checked = Properties.Settings.Default.ignoreController;
|
||||
eulerFilter.Checked = Properties.Settings.Default.eulerFilter;
|
||||
filterPrecision.Value = Properties.Settings.Default.filterPrecision;
|
||||
exportAllNodes.Checked = Properties.Settings.Default.exportAllNodes;
|
||||
exportSkins.Checked = Properties.Settings.Default.exportSkins;
|
||||
exportAnimations.Checked = Properties.Settings.Default.exportAnimations;
|
||||
exportBlendShape.Checked = Properties.Settings.Default.exportBlendShape;
|
||||
castToBone.Checked = Properties.Settings.Default.castToBone;
|
||||
exportAllUvsAsDiffuseMaps.Checked = Properties.Settings.Default.exportAllUvsAsDiffuseMaps;
|
||||
boneSize.Value = Properties.Settings.Default.boneSize;
|
||||
scaleFactor.Value = Properties.Settings.Default.scaleFactor;
|
||||
fbxVersion.SelectedIndex = Properties.Settings.Default.fbxVersion;
|
||||
fbxFormat.SelectedIndex = Properties.Settings.Default.fbxFormat;
|
||||
}
|
||||
|
||||
private void OKbutton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Properties.Settings.Default.assetGroupOption = assetGroupOptions.SelectedIndex;
|
||||
Properties.Settings.Default.restoreExtensionName = restoreExtensionName.Checked;
|
||||
Properties.Settings.Default.convertTexture = converttexture.Checked;
|
||||
Properties.Settings.Default.convertAudio = convertAudio.Checked;
|
||||
foreach (Control c in panel1.Controls)
|
||||
{
|
||||
if (((RadioButton)c).Checked)
|
||||
{
|
||||
Properties.Settings.Default.convertType = (ImageFormat)Enum.Parse(typeof(ImageFormat), c.Text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Properties.Settings.Default.openAfterExport = openAfterExport.Checked;
|
||||
Properties.Settings.Default.exportAssetBundle = exportAssetBundle.Checked;
|
||||
AssetBundle.Exportable = Properties.Settings.Default.exportAssetBundle;
|
||||
Properties.Settings.Default.exportIndexObject = exportIndexObject.Checked;
|
||||
IndexObject.Exportable = Properties.Settings.Default.exportAssetBundle;
|
||||
Properties.Settings.Default.disableRndrr = disableRndrr.Checked;
|
||||
Renderer.Parsable = !Properties.Settings.Default.disableRndrr;
|
||||
Properties.Settings.Default.disableShader = disableShader.Checked;
|
||||
Shader.Parsable = !Properties.Settings.Default.disableShader;
|
||||
Properties.Settings.Default.key = (byte)key.Value;
|
||||
Properties.Settings.Default.enableXor = enableXor.Checked;
|
||||
MiHoYoBinData.Key = (byte)key.Value;
|
||||
MiHoYoBinData.doXOR = enableXor.Checked;
|
||||
Properties.Settings.Default.ignoreController = ignoreController.Checked;
|
||||
Properties.Settings.Default.eulerFilter = eulerFilter.Checked;
|
||||
Properties.Settings.Default.filterPrecision = filterPrecision.Value;
|
||||
Properties.Settings.Default.exportAllNodes = exportAllNodes.Checked;
|
||||
Properties.Settings.Default.exportSkins = exportSkins.Checked;
|
||||
Properties.Settings.Default.exportAnimations = exportAnimations.Checked;
|
||||
Properties.Settings.Default.exportBlendShape = exportBlendShape.Checked;
|
||||
Properties.Settings.Default.castToBone = castToBone.Checked;
|
||||
Properties.Settings.Default.exportAllUvsAsDiffuseMaps = exportAllUvsAsDiffuseMaps.Checked;
|
||||
Properties.Settings.Default.boneSize = boneSize.Value;
|
||||
Properties.Settings.Default.scaleFactor = scaleFactor.Value;
|
||||
Properties.Settings.Default.fbxVersion = fbxVersion.SelectedIndex;
|
||||
Properties.Settings.Default.fbxFormat = fbxFormat.SelectedIndex;
|
||||
Properties.Settings.Default.Save();
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Cancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
123
AssetStudioGUI/ExportOptions.resx
Normal file
123
AssetStudioGUI/ExportOptions.resx
Normal file
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<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="exportUvsTooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
466
AssetStudioGUI/Exporter.cs
Normal file
466
AssetStudioGUI/Exporter.cs
Normal file
@@ -0,0 +1,466 @@
|
||||
using AssetStudio;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
internal static class Exporter
|
||||
{
|
||||
public static bool ExportTexture2D(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_Texture2D = (Texture2D)item.Asset;
|
||||
if (Properties.Settings.Default.convertTexture)
|
||||
{
|
||||
var type = Properties.Settings.Default.convertType;
|
||||
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
|
||||
return false;
|
||||
var image = m_Texture2D.ConvertToImage(true);
|
||||
if (image == null)
|
||||
return false;
|
||||
using (image)
|
||||
{
|
||||
using (var file = File.OpenWrite(exportFullPath))
|
||||
{
|
||||
image.WriteToStream(file, type);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, ".tex", out var exportFullPath))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullPath, m_Texture2D.image_data.GetData());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ExportAudioClip(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_AudioClip = (AudioClip)item.Asset;
|
||||
var m_AudioData = m_AudioClip.m_AudioData.GetData();
|
||||
if (m_AudioData == null || m_AudioData.Length == 0)
|
||||
return false;
|
||||
var converter = new AudioClipConverter(m_AudioClip);
|
||||
if (Properties.Settings.Default.convertAudio && converter.IsSupport)
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, ".wav", out var exportFullPath))
|
||||
return false;
|
||||
var buffer = converter.ConvertToWav();
|
||||
if (buffer == null)
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullPath, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, converter.GetExtensionName(), out var exportFullPath))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullPath, m_AudioData);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportShader(AssetItem item, string exportPath)
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, ".shader", out var exportFullPath))
|
||||
return false;
|
||||
var m_Shader = (Shader)item.Asset;
|
||||
var str = m_Shader.Convert(Studio.Game);
|
||||
File.WriteAllText(exportFullPath, str);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportTextAsset(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_TextAsset = (TextAsset)(item.Asset);
|
||||
var extension = ".txt";
|
||||
if (Properties.Settings.Default.restoreExtensionName)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(item.Container))
|
||||
{
|
||||
extension = Path.GetExtension(item.Container);
|
||||
}
|
||||
}
|
||||
if (!TryExportFile(exportPath, item, extension, out var exportFullPath))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullPath, m_TextAsset.m_Script);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportMonoBehaviour(AssetItem item, string exportPath)
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, ".json", out var exportFullPath))
|
||||
return false;
|
||||
var m_MonoBehaviour = (MonoBehaviour)item.Asset;
|
||||
var type = m_MonoBehaviour.ToType();
|
||||
if (type == null)
|
||||
{
|
||||
var m_Type = Studio.MonoBehaviourToTypeTree(m_MonoBehaviour);
|
||||
type = m_MonoBehaviour.ToType(m_Type);
|
||||
}
|
||||
var str = JsonConvert.SerializeObject(type, Formatting.Indented);
|
||||
File.WriteAllText(exportFullPath, str);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportAssetBundle(AssetItem item, string exportPath)
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, ".json", out var exportFullPath))
|
||||
return false;
|
||||
var m_AssetBundle = (AssetBundle)item.Asset;
|
||||
var str = JsonConvert.SerializeObject(m_AssetBundle, Formatting.Indented);
|
||||
File.WriteAllText(exportFullPath, str);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportIndexObject(AssetItem item, string exportPath)
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, ".json", out var exportFullPath))
|
||||
return false;
|
||||
var m_IndexObject = (IndexObject)item.Asset;
|
||||
var str = JsonConvert.SerializeObject(m_IndexObject, Formatting.Indented);
|
||||
File.WriteAllText(exportFullPath, str);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportMiHoYoBinData(AssetItem item, string exportPath)
|
||||
{
|
||||
string exportFullPath;
|
||||
if (item.Asset is MiHoYoBinData m_MiHoYoBinData)
|
||||
{
|
||||
switch (m_MiHoYoBinData.Type)
|
||||
{
|
||||
case MiHoYoBinDataType.JSON:
|
||||
if (!TryExportFile(exportPath, item, ".json", out exportFullPath))
|
||||
return false;
|
||||
var json = m_MiHoYoBinData.Dump() as string;
|
||||
if (json.Length != 0)
|
||||
{
|
||||
File.WriteAllText(exportFullPath, json);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case MiHoYoBinDataType.Bytes:
|
||||
if (!TryExportFile(exportPath, item, ".bin", out exportFullPath))
|
||||
return false;
|
||||
var bytes = m_MiHoYoBinData.Dump() as byte[];
|
||||
if (bytes.Length != 0)
|
||||
{
|
||||
File.WriteAllBytes(exportFullPath, bytes);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ExportFont(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_Font = (Font)item.Asset;
|
||||
if (m_Font.m_FontData != null)
|
||||
{
|
||||
var extension = ".ttf";
|
||||
if (m_Font.m_FontData[0] == 79 && m_Font.m_FontData[1] == 84 && m_Font.m_FontData[2] == 84 && m_Font.m_FontData[3] == 79)
|
||||
{
|
||||
extension = ".otf";
|
||||
}
|
||||
if (!TryExportFile(exportPath, item, extension, out var exportFullPath))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullPath, m_Font.m_FontData);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ExportMesh(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_Mesh = (Mesh)item.Asset;
|
||||
if (m_Mesh.m_VertexCount <= 0)
|
||||
return false;
|
||||
if (!TryExportFile(exportPath, item, ".obj", out var exportFullPath))
|
||||
return false;
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("g " + m_Mesh.m_Name);
|
||||
#region Vertices
|
||||
if (m_Mesh.m_Vertices == null || m_Mesh.m_Vertices.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int c = 3;
|
||||
if (m_Mesh.m_Vertices.Length == m_Mesh.m_VertexCount * 4)
|
||||
{
|
||||
c = 4;
|
||||
}
|
||||
for (int v = 0; v < m_Mesh.m_VertexCount; v++)
|
||||
{
|
||||
sb.AppendFormat("v {0} {1} {2}\r\n", -m_Mesh.m_Vertices[v * c], m_Mesh.m_Vertices[v * c + 1], m_Mesh.m_Vertices[v * c + 2]);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UV
|
||||
if (m_Mesh.m_UV0?.Length > 0)
|
||||
{
|
||||
c = 4;
|
||||
if (m_Mesh.m_UV0.Length == m_Mesh.m_VertexCount * 2)
|
||||
{
|
||||
c = 2;
|
||||
}
|
||||
else if (m_Mesh.m_UV0.Length == m_Mesh.m_VertexCount * 3)
|
||||
{
|
||||
c = 3;
|
||||
}
|
||||
for (int v = 0; v < m_Mesh.m_VertexCount; v++)
|
||||
{
|
||||
sb.AppendFormat("vt {0} {1}\r\n", m_Mesh.m_UV0[v * c], m_Mesh.m_UV0[v * c + 1]);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Normals
|
||||
if (m_Mesh.m_Normals?.Length > 0)
|
||||
{
|
||||
if (m_Mesh.m_Normals.Length == m_Mesh.m_VertexCount * 3)
|
||||
{
|
||||
c = 3;
|
||||
}
|
||||
else if (m_Mesh.m_Normals.Length == m_Mesh.m_VertexCount * 4)
|
||||
{
|
||||
c = 4;
|
||||
}
|
||||
for (int v = 0; v < m_Mesh.m_VertexCount; v++)
|
||||
{
|
||||
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
|
||||
|
||||
#region Face
|
||||
int sum = 0;
|
||||
for (var i = 0; i < m_Mesh.m_SubMeshes.Length; i++)
|
||||
{
|
||||
sb.AppendLine($"g {m_Mesh.m_Name}_{i}");
|
||||
int indexCount = (int)m_Mesh.m_SubMeshes[i].indexCount;
|
||||
var end = sum + indexCount / 3;
|
||||
for (int f = sum; f < end; f++)
|
||||
{
|
||||
sb.AppendFormat("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}\r\n", m_Mesh.m_Indices[f * 3 + 2] + 1, m_Mesh.m_Indices[f * 3 + 1] + 1, m_Mesh.m_Indices[f * 3] + 1);
|
||||
}
|
||||
sum = end;
|
||||
}
|
||||
#endregion
|
||||
|
||||
sb.Replace("NaN", "0");
|
||||
File.WriteAllText(exportFullPath, sb.ToString());
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportVideoClip(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_VideoClip = (VideoClip)item.Asset;
|
||||
if (m_VideoClip.m_ExternalResources.m_Size > 0)
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, Path.GetExtension(m_VideoClip.m_OriginalPath), out var exportFullPath))
|
||||
return false;
|
||||
m_VideoClip.m_VideoData.WriteData(exportFullPath);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ExportMovieTexture(AssetItem item, string exportPath)
|
||||
{
|
||||
var m_MovieTexture = (MovieTexture)item.Asset;
|
||||
if (!TryExportFile(exportPath, item, ".ogv", out var exportFullPath))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullPath, m_MovieTexture.m_MovieData);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportSprite(AssetItem item, string exportPath)
|
||||
{
|
||||
var type = Properties.Settings.Default.convertType;
|
||||
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
|
||||
return false;
|
||||
var image = ((Sprite)item.Asset).GetImage();
|
||||
if (image != null)
|
||||
{
|
||||
using (image)
|
||||
{
|
||||
using (var file = File.OpenWrite(exportFullPath))
|
||||
{
|
||||
image.WriteToStream(file, type);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ExportMaterial(AssetItem item, string exportPath)
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, ".json", out var exportFullPath))
|
||||
return false;
|
||||
var m_Material = (Material)item.Asset;
|
||||
var str = JsonConvert.SerializeObject(m_Material, Formatting.Indented);
|
||||
File.WriteAllText(exportFullPath, str);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportRawFile(AssetItem item, string exportPath)
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, ".dat", out var exportFullPath))
|
||||
return false;
|
||||
File.WriteAllBytes(exportFullPath, item.Asset.GetRawData());
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool TryExportFile(string dir, AssetItem item, string extension, out string fullPath)
|
||||
{
|
||||
var fileName = FixFileName(item.Text);
|
||||
fullPath = Path.Combine(dir, fileName + extension);
|
||||
if (!File.Exists(fullPath))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
return true;
|
||||
}
|
||||
fullPath = Path.Combine(dir, fileName + item.UniqueID + extension);
|
||||
if (!File.Exists(fullPath))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ExportAnimationClip(AssetItem item, string exportPath)
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, ".anim", out var exportFullPath))
|
||||
return false;
|
||||
var m_AnimationClip = (AnimationClip)item.Asset;
|
||||
var str = m_AnimationClip.Convert(Studio.Game);
|
||||
File.WriteAllText(exportFullPath, str);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ExportAnimator(AssetItem item, string exportPath, List<AssetItem> animationList = null)
|
||||
{
|
||||
var exportFullPath = Path.Combine(exportPath, item.Text, item.Text + ".fbx");
|
||||
if (File.Exists(exportFullPath))
|
||||
{
|
||||
exportFullPath = Path.Combine(exportPath, item.Text + item.UniqueID, item.Text + ".fbx");
|
||||
}
|
||||
var m_Animator = (Animator)item.Asset;
|
||||
var convert = animationList != null
|
||||
? new ModelConverter(m_Animator, Properties.Settings.Default.convertType, Studio.Game, animationList.Select(x => (AnimationClip)x.Asset).ToArray(), Properties.Settings.Default.ignoreController)
|
||||
: new ModelConverter(m_Animator, Properties.Settings.Default.convertType, Studio.Game, ignoreController: Properties.Settings.Default.ignoreController);
|
||||
ExportFbx(convert, exportFullPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void ExportGameObject(GameObject gameObject, string exportPath, List<AssetItem> animationList = null)
|
||||
{
|
||||
var convert = animationList != null
|
||||
? new ModelConverter(gameObject, Properties.Settings.Default.convertType, Studio.Game, animationList.Select(x => (AnimationClip)x.Asset).ToArray(), Properties.Settings.Default.ignoreController)
|
||||
: new ModelConverter(gameObject, Properties.Settings.Default.convertType, Studio.Game, ignoreController: Properties.Settings.Default.ignoreController);
|
||||
exportPath = exportPath + FixFileName(gameObject.m_Name) + ".fbx";
|
||||
ExportFbx(convert, exportPath);
|
||||
}
|
||||
|
||||
public static void ExportGameObjectMerge(List<GameObject> gameObject, string exportPath, List<AssetItem> animationList = null)
|
||||
{
|
||||
var rootName = Path.GetFileNameWithoutExtension(exportPath);
|
||||
var convert = animationList != null
|
||||
? new ModelConverter(rootName, gameObject, Properties.Settings.Default.convertType, Studio.Game, animationList.Select(x => (AnimationClip)x.Asset).ToArray(), Properties.Settings.Default.ignoreController)
|
||||
: new ModelConverter(rootName, gameObject, Properties.Settings.Default.convertType, Studio.Game, ignoreController: Properties.Settings.Default.ignoreController);
|
||||
ExportFbx(convert, exportPath);
|
||||
}
|
||||
|
||||
private static void ExportFbx(IImported convert, string exportPath)
|
||||
{
|
||||
var eulerFilter = Properties.Settings.Default.eulerFilter;
|
||||
var filterPrecision = (float)Properties.Settings.Default.filterPrecision;
|
||||
var exportAllNodes = Properties.Settings.Default.exportAllNodes;
|
||||
var exportSkins = Properties.Settings.Default.exportSkins;
|
||||
var exportAnimations = Properties.Settings.Default.exportAnimations;
|
||||
var exportBlendShape = Properties.Settings.Default.exportBlendShape;
|
||||
var castToBone = Properties.Settings.Default.castToBone;
|
||||
var boneSize = (int)Properties.Settings.Default.boneSize;
|
||||
var exportAllUvsAsDiffuseMaps = Properties.Settings.Default.exportAllUvsAsDiffuseMaps;
|
||||
var scaleFactor = (float)Properties.Settings.Default.scaleFactor;
|
||||
var fbxVersion = Properties.Settings.Default.fbxVersion;
|
||||
var fbxFormat = Properties.Settings.Default.fbxFormat;
|
||||
ModelExporter.ExportFbx(exportPath, convert, eulerFilter, filterPrecision,
|
||||
exportAllNodes, exportSkins, exportAnimations, exportBlendShape, castToBone, boneSize, exportAllUvsAsDiffuseMaps, scaleFactor, fbxVersion, fbxFormat == 1);
|
||||
}
|
||||
|
||||
public static bool ExportDumpFile(AssetItem item, string exportPath)
|
||||
{
|
||||
if (!TryExportFile(exportPath, item, ".txt", out var exportFullPath))
|
||||
return false;
|
||||
var str = item.Asset.Dump();
|
||||
if (str == null && item.Asset is MonoBehaviour m_MonoBehaviour)
|
||||
{
|
||||
var m_Type = Studio.MonoBehaviourToTypeTree(m_MonoBehaviour);
|
||||
str = m_MonoBehaviour.Dump(m_Type);
|
||||
}
|
||||
if (str != null)
|
||||
{
|
||||
File.WriteAllText(exportFullPath, str);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ExportConvertFile(AssetItem item, string exportPath)
|
||||
{
|
||||
switch (item.Type)
|
||||
{
|
||||
case ClassIDType.Texture2D:
|
||||
return ExportTexture2D(item, exportPath);
|
||||
case ClassIDType.AudioClip:
|
||||
return ExportAudioClip(item, exportPath);
|
||||
case ClassIDType.Shader:
|
||||
return ExportShader(item, exportPath);
|
||||
case ClassIDType.TextAsset:
|
||||
return ExportTextAsset(item, exportPath);
|
||||
case ClassIDType.MonoBehaviour:
|
||||
return ExportMonoBehaviour(item, exportPath);
|
||||
case ClassIDType.Font:
|
||||
return ExportFont(item, exportPath);
|
||||
case ClassIDType.Mesh:
|
||||
return ExportMesh(item, exportPath);
|
||||
case ClassIDType.VideoClip:
|
||||
return ExportVideoClip(item, exportPath);
|
||||
case ClassIDType.MovieTexture:
|
||||
return ExportMovieTexture(item, exportPath);
|
||||
case ClassIDType.Sprite:
|
||||
return ExportSprite(item, exportPath);
|
||||
case ClassIDType.Material:
|
||||
return ExportMaterial(item, exportPath);
|
||||
case ClassIDType.Animator:
|
||||
return ExportAnimator(item, exportPath);
|
||||
case ClassIDType.AnimationClip:
|
||||
return ExportAnimationClip(item, exportPath);
|
||||
case ClassIDType.AssetBundle:
|
||||
return ExportAssetBundle(item, exportPath);
|
||||
case ClassIDType.IndexObject:
|
||||
return ExportIndexObject(item, exportPath);
|
||||
case ClassIDType.MiHoYoBinData:
|
||||
return ExportMiHoYoBinData(item, exportPath);
|
||||
default:
|
||||
return ExportRawFile(item, exportPath);
|
||||
}
|
||||
}
|
||||
|
||||
public static string FixFileName(string str)
|
||||
{
|
||||
if (str.Length >= 260) return Path.GetRandomFileName();
|
||||
return Path.GetInvalidFileNameChars().Aggregate(str, (current, c) => current.Replace(c, '_'));
|
||||
}
|
||||
}
|
||||
}
|
||||
34
AssetStudioGUI/GUILogger.cs
Normal file
34
AssetStudioGUI/GUILogger.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using AssetStudio;
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
class GUILogger : ILogger
|
||||
{
|
||||
public bool ShowErrorMessage = true;
|
||||
private Action<string> action;
|
||||
|
||||
public GUILogger(Action<string> action)
|
||||
{
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public void Log(LoggerEvent loggerEvent, string message)
|
||||
{
|
||||
switch (loggerEvent)
|
||||
{
|
||||
case LoggerEvent.Error:
|
||||
if (ShowErrorMessage)
|
||||
{
|
||||
MessageBox.Show(message);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
action(message);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
AssetStudioGUI/Libraries/OpenTK.WinForms.dll
Normal file
BIN
AssetStudioGUI/Libraries/OpenTK.WinForms.dll
Normal file
Binary file not shown.
25
AssetStudioGUI/Program.cs
Normal file
25
AssetStudioGUI/Program.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
#if !NETFRAMEWORK
|
||||
Application.SetHighDpiMode(HighDpiMode.SystemAware);
|
||||
#endif
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new AssetStudioGUIForm());
|
||||
}
|
||||
}
|
||||
}
|
||||
166
AssetStudioGUI/Properties/Resources.Designer.cs
generated
Normal file
166
AssetStudioGUI/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,166 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace AssetStudioGUI.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AssetStudioGUI.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||
/// </summary>
|
||||
internal static System.Drawing.Icon _as {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("_as", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to #version 140
|
||||
///
|
||||
///in vec3 normal;
|
||||
///
|
||||
///out vec4 outputColor;
|
||||
///
|
||||
///void main()
|
||||
///{
|
||||
/// vec3 unitNormal = normalize(normal);
|
||||
/// float nDotProduct = clamp(dot(unitNormal, vec3(0.707, 0, 0.707)), 0, 1);
|
||||
/// vec2 ContributionWeightsSqrt = vec2(0.5, 0.5f) + vec2(0.5f, -0.5f) * unitNormal.y;
|
||||
/// vec2 ContributionWeights = ContributionWeightsSqrt * ContributionWeightsSqrt;
|
||||
///
|
||||
/// vec3 color = nDotProduct * vec3(1, 0.957, 0.839) / 3.14159;
|
||||
/// color += vec3(0.779, 0.716, 0.453) * ContributionWeights.y;
|
||||
/// color += vec3(0.368, 0.477, 0. [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string fs {
|
||||
get {
|
||||
return ResourceManager.GetString("fs", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to #version 140
|
||||
///
|
||||
///out vec4 outputColor;
|
||||
///
|
||||
///void main()
|
||||
///{
|
||||
/// outputColor = vec4(0, 0, 0, 1);
|
||||
///}.
|
||||
/// </summary>
|
||||
internal static string fsBlack {
|
||||
get {
|
||||
return ResourceManager.GetString("fsBlack", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to #version 140
|
||||
///
|
||||
///out vec4 outputColor;
|
||||
///in vec4 color;
|
||||
///
|
||||
///void main()
|
||||
///{
|
||||
/// outputColor = color;
|
||||
///}.
|
||||
/// </summary>
|
||||
internal static string fsColor {
|
||||
get {
|
||||
return ResourceManager.GetString("fsColor", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap preview {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("preview", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to #version 140
|
||||
///
|
||||
///in vec3 vertexPosition;
|
||||
///in vec3 normalDirection;
|
||||
///in vec4 vertexColor;
|
||||
///uniform mat4 modelMatrix;
|
||||
///uniform mat4 viewMatrix;
|
||||
///uniform mat4 projMatrix;
|
||||
///
|
||||
///out vec3 normal;
|
||||
///out vec4 color;
|
||||
///
|
||||
///void main()
|
||||
///{
|
||||
/// gl_Position = projMatrix * viewMatrix * modelMatrix * vec4(vertexPosition, 1.0);
|
||||
/// normal = normalDirection;
|
||||
/// color = vertexColor;
|
||||
///}.
|
||||
/// </summary>
|
||||
internal static string vs {
|
||||
get {
|
||||
return ResourceManager.GetString("vs", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
188
AssetStudioGUI/Properties/Resources.resx
Normal file
188
AssetStudioGUI/Properties/Resources.resx
Normal file
@@ -0,0 +1,188 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<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>
|
||||
<data name="fs" xml:space="preserve">
|
||||
<value>#version 140
|
||||
|
||||
in vec3 normal;
|
||||
|
||||
out vec4 outputColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 unitNormal = normalize(normal);
|
||||
float nDotProduct = clamp(dot(unitNormal, vec3(0.707, 0, 0.707)), 0, 1);
|
||||
vec2 ContributionWeightsSqrt = vec2(0.5, 0.5f) + vec2(0.5f, -0.5f) * unitNormal.y;
|
||||
vec2 ContributionWeights = ContributionWeightsSqrt * ContributionWeightsSqrt;
|
||||
|
||||
vec3 color = nDotProduct * vec3(1, 0.957, 0.839) / 3.14159;
|
||||
color += vec3(0.779, 0.716, 0.453) * ContributionWeights.y;
|
||||
color += vec3(0.368, 0.477, 0.735) * ContributionWeights.x;
|
||||
outputColor = vec4(sqrt(color), 1);
|
||||
}</value>
|
||||
</data>
|
||||
<data name="fsBlack" xml:space="preserve">
|
||||
<value>#version 140
|
||||
|
||||
out vec4 outputColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
outputColor = vec4(0, 0, 0, 1);
|
||||
}</value>
|
||||
</data>
|
||||
<data name="fsColor" xml:space="preserve">
|
||||
<value>#version 140
|
||||
|
||||
out vec4 outputColor;
|
||||
in vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
outputColor = color;
|
||||
}</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="preview" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\preview.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="vs" xml:space="preserve">
|
||||
<value>#version 140
|
||||
|
||||
in vec3 vertexPosition;
|
||||
in vec3 normalDirection;
|
||||
in vec4 vertexColor;
|
||||
uniform mat4 modelMatrix;
|
||||
uniform mat4 viewMatrix;
|
||||
uniform mat4 projMatrix;
|
||||
|
||||
out vec3 normal;
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projMatrix * viewMatrix * modelMatrix * vec4(vertexPosition, 1.0);
|
||||
normal = normalDirection;
|
||||
color = vertexColor;
|
||||
}</value>
|
||||
</data>
|
||||
<data name="_as" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\as.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
495
AssetStudioGUI/Properties/Settings.Designer.cs
generated
Normal file
495
AssetStudioGUI/Properties/Settings.Designer.cs
generated
Normal file
@@ -0,0 +1,495 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace AssetStudioGUI.Properties
|
||||
{
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool console
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["console"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["console"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool displayAll
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["displayAll"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["displayAll"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool enablePreview
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["enablePreview"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["enablePreview"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool enableResolveDependencies
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["enableResolveDependencies"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["enableResolveDependencies"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool displayInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["displayInfo"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["displayInfo"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool openAfterExport
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["openAfterExport"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["openAfterExport"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
public int selectedGame
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((int)(this["selectedGame"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["selectedGame"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
public int assetGroupOption
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((int)(this["assetGroupOption"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["assetGroupOption"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool convertTexture
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["convertTexture"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["convertTexture"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool convertAudio
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["convertAudio"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["convertAudio"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("Png")]
|
||||
public global::AssetStudio.ImageFormat convertType
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((global::AssetStudio.ImageFormat)(this["convertType"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["convertType"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool exportAssetBundle
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["exportAssetBundle"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["exportAssetBundle"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool exportIndexObject
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["exportIndexObject"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["exportIndexObject"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool disableRndrr
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["disableRndrr"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["disableRndrr"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool disableShader
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["disableShader"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["disableShader"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("147")]
|
||||
public byte key
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((byte)(this["key"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["key"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool enableXor
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["enableXor"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["enableXor"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool ignoreController
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["ignoreController"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["ignoreController"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool eulerFilter
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["eulerFilter"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["eulerFilter"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0.25")]
|
||||
public decimal filterPrecision
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((decimal)(this["filterPrecision"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["filterPrecision"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool exportAllNodes
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["exportAllNodes"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["exportAllNodes"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool exportSkins
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["exportSkins"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["exportSkins"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool exportAnimations
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["exportAnimations"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["exportAnimations"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("10")]
|
||||
public decimal boneSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((decimal)(this["boneSize"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["boneSize"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("3")]
|
||||
public int fbxVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((int)(this["fbxVersion"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["fbxVersion"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
public int fbxFormat
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((int)(this["fbxFormat"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["fbxFormat"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("1")]
|
||||
public decimal scaleFactor
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((decimal)(this["scaleFactor"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["scaleFactor"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool exportBlendShape
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["exportBlendShape"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["exportBlendShape"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool castToBone
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["castToBone"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["castToBone"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool restoreExtensionName
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["restoreExtensionName"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["restoreExtensionName"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool exportAllUvsAsDiffuseMaps
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((bool)(this["exportAllUvsAsDiffuseMaps"]));
|
||||
}
|
||||
set
|
||||
{
|
||||
this["exportAllUvsAsDiffuseMaps"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
99
AssetStudioGUI/Properties/Settings.settings
Normal file
99
AssetStudioGUI/Properties/Settings.settings
Normal file
@@ -0,0 +1,99 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="AssetStudioGUI.Properties" GeneratedClassName="Settings">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="displayAll" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="enablePreview" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="displayInfo" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="openAfterExport" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="assetGroupOption" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">0</Value>
|
||||
</Setting>
|
||||
<Setting Name="convertTexture" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="convertAudio" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="convertType" Type="AssetStudio.ImageFormat" Scope="User">
|
||||
<Value Profile="(Default)">Png</Value>
|
||||
</Setting>
|
||||
<Setting Name="eulerFilter" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="filterPrecision" Type="System.Decimal" Scope="User">
|
||||
<Value Profile="(Default)">0.25</Value>
|
||||
</Setting>
|
||||
<Setting Name="exportAllNodes" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="exportSkins" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="exportAnimations" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="boneSize" Type="System.Decimal" Scope="User">
|
||||
<Value Profile="(Default)">10</Value>
|
||||
</Setting>
|
||||
<Setting Name="fbxVersion" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">3</Value>
|
||||
</Setting>
|
||||
<Setting Name="fbxFormat" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">0</Value>
|
||||
</Setting>
|
||||
<Setting Name="scaleFactor" Type="System.Decimal" Scope="User">
|
||||
<Value Profile="(Default)">1</Value>
|
||||
</Setting>
|
||||
<Setting Name="exportBlendShape" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="castToBone" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="restoreExtensionName" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="exportAllUvsAsDiffuseMaps" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="key" Type="System.Byte" Scope="User">
|
||||
<Value Profile="(Default)">147</Value>
|
||||
</Setting>
|
||||
<Setting Name="console" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="eanbleXor" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="disableRndrr" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="exportAssetBundle" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="exportIndexObject" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="selectedGame" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">0</Value>
|
||||
</Setting>
|
||||
<Setting Name="ignoreController" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="disableShader" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="enableResolveDependencies" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
BIN
AssetStudioGUI/Resources/as.ico
Normal file
BIN
AssetStudioGUI/Resources/as.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
BIN
AssetStudioGUI/Resources/preview.png
Normal file
BIN
AssetStudioGUI/Resources/preview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
985
AssetStudioGUI/Studio.cs
Normal file
985
AssetStudioGUI/Studio.cs
Normal file
@@ -0,0 +1,985 @@
|
||||
using AssetStudio;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using System.Xml.Linq;
|
||||
using static AssetStudioGUI.Exporter;
|
||||
using Object = AssetStudio.Object;
|
||||
|
||||
namespace AssetStudioGUI
|
||||
{
|
||||
internal enum ExportType
|
||||
{
|
||||
Convert,
|
||||
Raw,
|
||||
Dump
|
||||
}
|
||||
|
||||
internal enum ExportFilter
|
||||
{
|
||||
All,
|
||||
Selected,
|
||||
Filtered
|
||||
}
|
||||
|
||||
internal enum AssetGroupOption
|
||||
{
|
||||
ByType,
|
||||
ByContainer,
|
||||
BySource,
|
||||
None
|
||||
}
|
||||
|
||||
internal enum ExportListType
|
||||
{
|
||||
XML
|
||||
}
|
||||
|
||||
internal static class Studio
|
||||
{
|
||||
public static AssetsManager assetsManager = new AssetsManager();
|
||||
public static AssemblyLoader assemblyLoader = new AssemblyLoader();
|
||||
public static List<AssetItem> exportableAssets = new List<AssetItem>();
|
||||
public static List<AssetItem> visibleAssets = new List<AssetItem>();
|
||||
internal static Action<string> StatusStripUpdate = x => { };
|
||||
public static Game Game;
|
||||
|
||||
public static int ExtractFolder(string path, string savePath)
|
||||
{
|
||||
int extractedCount = 0;
|
||||
Progress.Reset();
|
||||
var files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
{
|
||||
var file = files[i];
|
||||
var fileOriPath = Path.GetDirectoryName(file);
|
||||
var fileSavePath = fileOriPath.Replace(path, savePath);
|
||||
extractedCount += ExtractFile(file, fileSavePath);
|
||||
Progress.Report(i + 1, files.Length);
|
||||
}
|
||||
return extractedCount;
|
||||
}
|
||||
|
||||
public static int ExtractFile(string[] fileNames, string savePath)
|
||||
{
|
||||
int extractedCount = 0;
|
||||
Progress.Reset();
|
||||
for (var i = 0; i < fileNames.Length; i++)
|
||||
{
|
||||
var fileName = fileNames[i];
|
||||
extractedCount += ExtractFile(fileName, savePath);
|
||||
Progress.Report(i + 1, fileNames.Length);
|
||||
}
|
||||
return extractedCount;
|
||||
}
|
||||
|
||||
public static int ExtractFile(string fileName, string savePath)
|
||||
{
|
||||
int extractedCount = 0;
|
||||
var reader = new FileReader(fileName, Game);
|
||||
if (reader.FileType == FileType.BundleFile)
|
||||
extractedCount += ExtractBundleFile(reader, savePath);
|
||||
else if (reader.FileType == FileType.WebFile)
|
||||
extractedCount += ExtractWebDataFile(reader, savePath);
|
||||
else if (reader.FileType == FileType.GameFile)
|
||||
extractedCount += ExtractGameFile(reader, savePath);
|
||||
else
|
||||
reader.Dispose();
|
||||
return extractedCount;
|
||||
}
|
||||
|
||||
private static int ExtractBundleFile(FileReader reader, string savePath)
|
||||
{
|
||||
StatusStripUpdate($"Decompressing {reader.FileName} ...");
|
||||
var bundleFile = new BundleFile(reader);
|
||||
reader.Dispose();
|
||||
if (bundleFile.FileList.Length > 0)
|
||||
{
|
||||
var extractPath = Path.Combine(savePath, reader.FileName + "_unpacked");
|
||||
return ExtractStreamFile(extractPath, bundleFile.FileList);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int ExtractWebDataFile(FileReader reader, string savePath)
|
||||
{
|
||||
StatusStripUpdate($"Decompressing {reader.FileName} ...");
|
||||
var webFile = new WebFile(reader);
|
||||
reader.Dispose();
|
||||
if (webFile.fileList.Length > 0)
|
||||
{
|
||||
var extractPath = Path.Combine(savePath, reader.FileName + "_unpacked");
|
||||
return ExtractStreamFile(extractPath, webFile.fileList);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int ExtractGameFile(FileReader reader, string savePath)
|
||||
{
|
||||
StatusStripUpdate($"Decompressing {reader.FileName}...");
|
||||
var gameFile = new GameFile(reader);
|
||||
reader.Dispose();
|
||||
var fileList = gameFile.Bundles.SelectMany(x => x.Value).ToList();
|
||||
if (fileList.Count > 0)
|
||||
{
|
||||
var extractPath = Path.Combine(savePath, Path.GetFileNameWithoutExtension(reader.FileName));
|
||||
return ExtractStreamFile(extractPath, fileList.ToArray());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int ExtractStreamFile(string extractPath, StreamFile[] fileList)
|
||||
{
|
||||
int extractedCount = 0;
|
||||
foreach (var file in fileList)
|
||||
{
|
||||
var filePath = Path.Combine(extractPath, file.path);
|
||||
var fileDirectory = Path.GetDirectoryName(filePath);
|
||||
if (!Directory.Exists(fileDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(fileDirectory);
|
||||
}
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
using (var fileStream = File.Create(filePath))
|
||||
{
|
||||
file.stream.CopyTo(fileStream);
|
||||
}
|
||||
extractedCount += 1;
|
||||
}
|
||||
file.stream.Dispose();
|
||||
}
|
||||
return extractedCount;
|
||||
}
|
||||
|
||||
public static List<AssetEntry> BuildAssetMap(List<string> files)
|
||||
{
|
||||
var assets = new List<AssetEntry>();
|
||||
for (int i = 0; i < files.Count; i++)
|
||||
{
|
||||
var file = files[i];
|
||||
var reader = new FileReader(file, Game);
|
||||
var gameFile = new GameFile(reader);
|
||||
reader.Dispose();
|
||||
|
||||
foreach (var bundle in gameFile.Bundles)
|
||||
{
|
||||
foreach (var cab in bundle.Value)
|
||||
{
|
||||
var dummyPath = Path.Combine(Path.GetDirectoryName(file), cab.fileName);
|
||||
using (var cabReader = new FileReader(dummyPath, cab.stream, Game))
|
||||
{
|
||||
if (cabReader.FileType == FileType.AssetsFile)
|
||||
{
|
||||
var assetsFile = new SerializedFile(cabReader, assetsManager, file);
|
||||
assetsManager.assetsFileList.Add(assetsFile);
|
||||
|
||||
assetsFile.m_Objects = assetsFile.m_Objects.Where(x => x.HasExportableType()).ToList();
|
||||
|
||||
IndexObject indexObject = null;
|
||||
var containers = new List<(PPtr<Object>, string)>(assetsFile.m_Objects.Count);
|
||||
var animators = new List<(PPtr<GameObject>, AssetEntry)>(assetsFile.m_Objects.Count);
|
||||
var objectAssetItemDic = new Dictionary<Object, AssetEntry>(assetsFile.m_Objects.Count);
|
||||
foreach (var objInfo in assetsFile.m_Objects)
|
||||
{
|
||||
var objectReader = new ObjectReader(assetsFile.reader, assetsFile, objInfo);
|
||||
var obj = new Object(objectReader);
|
||||
var asset = new AssetEntry()
|
||||
{
|
||||
Source = file,
|
||||
PathID = objectReader.m_PathID,
|
||||
Type = objectReader.type,
|
||||
Container = ""
|
||||
};
|
||||
|
||||
var exportable = true;
|
||||
switch (objectReader.type)
|
||||
{
|
||||
case ClassIDType.AssetBundle:
|
||||
var assetBundle = new AssetBundle(objectReader);
|
||||
foreach (var m_Container in assetBundle.Container)
|
||||
{
|
||||
var preloadIndex = m_Container.Value.preloadIndex;
|
||||
var preloadSize = m_Container.Value.preloadSize;
|
||||
var preloadEnd = preloadIndex + preloadSize;
|
||||
for (int k = preloadIndex; k < preloadEnd; k++)
|
||||
{
|
||||
if (Game.Name == "GI" || Game.Name == "CB2" || Game.Name == "CB3")
|
||||
{
|
||||
if (long.TryParse(m_Container.Key, out var containerValue))
|
||||
{
|
||||
var last = unchecked((uint)containerValue);
|
||||
var path = ResourceIndex.GetBundlePath(last);
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
containers.Add((assetBundle.PreloadTable[k], path));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
containers.Add((assetBundle.PreloadTable[k], m_Container.Key));
|
||||
}
|
||||
}
|
||||
obj = null;
|
||||
asset.Name = assetBundle.m_Name;
|
||||
exportable = AssetBundle.Exportable;
|
||||
break;
|
||||
case ClassIDType.GameObject:
|
||||
var gameObject = new GameObject(objectReader);
|
||||
obj = gameObject;
|
||||
asset.Name = gameObject.m_Name;
|
||||
exportable = false;
|
||||
break;
|
||||
case ClassIDType.Shader:
|
||||
asset.Name = objectReader.ReadAlignedString();
|
||||
if (string.IsNullOrEmpty(asset.Name))
|
||||
{
|
||||
var m_parsedForm = new SerializedShader(objectReader);
|
||||
asset.Name = m_parsedForm.m_Name;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.Animator:
|
||||
var component = new PPtr<GameObject>(objectReader);
|
||||
animators.Add((component, asset));
|
||||
break;
|
||||
case ClassIDType.MiHoYoBinData:
|
||||
if (indexObject.Names.TryGetValue(objectReader.m_PathID, out var binName))
|
||||
{
|
||||
var path = ResourceIndex.GetContainerFromBinName(file, binName);
|
||||
asset.Container = path;
|
||||
asset.Name = !string.IsNullOrEmpty(path) ? Path.GetFileName(path) : binName;
|
||||
}
|
||||
exportable = IndexObject.Exportable;
|
||||
break;
|
||||
case ClassIDType.IndexObject:
|
||||
indexObject = new IndexObject(objectReader);
|
||||
obj = null;
|
||||
asset.Name = "IndexObject";
|
||||
exportable = IndexObject.Exportable;
|
||||
break;
|
||||
default:
|
||||
asset.Name = objectReader.ReadAlignedString();
|
||||
break;
|
||||
}
|
||||
if (obj != null)
|
||||
{
|
||||
objectAssetItemDic.Add(obj, asset);
|
||||
assetsFile.AddObject(obj);
|
||||
}
|
||||
if (exportable)
|
||||
{
|
||||
assets.Add(asset);
|
||||
}
|
||||
}
|
||||
foreach (var pair in animators)
|
||||
{
|
||||
if (pair.Item1.TryGet(out var gameObject))
|
||||
{
|
||||
pair.Item2.Name = gameObject.m_Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Warning($"Unable to find GameObject with PathID {pair.Item1.m_PathID}, removing...");
|
||||
assets.Remove(pair.Item2);
|
||||
}
|
||||
}
|
||||
foreach ((var pptr, var container) in containers)
|
||||
{
|
||||
if (pptr.TryGet(out var obj))
|
||||
{
|
||||
objectAssetItemDic[obj].Container = container;
|
||||
}
|
||||
}
|
||||
assetsManager.assetsFileList.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Logger.Info($"[{i + 1}/{files.Count}] Processed {Path.GetFileName(file)}");
|
||||
Progress.Report(i + 1, files.Count);
|
||||
}
|
||||
|
||||
return assets;
|
||||
}
|
||||
|
||||
public static (string, List<TreeNode>) BuildAssetData()
|
||||
{
|
||||
StatusStripUpdate("Building asset list...");
|
||||
|
||||
string productName = null;
|
||||
var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
|
||||
var objectAssetItemDic = new Dictionary<Object, AssetItem>(objectCount);
|
||||
var containers = new List<(PPtr<Object>, string)>();
|
||||
int i = 0;
|
||||
Progress.Reset();
|
||||
foreach (var assetsFile in assetsManager.assetsFileList)
|
||||
{
|
||||
foreach (var asset in assetsFile.Objects)
|
||||
{
|
||||
var assetItem = new AssetItem(asset);
|
||||
objectAssetItemDic.Add(asset, assetItem);
|
||||
assetItem.UniqueID = "#" + i;
|
||||
var exportable = false;
|
||||
switch (asset)
|
||||
{
|
||||
case GameObject m_GameObject:
|
||||
assetItem.Text = m_GameObject.m_Name;
|
||||
break;
|
||||
case Texture2D m_Texture2D:
|
||||
if (!string.IsNullOrEmpty(m_Texture2D.m_StreamData?.path))
|
||||
assetItem.FullSize = asset.byteSize + m_Texture2D.m_StreamData.size;
|
||||
assetItem.Text = m_Texture2D.m_Name;
|
||||
exportable = true;
|
||||
break;
|
||||
case AudioClip m_AudioClip:
|
||||
if (!string.IsNullOrEmpty(m_AudioClip.m_Source))
|
||||
assetItem.FullSize = asset.byteSize + m_AudioClip.m_Size;
|
||||
assetItem.Text = m_AudioClip.m_Name;
|
||||
exportable = true;
|
||||
break;
|
||||
case VideoClip m_VideoClip:
|
||||
if (!string.IsNullOrEmpty(m_VideoClip.m_OriginalPath))
|
||||
assetItem.FullSize = asset.byteSize + (long)m_VideoClip.m_ExternalResources.m_Size;
|
||||
assetItem.Text = m_VideoClip.m_Name;
|
||||
exportable = true;
|
||||
break;
|
||||
case Shader m_Shader:
|
||||
assetItem.Text = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name;
|
||||
exportable = true;
|
||||
break;
|
||||
case Mesh _:
|
||||
case TextAsset _:
|
||||
case AnimationClip _:
|
||||
case Font _:
|
||||
case MovieTexture _:
|
||||
case Sprite _:
|
||||
case Material _:
|
||||
assetItem.Text = ((NamedObject)asset).m_Name;
|
||||
exportable = true;
|
||||
break;
|
||||
case Animator m_Animator:
|
||||
if (m_Animator.m_GameObject.TryGet(out var gameObject))
|
||||
{
|
||||
assetItem.Text = gameObject.m_Name;
|
||||
}
|
||||
exportable = true;
|
||||
break;
|
||||
case MonoBehaviour m_MonoBehaviour:
|
||||
if (m_MonoBehaviour.m_Name == "" && m_MonoBehaviour.m_Script.TryGet(out var m_Script))
|
||||
{
|
||||
assetItem.Text = m_Script.m_ClassName;
|
||||
}
|
||||
else
|
||||
{
|
||||
assetItem.Text = m_MonoBehaviour.m_Name;
|
||||
}
|
||||
exportable = true;
|
||||
break;
|
||||
case PlayerSettings m_PlayerSettings:
|
||||
productName = m_PlayerSettings.productName;
|
||||
break;
|
||||
case AssetBundle m_AssetBundle:
|
||||
foreach (var m_Container in m_AssetBundle.Container)
|
||||
{
|
||||
var preloadIndex = m_Container.Value.preloadIndex;
|
||||
var preloadSize = m_Container.Value.preloadSize;
|
||||
var preloadEnd = preloadIndex + preloadSize;
|
||||
for (int k = preloadIndex; k < preloadEnd; k++)
|
||||
{
|
||||
if (Game.Name == "GI" || Game.Name == "CB2" || Game.Name == "CB3")
|
||||
{
|
||||
if (long.TryParse(m_Container.Key, out var containerValue))
|
||||
{
|
||||
var last = unchecked((uint)containerValue);
|
||||
var path = ResourceIndex.GetBundlePath(last);
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
containers.Add((m_AssetBundle.PreloadTable[k], path));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
containers.Add((m_AssetBundle.PreloadTable[k], m_Container.Key));
|
||||
}
|
||||
}
|
||||
assetItem.Text = m_AssetBundle.m_Name;
|
||||
exportable = AssetBundle.Exportable;
|
||||
break;
|
||||
case IndexObject m_IndexObject:
|
||||
assetItem.Text = "IndexObject";
|
||||
exportable = IndexObject.Exportable;
|
||||
break;
|
||||
case ResourceManager m_ResourceManager:
|
||||
foreach (var m_Container in m_ResourceManager.m_Container)
|
||||
{
|
||||
containers.Add((m_Container.Value, m_Container.Key));
|
||||
}
|
||||
break;
|
||||
case MiHoYoBinData m_MiHoYoBinData:
|
||||
if (m_MiHoYoBinData.assetsFile.ObjectsDic.TryGetValue(2, out var obj) && obj is IndexObject indexObject)
|
||||
{
|
||||
if (indexObject.Names.TryGetValue(m_MiHoYoBinData.m_PathID, out var binName))
|
||||
{
|
||||
string path = "";
|
||||
var game = GameManager.GetGame("GI");
|
||||
if (Path.GetExtension(assetsFile.originalPath) == game.Extension)
|
||||
{
|
||||
path = ResourceIndex.GetContainerFromBinName(assetsFile.originalPath, binName);
|
||||
}
|
||||
else
|
||||
{
|
||||
var last = Convert.ToUInt32(binName, 16);
|
||||
path = ResourceIndex.GetBundlePath(last) ?? "";
|
||||
}
|
||||
assetItem.Container = path;
|
||||
assetItem.Text = !string.IsNullOrEmpty(path) ? Path.GetFileName(path) : binName;
|
||||
}
|
||||
}
|
||||
else assetItem.Text = string.Format("BinFile #{0}", assetItem.m_PathID);
|
||||
exportable = true;
|
||||
break;
|
||||
case NamedObject m_NamedObject:
|
||||
assetItem.Text = m_NamedObject.m_Name;
|
||||
break;
|
||||
}
|
||||
if (assetItem.Text == "")
|
||||
{
|
||||
assetItem.Text = assetItem.TypeString + assetItem.UniqueID;
|
||||
}
|
||||
if (Properties.Settings.Default.displayAll || exportable)
|
||||
{
|
||||
exportableAssets.Add(assetItem);
|
||||
}
|
||||
Progress.Report(++i, objectCount);
|
||||
}
|
||||
}
|
||||
foreach ((var pptr, var container) in containers)
|
||||
{
|
||||
if (pptr.TryGet(out var obj))
|
||||
{
|
||||
objectAssetItemDic[obj].Container = container;
|
||||
}
|
||||
}
|
||||
foreach (var tmp in exportableAssets)
|
||||
{
|
||||
tmp.SetSubItems();
|
||||
}
|
||||
containers.Clear();
|
||||
|
||||
visibleAssets = exportableAssets;
|
||||
|
||||
StatusStripUpdate("Building tree structure...");
|
||||
|
||||
var treeNodeCollection = new List<TreeNode>();
|
||||
var treeNodeDictionary = new Dictionary<GameObject, GameObjectTreeNode>();
|
||||
var assetsFileCount = assetsManager.assetsFileList.Count;
|
||||
int j = 0;
|
||||
Progress.Reset();
|
||||
foreach (var assetsFile in assetsManager.assetsFileList)
|
||||
{
|
||||
var fileNode = new TreeNode(assetsFile.fileName); //RootNode
|
||||
|
||||
foreach (var obj in assetsFile.Objects)
|
||||
{
|
||||
if (obj is GameObject m_GameObject)
|
||||
{
|
||||
if (!treeNodeDictionary.TryGetValue(m_GameObject, out var currentNode))
|
||||
{
|
||||
currentNode = new GameObjectTreeNode(m_GameObject);
|
||||
treeNodeDictionary.Add(m_GameObject, currentNode);
|
||||
}
|
||||
|
||||
foreach (var pptr in m_GameObject.m_Components)
|
||||
{
|
||||
if (pptr.TryGet(out var m_Component))
|
||||
{
|
||||
objectAssetItemDic[m_Component].TreeNode = currentNode;
|
||||
if (m_Component is MeshFilter m_MeshFilter)
|
||||
{
|
||||
if (m_MeshFilter.m_Mesh.TryGet(out var m_Mesh))
|
||||
{
|
||||
objectAssetItemDic[m_Mesh].TreeNode = currentNode;
|
||||
}
|
||||
}
|
||||
else if (m_Component is SkinnedMeshRenderer m_SkinnedMeshRenderer)
|
||||
{
|
||||
if (m_SkinnedMeshRenderer.m_Mesh.TryGet(out var m_Mesh))
|
||||
{
|
||||
objectAssetItemDic[m_Mesh].TreeNode = currentNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var parentNode = fileNode;
|
||||
|
||||
if (m_GameObject.m_Transform != null)
|
||||
{
|
||||
if (m_GameObject.m_Transform.m_Father.TryGet(out var m_Father))
|
||||
{
|
||||
if (m_Father.m_GameObject.TryGet(out var parentGameObject))
|
||||
{
|
||||
if (!treeNodeDictionary.TryGetValue(parentGameObject, out var parentGameObjectNode))
|
||||
{
|
||||
parentGameObjectNode = new GameObjectTreeNode(parentGameObject);
|
||||
treeNodeDictionary.Add(parentGameObject, parentGameObjectNode);
|
||||
}
|
||||
parentNode = parentGameObjectNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parentNode.Nodes.Add(currentNode);
|
||||
}
|
||||
}
|
||||
|
||||
if (fileNode.Nodes.Count > 0)
|
||||
{
|
||||
treeNodeCollection.Add(fileNode);
|
||||
}
|
||||
|
||||
Progress.Report(++j, assetsFileCount);
|
||||
}
|
||||
treeNodeDictionary.Clear();
|
||||
|
||||
objectAssetItemDic.Clear();
|
||||
|
||||
return (productName, treeNodeCollection);
|
||||
}
|
||||
|
||||
public static Dictionary<string, SortedDictionary<int, TypeTreeItem>> BuildClassStructure()
|
||||
{
|
||||
var typeMap = new Dictionary<string, SortedDictionary<int, TypeTreeItem>>();
|
||||
foreach (var assetsFile in assetsManager.assetsFileList)
|
||||
{
|
||||
if (typeMap.TryGetValue(assetsFile.unityVersion, out var curVer))
|
||||
{
|
||||
foreach (var type in assetsFile.m_Types.Where(x => x.m_Type != null))
|
||||
{
|
||||
var key = type.classID;
|
||||
if (type.m_ScriptTypeIndex >= 0)
|
||||
{
|
||||
key = -1 - type.m_ScriptTypeIndex;
|
||||
}
|
||||
curVer[key] = new TypeTreeItem(key, type.m_Type);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var items = new SortedDictionary<int, TypeTreeItem>();
|
||||
foreach (var type in assetsFile.m_Types.Where(x => x.m_Type != null))
|
||||
{
|
||||
var key = type.classID;
|
||||
if (type.m_ScriptTypeIndex >= 0)
|
||||
{
|
||||
key = -1 - type.m_ScriptTypeIndex;
|
||||
}
|
||||
items[key] = new TypeTreeItem(key, type.m_Type);
|
||||
}
|
||||
typeMap.Add(assetsFile.unityVersion, items);
|
||||
}
|
||||
}
|
||||
|
||||
return typeMap;
|
||||
}
|
||||
|
||||
public static void ExportAssets(string savePath, List<AssetItem> toExportAssets, ExportType exportType)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
|
||||
|
||||
int toExportCount = toExportAssets.Count;
|
||||
int exportedCount = 0;
|
||||
int i = 0;
|
||||
Progress.Reset();
|
||||
foreach (var asset in toExportAssets)
|
||||
{
|
||||
string exportPath;
|
||||
switch ((AssetGroupOption)Properties.Settings.Default.assetGroupOption)
|
||||
{
|
||||
case AssetGroupOption.ByType: //type name
|
||||
exportPath = Path.Combine(savePath, asset.TypeString);
|
||||
break;
|
||||
case AssetGroupOption.ByContainer: //container path
|
||||
if (!string.IsNullOrEmpty(asset.Container))
|
||||
{
|
||||
exportPath = Game.Name == "GI" || Game.Name == "CB2" || Game.Name == "CB3" ? Path.Combine(savePath, Path.GetDirectoryName(asset.Container)) : Path.Combine(savePath, asset.Container);
|
||||
}
|
||||
else
|
||||
{
|
||||
exportPath = Path.Combine(savePath, asset.TypeString);
|
||||
}
|
||||
break;
|
||||
case AssetGroupOption.BySource: //source file
|
||||
if (string.IsNullOrEmpty(asset.SourceFile.originalPath))
|
||||
{
|
||||
exportPath = Path.Combine(savePath, asset.SourceFile.fileName + "_export");
|
||||
}
|
||||
else
|
||||
{
|
||||
exportPath = Path.Combine(savePath, Path.GetFileName(asset.SourceFile.originalPath) + "_export", asset.SourceFile.fileName);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
exportPath = savePath;
|
||||
break;
|
||||
}
|
||||
exportPath += Path.DirectorySeparatorChar;
|
||||
StatusStripUpdate($"[{exportedCount}/{toExportCount}] Exporting {asset.TypeString}: {asset.Text}");
|
||||
try
|
||||
{
|
||||
switch (exportType)
|
||||
{
|
||||
case ExportType.Raw:
|
||||
if (ExportRawFile(asset, exportPath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
case ExportType.Dump:
|
||||
if (ExportDumpFile(asset, exportPath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
case ExportType.Convert:
|
||||
if (ExportConvertFile(asset, exportPath))
|
||||
{
|
||||
exportedCount++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Export {asset.Type}:{asset.Text} error\r\n{ex.Message}\r\n{ex.StackTrace}");
|
||||
}
|
||||
|
||||
Progress.Report(++i, toExportCount);
|
||||
}
|
||||
|
||||
var statusText = exportedCount == 0 ? "Nothing exported." : $"Finished exporting {exportedCount} assets.";
|
||||
|
||||
if (toExportCount > exportedCount)
|
||||
{
|
||||
statusText += $" {toExportCount - exportedCount} assets skipped (not extractable or files already exist)";
|
||||
}
|
||||
|
||||
StatusStripUpdate(statusText);
|
||||
|
||||
if (Properties.Settings.Default.openAfterExport && exportedCount > 0)
|
||||
{
|
||||
OpenFolderInExplorer(savePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void ExportAssetsMap(string savePath, List<AssetEntry> toExportAssets, ExportListType exportListType)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
|
||||
|
||||
Progress.Reset();
|
||||
|
||||
string filename;
|
||||
switch (exportListType)
|
||||
{
|
||||
case ExportListType.XML:
|
||||
filename = Path.Combine(savePath, $"assets_map_{Game.Name}.xml");
|
||||
var doc = new XDocument(
|
||||
new XElement("Assets",
|
||||
new XAttribute("filename", filename),
|
||||
new XAttribute("createdAt", DateTime.UtcNow.ToString("s")),
|
||||
toExportAssets.Select(
|
||||
asset => new XElement("Asset",
|
||||
new XElement("Name", asset.Name),
|
||||
new XElement("Container", asset.Container),
|
||||
new XElement("Type", new XAttribute("id", (int)asset.Type), asset.Type.ToString()),
|
||||
new XElement("PathID", asset.PathID),
|
||||
new XElement("Source", asset.Source)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
doc.Save(filename);
|
||||
break;
|
||||
}
|
||||
|
||||
var statusText = $"Finished exporting asset list with {toExportAssets.Count()} items.";
|
||||
|
||||
StatusStripUpdate(statusText);
|
||||
|
||||
Logger.Info($"AssetMap build successfully !!");
|
||||
|
||||
if (Properties.Settings.Default.openAfterExport && toExportAssets.Count() > 0)
|
||||
{
|
||||
OpenFolderInExplorer(savePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void ExportAssetsList(string savePath, List<AssetItem> toExportAssets, ExportListType exportListType)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
|
||||
|
||||
Progress.Reset();
|
||||
|
||||
switch (exportListType)
|
||||
{
|
||||
case ExportListType.XML:
|
||||
var filename = Path.Combine(savePath, "assets.xml");
|
||||
var doc = new XDocument(
|
||||
new XElement("Assets",
|
||||
new XAttribute("filename", filename),
|
||||
new XAttribute("createdAt", DateTime.UtcNow.ToString("s")),
|
||||
toExportAssets.Select(
|
||||
asset => new XElement("Asset",
|
||||
new XElement("Name", asset.Text),
|
||||
new XElement("Container", asset.Container),
|
||||
new XElement("Type", new XAttribute("id", (int)asset.Type), asset.TypeString),
|
||||
new XElement("PathID", asset.m_PathID),
|
||||
new XElement("Source", asset.SourceFile.fullName),
|
||||
new XElement("OriginalPath", asset.SourceFile.originalPath),
|
||||
new XElement("Size", asset.FullSize)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
doc.Save(filename);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
var statusText = $"Finished exporting asset list with {toExportAssets.Count()} items.";
|
||||
|
||||
StatusStripUpdate(statusText);
|
||||
|
||||
if (Properties.Settings.Default.openAfterExport && toExportAssets.Count() > 0)
|
||||
{
|
||||
OpenFolderInExplorer(savePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void ExportSplitObjects(string savePath, TreeNodeCollection nodes)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
var count = nodes.Cast<TreeNode>().Sum(x => x.Nodes.Count);
|
||||
int k = 0;
|
||||
Progress.Reset();
|
||||
foreach (TreeNode node in nodes)
|
||||
{
|
||||
//遍历一级子节点
|
||||
foreach (GameObjectTreeNode j in node.Nodes)
|
||||
{
|
||||
//收集所有子节点
|
||||
var gameObjects = new List<GameObject>();
|
||||
CollectNode(j, gameObjects);
|
||||
//跳过一些不需要导出的object
|
||||
if (gameObjects.All(x => x.m_SkinnedMeshRenderer == null && x.m_MeshFilter == null))
|
||||
{
|
||||
Progress.Report(++k, count);
|
||||
continue;
|
||||
}
|
||||
//处理非法文件名
|
||||
var filename = FixFileName(j.Text);
|
||||
//每个文件存放在单独的文件夹
|
||||
var targetPath = $"{savePath}{filename}{Path.DirectorySeparatorChar}";
|
||||
//重名文件处理
|
||||
for (int i = 1; ; i++)
|
||||
{
|
||||
if (Directory.Exists(targetPath))
|
||||
{
|
||||
targetPath = $"{savePath}{filename} ({i}){Path.DirectorySeparatorChar}";
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
Directory.CreateDirectory(targetPath);
|
||||
//导出FBX
|
||||
StatusStripUpdate($"Exporting {filename}.fbx");
|
||||
try
|
||||
{
|
||||
ExportGameObject(j.gameObject, targetPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Export GameObject:{j.Text} error\r\n{ex.Message}\r\n{ex.StackTrace}");
|
||||
}
|
||||
|
||||
Progress.Report(++k, count);
|
||||
StatusStripUpdate($"Finished exporting {filename}.fbx");
|
||||
}
|
||||
}
|
||||
if (Properties.Settings.Default.openAfterExport)
|
||||
{
|
||||
OpenFolderInExplorer(savePath);
|
||||
}
|
||||
StatusStripUpdate("Finished");
|
||||
});
|
||||
}
|
||||
|
||||
private static void CollectNode(GameObjectTreeNode node, List<GameObject> gameObjects)
|
||||
{
|
||||
gameObjects.Add(node.gameObject);
|
||||
foreach (GameObjectTreeNode i in node.Nodes)
|
||||
{
|
||||
CollectNode(i, gameObjects);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExportAnimatorWithAnimationClip(AssetItem animator, List<AssetItem> animationList, string exportPath)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
Progress.Reset();
|
||||
StatusStripUpdate($"Exporting {animator.Text}");
|
||||
try
|
||||
{
|
||||
ExportAnimator(animator, exportPath, animationList);
|
||||
if (Properties.Settings.Default.openAfterExport)
|
||||
{
|
||||
OpenFolderInExplorer(exportPath);
|
||||
}
|
||||
Progress.Report(1, 1);
|
||||
StatusStripUpdate($"Finished exporting {animator.Text}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Export Animator:{animator.Text} error\r\n{ex.Message}\r\n{ex.StackTrace}");
|
||||
StatusStripUpdate("Error in export");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void ExportObjectsWithAnimationClip(string exportPath, TreeNodeCollection nodes, List<AssetItem> animationList = null)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
var gameObjects = new List<GameObject>();
|
||||
GetSelectedParentNode(nodes, gameObjects);
|
||||
if (gameObjects.Count > 0)
|
||||
{
|
||||
var count = gameObjects.Count;
|
||||
int i = 0;
|
||||
Progress.Reset();
|
||||
foreach (var gameObject in gameObjects)
|
||||
{
|
||||
StatusStripUpdate($"Exporting {gameObject.m_Name}");
|
||||
try
|
||||
{
|
||||
var subExportPath = Path.Combine(exportPath, gameObject.m_Name) + Path.DirectorySeparatorChar;
|
||||
ExportGameObject(gameObject, subExportPath, animationList);
|
||||
StatusStripUpdate($"Finished exporting {gameObject.m_Name}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Export GameObject:{gameObject.m_Name} error\r\n{ex.Message}\r\n{ex.StackTrace}");
|
||||
StatusStripUpdate("Error in export");
|
||||
}
|
||||
|
||||
Progress.Report(++i, count);
|
||||
}
|
||||
if (Properties.Settings.Default.openAfterExport)
|
||||
{
|
||||
OpenFolderInExplorer(exportPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusStripUpdate("No Object selected for export.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void ExportObjectsMergeWithAnimationClip(string exportPath, List<GameObject> gameObjects, List<AssetItem> animationList = null)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(state =>
|
||||
{
|
||||
var name = Path.GetFileName(exportPath);
|
||||
Progress.Reset();
|
||||
StatusStripUpdate($"Exporting {name}");
|
||||
try
|
||||
{
|
||||
ExportGameObjectMerge(gameObjects, exportPath, animationList);
|
||||
Progress.Report(1, 1);
|
||||
StatusStripUpdate($"Finished exporting {name}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Export Model:{name} error\r\n{ex.Message}\r\n{ex.StackTrace}");
|
||||
StatusStripUpdate("Error in export");
|
||||
}
|
||||
if (Properties.Settings.Default.openAfterExport)
|
||||
{
|
||||
OpenFolderInExplorer(Path.GetDirectoryName(exportPath));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void GetSelectedParentNode(TreeNodeCollection nodes, List<GameObject> gameObjects)
|
||||
{
|
||||
foreach (TreeNode i in nodes)
|
||||
{
|
||||
if (i is GameObjectTreeNode gameObjectTreeNode && i.Checked)
|
||||
{
|
||||
gameObjects.Add(gameObjectTreeNode.gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetSelectedParentNode(i.Nodes, gameObjects);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static TypeTree MonoBehaviourToTypeTree(MonoBehaviour m_MonoBehaviour)
|
||||
{
|
||||
if (!assemblyLoader.Loaded)
|
||||
{
|
||||
var openFolderDialog = new OpenFolderDialog();
|
||||
openFolderDialog.Title = "Select Assembly Folder";
|
||||
if (openFolderDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
assemblyLoader.Load(openFolderDialog.Folder);
|
||||
}
|
||||
else
|
||||
{
|
||||
assemblyLoader.Loaded = true;
|
||||
}
|
||||
}
|
||||
return m_MonoBehaviour.ConvertToTypeTree(assemblyLoader);
|
||||
}
|
||||
|
||||
public static string DumpAsset(Object obj)
|
||||
{
|
||||
var str = obj.Dump();
|
||||
if (str == null && obj is MonoBehaviour m_MonoBehaviour)
|
||||
{
|
||||
var type = MonoBehaviourToTypeTree(m_MonoBehaviour);
|
||||
str = m_MonoBehaviour.Dump(type);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
public static void OpenFolderInExplorer(string path)
|
||||
{
|
||||
var info = new ProcessStartInfo(path);
|
||||
info.UseShellExecute = true;
|
||||
Process.Start(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user