3 Commits

Author SHA1 Message Date
VaDiM
eab789939d listSearh fix 2020-08-01 21:14:42 +03:00
VaDiM
04266251aa add "Dump with PathID as filename" feature 2020-07-27 23:22:53 +03:00
VaDiM
c5f7ef6e91 add some features
- Export tex2D/sprites with PathID as a filename
- Dump selected assets from the context menu strip
- Drag&Drop support by Jayatubi
- Sort by PathID by Tahvohck
2020-07-26 23:40:19 +03:00
189 changed files with 4102 additions and 15975 deletions

View File

@@ -1,17 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>0.16.8.1</Version>
<AssemblyVersion>0.16.8.1</AssemblyVersion>
<FileVersion>0.16.8.1</FileVersion>
<Copyright>Copyright © Perfare 2020-2021; Copyright © hozuki 2020</Copyright>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net472|AnyCPU'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
</Project>

View File

@@ -1,124 +0,0 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
namespace AssetStudio.PInvoke
{
public static class DllLoader
{
public static void PreloadDll(string dllName)
{
var dllDir = GetDirectedDllDirectory();
// Not using OperatingSystem.Platform.
// See: https://www.mono-project.com/docs/faq/technical/#how-to-detect-the-execution-platform
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Win32.LoadDll(dllDir, dllName);
}
else
{
Posix.LoadDll(dllDir, dllName);
}
}
private static string GetDirectedDllDirectory()
{
var localPath = Process.GetCurrentProcess().MainModule.FileName;
var localDir = Path.GetDirectoryName(localPath);
var subDir = Environment.Is64BitProcess ? "x64" : "x86";
var directedDllDir = Path.Combine(localDir, subDir);
return directedDllDir;
}
private static class Win32
{
internal static void LoadDll(string dllDir, string dllName)
{
var dllFileName = $"{dllName}.dll";
var directedDllPath = Path.Combine(dllDir, dllFileName);
// Specify SEARCH_DLL_LOAD_DIR to load dependent libraries located in the same platform-specific directory.
var hLibrary = LoadLibraryEx(directedDllPath, IntPtr.Zero, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
if (hLibrary == IntPtr.Zero)
{
var errorCode = Marshal.GetLastWin32Error();
var exception = new Win32Exception(errorCode);
throw new DllNotFoundException(exception.Message, exception);
}
}
// HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
// HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr LoadLibraryEx(string lpLibFileName, IntPtr hFile, uint dwFlags);
private const uint LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x1000;
private const uint LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x100;
}
private static class Posix
{
internal static void LoadDll(string dllDir, string dllName)
{
string dllExtension;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
dllExtension = ".so";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
dllExtension = ".dylib";
}
else
{
throw new NotSupportedException();
}
var dllFileName = $"lib{dllName}{dllExtension}";
var directedDllPath = Path.Combine(dllDir, dllFileName);
const int ldFlags = RTLD_NOW | RTLD_GLOBAL;
var hLibrary = DlOpen(directedDllPath, ldFlags);
if (hLibrary == IntPtr.Zero)
{
var pErrStr = DlError();
// `PtrToStringAnsi` always uses the specific constructor of `String` (see dotnet/core#2325),
// which in turn interprets the byte sequence with system default codepage. On OSX and Linux
// the codepage is UTF-8 so the error message should be handled correctly.
var errorMessage = Marshal.PtrToStringAnsi(pErrStr);
throw new DllNotFoundException(errorMessage);
}
}
// OSX and most Linux OS use LP64 so `int` is still 32-bit even on 64-bit platforms.
// void *dlopen(const char *filename, int flag);
[DllImport("libdl", EntryPoint = "dlopen")]
private static extern IntPtr DlOpen([MarshalAs(UnmanagedType.LPStr)] string fileName, int flags);
// char *dlerror(void);
[DllImport("libdl", EntryPoint = "dlerror")]
private static extern IntPtr DlError();
private const int RTLD_LAZY = 0x1;
private const int RTLD_NOW = 0x2;
private const int RTLD_GLOBAL = 0x100;
}
}
}

View File

@@ -1,100 +0,0 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32.SafeHandles;
namespace AssetStudio.PInvoke
{
// Generally the technique from Steamworks.NET
public class Utf8StringHandle : SafeHandleZeroOrMinusOneIsInvalid
{
static Utf8StringHandle()
{
Utf8 = new UTF8Encoding(false);
}
public Utf8StringHandle(string str)
: base(true)
{
IntPtr buffer;
if (str == null)
{
buffer = IntPtr.Zero;
}
else
{
if (str.Length == 0)
{
buffer = Marshal.AllocHGlobal(1);
unsafe
{
*(byte*)buffer = 0;
}
}
else
{
var strlen = Utf8.GetByteCount(str);
var strBuffer = new byte[strlen + 1];
Utf8.GetBytes(str, 0, str.Length, strBuffer, 0);
buffer = Marshal.AllocHGlobal(strBuffer.Length);
Marshal.Copy(strBuffer, 0, buffer, strBuffer.Length);
}
}
SetHandle(buffer);
}
public static string ReadUtf8StringFromPointer(IntPtr lpstr)
{
if (lpstr == IntPtr.Zero || lpstr == new IntPtr(-1))
{
return null;
}
var byteCount = 0;
unsafe
{
var p = (byte*)lpstr.ToPointer();
while (*p != 0)
{
byteCount += 1;
p += 1;
}
}
if (byteCount == 0)
{
return string.Empty;
}
var strBuffer = new byte[byteCount];
Marshal.Copy(lpstr, strBuffer, 0, byteCount);
var str = Utf8.GetString(strBuffer);
return str;
}
protected override bool ReleaseHandle()
{
if (!IsInvalid)
{
Marshal.FreeHGlobal(handle);
}
return true;
}
private static readonly UTF8Encoding Utf8;
}
}

View File

@@ -1,141 +1,71 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31410.357
VisualStudioVersion = 16.0.29920.165
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudio", "AssetStudio\AssetStudio.csproj", "{422FEC21-EF60-4F29-AA56-95DFDA23C913}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudio", "AssetStudio\AssetStudio.csproj", "{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudio.PInvoke", "AssetStudio.PInvoke\AssetStudio.PInvoke.csproj", "{0B2BE613-3049-4021-85D1-21C325F729F4}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssetStudioFBX", "AssetStudioFBX\AssetStudioFBX.vcxproj", "{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudioFBXWrapper", "AssetStudioFBXWrapper\AssetStudioFBXWrapper.csproj", "{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}"
ProjectSection(ProjectDependencies) = postProject
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027} = {11EA25A3-ED68-40EE-A9D0-7FDE3B583027}
EndProjectSection
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Texture2DDecoder", "Texture2DDecoder\Texture2DDecoder.vcxproj", "{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudioGUI", "AssetStudioGUI\AssetStudioGUI.csproj", "{29EAD018-1C67-497A-AB8E-727D595AD756}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioUtility", "AssetStudioUtility\AssetStudioUtility.csproj", "{80AEC261-21EE-4E4F-A93B-7A744DC84888}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudioUtility", "AssetStudioUtility\AssetStudioUtility.csproj", "{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Texture2DDecoderWrapper", "Texture2DDecoderWrapper\Texture2DDecoderWrapper.csproj", "{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}"
ProjectSection(ProjectDependencies) = postProject
{29356642-C46E-4144-83D8-22DC09D0D7FD} = {29356642-C46E-4144-83D8-22DC09D0D7FD}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssetStudioFBXNative", "AssetStudioFBXNative\AssetStudioFBXNative.vcxproj", "{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Texture2DDecoderNative", "Texture2DDecoderNative\Texture2DDecoderNative.vcxproj", "{29356642-C46E-4144-83D8-22DC09D0D7FD}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioGUI", "AssetStudioGUI\AssetStudioGUI.csproj", "{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|Any CPU.Build.0 = Debug|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x64.ActiveCfg = Debug|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x64.Build.0 = Debug|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x86.ActiveCfg = Debug|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x86.Build.0 = Debug|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|Any CPU.ActiveCfg = Release|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|Any CPU.Build.0 = Release|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x64.ActiveCfg = Release|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x64.Build.0 = Release|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x86.ActiveCfg = Release|Any CPU
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x86.Build.0 = Release|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x64.ActiveCfg = Debug|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x64.Build.0 = Debug|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x86.ActiveCfg = Debug|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x86.Build.0 = Debug|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|Any CPU.Build.0 = Release|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x64.ActiveCfg = Release|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x64.Build.0 = Release|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x86.ActiveCfg = Release|Any CPU
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x86.Build.0 = Release|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x64.ActiveCfg = Debug|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x64.Build.0 = Debug|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x86.ActiveCfg = Debug|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x86.Build.0 = Debug|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|Any CPU.Build.0 = Release|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|x64.ActiveCfg = Release|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|x64.Build.0 = Release|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|x86.ActiveCfg = Release|Any CPU
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|x86.Build.0 = Release|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|Any CPU.Build.0 = Debug|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|x64.ActiveCfg = Debug|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|x64.Build.0 = Debug|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|x86.ActiveCfg = Debug|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|x86.Build.0 = Debug|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|Any CPU.ActiveCfg = Release|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|Any CPU.Build.0 = Release|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|x64.ActiveCfg = Release|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|x64.Build.0 = Release|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|x86.ActiveCfg = Release|Any CPU
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|x86.Build.0 = Release|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|x64.ActiveCfg = Debug|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|x64.Build.0 = Debug|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|x86.ActiveCfg = Debug|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|x86.Build.0 = Debug|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|Any CPU.Build.0 = Release|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|x64.ActiveCfg = Release|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|x64.Build.0 = Release|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|x86.ActiveCfg = Release|Any CPU
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|x86.Build.0 = Release|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|x64.ActiveCfg = Debug|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|x64.Build.0 = Debug|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|x86.ActiveCfg = Debug|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|x86.Build.0 = Debug|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|Any CPU.Build.0 = Release|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|x64.ActiveCfg = Release|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|x64.Build.0 = Release|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|x86.ActiveCfg = Release|Any CPU
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|x86.Build.0 = Release|Any CPU
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|Any CPU.ActiveCfg = Debug|Win32
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|Any CPU.Build.0 = Debug|Win32
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|x64.ActiveCfg = Debug|x64
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|x64.Build.0 = Debug|x64
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|x86.ActiveCfg = Debug|Win32
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|x86.Build.0 = Debug|Win32
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|Any CPU.ActiveCfg = Release|Win32
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|Any CPU.Build.0 = Release|Win32
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|x64.ActiveCfg = Release|x64
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|x64.Build.0 = Release|x64
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|x86.ActiveCfg = Release|Win32
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|x86.Build.0 = Release|Win32
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|Any CPU.ActiveCfg = Debug|Win32
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|Any CPU.Build.0 = Debug|Win32
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|x64.ActiveCfg = Debug|x64
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|x64.Build.0 = Debug|x64
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|x86.ActiveCfg = Debug|Win32
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|x86.Build.0 = Debug|Win32
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|Any CPU.ActiveCfg = Release|Win32
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|Any CPU.Build.0 = Release|Win32
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|x64.ActiveCfg = Release|x64
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|x64.Build.0 = Release|x64
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|x86.ActiveCfg = Release|Win32
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|x86.Build.0 = Release|Win32
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x64.ActiveCfg = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x64.Build.0 = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x86.ActiveCfg = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x86.Build.0 = Debug|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x64.ActiveCfg = Release|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x64.Build.0 = Release|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x86.ActiveCfg = Release|Any CPU
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x86.Build.0 = Release|Any CPU
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Debug|x64.ActiveCfg = Debug|x64
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Debug|x64.Build.0 = Debug|x64
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Debug|x86.ActiveCfg = Debug|Win32
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Debug|x86.Build.0 = Debug|Win32
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Release|x64.ActiveCfg = Release|x64
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Release|x64.Build.0 = Release|x64
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Release|x86.ActiveCfg = Release|Win32
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Release|x86.Build.0 = Release|Win32
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Debug|x64.ActiveCfg = Debug|x64
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Debug|x64.Build.0 = Debug|x64
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Debug|x86.ActiveCfg = Debug|Win32
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Debug|x86.Build.0 = Debug|Win32
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Release|x64.ActiveCfg = Release|x64
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Release|x64.Build.0 = Release|x64
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Release|x86.ActiveCfg = Release|Win32
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Release|x86.Build.0 = Release|Win32
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x64.ActiveCfg = Debug|x64
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x64.Build.0 = Debug|x64
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x86.ActiveCfg = Debug|x86
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x86.Build.0 = Debug|x86
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x64.ActiveCfg = Release|x64
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x64.Build.0 = Release|x64
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x86.ActiveCfg = Release|x86
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x86.Build.0 = Release|x86
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x64.ActiveCfg = Debug|x64
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x64.Build.0 = Debug|x64
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x86.ActiveCfg = Debug|x86
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x86.Build.0 = Debug|x86
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x64.ActiveCfg = Release|x64
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x64.Build.0 = Release|x64
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x86.ActiveCfg = Release|x86
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3C074481-9CDD-4780-B9F6-57BBC5092EA2}
SolutionGuid = {F8734F96-97B6-40CA-B791-6D5467F2F713}
EndGlobalSection
EndGlobal

View File

@@ -1,16 +1,154 @@
<Project Sdk="Microsoft.NET.Sdk">
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
<Version>0.16.8.1</Version>
<AssemblyVersion>0.16.8.1</AssemblyVersion>
<FileVersion>0.16.8.1</FileVersion>
<Copyright>Copyright © Perfare 2018-2021</Copyright>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AssetStudio</RootNamespace>
<AssemblyName>AssetStudio</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net472|AnyCPU'">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
</Project>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="7zip\Common\CommandLineParser.cs" />
<Compile Include="7zip\Common\CRC.cs" />
<Compile Include="7zip\Common\InBuffer.cs" />
<Compile Include="7zip\Common\OutBuffer.cs" />
<Compile Include="7zip\Compress\LZMA\LzmaBase.cs" />
<Compile Include="7zip\Compress\LZMA\LzmaDecoder.cs" />
<Compile Include="7zip\Compress\LZMA\LzmaEncoder.cs" />
<Compile Include="7zip\Compress\LZ\IMatchFinder.cs" />
<Compile Include="7zip\Compress\LZ\LzBinTree.cs" />
<Compile Include="7zip\Compress\LZ\LzInWindow.cs" />
<Compile Include="7zip\Compress\LZ\LzOutWindow.cs" />
<Compile Include="7zip\Compress\RangeCoder\RangeCoder.cs" />
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBit.cs" />
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBitTree.cs" />
<Compile Include="7zip\ICoder.cs" />
<Compile Include="AssetsManager.cs" />
<Compile Include="Brotli\BitReader.cs" />
<Compile Include="Brotli\BrotliInputStream.cs" />
<Compile Include="Brotli\BrotliRuntimeException.cs" />
<Compile Include="Brotli\Context.cs" />
<Compile Include="Brotli\Decode.cs" />
<Compile Include="Brotli\Dictionary.cs" />
<Compile Include="Brotli\Huffman.cs" />
<Compile Include="Brotli\HuffmanTreeGroup.cs" />
<Compile Include="Brotli\IntReader.cs" />
<Compile Include="Brotli\Prefix.cs" />
<Compile Include="Brotli\RunningState.cs" />
<Compile Include="Brotli\State.cs" />
<Compile Include="Brotli\Transform.cs" />
<Compile Include="Brotli\Utils.cs" />
<Compile Include="Brotli\WordTransformType.cs" />
<Compile Include="BuildTarget.cs" />
<Compile Include="BuildType.cs" />
<Compile Include="BundleFile.cs" />
<Compile Include="Classes\Animation.cs" />
<Compile Include="Classes\AnimationClip.cs" />
<Compile Include="Classes\Animator.cs" />
<Compile Include="Classes\AnimatorController.cs" />
<Compile Include="Classes\AnimatorOverrideController.cs" />
<Compile Include="Classes\AssetBundle.cs" />
<Compile Include="Classes\AudioClip.cs" />
<Compile Include="Classes\Avatar.cs" />
<Compile Include="Classes\Behaviour.cs" />
<Compile Include="Classes\BuildSettings.cs" />
<Compile Include="Classes\Component.cs" />
<Compile Include="Classes\EditorExtension.cs" />
<Compile Include="Classes\Font.cs" />
<Compile Include="Classes\GameObject.cs" />
<Compile Include="Classes\Material.cs" />
<Compile Include="Classes\Mesh.cs" />
<Compile Include="Classes\MeshFilter.cs" />
<Compile Include="Classes\MeshRenderer.cs" />
<Compile Include="Classes\MonoBehaviour.cs" />
<Compile Include="Classes\MonoScript.cs" />
<Compile Include="Classes\MovieTexture.cs" />
<Compile Include="Classes\NamedObject.cs" />
<Compile Include="Classes\Object.cs" />
<Compile Include="Classes\PlayerSettings.cs" />
<Compile Include="Classes\PPtr.cs" />
<Compile Include="Classes\RectTransform.cs" />
<Compile Include="Classes\Renderer.cs" />
<Compile Include="Classes\RuntimeAnimatorController.cs" />
<Compile Include="Classes\Shader.cs" />
<Compile Include="Classes\SkinnedMeshRenderer.cs" />
<Compile Include="Classes\Sprite.cs" />
<Compile Include="Classes\SpriteAtlas.cs" />
<Compile Include="Classes\TextAsset.cs" />
<Compile Include="Classes\Texture.cs" />
<Compile Include="Classes\Texture2D.cs" />
<Compile Include="Classes\Transform.cs" />
<Compile Include="Classes\VideoClip.cs" />
<Compile Include="ClassIDType.cs" />
<Compile Include="CommonString.cs" />
<Compile Include="EndianBinaryReader.cs" />
<Compile Include="Extensions\BinaryReaderExtensions.cs" />
<Compile Include="Extensions\BinaryWriterExtensions.cs" />
<Compile Include="Extensions\StreamExtensions.cs" />
<Compile Include="FileIdentifier.cs" />
<Compile Include="IImported.cs" />
<Compile Include="ILogger.cs" />
<Compile Include="ImportHelper.cs" />
<Compile Include="IProgress.cs" />
<Compile Include="LocalSerializedObjectIdentifier.cs" />
<Compile Include="Logger.cs" />
<Compile Include="Lz4DecoderStream.cs" />
<Compile Include="Math\Color.cs" />
<Compile Include="Math\Half.cs" />
<Compile Include="Math\HalfHelper.cs" />
<Compile Include="Math\Matrix4x4.cs" />
<Compile Include="Math\Quaternion.cs" />
<Compile Include="Math\Vector2.cs" />
<Compile Include="Math\Vector3.cs" />
<Compile Include="Math\Vector4.cs" />
<Compile Include="ObjectInfo.cs" />
<Compile Include="ObjectReader.cs" />
<Compile Include="Progress.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ResourceReader.cs" />
<Compile Include="SerializedFile.cs" />
<Compile Include="SerializedFileHeader.cs" />
<Compile Include="SerializedType.cs" />
<Compile Include="SevenZipHelper.cs" />
<Compile Include="StreamFile.cs" />
<Compile Include="TypeTreeHelper.cs" />
<Compile Include="TypeTreeNode.cs" />
<Compile Include="UType.cs" />
<Compile Include="WebFile.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -2,16 +2,13 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using static AssetStudio.ImportHelper;
namespace AssetStudio
{
public class AssetsManager
{
public string SpecifyUnityVersion;
public List<SerializedFile> assetsFileList = new List<SerializedFile>();
internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
internal Dictionary<string, BinaryReader> resourceFileReaders = new Dictionary<string, BinaryReader>(StringComparer.OrdinalIgnoreCase);
@@ -61,54 +58,42 @@ namespace AssetStudio
private void LoadFile(string fullName)
{
var reader = new FileReader(fullName);
LoadFile(reader);
}
private void LoadFile(FileReader reader)
{
switch (reader.FileType)
switch (CheckFileType(fullName, out var reader))
{
case FileType.AssetsFile:
LoadAssetsFile(reader);
LoadAssetsFile(fullName, reader);
break;
case FileType.BundleFile:
LoadBundleFile(reader);
LoadBundleFile(fullName, reader);
break;
case FileType.WebFile:
LoadWebFile(reader);
break;
case FileType.GZipFile:
LoadFile(DecompressGZip(reader));
break;
case FileType.BrotliFile:
LoadFile(DecompressBrotli(reader));
LoadWebFile(fullName, reader);
break;
}
}
private void LoadAssetsFile(FileReader reader)
private void LoadAssetsFile(string fullName, EndianBinaryReader reader)
{
if (!assetsFileListHash.Contains(reader.FileName))
var fileName = Path.GetFileName(fullName);
if (!assetsFileListHash.Contains(fileName))
{
Logger.Info($"Loading {reader.FileName}");
Logger.Info($"Loading {fileName}");
try
{
var assetsFile = new SerializedFile(reader, this);
CheckStrippedVersion(assetsFile);
var assetsFile = new SerializedFile(this, fullName, reader);
assetsFileList.Add(assetsFile);
assetsFileListHash.Add(assetsFile.fileName);
foreach (var sharedFile in assetsFile.m_Externals)
{
var sharedFilePath = Path.GetDirectoryName(fullName) + "\\" + sharedFile.fileName;
var sharedFileName = sharedFile.fileName;
if (!importFilesHash.Contains(sharedFileName))
{
var sharedFilePath = Path.Combine(Path.GetDirectoryName(reader.FullPath), sharedFileName);
if (!File.Exists(sharedFilePath))
{
var findFiles = Directory.GetFiles(Path.GetDirectoryName(reader.FullPath), sharedFileName, SearchOption.AllDirectories);
var findFiles = Directory.GetFiles(Path.GetDirectoryName(fullName), sharedFileName, SearchOption.AllDirectories);
if (findFiles.Length > 0)
{
sharedFilePath = findFiles[0];
@@ -123,10 +108,10 @@ namespace AssetStudio
}
}
}
catch (Exception e)
catch
{
Logger.Error($"Error while reading assets file {reader.FileName}", e);
reader.Dispose();
//Logger.Warning($"Unable to load assets file {fileName}");
}
}
else
@@ -135,58 +120,59 @@ namespace AssetStudio
}
}
private void LoadAssetsFromMemory(FileReader reader, string originalPath, string unityVersion = null)
private void LoadAssetsFromMemory(string fullName, EndianBinaryReader reader, string originalPath, string unityVersion = null)
{
if (!assetsFileListHash.Contains(reader.FileName))
var fileName = Path.GetFileName(fullName);
if (!assetsFileListHash.Contains(fileName))
{
try
{
var assetsFile = new SerializedFile(reader, this);
var assetsFile = new SerializedFile(this, fullName, reader);
assetsFile.originalPath = originalPath;
if (!string.IsNullOrEmpty(unityVersion) && assetsFile.header.m_Version < SerializedFileFormatVersion.kUnknown_7)
if (assetsFile.header.m_Version < 7)
{
assetsFile.SetVersion(unityVersion);
}
CheckStrippedVersion(assetsFile);
assetsFileList.Add(assetsFile);
assetsFileListHash.Add(assetsFile.fileName);
}
catch (Exception e)
catch
{
Logger.Error($"Error while reading assets file {reader.FileName} from {Path.GetFileName(originalPath)}", e);
resourceFileReaders.Add(reader.FileName, reader);
//Logger.Error($"Unable to load assets file {fileName} from {Path.GetFileName(originalPath)}");
resourceFileReaders.Add(fileName, reader);
}
}
}
private void LoadBundleFile(FileReader reader, string originalPath = null)
private void LoadBundleFile(string fullName, EndianBinaryReader reader, string parentPath = null)
{
Logger.Info("Loading " + reader.FileName);
var fileName = Path.GetFileName(fullName);
Logger.Info("Loading " + fileName);
try
{
var bundleFile = new BundleFile(reader);
var bundleFile = new BundleFile(reader, fullName);
foreach (var file in bundleFile.fileList)
{
var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), file.fileName);
var subReader = new FileReader(dummyPath, file.stream);
if (subReader.FileType == FileType.AssetsFile)
var subReader = new EndianBinaryReader(file.stream);
if (SerializedFile.IsSerializedFile(subReader))
{
LoadAssetsFromMemory(subReader, originalPath ?? reader.FullPath, bundleFile.m_Header.unityRevision);
var dummyPath = Path.GetDirectoryName(fullName) + Path.DirectorySeparatorChar + file.fileName;
LoadAssetsFromMemory(dummyPath, subReader, parentPath ?? fullName, bundleFile.m_Header.unityRevision);
}
else if (!resourceFileReaders.ContainsKey(file.fileName))
else
{
resourceFileReaders.Add(file.fileName, subReader);
}
}
}
catch (Exception e)
catch
{
var str = $"Error while reading bundle file {reader.FileName}";
if (originalPath != null)
/*var str = $"Unable to load bundle file {fileName}";
if (parentPath != null)
{
str += $" from {Path.GetFileName(originalPath)}";
str += $" from {Path.GetFileName(parentPath)}";
}
Logger.Error(str, e);
Logger.Error(str);*/
}
finally
{
@@ -194,36 +180,36 @@ namespace AssetStudio
}
}
private void LoadWebFile(FileReader reader)
private void LoadWebFile(string fullName, EndianBinaryReader reader)
{
Logger.Info("Loading " + reader.FileName);
var fileName = Path.GetFileName(fullName);
Logger.Info("Loading " + fileName);
try
{
var webFile = new WebFile(reader);
foreach (var file in webFile.fileList)
{
var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), file.fileName);
var subReader = new FileReader(dummyPath, file.stream);
switch (subReader.FileType)
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
switch (CheckFileType(file.stream, out var fileReader))
{
case FileType.AssetsFile:
LoadAssetsFromMemory(subReader, reader.FullPath);
LoadAssetsFromMemory(dummyPath, fileReader, fullName);
break;
case FileType.BundleFile:
LoadBundleFile(subReader, reader.FullPath);
LoadBundleFile(dummyPath, fileReader, fullName);
break;
case FileType.WebFile:
LoadWebFile(subReader);
LoadWebFile(dummyPath, fileReader);
break;
case FileType.ResourceFile:
resourceFileReaders[file.fileName] = subReader; //TODO
resourceFileReaders.Add(file.fileName, fileReader);
break;
}
}
}
catch (Exception e)
catch
{
Logger.Error($"Error while reading web file {reader.FileName}", e);
//Logger.Error($"Unable to load web file {fileName}");
}
finally
{
@@ -231,18 +217,6 @@ namespace AssetStudio
}
}
public void CheckStrippedVersion(SerializedFile assetsFile)
{
if (assetsFile.IsVersionStripped && string.IsNullOrEmpty(SpecifyUnityVersion))
{
throw new Exception("The Unity version has been stripped, please set the version in the options");
}
if (!string.IsNullOrEmpty(SpecifyUnityVersion))
{
assetsFile.SetVersion(SpecifyUnityVersion);
}
}
public void Clear()
{
foreach (var assetsFile in assetsFileList)
@@ -359,9 +333,6 @@ namespace AssetStudio
case ClassIDType.VideoClip:
obj = new VideoClip(objectReader);
break;
case ClassIDType.ResourceManager:
obj = new ResourceManager(objectReader);
break;
default:
obj = new Object(objectReader);
break;
@@ -370,13 +341,13 @@ namespace AssetStudio
}
catch (Exception e)
{
var sb = new StringBuilder();
/*var sb = new StringBuilder();
sb.AppendLine("Unable to load object")
.AppendLine($"Assets {assetsFile.fileName}")
.AppendLine($"Type {objectReader.type}")
.AppendLine($"PathID {objectInfo.m_PathID}")
.Append(e);
Logger.Error(sb.ToString());
Logger.Error(sb.ToString());*/
}
Progress.Report(++i, progressCount);

View File

@@ -7,7 +7,7 @@ namespace AssetStudio
{
public enum BuildTarget
{
NoTarget = -2,
UnknownPlatform = 3716,
DashboardWidget = 1,
StandaloneOSX = 2,
StandaloneOSXPPC = 3,
@@ -42,12 +42,6 @@ namespace AssetStudio
WiiU,
tvOS,
Switch,
Lumin,
Stadia,
CloudRendering,
GameCoreXboxSeries,
GameCoreXboxOne,
PS5,
UnknownPlatform = 9999
NoTarget = -2
}
}

View File

@@ -41,37 +41,30 @@ namespace AssetStudio
public StreamFile[] fileList;
public BundleFile(FileReader reader)
public BundleFile(EndianBinaryReader reader, string path)
{
m_Header = new Header();
m_Header.signature = reader.ReadStringToNull();
m_Header.version = reader.ReadUInt32();
m_Header.unityVersion = reader.ReadStringToNull();
m_Header.unityRevision = reader.ReadStringToNull();
switch (m_Header.signature)
{
case "UnityArchive":
break; //TODO
case "UnityWeb":
case "UnityRaw":
if (m_Header.version == 6)
{
goto case "UnityFS";
}
ReadHeaderAndBlocksInfo(reader);
using (var blocksStream = CreateBlocksStream(reader.FullPath))
using (var blocksStream = CreateBlocksStream(path))
{
ReadBlocksAndDirectory(reader, blocksStream);
ReadFiles(blocksStream, reader.FullPath);
ReadFiles(blocksStream, path);
}
break;
case "UnityFS":
ReadHeader(reader);
ReadBlocksInfoAndDirectory(reader);
using (var blocksStream = CreateBlocksStream(reader.FullPath))
using (var blocksStream = CreateBlocksStream(path))
{
ReadBlocks(reader, blocksStream);
ReadFiles(blocksStream, reader.FullPath);
ReadFiles(blocksStream, path);
}
break;
}
@@ -80,13 +73,16 @@ namespace AssetStudio
private void ReadHeaderAndBlocksInfo(EndianBinaryReader reader)
{
var isCompressed = m_Header.signature == "UnityWeb";
m_Header.version = reader.ReadUInt32();
m_Header.unityVersion = reader.ReadStringToNull();
m_Header.unityRevision = reader.ReadStringToNull();
if (m_Header.version >= 4)
{
var hash = reader.ReadBytes(16);
var crc = reader.ReadUInt32();
}
var minimumStreamedBytes = reader.ReadUInt32();
m_Header.size = reader.ReadUInt32();
var headerSize = reader.ReadUInt32();
var numberOfLevelsToDownloadBeforeStreaming = reader.ReadUInt32();
var levelCount = reader.ReadInt32();
m_BlocksInfo = new StorageBlock[1];
@@ -111,7 +107,7 @@ namespace AssetStudio
{
var fileInfoHeaderSize = reader.ReadUInt32();
}
reader.Position = m_Header.size;
reader.Position = headerSize;
}
private Stream CreateBlocksStream(string path)
@@ -120,7 +116,7 @@ namespace AssetStudio
var uncompressedSizeSum = m_BlocksInfo.Sum(x => x.uncompressedSize);
if (uncompressedSizeSum >= int.MaxValue)
{
/*var memoryMappedFile = MemoryMappedFile.CreateNew(null, uncompressedSizeSum);
/*var memoryMappedFile = MemoryMappedFile.CreateNew(Path.GetFileName(path), uncompressedSizeSum);
assetsDataStream = memoryMappedFile.CreateViewStream();*/
blocksStream = new FileStream(path + ".temp", FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose);
}
@@ -171,15 +167,14 @@ namespace AssetStudio
var node = m_DirectoryInfo[i];
var file = new StreamFile();
fileList[i] = file;
file.path = node.path;
file.fileName = Path.GetFileName(node.path);
if (node.size >= int.MaxValue)
{
/*var memoryMappedFile = MemoryMappedFile.CreateNew(null, entryinfo_size);
/*var memoryMappedFile = MemoryMappedFile.CreateNew(file.fileName, entryinfo_size);
file.stream = memoryMappedFile.CreateViewStream();*/
var extractPath = path + "_unpacked" + Path.DirectorySeparatorChar;
Directory.CreateDirectory(extractPath);
file.stream = new FileStream(extractPath + file.fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
file.stream = File.Create(extractPath + file.fileName);
}
else
{
@@ -193,23 +188,18 @@ namespace AssetStudio
private void ReadHeader(EndianBinaryReader reader)
{
m_Header.version = reader.ReadUInt32();
m_Header.unityVersion = reader.ReadStringToNull();
m_Header.unityRevision = reader.ReadStringToNull();
m_Header.size = reader.ReadInt64();
m_Header.compressedBlocksInfoSize = reader.ReadUInt32();
m_Header.uncompressedBlocksInfoSize = reader.ReadUInt32();
m_Header.flags = reader.ReadUInt32();
if (m_Header.signature != "UnityFS")
{
reader.ReadByte();
}
}
private void ReadBlocksInfoAndDirectory(EndianBinaryReader reader)
{
byte[] blocksInfoBytes;
if (m_Header.version >= 7)
{
reader.AlignStream(16);
}
if ((m_Header.flags & 0x80) != 0) //kArchiveBlocksInfoAtTheEnd
{
var position = reader.Position;
@@ -219,6 +209,10 @@ namespace AssetStudio
}
else //0x40 kArchiveBlocksAndDirectoryInfoCombined
{
if (m_Header.version >= 7)
{
reader.AlignStream(16);
}
blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
}
var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes);
@@ -232,9 +226,7 @@ namespace AssetStudio
}
case 1: //LZMA
{
blocksInfoUncompresseddStream = new MemoryStream((int)(m_Header.uncompressedBlocksInfoSize));
SevenZipHelper.StreamDecompress(blocksInfoCompressedStream, blocksInfoUncompresseddStream, m_Header.compressedBlocksInfoSize, m_Header.uncompressedBlocksInfoSize);
blocksInfoUncompresseddStream.Position = 0;
blocksInfoUncompresseddStream = SevenZipHelper.StreamDecompress(blocksInfoCompressedStream);
blocksInfoCompressedStream.Close();
break;
}

View File

@@ -1,5 +1,4 @@
// official Class ID Reference: https://docs.unity3d.com/Manual/ClassIDReference.html
namespace AssetStudio
namespace AssetStudio
{
public enum ClassIDType
{
@@ -27,7 +26,7 @@ namespace AssetStudio
ParticleRenderer = 26,
Texture = 27,
Texture2D = 28,
OcclusionCullingSettings = 29,
SceneSettings = 29,
GraphicsSettings = 30,
MeshFilter = 33,
OcclusionPortal = 41,
@@ -50,7 +49,7 @@ namespace AssetStudio
PhysicsMaterial2D = 62,
MeshCollider = 64,
BoxCollider = 65,
CompositeCollider2D = 66,
SpriteCollider2D = 66,
EdgeCollider2D = 68,
CapsuleCollider2D = 70,
ComputeShader = 72,
@@ -93,7 +92,6 @@ namespace AssetStudio
FlareLayer = 124,
HaloLayer = 125,
NavMeshAreas = 126,
NavMeshProjectSettings = 126,
HaloManager = 127,
Font = 128,
PlayerSettings = 129,
@@ -160,7 +158,7 @@ namespace AssetStudio
BlendTree = 206,
Motion = 207,
NavMeshObstacle = 208,
SortingGroup = 210,
TerrainInstance = 210,
SpriteRenderer = 212,
Sprite = 213,
CachedSpriteAtlas = 214,
@@ -218,19 +216,15 @@ namespace AssetStudio
PerformanceReportingManager = 305,
UnityConnectSettings = 310,
AvatarMask = 319,
PlayableDirector = 320,
VideoPlayer = 328,
VideoClip = 329,
ParticleSystemForceField = 330,
SpriteMask = 331,
WorldAnchor = 362,
OcclusionCullingData = 363,
//kLargestRuntimeClassID = 364
SmallestEditorClassID = 1000,
PrefabInstance = 1001,
Prefab = 1001,
EditorExtensionImpl = 1002,
AssetImporter = 1003,
AssetDatabaseV1 = 1004,
AssetDatabase = 1004,
Mesh3DSImporter = 1005,
TextureImporter = 1006,
ShaderImporter = 1007,
@@ -265,13 +259,13 @@ namespace AssetStudio
AnimatorState = 1102,
HumanTemplate = 1105,
AnimatorStateMachine = 1107,
PreviewAnimationClip = 1108,
PreviewAssetType = 1108,
AnimatorTransition = 1109,
SpeedTreeImporter = 1110,
AnimatorTransitionBase = 1111,
SubstanceImporter = 1112,
LightmapParameters = 1113,
LightingDataAsset = 1120,
LightmapSnapshot = 1120,
GISRaster = 1121,
GISRasterImporter = 1122,
CadImporter = 1123,
@@ -282,98 +276,11 @@ namespace AssetStudio
ActivationLogComponent = 2000,
//kLargestEditorClassID = 2001
//kClassIdOutOfHierarchy = 100000
//int = 100000,
//bool = 100001,
//float = 100002,
MonoObject = 100003,
Collision = 100004,
Vector3f = 100005,
RootMotionData = 100006,
Collision2D = 100007,
AudioMixerLiveUpdateFloat = 100008,
AudioMixerLiveUpdateBool = 100009,
Polygon2D = 100010,
//void = 100011,
TilemapCollider2D = 19719996,
AssetImporterLog = 41386430,
VFXRenderer = 73398921,
SerializableManagedRefTestClass = 76251197,
Grid = 156049354,
ScenesUsingAssets = 156483287,
ArticulationBody = 171741748,
Preset = 181963792,
EmptyObject = 277625683,
IConstraint = 285090594,
TestObjectWithSpecialLayoutOne = 293259124,
AssemblyDefinitionReferenceImporter = 294290339,
SiblingDerived = 334799969,
TestObjectWithSerializedMapStringNonAlignedStruct = 342846651,
SubDerived = 367388927,
AssetImportInProgressProxy = 369655926,
PluginBuildInfo = 382020655,
EditorProjectAccess = 426301858,
PrefabImporter = 468431735,
TestObjectWithSerializedArray = 478637458,
TestObjectWithSerializedAnimationCurve = 478637459,
TilemapRenderer = 483693784,
ScriptableCamera = 488575907,
SpriteAtlasAsset = 612988286,
SpriteAtlasDatabase = 638013454,
AudioBuildInfo = 641289076,
CachedSpriteAtlasRuntimeData = 644342135,
RendererFake = 646504946,
AssemblyDefinitionReferenceAsset = 662584278,
BuiltAssetBundleInfoSet = 668709126,
SiblingDerived = 334799969,
SpriteAtlas = 687078895,
RayTracingShaderImporter = 747330370,
RayTracingShader = 825902497,
LightingSettings = 850595691,
PlatformModuleSetup = 877146078,
VersionControlSettings = 890905787,
AimConstraint = 895512359,
VFXManager = 937362698,
VisualEffectSubgraph = 994735392,
VisualEffectSubgraphOperator = 994735403,
VisualEffectSubgraphBlock = 994735404,
LocalizationImporter = 1027052791,
Derived = 1091556383,
PropertyModificationsTargetTestObject = 1111377672,
ReferencesArtifactGenerator = 1114811875,
AssemblyDefinitionAsset = 1152215463,
SceneVisibilityState = 1154873562,
LookAtConstraint = 1183024399,
SpriteAtlasImporter = 1210832254,
MultiArtifactTestImporter = 1223240404,
GameObjectRecorder = 1268269756,
LightingDataAssetParent = 1325145578,
PresetManager = 1386491679,
TestObjectWithSpecialLayoutTwo = 1392443030,
StreamingManager = 1403656975,
LowerResBlitTexture = 1480428607,
StreamingController = 1542919678,
RenderPassAttachment = 1571458007,
TestObjectVectorPairStringBool = 1628831178,
GridLayout = 1742807556,
AssemblyDefinitionImporter = 1766753193,
ParentConstraint = 1773428102,
FakeComponent = 1803986026,
PositionConstraint = 1818360608,
RotationConstraint = 1818360609,
ScaleConstraint = 1818360610,
Tilemap = 1839735485,
PackageManifest = 1896753125,
PackageManifestImporter = 1896753126,
TerrainLayer = 1953259897,
SpriteShapeRenderer = 1971053207,
NativeObjectType = 1977754360,
TestObjectWithSerializedMapStringBool = 1981279845,
SerializableManagedHost = 1995898324,
VisualEffectAsset = 2058629509,
VisualEffectImporter = 2058629510,
VisualEffectResource = 2058629511,
VisualEffectObject = 2059678085,
VisualEffect = 2083052967,
LocalizationAsset = 2083778819,
ScriptedImporter = 2089858483
RenderPassAttachment = 1571458007
}
}

View File

@@ -637,50 +637,6 @@ namespace AssetStudio
m_Binding = new ValueArrayConstant(reader);
}
}
public AnimationClipBindingConstant ConvertValueArrayToGenericBinding()
{
var bindings = new AnimationClipBindingConstant();
var genericBindings = new List<GenericBinding>();
var values = m_Binding;
for (int i = 0; i < values.m_ValueArray.Length;)
{
var curveID = values.m_ValueArray[i].m_ID;
var curveTypeID = values.m_ValueArray[i].m_TypeID;
var binding = new GenericBinding();
genericBindings.Add(binding);
if (curveTypeID == 4174552735) //CRC(PositionX))
{
binding.path = curveID;
binding.attribute = 1; //kBindTransformPosition
binding.typeID = ClassIDType.Transform;
i += 3;
}
else if (curveTypeID == 2211994246) //CRC(QuaternionX))
{
binding.path = curveID;
binding.attribute = 2; //kBindTransformRotation
binding.typeID = ClassIDType.Transform;
i += 4;
}
else if (curveTypeID == 1512518241) //CRC(ScaleX))
{
binding.path = curveID;
binding.attribute = 3; //kBindTransformScale
binding.typeID = ClassIDType.Transform;
i += 3;
}
else
{
binding.typeID = ClassIDType.Animator;
binding.path = 0;
binding.attribute = curveID;
i++;
}
}
bindings.genericBindings = genericBindings.ToArray();
return bindings;
}
}
public class ValueDelta
@@ -798,8 +754,6 @@ namespace AssetStudio
public byte customType;
public byte isPPtrCurve;
public GenericBinding() { }
public GenericBinding(ObjectReader reader)
{
var version = reader.version;
@@ -825,8 +779,6 @@ namespace AssetStudio
public GenericBinding[] genericBindings;
public PPtr<Object>[] pptrCurveMapping;
public AnimationClipBindingConstant() { }
public AnimationClipBindingConstant(ObjectReader reader)
{
int numBindings = reader.ReadInt32();

View File

@@ -31,10 +31,6 @@ namespace AssetStudio
if (version[0] >= 5) //5.0 and up
{
var m_LinearVelocityBlending = reader.ReadBoolean();
if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 2)) //2021.2 and up
{
var m_StabilizeFeet = reader.ReadBoolean();
}
reader.AlignStream();
}

View File

@@ -27,8 +27,8 @@ namespace AssetStudio
public AudioCompressionFormat m_CompressionFormat;
public string m_Source;
public long m_Offset; //ulong
public long m_Size; //ulong
public long m_Offset;
public long m_Size;
public ResourceReader m_AudioData;
public AudioClip(ObjectReader reader) : base(reader)
@@ -48,7 +48,7 @@ namespace AssetStudio
var tsize = m_Size % 4 != 0 ? m_Size + 4 - m_Size % 4 : m_Size;
if (reader.byteSize + reader.byteStart - reader.Position != tsize)
{
m_Offset = reader.ReadUInt32();
m_Offset = reader.ReadInt32();
m_Source = assetsFile.fullName + ".resS";
}
}
@@ -72,7 +72,6 @@ namespace AssetStudio
m_Legacy3D = reader.ReadBoolean();
reader.AlignStream();
//StreamedResource m_Resource
m_Source = reader.ReadAlignedString();
m_Offset = reader.ReadInt64();
m_Size = reader.ReadInt64();
@@ -82,11 +81,11 @@ namespace AssetStudio
ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_Source))
{
resourceReader = new ResourceReader(m_Source, assetsFile, m_Offset, m_Size);
resourceReader = new ResourceReader(m_Source, assetsFile, m_Offset, (int)m_Size);
}
else
{
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, m_Size);
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, (int)m_Size);
}
m_AudioData = resourceReader;
}

View File

@@ -19,14 +19,11 @@ namespace AssetStudio
public class UnityPropertySheet
{
public KeyValuePair<string, UnityTexEnv>[] m_TexEnvs;
public KeyValuePair<string, int>[] m_Ints;
public KeyValuePair<string, float>[] m_Floats;
public KeyValuePair<string, Color>[] m_Colors;
public UnityPropertySheet(ObjectReader reader)
{
var version = reader.version;
int m_TexEnvsSize = reader.ReadInt32();
m_TexEnvs = new KeyValuePair<string, UnityTexEnv>[m_TexEnvsSize];
for (int i = 0; i < m_TexEnvsSize; i++)
@@ -34,16 +31,6 @@ namespace AssetStudio
m_TexEnvs[i] = new KeyValuePair<string, UnityTexEnv>(reader.ReadAlignedString(), new UnityTexEnv(reader));
}
if (version[0] >= 2021) //2021.1 and up
{
int m_IntsSize = reader.ReadInt32();
m_Ints = new KeyValuePair<string, int>[m_IntsSize];
for (int i = 0; i < m_IntsSize; i++)
{
m_Ints[i] = new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32());
}
}
int m_FloatsSize = reader.ReadInt32();
m_Floats = new KeyValuePair<string, float>[m_FloatsSize];
for (int i = 0; i < m_FloatsSize; i++)
@@ -108,8 +95,6 @@ namespace AssetStudio
}
m_SavedProperties = new UnityPropertySheet(reader);
//vector m_BuildTextureStacks 2020 and up
}
}
}

View File

@@ -174,7 +174,7 @@ namespace AssetStudio
GetStreams(version);
}
m_DataSize = reader.ReadUInt8Array();
m_DataSize = reader.ReadBytes(reader.ReadInt32());
reader.AlignStream();
}
@@ -195,7 +195,7 @@ namespace AssetStudio
if (m_Channel.dimension > 0)
{
chnMask |= 1u << chn;
stride += m_Channel.dimension * MeshHelper.GetFormatSize(MeshHelper.ToVertexFormat(m_Channel.format, version));
stride += m_Channel.dimension * MeshHelper.GetFormatSize(version, m_Channel.format);
}
}
}
@@ -253,7 +253,7 @@ namespace AssetStudio
m_Channel.dimension = 4;
break;
}
offset += (byte)(m_Channel.dimension * MeshHelper.GetFormatSize(MeshHelper.ToVertexFormat(m_Channel.format, version)));
offset += (byte)(m_Channel.dimension * MeshHelper.GetFormatSize(version, m_Channel.format));
}
}
}
@@ -446,7 +446,7 @@ namespace AssetStudio
public sealed class Mesh : NamedObject
{
private bool m_Use16BitIndices = true;
private bool m_Use16BitIndices = true; //3.5.0 and newer always uses 16bit indices;
public SubMesh[] m_SubMeshes;
private uint[] m_IndexBuffer;
public BlendShapeData m_Shapes;
@@ -550,7 +550,6 @@ namespace AssetStudio
((version[0] == 2017 && version[1] == 3) && m_MeshCompression == 0))//2017.3.xfx with no compression
{
var m_IndexFormat = reader.ReadInt32();
m_Use16BitIndices = m_IndexFormat == 0;
}
int m_IndexBuffer_size = reader.ReadInt32();
@@ -653,9 +652,9 @@ namespace AssetStudio
if (version[0] >= 5) //5.0 and up
{
var m_BakedConvexCollisionMesh = reader.ReadUInt8Array();
var m_BakedConvexCollisionMesh = reader.ReadBytes(reader.ReadInt32());
reader.AlignStream();
var m_BakedTriangleCollisionMesh = reader.ReadUInt8Array();
var m_BakedTriangleCollisionMesh = reader.ReadBytes(reader.ReadInt32());
reader.AlignStream();
}
@@ -681,7 +680,7 @@ namespace AssetStudio
{
if (m_VertexData.m_VertexCount > 0)
{
var resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size);
var resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, (int)m_StreamData.size);
m_VertexData.m_DataSize = resourceReader.GetData();
}
}
@@ -711,13 +710,12 @@ namespace AssetStudio
var channelMask = new BitArray(new[] { (int)m_Stream.channelMask });
if (channelMask.Get(chn))
{
if (version[0] < 2018 && chn == 2 && m_Channel.format == 2) //kShaderChannelColor && kChannelFormatColor
if (version[0] < 2018 && chn == 2 && m_Channel.format == 2)
{
m_Channel.dimension = 4;
}
var vertexFormat = MeshHelper.ToVertexFormat(m_Channel.format, version);
var componentByteSize = (int)MeshHelper.GetFormatSize(vertexFormat);
var componentByteSize = (int)MeshHelper.GetFormatSize(version, m_Channel.format);
var componentBytes = new byte[m_VertexCount * m_Channel.dimension * componentByteSize];
for (int v = 0; v < m_VertexCount; v++)
{
@@ -742,10 +740,10 @@ namespace AssetStudio
int[] componentsIntArray = null;
float[] componentsFloatArray = null;
if (MeshHelper.IsIntFormat(vertexFormat))
componentsIntArray = MeshHelper.BytesToIntArray(componentBytes, vertexFormat);
if (MeshHelper.IsIntFormat(version, m_Channel.format))
componentsIntArray = MeshHelper.BytesToIntArray(componentBytes, componentByteSize);
else
componentsFloatArray = MeshHelper.BytesToFloatArray(componentBytes, vertexFormat);
componentsFloatArray = MeshHelper.BytesToFloatArray(componentBytes, componentByteSize);
if (version[0] >= 2018)
{
@@ -1191,7 +1189,7 @@ namespace AssetStudio
public static class MeshHelper
{
public enum VertexChannelFormat
private enum VertexChannelFormat
{
kChannelFormatFloat,
kChannelFormatFloat16,
@@ -1200,7 +1198,7 @@ namespace AssetStudio
kChannelFormatUInt32
}
public enum VertexFormat2017
private enum VertexFormat
{
kVertexFormatFloat,
kVertexFormatFloat16,
@@ -1217,7 +1215,7 @@ namespace AssetStudio
kVertexFormatSInt32
}
public enum VertexFormat
private enum VertexFormatV2019
{
kVertexFormatFloat,
kVertexFormatFloat16,
@@ -1233,146 +1231,147 @@ namespace AssetStudio
kVertexFormatSInt32
}
public static VertexFormat ToVertexFormat(int format, int[] version)
public static uint GetFormatSize(int[] version, int format)
{
if (version[0] < 2017)
{
switch ((VertexChannelFormat)format)
{
case VertexChannelFormat.kChannelFormatFloat:
return VertexFormat.kVertexFormatFloat;
return 4u;
case VertexChannelFormat.kChannelFormatFloat16:
return VertexFormat.kVertexFormatFloat16;
return 2u;
case VertexChannelFormat.kChannelFormatColor: //in 4.x is size 4
return VertexFormat.kVertexFormatUNorm8;
return 1u;
case VertexChannelFormat.kChannelFormatByte:
return VertexFormat.kVertexFormatUInt8;
return 1u;
case VertexChannelFormat.kChannelFormatUInt32: //in 5.x
return VertexFormat.kVertexFormatUInt32;
return 4u;
default:
throw new ArgumentOutOfRangeException(nameof(format), format, null);
}
}
else if (version[0] < 2019)
{
switch ((VertexFormat2017)format)
switch ((VertexFormat)format)
{
case VertexFormat2017.kVertexFormatFloat:
return VertexFormat.kVertexFormatFloat;
case VertexFormat2017.kVertexFormatFloat16:
return VertexFormat.kVertexFormatFloat16;
case VertexFormat2017.kVertexFormatColor:
case VertexFormat2017.kVertexFormatUNorm8:
return VertexFormat.kVertexFormatUNorm8;
case VertexFormat2017.kVertexFormatSNorm8:
return VertexFormat.kVertexFormatSNorm8;
case VertexFormat2017.kVertexFormatUNorm16:
return VertexFormat.kVertexFormatUNorm16;
case VertexFormat2017.kVertexFormatSNorm16:
return VertexFormat.kVertexFormatSNorm16;
case VertexFormat2017.kVertexFormatUInt8:
return VertexFormat.kVertexFormatUInt8;
case VertexFormat2017.kVertexFormatSInt8:
return VertexFormat.kVertexFormatSInt8;
case VertexFormat2017.kVertexFormatUInt16:
return VertexFormat.kVertexFormatUInt16;
case VertexFormat2017.kVertexFormatSInt16:
return VertexFormat.kVertexFormatSInt16;
case VertexFormat2017.kVertexFormatUInt32:
return VertexFormat.kVertexFormatUInt32;
case VertexFormat2017.kVertexFormatSInt32:
return VertexFormat.kVertexFormatSInt32;
case VertexFormat.kVertexFormatFloat:
return 4u;
case VertexFormat.kVertexFormatFloat16:
return 2u;
case VertexFormat.kVertexFormatColor:
return 1u;
case VertexFormat.kVertexFormatUNorm8:
return 1u;
case VertexFormat.kVertexFormatSNorm8:
return 1u;
case VertexFormat.kVertexFormatUNorm16:
return 2u;
case VertexFormat.kVertexFormatSNorm16:
return 2u;
case VertexFormat.kVertexFormatUInt8:
return 1u;
case VertexFormat.kVertexFormatSInt8:
return 1u;
case VertexFormat.kVertexFormatUInt16:
return 2u;
case VertexFormat.kVertexFormatSInt16:
return 2u;
case VertexFormat.kVertexFormatUInt32:
return 4u;
case VertexFormat.kVertexFormatSInt32:
return 4u;
default:
throw new ArgumentOutOfRangeException(nameof(format), format, null);
}
}
else
{
return (VertexFormat)format;
}
}
public static uint GetFormatSize(VertexFormat format)
{
switch (format)
{
case VertexFormat.kVertexFormatFloat:
case VertexFormat.kVertexFormatUInt32:
case VertexFormat.kVertexFormatSInt32:
return 4u;
case VertexFormat.kVertexFormatFloat16:
case VertexFormat.kVertexFormatUNorm16:
case VertexFormat.kVertexFormatSNorm16:
case VertexFormat.kVertexFormatUInt16:
case VertexFormat.kVertexFormatSInt16:
return 2u;
case VertexFormat.kVertexFormatUNorm8:
case VertexFormat.kVertexFormatSNorm8:
case VertexFormat.kVertexFormatUInt8:
case VertexFormat.kVertexFormatSInt8:
return 1u;
default:
throw new ArgumentOutOfRangeException(nameof(format), format, null);
}
}
public static bool IsIntFormat(VertexFormat format)
{
return format >= VertexFormat.kVertexFormatUInt8;
}
public static float[] BytesToFloatArray(byte[] inputBytes, VertexFormat format)
{
var size = GetFormatSize(format);
var len = inputBytes.Length / size;
var result = new float[len];
for (int i = 0; i < len; i++)
{
switch (format)
switch ((VertexFormatV2019)format)
{
case VertexFormat.kVertexFormatFloat:
result[i] = BitConverter.ToSingle(inputBytes, i * 4);
case VertexFormatV2019.kVertexFormatFloat:
return 4u;
case VertexFormatV2019.kVertexFormatFloat16:
return 2u;
case VertexFormatV2019.kVertexFormatUNorm8:
return 1u;
case VertexFormatV2019.kVertexFormatSNorm8:
return 1u;
case VertexFormatV2019.kVertexFormatUNorm16:
return 2u;
case VertexFormatV2019.kVertexFormatSNorm16:
return 2u;
case VertexFormatV2019.kVertexFormatUInt8:
return 1u;
case VertexFormatV2019.kVertexFormatSInt8:
return 1u;
case VertexFormatV2019.kVertexFormatUInt16:
return 2u;
case VertexFormatV2019.kVertexFormatSInt16:
return 2u;
case VertexFormatV2019.kVertexFormatUInt32:
return 4u;
case VertexFormatV2019.kVertexFormatSInt32:
return 4u;
default:
throw new ArgumentOutOfRangeException(nameof(format), format, null);
}
}
}
public static bool IsIntFormat(int[] version, int format)
{
if (version[0] < 2017)
{
return format == 4;
}
else if (version[0] < 2019)
{
return format >= 7;
}
else
{
return format >= 6;
}
}
public static float[] BytesToFloatArray(byte[] inputBytes, int size)
{
var result = new float[inputBytes.Length / size];
for (int i = 0; i < inputBytes.Length / size; i++)
{
var value = 0f;
switch (size)
{
case 1:
value = inputBytes[i] / 255.0f;
break;
case VertexFormat.kVertexFormatFloat16:
result[i] = Half.ToHalf(inputBytes, i * 2);
case 2:
value = Half.ToHalf(inputBytes, i * 2);
break;
case VertexFormat.kVertexFormatUNorm8:
result[i] = inputBytes[i] / 255f;
break;
case VertexFormat.kVertexFormatSNorm8:
result[i] = Math.Max((sbyte)inputBytes[i] / 127f, -1f);
break;
case VertexFormat.kVertexFormatUNorm16:
result[i] = BitConverter.ToUInt16(inputBytes, i * 2) / 65535f;
break;
case VertexFormat.kVertexFormatSNorm16:
result[i] = Math.Max(BitConverter.ToInt16(inputBytes, i * 2) / 32767f, -1f);
case 4:
value = BitConverter.ToSingle(inputBytes, i * 4);
break;
}
result[i] = value;
}
return result;
}
public static int[] BytesToIntArray(byte[] inputBytes, VertexFormat format)
public static int[] BytesToIntArray(byte[] inputBytes, int size)
{
var size = GetFormatSize(format);
var len = inputBytes.Length / size;
var result = new int[len];
for (int i = 0; i < len; i++)
var result = new int[inputBytes.Length / size];
for (int i = 0; i < inputBytes.Length / size; i++)
{
switch (format)
switch (size)
{
case VertexFormat.kVertexFormatUInt8:
case VertexFormat.kVertexFormatSInt8:
case 1:
result[i] = inputBytes[i];
break;
case VertexFormat.kVertexFormatUInt16:
case VertexFormat.kVertexFormatSInt16:
case 2:
result[i] = BitConverter.ToInt16(inputBytes, i * 2);
break;
case VertexFormat.kVertexFormatUInt32:
case VertexFormat.kVertexFormatSInt32:
case 4:
result[i] = BitConverter.ToInt32(inputBytes, i * 4);
break;
}

View File

@@ -8,7 +8,7 @@ namespace AssetStudio
public sealed class MonoScript : NamedObject
{
public string m_ClassName;
public string m_Namespace;
public string m_Namespace = string.Empty;
public string m_AssemblyName;
public MonoScript(ObjectReader reader) : base(reader)

View File

@@ -15,7 +15,7 @@ namespace AssetStudio
var m_Loop = reader.ReadBoolean();
reader.AlignStream();
m_AudioClip = new PPtr<AudioClip>(reader);
m_MovieData = reader.ReadUInt8Array();
m_MovieData = reader.ReadBytes(reader.ReadInt32());
}
}
}

View File

@@ -1,4 +1,7 @@
using System.Collections.Specialized;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
@@ -33,38 +36,19 @@ namespace AssetStudio
}
}
protected bool HasStructMember(string name)
{
return serializedType?.m_Nodes != null && serializedType.m_Nodes.Any(x => x.m_Name == name);
}
public string Dump()
{
if (serializedType?.m_Type != null)
reader.Reset();
if (serializedType?.m_Nodes != null)
{
return TypeTreeHelper.ReadTypeString(serializedType.m_Type, reader);
}
return null;
}
public string Dump(TypeTree m_Type)
{
if (m_Type != null)
{
return TypeTreeHelper.ReadTypeString(m_Type, reader);
}
return null;
}
public OrderedDictionary ToType()
{
if (serializedType?.m_Type != null)
{
return TypeTreeHelper.ReadType(serializedType.m_Type, reader);
}
return null;
}
public OrderedDictionary ToType(TypeTree m_Type)
{
if (m_Type != null)
{
return TypeTreeHelper.ReadType(m_Type, reader);
var sb = new StringBuilder();
TypeTreeHelper.ReadTypeString(sb, serializedType.m_Nodes, reader);
return sb.ToString();
}
return null;
}

View File

@@ -13,7 +13,7 @@ namespace AssetStudio
public PPtr(ObjectReader reader)
{
m_FileID = reader.ReadInt32();
m_PathID = reader.m_Version < SerializedFileFormatVersion.kUnknown_14 ? reader.ReadInt32() : reader.ReadInt64();
m_PathID = reader.m_Version < 14 ? reader.ReadInt32() : reader.ReadInt64();
assetsFile = reader.assetsFile;
}

View File

@@ -43,10 +43,6 @@ namespace AssetStudio
{
var m_DynamicOccludee = reader.ReadByte();
}
if (version[0] >= 2021) //2021.1 and up
{
var m_StaticShadowCaster = reader.ReadByte();
}
var m_MotionVectors = reader.ReadByte();
var m_LightProbeUsage = reader.ReadByte();
var m_ReflectionProbeUsage = reader.ReadByte();
@@ -54,10 +50,6 @@ namespace AssetStudio
{
var m_RayTracingMode = reader.ReadByte();
}
if (version[0] >= 2020) //2020.1 and up
{
var m_RayTraceProcedural = reader.ReadByte();
}
reader.AlignStream();
}
else

View File

@@ -1,19 +0,0 @@
using System.Collections.Generic;
namespace AssetStudio
{
public class ResourceManager : Object
{
public KeyValuePair<string, PPtr<Object>>[] m_Container;
public ResourceManager(ObjectReader reader) : base(reader)
{
var m_ContainerSize = reader.ReadInt32();
m_Container = new KeyValuePair<string, PPtr<Object>>[m_ContainerSize];
for (int i = 0; i < m_ContainerSize; i++)
{
m_Container[i] = new KeyValuePair<string, PPtr<Object>>(reader.ReadAlignedString(), new PPtr<Object>(reader));
}
}
}
}

View File

@@ -5,16 +5,6 @@ using System.Linq;
namespace AssetStudio
{
public class Hash128
{
public byte[] bytes;
public Hash128(BinaryReader reader)
{
bytes = reader.ReadBytes(16);
}
}
public class StructParameter
{
public MatrixParameter[] m_MatrixParams;
@@ -211,7 +201,6 @@ namespace AssetStudio
public SerializedShaderFloatValue zTest;
public SerializedShaderFloatValue zWrite;
public SerializedShaderFloatValue culling;
public SerializedShaderFloatValue conservative;
public SerializedShaderFloatValue offsetFactor;
public SerializedShaderFloatValue offsetUnits;
public SerializedShaderFloatValue alphaToMask;
@@ -250,10 +239,6 @@ namespace AssetStudio
zTest = new SerializedShaderFloatValue(reader);
zWrite = new SerializedShaderFloatValue(reader);
culling = new SerializedShaderFloatValue(reader);
if (version[0] >= 2020) //2020.1 and up
{
conservative = new SerializedShaderFloatValue(reader);
}
offsetFactor = new SerializedShaderFloatValue(reader);
offsetUnits = new SerializedShaderFloatValue(reader);
alphaToMask = new SerializedShaderFloatValue(reader);
@@ -372,18 +357,11 @@ namespace AssetStudio
{
public int m_NameIndex;
public int m_Index;
public int m_ArraySize;
public BufferBinding(ObjectReader reader)
public BufferBinding(BinaryReader reader)
{
var version = reader.version;
m_NameIndex = reader.ReadInt32();
m_Index = reader.ReadInt32();
if (version[0] >= 2020) //2020.1 and up
{
m_ArraySize = reader.ReadInt32();
}
}
}
@@ -394,7 +372,6 @@ namespace AssetStudio
public VectorParameter[] m_VectorParams;
public StructParameter[] m_StructParams;
public int m_Size;
public bool m_IsPartialCB;
public ConstantBuffer(ObjectReader reader)
{
@@ -425,15 +402,6 @@ namespace AssetStudio
}
}
m_Size = reader.ReadInt32();
if ((version[0] == 2020 && version[1] > 3) ||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
(version[0] == 2021 && version[1] > 1) ||
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 and up
{
m_IsPartialCB = reader.ReadBoolean();
reader.AlignStream();
}
}
}
@@ -479,16 +447,16 @@ namespace AssetStudio
kShaderGpuProgramMetalVS = 23,
kShaderGpuProgramMetalFS = 24,
kShaderGpuProgramSPIRV = 25,
kShaderGpuProgramConsoleVS = 26,
kShaderGpuProgramConsoleFS = 27,
kShaderGpuProgramConsoleHS = 28,
kShaderGpuProgramConsoleDS = 29,
kShaderGpuProgramConsoleGS = 30,
kShaderGpuProgramRayTracing = 31,
kShaderGpuProgramConsole = 26
};
public class SerializedProgramParameters
public class SerializedSubProgram
{
public uint m_BlobIndex;
public ParserBindChannels m_Channels;
public ushort[] m_KeywordIndices;
public sbyte m_ShaderHardwareTier;
public ShaderGpuProgramType m_GpuProgramType;
public VectorParameter[] m_VectorParams;
public MatrixParameter[] m_MatrixParams;
public TextureParameter[] m_TextureParams;
@@ -498,8 +466,33 @@ namespace AssetStudio
public UAVParameter[] m_UAVParams;
public SamplerParameter[] m_Samplers;
public SerializedProgramParameters(ObjectReader reader)
public SerializedSubProgram(ObjectReader reader)
{
var version = reader.version;
m_BlobIndex = reader.ReadUInt32();
m_Channels = new ParserBindChannels(reader);
if (version[0] >= 2019) //2019 and up
{
var m_GlobalKeywordIndices = reader.ReadUInt16Array();
reader.AlignStream();
var m_LocalKeywordIndices = reader.ReadUInt16Array();
reader.AlignStream();
}
else
{
m_KeywordIndices = reader.ReadUInt16Array();
if (version[0] >= 2017) //2017 and up
{
reader.AlignStream();
}
}
m_ShaderHardwareTier = reader.ReadSByte();
m_GpuProgramType = (ShaderGpuProgramType)reader.ReadSByte();
reader.AlignStream();
int numVectorParams = reader.ReadInt32();
m_VectorParams = new VectorParameter[numVectorParams];
for (int i = 0; i < numVectorParams; i++)
@@ -549,138 +542,18 @@ namespace AssetStudio
m_UAVParams[i] = new UAVParameter(reader);
}
int numSamplers = reader.ReadInt32();
m_Samplers = new SamplerParameter[numSamplers];
for (int i = 0; i < numSamplers; i++)
if (version[0] >= 2017) //2017 and up
{
m_Samplers[i] = new SamplerParameter(reader);
}
}
}
public class SerializedSubProgram
{
public uint m_BlobIndex;
public ParserBindChannels m_Channels;
public ushort[] m_KeywordIndices;
public sbyte m_ShaderHardwareTier;
public ShaderGpuProgramType m_GpuProgramType;
public SerializedProgramParameters m_Parameters;
public VectorParameter[] m_VectorParams;
public MatrixParameter[] m_MatrixParams;
public TextureParameter[] m_TextureParams;
public BufferBinding[] m_BufferParams;
public ConstantBuffer[] m_ConstantBuffers;
public BufferBinding[] m_ConstantBufferBindings;
public UAVParameter[] m_UAVParams;
public SamplerParameter[] m_Samplers;
public SerializedSubProgram(ObjectReader reader)
{
var version = reader.version;
m_BlobIndex = reader.ReadUInt32();
m_Channels = new ParserBindChannels(reader);
if ((version[0] >= 2019 && version[0] < 2021) || (version[0] == 2021 && version[1] < 2)) //2019 ~2021.1
{
var m_GlobalKeywordIndices = reader.ReadUInt16Array();
reader.AlignStream();
var m_LocalKeywordIndices = reader.ReadUInt16Array();
reader.AlignStream();
}
else
{
m_KeywordIndices = reader.ReadUInt16Array();
if (version[0] >= 2017) //2017 and up
int numSamplers = reader.ReadInt32();
m_Samplers = new SamplerParameter[numSamplers];
for (int i = 0; i < numSamplers; i++)
{
reader.AlignStream();
m_Samplers[i] = new SamplerParameter(reader);
}
}
m_ShaderHardwareTier = reader.ReadSByte();
m_GpuProgramType = (ShaderGpuProgramType)reader.ReadSByte();
reader.AlignStream();
if ((version[0] == 2020 && version[1] > 3) ||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
(version[0] == 2021 && version[1] > 1) ||
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 and up
{
m_Parameters = new SerializedProgramParameters(reader);
}
else
{
int numVectorParams = reader.ReadInt32();
m_VectorParams = new VectorParameter[numVectorParams];
for (int i = 0; i < numVectorParams; i++)
{
m_VectorParams[i] = new VectorParameter(reader);
}
int numMatrixParams = reader.ReadInt32();
m_MatrixParams = new MatrixParameter[numMatrixParams];
for (int i = 0; i < numMatrixParams; i++)
{
m_MatrixParams[i] = new MatrixParameter(reader);
}
int numTextureParams = reader.ReadInt32();
m_TextureParams = new TextureParameter[numTextureParams];
for (int i = 0; i < numTextureParams; i++)
{
m_TextureParams[i] = new TextureParameter(reader);
}
int numBufferParams = reader.ReadInt32();
m_BufferParams = new BufferBinding[numBufferParams];
for (int i = 0; i < numBufferParams; i++)
{
m_BufferParams[i] = new BufferBinding(reader);
}
int numConstantBuffers = reader.ReadInt32();
m_ConstantBuffers = new ConstantBuffer[numConstantBuffers];
for (int i = 0; i < numConstantBuffers; i++)
{
m_ConstantBuffers[i] = new ConstantBuffer(reader);
}
int numConstantBufferBindings = reader.ReadInt32();
m_ConstantBufferBindings = new BufferBinding[numConstantBufferBindings];
for (int i = 0; i < numConstantBufferBindings; i++)
{
m_ConstantBufferBindings[i] = new BufferBinding(reader);
}
int numUAVParams = reader.ReadInt32();
m_UAVParams = new UAVParameter[numUAVParams];
for (int i = 0; i < numUAVParams; i++)
{
m_UAVParams[i] = new UAVParameter(reader);
}
if (version[0] >= 2017) //2017 and up
{
int numSamplers = reader.ReadInt32();
m_Samplers = new SamplerParameter[numSamplers];
for (int i = 0; i < numSamplers; i++)
{
m_Samplers[i] = new SamplerParameter(reader);
}
}
}
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
{
if (version[0] >= 2021) //2021.1 and up
{
var m_ShaderRequirements = reader.ReadInt64();
}
else
{
var m_ShaderRequirements = reader.ReadInt32();
}
var m_ShaderRequirements = reader.ReadInt32();
}
}
}
@@ -688,26 +561,15 @@ namespace AssetStudio
public class SerializedProgram
{
public SerializedSubProgram[] m_SubPrograms;
public SerializedProgramParameters m_CommonParameters;
public SerializedProgram(ObjectReader reader)
{
var version = reader.version;
int numSubPrograms = reader.ReadInt32();
m_SubPrograms = new SerializedSubProgram[numSubPrograms];
for (int i = 0; i < numSubPrograms; i++)
{
m_SubPrograms[i] = new SerializedSubProgram(reader);
}
if ((version[0] == 2020 && version[1] > 3) ||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
(version[0] == 2021 && version[1] > 1) ||
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 and up
{
m_CommonParameters = new SerializedProgramParameters(reader);
}
}
}
@@ -720,10 +582,6 @@ namespace AssetStudio
public class SerializedPass
{
public Hash128[] m_EditorDataHash;
public byte[] m_Platforms;
public ushort[] m_LocalKeywordMask;
public ushort[] m_GlobalKeywordMask;
public KeyValuePair<string, int>[] m_NameIndices;
public PassType m_Type;
public SerializedShaderState m_State;
@@ -739,32 +597,11 @@ namespace AssetStudio
public string m_Name;
public string m_TextureName;
public SerializedTagMap m_Tags;
public ushort[] m_SerializedKeywordStateMask;
public SerializedPass(ObjectReader reader)
{
var version = reader.version;
if (version[0] > 2020 || (version[0] == 2020 && version[1] >= 2)) //2020.2 and up
{
int numEditorDataHash = reader.ReadInt32();
m_EditorDataHash = new Hash128[numEditorDataHash];
for (int i = 0; i < numEditorDataHash; i++)
{
m_EditorDataHash[i] = new Hash128(reader);
}
reader.AlignStream();
m_Platforms = reader.ReadUInt8Array();
reader.AlignStream();
if (version[0] < 2021 || (version[0] == 2021 && version[1] < 2)) //2021.1 and down
{
m_LocalKeywordMask = reader.ReadUInt16Array();
reader.AlignStream();
m_GlobalKeywordMask = reader.ReadUInt16Array();
reader.AlignStream();
}
}
int numIndices = reader.ReadInt32();
m_NameIndices = new KeyValuePair<string, int>[numIndices];
for (int i = 0; i < numIndices; i++)
@@ -794,11 +631,6 @@ namespace AssetStudio
m_Name = reader.ReadAlignedString();
m_TextureName = reader.ReadAlignedString();
m_Tags = new SerializedTagMap(reader);
if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 2)) //2021.2 and up
{
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
reader.AlignStream();
}
}
}
@@ -849,35 +681,18 @@ namespace AssetStudio
}
}
public class SerializedCustomEditorForRenderPipeline
{
public string customEditorName;
public string renderPipelineType;
public SerializedCustomEditorForRenderPipeline(BinaryReader reader)
{
customEditorName = reader.ReadAlignedString();
renderPipelineType = reader.ReadAlignedString();
}
}
public class SerializedShader
{
public SerializedProperties m_PropInfo;
public SerializedSubShader[] m_SubShaders;
public string[] m_KeywordNames;
public byte[] m_KeywordFlags;
public string m_Name;
public string m_CustomEditorName;
public string m_FallbackName;
public SerializedShaderDependency[] m_Dependencies;
public SerializedCustomEditorForRenderPipeline[] m_CustomEditorForRenderPipelines;
public bool m_DisableNoSubshadersMessage;
public SerializedShader(ObjectReader reader)
{
var version = reader.version;
m_PropInfo = new SerializedProperties(reader);
int numSubShaders = reader.ReadInt32();
@@ -887,13 +702,6 @@ namespace AssetStudio
m_SubShaders[i] = new SerializedSubShader(reader);
}
if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 2)) //2021.2 and up
{
m_KeywordNames = reader.ReadStringArray();
m_KeywordFlags = reader.ReadUInt8Array();
reader.AlignStream();
}
m_Name = reader.ReadAlignedString();
m_CustomEditorName = reader.ReadAlignedString();
m_FallbackName = reader.ReadAlignedString();
@@ -905,16 +713,6 @@ namespace AssetStudio
m_Dependencies[i] = new SerializedShaderDependency(reader);
}
if (version[0] >= 2021) //2021.1 and up
{
int m_CustomEditorForRenderPipelinesSize = reader.ReadInt32();
m_CustomEditorForRenderPipelines = new SerializedCustomEditorForRenderPipeline[m_CustomEditorForRenderPipelinesSize];
for (int i = 0; i < m_CustomEditorForRenderPipelinesSize; i++)
{
m_CustomEditorForRenderPipelines[i] = new SerializedCustomEditorForRenderPipeline(reader);
}
}
m_DisableNoSubshadersMessage = reader.ReadBoolean();
reader.AlignStream();
}
@@ -943,11 +741,7 @@ namespace AssetStudio
kShaderCompPlatformWiiU = 17,
kShaderCompPlatformVulkan = 18,
kShaderCompPlatformSwitch = 19,
kShaderCompPlatformXboxOneD3D12 = 20,
kShaderCompPlatformGameCoreXboxOne = 21,
kShaderCompPlatformGameCoreScarlett = 22,
kShaderCompPlatformPS5 = 23,
kShaderCompPlatformPS5NGGC = 24,
kShaderCompPlatformXboxOneD3D12 = 20
};
public class Shader : NamedObject
@@ -982,37 +776,17 @@ namespace AssetStudio
compressedLengths = reader.ReadUInt32Array();
decompressedLengths = reader.ReadUInt32Array();
}
compressedBlob = reader.ReadUInt8Array();
reader.AlignStream();
var m_DependenciesCount = reader.ReadInt32();
for (int i = 0; i < m_DependenciesCount; i++)
{
new PPtr<Shader>(reader);
}
if (version[0] >= 2018)
{
var m_NonModifiableTexturesCount = reader.ReadInt32();
for (int i = 0; i < m_NonModifiableTexturesCount; i++)
{
var first = reader.ReadAlignedString();
new PPtr<Texture>(reader);
}
}
var m_ShaderIsBaked = reader.ReadBoolean();
reader.AlignStream();
compressedBlob = reader.ReadBytes(reader.ReadInt32());
}
else
{
m_Script = reader.ReadUInt8Array();
m_Script = reader.ReadBytes(reader.ReadInt32());
reader.AlignStream();
var m_PathName = reader.ReadAlignedString();
if (version[0] == 5 && version[1] >= 3) //5.3 - 5.4
{
decompressedSize = reader.ReadUInt32();
m_SubProgramBlob = reader.ReadUInt8Array();
m_SubProgramBlob = reader.ReadBytes(reader.ReadInt32());
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
namespace AssetStudio
@@ -87,7 +88,7 @@ namespace AssetStudio
public ushort[] indices;
public Matrix4x4[] m_Bindpose;
public BoneWeights4[] m_SourceSkin;
public Rectf textureRect;
public RectangleF textureRect;
public Vector2 textureRectOffset;
public Vector2 atlasRectOffset;
public SpriteSettings settingsRaw;
@@ -123,7 +124,7 @@ namespace AssetStudio
m_SubMeshes[i] = new SubMesh(reader);
}
m_IndexBuffer = reader.ReadUInt8Array();
m_IndexBuffer = reader.ReadBytes(reader.ReadInt32());
reader.AlignStream();
m_VertexData = new VertexData(reader);
@@ -155,7 +156,7 @@ namespace AssetStudio
}
}
textureRect = new Rectf(reader);
textureRect = reader.ReadRectangleF();
textureRectOffset = reader.ReadVector2();
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
@@ -175,25 +176,9 @@ namespace AssetStudio
}
}
public class Rectf
{
public float x;
public float y;
public float width;
public float height;
public Rectf(BinaryReader reader)
{
x = reader.ReadSingle();
y = reader.ReadSingle();
width = reader.ReadSingle();
height = reader.ReadSingle();
}
}
public sealed class Sprite : NamedObject
{
public Rectf m_Rect;
public RectangleF m_Rect;
public Vector2 m_Offset;
public Vector4 m_Border;
public float m_PixelsToUnits;
@@ -208,7 +193,7 @@ namespace AssetStudio
public Sprite(ObjectReader reader) : base(reader)
{
m_Rect = new Rectf(reader);
m_Rect = reader.ReadRectangleF();
m_Offset = reader.ReadVector2();
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
{

View File

@@ -7,20 +7,19 @@ namespace AssetStudio
{
public PPtr<Texture2D> texture;
public PPtr<Texture2D> alphaTexture;
public Rectf textureRect;
public System.Drawing.RectangleF textureRect;
public Vector2 textureRectOffset;
public Vector2 atlasRectOffset;
public Vector4 uvTransform;
public float downscaleMultiplier;
public SpriteSettings settingsRaw;
public SecondarySpriteTexture[] secondaryTextures;
public SpriteAtlasData(ObjectReader reader)
{
var version = reader.version;
texture = new PPtr<Texture2D>(reader);
alphaTexture = new PPtr<Texture2D>(reader);
textureRect = new Rectf(reader);
textureRect = reader.ReadRectangleF();
textureRectOffset = reader.ReadVector2();
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
{
@@ -29,16 +28,6 @@ namespace AssetStudio
uvTransform = reader.ReadVector4();
downscaleMultiplier = reader.ReadSingle();
settingsRaw = new SpriteSettings(reader);
if (version[0] > 2020 || (version[0] == 2020 && version[1] >= 2)) //2020.2 and up
{
var secondaryTexturesSize = reader.ReadInt32();
secondaryTextures = new SecondarySpriteTexture[secondaryTexturesSize];
for (int i = 0; i < secondaryTexturesSize; i++)
{
secondaryTextures[i] = new SecondarySpriteTexture(reader);
}
reader.AlignStream();
}
}
}

View File

@@ -12,7 +12,7 @@ namespace AssetStudio
public TextAsset(ObjectReader reader) : base(reader)
{
m_Script = reader.ReadUInt8Array();
m_Script = reader.ReadBytes(reader.ReadInt32());
}
}
}

View File

@@ -13,10 +13,6 @@ namespace AssetStudio
{
var m_ForcedFallbackFormat = reader.ReadInt32();
var m_DownscaleFallback = reader.ReadBoolean();
if (version[0] > 2020 || (version[0] == 2020 && version[1] >= 2)) //2020.2 and up
{
var m_IsAlphaChannelOptional = reader.ReadBoolean();
}
reader.AlignStream();
}
}

View File

@@ -4,22 +4,13 @@ namespace AssetStudio
{
public class StreamingInfo
{
public long offset; //ulong
public uint offset;
public uint size;
public string path;
public StreamingInfo(ObjectReader reader)
{
var version = reader.version;
if (version[0] >= 2020) //2020.1 and up
{
offset = reader.ReadInt64();
}
else
{
offset = reader.ReadUInt32();
}
offset = reader.ReadUInt32();
size = reader.ReadUInt32();
path = reader.ReadAlignedString();
}
@@ -68,10 +59,6 @@ namespace AssetStudio
m_Width = reader.ReadInt32();
m_Height = reader.ReadInt32();
var m_CompleteImageSize = reader.ReadInt32();
if (version[0] >= 2020) //2020.1 and up
{
var m_MipsStripped = reader.ReadInt32();
}
m_TextureFormat = (TextureFormat)reader.ReadInt32();
if (version[0] < 5 || (version[0] == 5 && version[1] < 2)) //5.2 down
{
@@ -81,29 +68,9 @@ namespace AssetStudio
{
m_MipCount = reader.ReadInt32();
}
if (version[0] > 2 || (version[0] == 2 && version[1] >= 6)) //2.6.0 and up
{
var m_IsReadable = reader.ReadBoolean();
}
if (version[0] >= 2020) //2020.1 and up
{
var m_IsPreProcessed = reader.ReadBoolean();
}
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
{
var m_IgnoreMasterTextureLimit = reader.ReadBoolean();
}
if (version[0] >= 3) //3.0.0 - 5.4
{
if (version[0] < 5 || (version[0] == 5 && version[1] <= 4))
{
var m_ReadAllowed = reader.ReadBoolean();
}
}
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
{
var m_StreamingMipmaps = reader.ReadBoolean();
}
var m_IsReadable = reader.ReadBoolean(); //2.6.0 and up
var m_ReadAllowed = reader.ReadBoolean(); //3.0.0 - 5.4
//bool m_StreamingMipmaps 2018.2 and up
reader.AlignStream();
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
{
@@ -120,11 +87,6 @@ namespace AssetStudio
{
var m_ColorSpace = reader.ReadInt32();
}
if (version[0] > 2020 || (version[0] == 2020 && version[1] >= 2)) //2020.2 and up
{
var m_PlatformBlob = reader.ReadUInt8Array();
reader.AlignStream();
}
var image_data_size = reader.ReadInt32();
if (image_data_size == 0 && ((version[0] == 5 && version[1] >= 3) || version[0] > 5))//5.3.0 and up
{
@@ -134,7 +96,7 @@ namespace AssetStudio
ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_StreamData?.path))
{
resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size);
resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, (int)m_StreamData.size);
}
else
{
@@ -209,8 +171,5 @@ namespace AssetStudio
ASTC_HDR_8x8,
ASTC_HDR_10x10,
ASTC_HDR_12x12,
RG32,
RGB48,
RGBA64
}
}

View File

@@ -1,26 +1,17 @@
using System.IO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public class StreamedResource
{
public string m_Source;
public long m_Offset; //ulong
public long m_Size; //ulong
public StreamedResource(BinaryReader reader)
{
m_Source = reader.ReadAlignedString();
m_Offset = reader.ReadInt64();
m_Size = reader.ReadInt64();
}
}
public sealed class VideoClip : NamedObject
{
public ResourceReader m_VideoData;
public string m_OriginalPath;
public StreamedResource m_ExternalResources;
public string m_Source;
public ulong m_Size;
public VideoClip(ObjectReader reader) : base(reader)
{
@@ -41,30 +32,20 @@ namespace AssetStudio
reader.AlignStream();
var m_AudioSampleRate = reader.ReadUInt32Array();
var m_AudioLanguage = reader.ReadStringArray();
if (version[0] >= 2020) //2020.1 and up
{
var m_VideoShadersSize = reader.ReadInt32();
var m_VideoShaders = new PPtr<Shader>[m_VideoShadersSize];
for (int i = 0; i < m_VideoShadersSize; i++)
{
m_VideoShaders[i] = new PPtr<Shader>(reader);
}
}
m_ExternalResources = new StreamedResource(reader);
//StreamedResource m_ExternalResources
m_Source = reader.ReadAlignedString();
var m_Offset = reader.ReadUInt64();
m_Size = reader.ReadUInt64();
var m_HasSplitAlpha = reader.ReadBoolean();
if (version[0] >= 2020) //2020.1 and up
{
var m_sRGB = reader.ReadBoolean();
}
ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_ExternalResources.m_Source))
if (!string.IsNullOrEmpty(m_Source))
{
resourceReader = new ResourceReader(m_ExternalResources.m_Source, assetsFile, m_ExternalResources.m_Offset, m_ExternalResources.m_Size);
resourceReader = new ResourceReader(m_Source, assetsFile, (long)m_Offset, (int)m_Size);
}
else
{
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, m_ExternalResources.m_Size);
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, (int)m_Size);
}
m_VideoData = resourceReader;
}

View File

@@ -113,8 +113,7 @@ namespace AssetStudio
{1093, "m_CorrespondingSourceObject"},
{1121, "m_PrefabInstance"},
{1138, "m_PrefabAsset"},
{1152, "FileSize"},
{1161, "Hash128"}
{1152, "FileSize"}
};
}
}

View File

@@ -72,6 +72,11 @@ namespace AssetStudio
return new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
}
public static System.Drawing.RectangleF ReadRectangleF(this BinaryReader reader)
{
return new System.Drawing.RectangleF(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
}
public static Color ReadColor4(this BinaryReader reader)
{
return new Color(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
@@ -97,11 +102,6 @@ namespace AssetStudio
return ReadArray(reader.ReadBoolean, reader.ReadInt32());
}
public static byte[] ReadUInt8Array(this BinaryReader reader)
{
return reader.ReadBytes(reader.ReadInt32());
}
public static ushort[] ReadUInt16Array(this BinaryReader reader)
{
return ReadArray(reader.ReadUInt16, reader.ReadInt32());

View File

@@ -1,100 +0,0 @@
using System.IO;
using System.Linq;
namespace AssetStudio
{
public class FileReader : EndianBinaryReader
{
public string FullPath;
public string FileName;
public FileType FileType;
private static readonly byte[] gzipMagic = { 0x1f, 0x8b };
private static readonly byte[] brotliMagic = { 0x62, 0x72, 0x6F, 0x74, 0x6C, 0x69 };
public FileReader(string path) : this(path, File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { }
public FileReader(string path, Stream stream) : base(stream, EndianType.BigEndian)
{
FullPath = Path.GetFullPath(path);
FileName = Path.GetFileName(path);
FileType = CheckFileType();
}
private FileType CheckFileType()
{
var signature = this.ReadStringToNull(20);
Position = 0;
switch (signature)
{
case "UnityWeb":
case "UnityRaw":
case "UnityArchive":
case "UnityFS":
return FileType.BundleFile;
case "UnityWebData1.0":
return FileType.WebFile;
default:
{
var magic = ReadBytes(2);
Position = 0;
if (gzipMagic.SequenceEqual(magic))
{
return FileType.GZipFile;
}
Position = 0x20;
magic = ReadBytes(6);
Position = 0;
if (brotliMagic.SequenceEqual(magic))
{
return FileType.BrotliFile;
}
if (IsSerializedFile())
{
return FileType.AssetsFile;
}
else
{
return FileType.ResourceFile;
}
}
}
}
private bool IsSerializedFile()
{
var fileSize = BaseStream.Length;
if (fileSize < 20)
{
return false;
}
var m_MetadataSize = ReadUInt32();
long m_FileSize = ReadUInt32();
var m_Version = ReadUInt32();
long m_DataOffset = ReadUInt32();
var m_Endianess = ReadByte();
var m_Reserved = ReadBytes(3);
if (m_Version >= 22)
{
if (fileSize < 48)
{
Position = 0;
return false;
}
m_MetadataSize = ReadUInt32();
m_FileSize = ReadInt64();
m_DataOffset = ReadInt64();
}
Position = 0;
if (m_FileSize != fileSize)
{
return false;
}
if (m_DataOffset > fileSize)
{
return false;
}
return true;
}
}
}

View File

@@ -1,18 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AssetStudio
{
public enum FileType
{
AssetsFile,
BundleFile,
WebFile,
ResourceFile,
GZipFile,
BrotliFile
}
}

View File

@@ -132,7 +132,6 @@ namespace AssetStudio
public class ImportedMesh
{
public string Path { get; set; }
public List<ImportedVertex> VertexList { get; set; }
public List<ImportedSubmesh> SubmeshList { get; set; }
public List<ImportedBone> BoneList { get; set; }
public bool hasNormal { get; set; }
@@ -143,9 +142,9 @@ namespace AssetStudio
public class ImportedSubmesh
{
public List<ImportedVertex> VertexList { get; set; }
public List<ImportedFace> FaceList { get; set; }
public string Material { get; set; }
public int BaseVertex { get; set; }
}
public class ImportedVertex

View File

@@ -1,11 +1,17 @@
using Org.Brotli.Dec;
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
namespace AssetStudio
{
public enum FileType
{
AssetsFile,
BundleFile,
WebFile,
ResourceFile
}
public static class ImportHelper
{
public static void MergeSplitAssets(string path, bool allDirectories = false)
@@ -14,8 +20,8 @@ namespace AssetStudio
foreach (var splitFile in splitFiles)
{
var destFile = Path.GetFileNameWithoutExtension(splitFile);
var destPath = Path.GetDirectoryName(splitFile);
var destFull = Path.Combine(destPath, destFile);
var destPath = Path.GetDirectoryName(splitFile) + "\\";
var destFull = destPath + destFile;
if (!File.Exists(destFull))
{
var splitParts = Directory.GetFiles(destPath, destFile + ".split*");
@@ -37,7 +43,7 @@ namespace AssetStudio
public static string[] ProcessingSplitFiles(List<string> selectFile)
{
var splitFiles = selectFile.Where(x => x.Contains(".split"))
.Select(x => Path.Combine(Path.GetDirectoryName(x), Path.GetFileNameWithoutExtension(x)))
.Select(x => Path.GetDirectoryName(x) + "\\" + Path.GetFileNameWithoutExtension(x))
.Distinct()
.ToList();
selectFile.RemoveAll(x => x.Contains(".split"));
@@ -51,31 +57,55 @@ namespace AssetStudio
return selectFile.Distinct().ToArray();
}
public static FileReader DecompressGZip(FileReader reader)
public static FileType CheckFileType(Stream stream, out EndianBinaryReader reader)
{
using (reader)
{
var stream = new MemoryStream();
using (var gs = new GZipStream(reader.BaseStream, CompressionMode.Decompress))
{
gs.CopyTo(stream);
}
stream.Position = 0;
return new FileReader(reader.FullPath, stream);
}
reader = new EndianBinaryReader(stream);
return CheckFileType(reader);
}
public static FileReader DecompressBrotli(FileReader reader)
public static FileType CheckFileType(string fileName, out EndianBinaryReader reader)
{
using (reader)
reader = new EndianBinaryReader(File.OpenRead(fileName));
return CheckFileType(reader);
}
private static FileType CheckFileType(EndianBinaryReader reader)
{
var signature = reader.ReadStringToNull(20);
reader.Position = 0;
switch (signature)
{
var stream = new MemoryStream();
using (var brotliStream = new BrotliInputStream(reader.BaseStream))
{
brotliStream.CopyTo(stream);
}
stream.Position = 0;
return new FileReader(reader.FullPath, stream);
case "UnityWeb":
case "UnityRaw":
case "UnityArchive":
case "UnityFS":
return FileType.BundleFile;
case "UnityWebData1.0":
return FileType.WebFile;
default:
{
var magic = reader.ReadBytes(2);
reader.Position = 0;
if (WebFile.gzipMagic.SequenceEqual(magic))
{
return FileType.WebFile;
}
reader.Position = 0x20;
magic = reader.ReadBytes(6);
reader.Position = 0;
if (WebFile.brotliMagic.SequenceEqual(magic))
{
return FileType.WebFile;
}
if (SerializedFile.IsSerializedFile(reader))
{
return FileType.AssetsFile;
}
else
{
return FileType.ResourceFile;
}
}
}
}
}

View File

@@ -14,13 +14,5 @@ namespace AssetStudio
public static void Info(string message) => Default.Log(LoggerEvent.Info, message);
public static void Warning(string message) => Default.Log(LoggerEvent.Warning, message);
public static void Error(string message) => Default.Log(LoggerEvent.Error, message);
public static void Error(string message, Exception e)
{
var sb = new StringBuilder();
sb.AppendLine(message);
sb.AppendLine(e.ToString());
Default.Log(LoggerEvent.Error, sb.ToString());
}
}
}

View File

@@ -1,8 +1,8 @@
using System;
using System.Diagnostics;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
namespace AssetStudio
namespace System
{
/// <summary>
/// Represents a half-precision floating point number.

View File

@@ -1,7 +1,6 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices;
namespace AssetStudio
namespace System
{
/// <summary>
/// Helper class for Half conversions and some low level operations.

View File

@@ -11,8 +11,6 @@ namespace AssetStudio
public uint byteSize;
public int typeID;
public int classID;
public ushort isDestroyed;
public byte stripped;
public long m_PathID;
public SerializedType serializedType;

View File

@@ -15,7 +15,7 @@ namespace AssetStudio
public ClassIDType type;
public SerializedType serializedType;
public BuildTarget platform;
public SerializedFileFormatVersion m_Version;
public uint m_Version;
public int[] version => assetsFile.version;
public BuildType buildType => assetsFile.buildType;

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("AssetStudio")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssetStudio")]
[assembly: AssemblyCopyright("Copyright © Perfare 2018-2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("7662f8c2-7bfd-442e-a948-a43b4f7eb06e")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.14.38.5")]
[assembly: AssemblyFileVersion("0.14.38.5")]

View File

@@ -8,10 +8,11 @@ namespace AssetStudio
private string path;
private SerializedFile assetsFile;
private long offset;
private long size;
private int size;
private BinaryReader reader;
public ResourceReader(string path, SerializedFile assetsFile, long offset, long size)
public ResourceReader(string path, SerializedFile assetsFile, long offset, int size)
{
needSearch = true;
this.path = path;
@@ -20,25 +21,28 @@ namespace AssetStudio
this.size = size;
}
public ResourceReader(BinaryReader reader, long offset, long size)
public ResourceReader(BinaryReader reader, long offset, int size)
{
this.reader = reader;
this.offset = offset;
this.size = size;
}
private BinaryReader GetReader()
public byte[] GetData()
{
if (needSearch)
{
var resourceFileName = Path.GetFileName(path);
if (assetsFile.assetsManager.resourceFileReaders.TryGetValue(resourceFileName, out reader))
{
needSearch = false;
return reader;
reader.BaseStream.Position = offset;
return reader.ReadBytes(size);
}
var assetsFileDirectory = Path.GetDirectoryName(assetsFile.fullName);
var resourceFilePath = Path.Combine(assetsFileDirectory, resourceFileName);
var resourceFilePath = assetsFileDirectory + Path.DirectorySeparatorChar + resourceFileName;
if (!File.Exists(resourceFilePath))
{
var findFiles = Directory.GetFiles(assetsFileDirectory, resourceFileName, SearchOption.AllDirectories);
@@ -49,34 +53,18 @@ namespace AssetStudio
}
if (File.Exists(resourceFilePath))
{
needSearch = false;
reader = new BinaryReader(File.OpenRead(resourceFilePath));
needSearch = false;
assetsFile.assetsManager.resourceFileReaders.Add(resourceFileName, reader);
return reader;
reader.BaseStream.Position = offset;
return reader.ReadBytes(size);
}
throw new FileNotFoundException($"Can't find the resource file {resourceFileName}");
}
else
{
return reader;
}
}
public byte[] GetData()
{
var binaryReader = GetReader();
binaryReader.BaseStream.Position = offset;
return binaryReader.ReadBytes((int)size);
}
public void WriteData(string path)
{
var binaryReader = GetReader();
binaryReader.BaseStream.Position = offset;
using (var writer = File.OpenWrite(path))
{
binaryReader.BaseStream.CopyTo(writer, size);
}
reader.BaseStream.Position = offset;
return reader.ReadBytes(size);
}
}
}

View File

@@ -9,7 +9,7 @@ namespace AssetStudio
public class SerializedFile
{
public AssetsManager assetsManager;
public FileReader reader;
public EndianBinaryReader reader;
public string fullName;
public string originalPath;
public string fileName;
@@ -19,45 +19,43 @@ namespace AssetStudio
public Dictionary<long, Object> ObjectsDic;
public SerializedFileHeader header;
private byte m_FileEndianess;
private EndianType m_FileEndianess;
public string unityVersion = "2.5.0f5";
public BuildTarget m_TargetPlatform = BuildTarget.UnknownPlatform;
private bool m_EnableTypeTree = true;
public List<SerializedType> m_Types;
public int bigIDEnabled = 0;
public List<SerializedType> m_RefTypes;
public List<ObjectInfo> m_Objects;
private List<LocalSerializedObjectIdentifier> m_ScriptTypes;
public List<FileIdentifier> m_Externals;
public List<SerializedType> m_RefTypes;
public string userInformation;
public SerializedFile(FileReader reader, AssetsManager assetsManager)
public SerializedFile(AssetsManager assetsManager, string fullName, EndianBinaryReader reader)
{
this.assetsManager = assetsManager;
this.reader = reader;
fullName = reader.FullPath;
fileName = reader.FileName;
this.fullName = fullName;
fileName = Path.GetFileName(fullName);
// ReadHeader
//ReadHeader
header = new SerializedFileHeader();
header.m_MetadataSize = reader.ReadUInt32();
header.m_FileSize = reader.ReadUInt32();
header.m_Version = (SerializedFileFormatVersion)reader.ReadUInt32();
header.m_Version = reader.ReadUInt32();
header.m_DataOffset = reader.ReadUInt32();
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_9)
if (header.m_Version >= 9)
{
header.m_Endianess = reader.ReadByte();
header.m_Reserved = reader.ReadBytes(3);
m_FileEndianess = header.m_Endianess;
m_FileEndianess = (EndianType)header.m_Endianess;
}
else
{
reader.Position = header.m_FileSize - header.m_MetadataSize;
m_FileEndianess = reader.ReadByte();
m_FileEndianess = (EndianType)reader.ReadByte();
}
if (header.m_Version >= SerializedFileFormatVersion.kLargeFilesSupport)
if (header.m_Version >= 22)
{
header.m_MetadataSize = reader.ReadUInt32();
header.m_FileSize = reader.ReadInt64();
@@ -65,17 +63,17 @@ namespace AssetStudio
reader.ReadInt64(); // unknown
}
// ReadMetadata
if (m_FileEndianess == 0)
//ReadMetadata
if (m_FileEndianess == EndianType.LittleEndian)
{
reader.endian = EndianType.LittleEndian;
}
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_7)
if (header.m_Version >= 7)
{
unityVersion = reader.ReadStringToNull();
SetVersion(unityVersion);
}
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_8)
if (header.m_Version >= 8)
{
m_TargetPlatform = (BuildTarget)reader.ReadInt32();
if (!Enum.IsDefined(typeof(BuildTarget), m_TargetPlatform))
@@ -83,25 +81,26 @@ namespace AssetStudio
m_TargetPlatform = BuildTarget.UnknownPlatform;
}
}
if (header.m_Version >= SerializedFileFormatVersion.kHasTypeTreeHashes)
if (header.m_Version >= 13)
{
m_EnableTypeTree = reader.ReadBoolean();
}
// Read Types
//ReadTypes
int typeCount = reader.ReadInt32();
m_Types = new List<SerializedType>(typeCount);
for (int i = 0; i < typeCount; i++)
{
m_Types.Add(ReadSerializedType(false));
m_Types.Add(ReadSerializedType());
}
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_7 && header.m_Version < SerializedFileFormatVersion.kUnknown_14)
var bigIDEnabled = 0;
if (header.m_Version >= 7 && header.m_Version < 14)
{
bigIDEnabled = reader.ReadInt32();
}
// Read Objects
//ReadObjects
int objectCount = reader.ReadInt32();
m_Objects = new List<ObjectInfo>(objectCount);
Objects = new List<Object>(objectCount);
@@ -113,7 +112,7 @@ namespace AssetStudio
{
objectInfo.m_PathID = reader.ReadInt64();
}
else if (header.m_Version < SerializedFileFormatVersion.kUnknown_14)
else if (header.m_Version < 14)
{
objectInfo.m_PathID = reader.ReadInt32();
}
@@ -123,7 +122,7 @@ namespace AssetStudio
objectInfo.m_PathID = reader.ReadInt64();
}
if (header.m_Version >= SerializedFileFormatVersion.kLargeFilesSupport)
if (header.m_Version >= 22)
objectInfo.byteStart = reader.ReadInt64();
else
objectInfo.byteStart = reader.ReadUInt32();
@@ -131,7 +130,7 @@ namespace AssetStudio
objectInfo.byteStart += header.m_DataOffset;
objectInfo.byteSize = reader.ReadUInt32();
objectInfo.typeID = reader.ReadInt32();
if (header.m_Version < SerializedFileFormatVersion.kRefactoredClassId)
if (header.m_Version < 16)
{
objectInfo.classID = reader.ReadUInt16();
objectInfo.serializedType = m_Types.Find(x => x.classID == objectInfo.typeID);
@@ -142,24 +141,24 @@ namespace AssetStudio
objectInfo.serializedType = type;
objectInfo.classID = type.classID;
}
if (header.m_Version < SerializedFileFormatVersion.kHasScriptTypeIndex)
if (header.m_Version < 11)
{
objectInfo.isDestroyed = reader.ReadUInt16();
var isDestroyed = reader.ReadUInt16();
}
if (header.m_Version >= SerializedFileFormatVersion.kHasScriptTypeIndex && header.m_Version < SerializedFileFormatVersion.kRefactorTypeData)
if (header.m_Version >= 11 && header.m_Version < 17)
{
var m_ScriptTypeIndex = reader.ReadInt16();
if (objectInfo.serializedType != null)
objectInfo.serializedType.m_ScriptTypeIndex = m_ScriptTypeIndex;
}
if (header.m_Version == SerializedFileFormatVersion.kSupportsStrippedObject || header.m_Version == SerializedFileFormatVersion.kRefactoredClassId)
if (header.m_Version == 15 || header.m_Version == 16)
{
objectInfo.stripped = reader.ReadByte();
var stripped = reader.ReadByte();
}
m_Objects.Add(objectInfo);
}
if (header.m_Version >= SerializedFileFormatVersion.kHasScriptTypeIndex)
if (header.m_Version >= 11)
{
int scriptCount = reader.ReadInt32();
m_ScriptTypes = new List<LocalSerializedObjectIdentifier>(scriptCount);
@@ -167,7 +166,7 @@ namespace AssetStudio
{
var m_ScriptType = new LocalSerializedObjectIdentifier();
m_ScriptType.localSerializedFileIndex = reader.ReadInt32();
if (header.m_Version < SerializedFileFormatVersion.kUnknown_14)
if (header.m_Version < 14)
{
m_ScriptType.localIdentifierInFile = reader.ReadInt32();
}
@@ -185,11 +184,11 @@ namespace AssetStudio
for (int i = 0; i < externalsCount; i++)
{
var m_External = new FileIdentifier();
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_6)
if (header.m_Version >= 6)
{
var tempEmpty = reader.ReadStringToNull();
}
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_5)
if (header.m_Version >= 5)
{
m_External.guid = new Guid(reader.ReadBytes(16));
m_External.type = reader.ReadInt32();
@@ -199,19 +198,19 @@ namespace AssetStudio
m_Externals.Add(m_External);
}
if (header.m_Version >= SerializedFileFormatVersion.kSupportsRefObject)
if (header.m_Version >= 20)
{
int refTypesCount = reader.ReadInt32();
m_RefTypes = new List<SerializedType>(refTypesCount);
for (int i = 0; i < refTypesCount; i++)
{
m_RefTypes.Add(ReadSerializedType(true));
m_RefTypes.Add(ReadSerializedType());
}
}
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_5)
if (header.m_Version >= 5)
{
userInformation = reader.ReadStringToNull();
var userInformation = reader.ReadStringToNull();
}
//reader.AlignStream(16);
@@ -219,94 +218,80 @@ namespace AssetStudio
public void SetVersion(string stringVersion)
{
if (stringVersion != strippedVersion)
{
unityVersion = stringVersion;
var buildSplit = Regex.Replace(stringVersion, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
buildType = new BuildType(buildSplit[0]);
var versionSplit = Regex.Replace(stringVersion, @"\D", ".").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
version = versionSplit.Select(int.Parse).ToArray();
}
unityVersion = stringVersion;
var buildSplit = Regex.Replace(stringVersion, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
buildType = new BuildType(buildSplit[0]);
var versionSplit = Regex.Replace(stringVersion, @"\D", ".").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
version = versionSplit.Select(int.Parse).ToArray();
}
private SerializedType ReadSerializedType(bool isRefType)
private SerializedType ReadSerializedType()
{
var type = new SerializedType();
type.classID = reader.ReadInt32();
if (header.m_Version >= SerializedFileFormatVersion.kRefactoredClassId)
if (header.m_Version >= 16)
{
type.m_IsStrippedType = reader.ReadBoolean();
}
if (header.m_Version >= SerializedFileFormatVersion.kRefactorTypeData)
if (header.m_Version >= 17)
{
type.m_ScriptTypeIndex = reader.ReadInt16();
}
if (header.m_Version >= SerializedFileFormatVersion.kHasTypeTreeHashes)
if (header.m_Version >= 13)
{
if (isRefType && type.m_ScriptTypeIndex >= 0)
if ((header.m_Version < 16 && type.classID < 0) || (header.m_Version >= 16 && type.classID == 114))
{
type.m_ScriptID = reader.ReadBytes(16);
type.m_ScriptID = reader.ReadBytes(16); //Hash128
}
else if ((header.m_Version < SerializedFileFormatVersion.kRefactoredClassId && type.classID < 0) || (header.m_Version >= SerializedFileFormatVersion.kRefactoredClassId && type.classID == 114))
{
type.m_ScriptID = reader.ReadBytes(16);
}
type.m_OldTypeHash = reader.ReadBytes(16);
type.m_OldTypeHash = reader.ReadBytes(16); //Hash128
}
if (m_EnableTypeTree)
{
type.m_Type = new TypeTree();
type.m_Type.m_Nodes = new List<TypeTreeNode>();
if (header.m_Version >= SerializedFileFormatVersion.kUnknown_12 || header.m_Version == SerializedFileFormatVersion.kUnknown_10)
var typeTree = new List<TypeTreeNode>();
if (header.m_Version >= 12 || header.m_Version == 10)
{
TypeTreeBlobRead(type.m_Type);
TypeTreeBlobRead(typeTree);
}
else
{
ReadTypeTree(type.m_Type);
ReadTypeTree(typeTree);
}
if (header.m_Version >= SerializedFileFormatVersion.kStoresTypeDependencies)
if (header.m_Version >= 21)
{
if (isRefType)
{
type.m_KlassName = reader.ReadStringToNull();
type.m_NameSpace = reader.ReadStringToNull();
type.m_AsmName = reader.ReadStringToNull();
}
else
{
type.m_TypeDependencies = reader.ReadInt32Array();
}
type.m_TypeDependencies = reader.ReadInt32Array();
}
type.m_Nodes = typeTree;
}
return type;
}
private void ReadTypeTree(TypeTree m_Type, int level = 0)
private void ReadTypeTree(List<TypeTreeNode> typeTree, int level = 0)
{
var typeTreeNode = new TypeTreeNode();
m_Type.m_Nodes.Add(typeTreeNode);
typeTree.Add(typeTreeNode);
typeTreeNode.m_Level = level;
typeTreeNode.m_Type = reader.ReadStringToNull();
typeTreeNode.m_Name = reader.ReadStringToNull();
typeTreeNode.m_ByteSize = reader.ReadInt32();
if (header.m_Version == SerializedFileFormatVersion.kUnknown_2)
if (header.m_Version == 2)
{
var variableCount = reader.ReadInt32();
}
if (header.m_Version != SerializedFileFormatVersion.kUnknown_3)
if (header.m_Version != 3)
{
typeTreeNode.m_Index = reader.ReadInt32();
}
typeTreeNode.m_TypeFlags = reader.ReadInt32();
typeTreeNode.m_IsArray = reader.ReadInt32();
typeTreeNode.m_Version = reader.ReadInt32();
if (header.m_Version != SerializedFileFormatVersion.kUnknown_3)
if (header.m_Version != 3)
{
typeTreeNode.m_MetaFlag = reader.ReadInt32();
}
@@ -314,40 +299,40 @@ namespace AssetStudio
int childrenCount = reader.ReadInt32();
for (int i = 0; i < childrenCount; i++)
{
ReadTypeTree(m_Type, level + 1);
ReadTypeTree(typeTree, level + 1);
}
}
private void TypeTreeBlobRead(TypeTree m_Type)
private void TypeTreeBlobRead(List<TypeTreeNode> typeTree)
{
int numberOfNodes = reader.ReadInt32();
int stringBufferSize = reader.ReadInt32();
for (int i = 0; i < numberOfNodes; i++)
{
var typeTreeNode = new TypeTreeNode();
m_Type.m_Nodes.Add(typeTreeNode);
typeTree.Add(typeTreeNode);
typeTreeNode.m_Version = reader.ReadUInt16();
typeTreeNode.m_Level = reader.ReadByte();
typeTreeNode.m_TypeFlags = reader.ReadByte();
typeTreeNode.m_IsArray = reader.ReadBoolean() ? 1 : 0;
typeTreeNode.m_TypeStrOffset = reader.ReadUInt32();
typeTreeNode.m_NameStrOffset = reader.ReadUInt32();
typeTreeNode.m_ByteSize = reader.ReadInt32();
typeTreeNode.m_Index = reader.ReadInt32();
typeTreeNode.m_MetaFlag = reader.ReadInt32();
if (header.m_Version >= SerializedFileFormatVersion.kTypeTreeNodeWithTypeFlags)
if (header.m_Version >= 19)
{
typeTreeNode.m_RefTypeHash = reader.ReadUInt64();
}
}
m_Type.m_StringBuffer = reader.ReadBytes(stringBufferSize);
var m_StringBuffer = reader.ReadBytes(stringBufferSize);
using (var stringBufferReader = new BinaryReader(new MemoryStream(m_Type.m_StringBuffer)))
using (var stringBufferReader = new BinaryReader(new MemoryStream(m_StringBuffer)))
{
for (int i = 0; i < numberOfNodes; i++)
{
var m_Node = m_Type.m_Nodes[i];
m_Node.m_Type = ReadString(stringBufferReader, m_Node.m_TypeStrOffset);
m_Node.m_Name = ReadString(stringBufferReader, m_Node.m_NameStrOffset);
var typeTreeNode = typeTree[i];
typeTreeNode.m_Type = ReadString(stringBufferReader, typeTreeNode.m_TypeStrOffset);
typeTreeNode.m_Name = ReadString(stringBufferReader, typeTreeNode.m_NameStrOffset);
}
}
@@ -374,8 +359,41 @@ namespace AssetStudio
ObjectsDic.Add(obj.m_PathID, obj);
}
public bool IsVersionStripped => unityVersion == strippedVersion;
private const string strippedVersion = "0.0.0";
public static bool IsSerializedFile(EndianBinaryReader reader)
{
var fileSize = reader.BaseStream.Length;
if (fileSize < 20)
{
return false;
}
var m_MetadataSize = reader.ReadUInt32();
long m_FileSize = reader.ReadUInt32();
var m_Version = reader.ReadUInt32();
long m_DataOffset = reader.ReadUInt32();
var m_Endianess = reader.ReadByte();
var m_Reserved = reader.ReadBytes(3);
if (m_Version >= 22)
{
if (fileSize < 48)
{
return false;
}
m_MetadataSize = reader.ReadUInt32();
m_FileSize = reader.ReadInt64();
m_DataOffset = reader.ReadInt64();
}
if (m_FileSize != fileSize)
{
reader.Position = 0;
return false;
}
if (m_DataOffset > fileSize)
{
reader.Position = 0;
return false;
}
reader.Position = 0;
return true;
}
}
}

View File

@@ -1,87 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AssetStudio
{
public enum SerializedFileFormatVersion
{
kUnsupported = 1,
kUnknown_2 = 2,
kUnknown_3 = 3,
/// <summary>
/// 1.2.0 to 2.0.0
/// </summary>
kUnknown_5 = 5,
/// <summary>
/// 2.1.0 to 2.6.1
/// </summary>
kUnknown_6 = 6,
/// <summary>
/// 3.0.0b
/// </summary>
kUnknown_7 = 7,
/// <summary>
/// 3.0.0 to 3.4.2
/// </summary>
kUnknown_8 = 8,
/// <summary>
/// 3.5.0 to 4.7.2
/// </summary>
kUnknown_9 = 9,
/// <summary>
/// 5.0.0aunk1
/// </summary>
kUnknown_10 = 10,
/// <summary>
/// 5.0.0aunk2
/// </summary>
kHasScriptTypeIndex = 11,
/// <summary>
/// 5.0.0aunk3
/// </summary>
kUnknown_12 = 12,
/// <summary>
/// 5.0.0aunk4
/// </summary>
kHasTypeTreeHashes = 13,
/// <summary>
/// 5.0.0unk
/// </summary>
kUnknown_14 = 14,
/// <summary>
/// 5.0.1 to 5.4.0
/// </summary>
kSupportsStrippedObject = 15,
/// <summary>
/// 5.5.0a
/// </summary>
kRefactoredClassId = 16,
/// <summary>
/// 5.5.0unk to 2018.4
/// </summary>
kRefactorTypeData = 17,
/// <summary>
/// 2019.1a
/// </summary>
kRefactorShareableTypeTreeData = 18,
/// <summary>
/// 2019.1unk
/// </summary>
kTypeTreeNodeWithTypeFlags = 19,
/// <summary>
/// 2019.2
/// </summary>
kSupportsRefObject = 20,
/// <summary>
/// 2019.3 to 2019.4
/// </summary>
kStoresTypeDependencies = 21,
/// <summary>
/// 2020.1 to x
/// </summary>
kLargeFilesSupport = 22
}
}

View File

@@ -9,7 +9,7 @@ namespace AssetStudio
{
public uint m_MetadataSize;
public long m_FileSize;
public SerializedFileFormatVersion m_Version;
public uint m_Version;
public long m_DataOffset;
public byte m_Endianess;
public byte[] m_Reserved;

View File

@@ -10,12 +10,9 @@ namespace AssetStudio
public int classID;
public bool m_IsStrippedType;
public short m_ScriptTypeIndex = -1;
public TypeTree m_Type;
public List<TypeTreeNode> m_Nodes;
public byte[] m_ScriptID; //Hash128
public byte[] m_OldTypeHash; //Hash128
public int[] m_TypeDependencies;
public string m_KlassName;
public string m_NameSpace;
public string m_AsmName;
}
}

View File

@@ -34,16 +34,15 @@ namespace AssetStudio
return newOutStream;
}
public static void StreamDecompress(Stream compressedStream, Stream decompressedStream, long compressedSize, long decompressedSize)
public static void StreamDecompress(Stream inStream, Stream outStream, long inSize, long outSize)
{
var basePosition = compressedStream.Position;
var decoder = new Decoder();
var properties = new byte[5];
if (compressedStream.Read(properties, 0, 5) != 5)
if (inStream.Read(properties, 0, 5) != 5)
throw new Exception("input .lzma is too short");
decoder.SetDecoderProperties(properties);
decoder.Code(compressedStream, decompressedStream, compressedSize - 5, decompressedSize, null);
compressedStream.Position = basePosition + compressedSize;
inSize -= 5L;
decoder.Code(inStream, outStream, inSize, outSize, null);
}
}
}

View File

@@ -4,7 +4,6 @@ namespace AssetStudio
{
public class StreamFile
{
public string path;
public string fileName;
public Stream stream;
}

View File

@@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AssetStudio
{
public class TypeTree
{
public List<TypeTreeNode> m_Nodes;
public byte[] m_StringBuffer;
}
}

View File

@@ -1,38 +1,30 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public static class TypeTreeHelper
{
public static string ReadTypeString(TypeTree m_Type, ObjectReader reader)
public static void ReadTypeString(StringBuilder sb, List<TypeTreeNode> members, BinaryReader reader)
{
reader.Reset();
var sb = new StringBuilder();
var m_Nodes = m_Type.m_Nodes;
for (int i = 0; i < m_Nodes.Count; i++)
for (int i = 0; i < members.Count; i++)
{
ReadStringValue(sb, m_Nodes, reader, ref i);
ReadStringValue(sb, members, reader, ref i);
}
var readed = reader.Position - reader.byteStart;
if (readed != reader.byteSize)
{
Logger.Info($"Error while read type, read {readed} bytes but expected {reader.byteSize} bytes");
}
return sb.ToString();
}
private static void ReadStringValue(StringBuilder sb, List<TypeTreeNode> m_Nodes, BinaryReader reader, ref int i)
private static void ReadStringValue(StringBuilder sb, List<TypeTreeNode> members, BinaryReader reader, ref int i)
{
var m_Node = m_Nodes[i];
var level = m_Node.m_Level;
var varTypeStr = m_Node.m_Type;
var varNameStr = m_Node.m_Name;
var member = members[i];
var level = member.m_Level;
var varTypeStr = member.m_Type;
var varNameStr = member.m_Name;
object value = null;
var append = true;
var align = (m_Node.m_MetaFlag & 0x4000) != 0;
var align = (member.m_MetaFlag & 0x4000) != 0;
switch (varTypeStr)
{
case "SInt8":
@@ -85,18 +77,18 @@ namespace AssetStudio
break;
case "map":
{
if ((m_Nodes[i + 1].m_MetaFlag & 0x4000) != 0)
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
align = true;
append = false;
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr);
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level + 1)), "Array", "Array");
var size = reader.ReadInt32();
sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level + 1)), "int", "size", size);
var map = GetNodes(m_Nodes, i);
var map = GetMembers(members, i);
i += map.Count - 1;
var first = GetNodes(map, 4);
var first = GetMembers(map, 4);
var next = 4 + first.Count;
var second = GetNodes(map, next);
var second = GetMembers(map, next);
for (int j = 0; j < size; j++)
{
sb.AppendFormat("{0}[{1}]\r\n", (new string('\t', level + 2)), j);
@@ -120,16 +112,16 @@ namespace AssetStudio
}
default:
{
if (i < m_Nodes.Count - 1 && m_Nodes[i + 1].m_Type == "Array") //Array
if (i < members.Count - 1 && members[i + 1].m_Type == "Array") //Array
{
if ((m_Nodes[i + 1].m_MetaFlag & 0x4000) != 0)
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
align = true;
append = false;
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr);
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level + 1)), "Array", "Array");
var size = reader.ReadInt32();
sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level + 1)), "int", "size", size);
var vector = GetNodes(m_Nodes, i);
var vector = GetMembers(members, i);
i += vector.Count - 1;
for (int j = 0; j < size; j++)
{
@@ -143,7 +135,7 @@ namespace AssetStudio
{
append = false;
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr);
var @class = GetNodes(m_Nodes, i);
var @class = GetMembers(members, i);
i += @class.Count - 1;
for (int j = 1; j < @class.Count; j++)
{
@@ -159,31 +151,24 @@ namespace AssetStudio
reader.AlignStream();
}
public static OrderedDictionary ReadType(TypeTree m_Types, ObjectReader reader)
public static UType ReadUType(List<TypeTreeNode> members, BinaryReader reader)
{
reader.Reset();
var obj = new OrderedDictionary();
var m_Nodes = m_Types.m_Nodes;
for (int i = 1; i < m_Nodes.Count; i++)
var obj = new UType();
for (int i = 1; i < members.Count; i++)
{
var m_Node = m_Nodes[i];
var varNameStr = m_Node.m_Name;
obj[varNameStr] = ReadValue(m_Nodes, reader, ref i);
}
var readed = reader.Position - reader.byteStart;
if (readed != reader.byteSize)
{
Logger.Info($"Error while read type, read {readed} bytes but expected {reader.byteSize} bytes");
var member = members[i];
var varNameStr = member.m_Name;
obj[varNameStr] = ReadValue(members, reader, ref i);
}
return obj;
}
private static object ReadValue(List<TypeTreeNode> m_Nodes, BinaryReader reader, ref int i)
private static object ReadValue(List<TypeTreeNode> members, BinaryReader reader, ref int i)
{
var m_Node = m_Nodes[i];
var varTypeStr = m_Node.m_Type;
var member = members[i];
var varTypeStr = member.m_Type;
object value;
var align = (m_Node.m_MetaFlag & 0x4000) != 0;
var align = (member.m_MetaFlag & 0x4000) != 0;
switch (varTypeStr)
{
case "SInt8":
@@ -234,13 +219,13 @@ namespace AssetStudio
break;
case "map":
{
if ((m_Nodes[i + 1].m_MetaFlag & 0x4000) != 0)
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
align = true;
var map = GetNodes(m_Nodes, i);
var map = GetMembers(members, i);
i += map.Count - 1;
var first = GetNodes(map, 4);
var first = GetMembers(map, 4);
var next = 4 + first.Count;
var second = GetNodes(map, next);
var second = GetMembers(map, next);
var size = reader.ReadInt32();
var dic = new List<KeyValuePair<object, object>>(size);
for (int j = 0; j < size; j++)
@@ -261,11 +246,11 @@ namespace AssetStudio
}
default:
{
if (i < m_Nodes.Count - 1 && m_Nodes[i + 1].m_Type == "Array") //Array
if (i < members.Count - 1 && members[i + 1].m_Type == "Array") //Array
{
if ((m_Nodes[i + 1].m_MetaFlag & 0x4000) != 0)
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
align = true;
var vector = GetNodes(m_Nodes, i);
var vector = GetMembers(members, i);
i += vector.Count - 1;
var size = reader.ReadInt32();
var list = new List<object>(size);
@@ -279,9 +264,9 @@ namespace AssetStudio
}
else //Class
{
var @class = GetNodes(m_Nodes, i);
var @class = GetMembers(members, i);
i += @class.Count - 1;
var obj = new OrderedDictionary();
var obj = new UType();
for (int j = 1; j < @class.Count; j++)
{
var classmember = @class[j];
@@ -298,22 +283,22 @@ namespace AssetStudio
return value;
}
private static List<TypeTreeNode> GetNodes(List<TypeTreeNode> m_Nodes, int index)
private static List<TypeTreeNode> GetMembers(List<TypeTreeNode> members, int index)
{
var nodes = new List<TypeTreeNode>();
nodes.Add(m_Nodes[index]);
var level = m_Nodes[index].m_Level;
for (int i = index + 1; i < m_Nodes.Count; i++)
var member2 = new List<TypeTreeNode>();
member2.Add(members[index]);
var level = members[index].m_Level;
for (int i = index + 1; i < members.Count; i++)
{
var member = m_Nodes[i];
var member = members[i];
var level2 = member.m_Level;
if (level2 <= level)
{
return nodes;
return member2;
}
nodes.Add(member);
member2.Add(member);
}
return nodes;
return member2;
}
}
}

View File

@@ -11,22 +11,12 @@ namespace AssetStudio
public string m_Name;
public int m_ByteSize;
public int m_Index;
public int m_TypeFlags; //m_IsArray
public int m_IsArray; //m_TypeFlags
public int m_Version;
public int m_MetaFlag;
public int m_Level;
public uint m_TypeStrOffset;
public uint m_NameStrOffset;
public ulong m_RefTypeHash;
public TypeTreeNode() { }
public TypeTreeNode(string type, string name, int level, bool align)
{
m_Type = type;
m_Name = name;
m_Level = level;
m_MetaFlag = align ? 0x4000 : 0;
}
}
}

108
AssetStudio/UType.cs Normal file
View File

@@ -0,0 +1,108 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public class UType : IDictionary<string, object>
{
private List<string> keys;
private IDictionary<string, object> values;
public UType()
{
keys = new List<string>();
values = new Dictionary<string, object>();
}
public object this[string key]
{
get
{
if (!values.ContainsKey(key))
{
return null;
}
return values[key];
}
set
{
if (!values.ContainsKey(key))
{
keys.Add(key);
}
values[key] = value;
}
}
public ICollection<string> Keys => keys;
public ICollection<object> Values => values.Values;
public int Count => keys.Count;
public bool IsReadOnly => false;
public void Add(string key, object value)
{
keys.Add(key);
values.Add(key, value);
}
public void Add(KeyValuePair<string, object> item)
{
keys.Add(item.Key);
values.Add(item);
}
public void Clear()
{
keys.Clear();
values.Clear();
}
public bool Contains(KeyValuePair<string, object> item)
{
return values.Contains(item);
}
public bool ContainsKey(string key)
{
return values.ContainsKey(key);
}
public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
{
values.CopyTo(array, arrayIndex);
}
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
return values.GetEnumerator();
}
public bool Remove(string key)
{
keys.Remove(key);
return values.Remove(key);
}
public bool Remove(KeyValuePair<string, object> item)
{
keys.Remove(item.Key);
return values.Remove(item);
}
public bool TryGetValue(string key, out object value)
{
return values.TryGetValue(key, out value);
}
IEnumerator IEnumerable.GetEnumerator()
{
return values.GetEnumerator();
}
}
}

View File

@@ -1,11 +1,17 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using Org.Brotli.Dec;
namespace AssetStudio
{
public class WebFile
{
public static byte[] gzipMagic = { 0x1f, 0x8b };
public static byte[] brotliMagic = { 0x62, 0x72, 0x6F, 0x74, 0x6C, 0x69 };
public StreamFile[] fileList;
private class WebData
@@ -17,8 +23,50 @@ namespace AssetStudio
public WebFile(EndianBinaryReader reader)
{
reader.endian = EndianType.LittleEndian;
var magic = reader.ReadBytes(2);
reader.Position = 0;
if (gzipMagic.SequenceEqual(magic))
{
var stream = new MemoryStream();
using (var gs = new GZipStream(reader.BaseStream, CompressionMode.Decompress))
{
gs.CopyTo(stream);
}
stream.Position = 0;
using (var binaryReader = new BinaryReader(stream))
{
ReadWebData(binaryReader);
}
}
else
{
reader.Position = 0x20;
magic = reader.ReadBytes(6);
reader.Position = 0;
if (brotliMagic.SequenceEqual(magic))
{
var brotliStream = new BrotliInputStream(reader.BaseStream);
var stream = new MemoryStream();
brotliStream.CopyTo(stream);
stream.Position = 0;
using (var binaryReader = new BinaryReader(stream))
{
ReadWebData(binaryReader);
}
}
else
{
reader.endian = EndianType.LittleEndian;
ReadWebData(reader);
}
}
}
private void ReadWebData(BinaryReader reader)
{
var signature = reader.ReadStringToNull();
if (signature != "UnityWebData1.0")
return;
var headLength = reader.ReadInt32();
var dataList = new List<WebData>();
while (reader.BaseStream.Position < headLength)
@@ -35,7 +83,6 @@ namespace AssetStudio
{
var data = dataList[i];
var file = new StreamFile();
file.path = data.path;
file.fileName = Path.GetFileName(data.path);
reader.BaseStream.Position = data.dataOffset;
file.stream = new MemoryStream(reader.ReadBytes(data.dataLength));

View File

@@ -0,0 +1,20 @@
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;
[assembly:AssemblyTitleAttribute(L"AssetStudioFBX")];
[assembly:AssemblyDescriptionAttribute(L"")];
[assembly:AssemblyConfigurationAttribute(L"")];
[assembly:AssemblyCompanyAttribute(L"")];
[assembly:AssemblyProductAttribute(L"AssetStudioFBX")];
[assembly:AssemblyCopyrightAttribute(L"Copyright © Perfare 2018-2020")];
[assembly:AssemblyTrademarkAttribute(L"")];
[assembly:AssemblyCultureAttribute(L"")];
[assembly:AssemblyVersionAttribute("1.0.*")];
[assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(true)];

View File

@@ -0,0 +1,43 @@
#include "AssetStudioFBX.h"
namespace AssetStudio
{
char* Fbx::StringToUTF8(String^ s)
{
auto bytes = Text::Encoding::UTF8->GetBytes(s);
auto chars = new char[bytes->Length + 1];
pin_ptr<unsigned char> ptr = &bytes[0];
memcpy(chars, ptr, bytes->Length);
chars[bytes->Length] = '\0';
return chars;
}
void Fbx::Init(FbxManager** pSdkManager, FbxScene** pScene)
{
*pSdkManager = FbxManager::Create();
if (!pSdkManager)
{
throw gcnew Exception(gcnew String("Unable to create the FBX SDK manager"));
}
FbxIOSettings* ios = FbxIOSettings::Create(*pSdkManager, IOSROOT);
(*pSdkManager)->SetIOSettings(ios);
*pScene = FbxScene::Create(*pSdkManager, "");
}
Vector3 Fbx::QuaternionToEuler(Quaternion q)
{
FbxAMatrix lMatrixRot;
lMatrixRot.SetQ(FbxQuaternion(q.X, q.Y, q.Z, q.W));
FbxVector4 lEuler = lMatrixRot.GetR();
return Vector3((float)lEuler[0], (float)lEuler[1], (float)lEuler[2]);
}
Quaternion Fbx::EulerToQuaternion(Vector3 v)
{
FbxAMatrix lMatrixRot;
lMatrixRot.SetR(FbxVector4(v.X, v.Y, v.Z));
FbxQuaternion lQuaternion = lMatrixRot.GetQ();
return Quaternion((float)lQuaternion[0], (float)lQuaternion[1], (float)lQuaternion[2], (float)lQuaternion[3]);
}
}

View File

@@ -0,0 +1,86 @@
#pragma once
#include <fbxsdk.h>
#ifdef IOS_REF
#undef IOS_REF
#define IOS_REF (*(pSdkManager->GetIOSettings()))
#endif
using namespace System;
using namespace System::Collections::Generic;
using namespace System::IO;
#define WITH_MARSHALLED_STRING(name,str,block)\
{ \
char* name; \
try \
{ \
name = StringToUTF8(str); \
block \
} \
finally \
{ \
delete name; \
} \
}
static char* FBXVersion[] =
{
FBX_2010_00_COMPATIBLE,
FBX_2011_00_COMPATIBLE,
FBX_2012_00_COMPATIBLE,
FBX_2013_00_COMPATIBLE,
FBX_2014_00_COMPATIBLE,
FBX_2016_00_COMPATIBLE
};
namespace AssetStudio {
public ref class Fbx
{
public:
static Vector3 QuaternionToEuler(Quaternion q);
static Quaternion EulerToQuaternion(Vector3 v);
static char* StringToUTF8(String^ s);
static void Init(FbxManager** pSdkManager, FbxScene** pScene);
ref class Exporter
{
public:
static void Export(String^ path, IImported^ imported, bool eulerFilter, float filterPrecision,
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, float scaleFactor, int versionIndex, bool isAscii);
private:
bool exportSkins;
float boneSize;
IImported^ imported;
HashSet<String^>^ framePaths;
Dictionary<ImportedFrame^, size_t>^ frameToNode;
List<ImportedFrame^>^ meshFrames;
char* cDest;
FbxManager* pSdkManager;
FbxScene* pScene;
FbxExporter* pExporter;
FbxArray<FbxSurfacePhong*>* pMaterials;
FbxArray<FbxFileTexture*>* pTextures;
FbxPose* pBindPose;
Exporter(String^ name, IImported^ imported, bool allNodes, bool skins, bool castToBone, float boneSize, float scaleFactor, int versionIndex, bool isAscii);
~Exporter();
void Exporter::LinkTexture(ImportedMaterialTexture^ texture, FbxFileTexture* pTexture, FbxProperty& prop);
void SetJointsNode(ImportedFrame^ frame, HashSet<String^>^ bonePaths, bool allBones);
HashSet<String^>^ SearchHierarchy();
void SearchHierarchy(ImportedFrame^ frame, HashSet<String^>^ exportFrames);
void SetJointsFromImportedMeshes(bool allBones);
void ExportFrame(FbxNode* pParentNode, ImportedFrame^ frame);
void ExportMesh(FbxNode* pFrameNode, ImportedMesh^ iMesh);
FbxFileTexture* ExportTexture(ImportedTexture^ matTex);
void ExportAnimations(bool eulerFilter, float filterValue);
void ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* eulerFilter, float filterPrecision);
void ExportMorphs();
};
};
}

View File

@@ -20,9 +20,10 @@
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{11ea25a3-ed68-40ee-a9d0-7fde3b583027}</ProjectGuid>
<RootNamespace>AssetStudioFBXNative</RootNamespace>
<ProjectGuid>{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}</ProjectGuid>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<Keyword>ManagedCProj</Keyword>
<RootNamespace>AssetStudioFBX</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
@@ -30,26 +31,28 @@
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CLRSupport>true</CLRSupport>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CLRSupport>true</CLRSupport>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CLRSupport>true</CLRSupport>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CLRSupport>true</CLRSupport>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -70,135 +73,69 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<TargetExt>.dll</TargetExt>
<OutDir>bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<TargetExt>.dll</TargetExt>
<OutDir>bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<TargetExt>.dll</TargetExt>
<OutDir>bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetExt>.dll</TargetExt>
<OutDir>bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_AS_DLL;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>FBXSDK_SHARED;WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x86\debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_AS_DLL;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>libfbxsdk.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x86\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_AS_DLL;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>FBXSDK_SHARED;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x64\debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<AdditionalDependencies>libfbxsdk.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PreprocessorDefinitions>FBXSDK_SHARED;WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>libfbxsdk.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x86\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_AS_DLL;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>FBXSDK_SHARED;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>libfbxsdk.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\lib\vs2017\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="asfbx_anim_context.cpp" />
<ClCompile Include="asfbx_context.cpp" />
<ClCompile Include="api.cpp" />
<ClCompile Include="asfbx_morph_context.cpp" />
<ClCompile Include="asfbx_skin_context.cpp" />
<ClCompile Include="utils.cpp" />
<ClInclude Include="AssetStudioFBX.h" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="api.h" />
<ClInclude Include="asfbx_anim_context.h" />
<ClInclude Include="asfbx_context.h" />
<ClInclude Include="asfbx_morph_context.h" />
<ClInclude Include="asfbx_skin_context.h" />
<ClInclude Include="bool32_t.h" />
<ClInclude Include="dllexport.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="utils.h" />
<ClCompile Include="AssemblyInfo.cpp" />
<ClCompile Include="AssetStudioFBX.cpp" />
<ClCompile Include="AssetStudioFBXExporter.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="AssetStudioFBXNative.rc" />
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj">
<Project>{7662f8c2-7bfd-442e-a948-a43b4f7eb06e}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<Target Name="AfterBuild">
<MSBuild Condition=" '$(Platform)' == 'Win32' " Projects="$(MSBuildProjectFile)" Properties="Platform=x64;PlatFormTarget=x64" RunEachTargetSeparately="true" />
</Target>
</Project>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="源文件">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="头文件">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="资源文件">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="AssetStudioFBX.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="AssemblyInfo.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="AssetStudioFBX.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="AssetStudioFBXExporter.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,915 @@
#include "AssetStudioFBX.h"
namespace AssetStudio
{
void Fbx::Exporter::Export(String^ path, IImported^ imported, bool eulerFilter, float filterPrecision,
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, float scaleFactor, int versionIndex, bool isAscii)
{
FileInfo^ file = gcnew FileInfo(path);
DirectoryInfo^ dir = file->Directory;
if (!dir->Exists)
{
dir->Create();
}
String^ currentDir = Directory::GetCurrentDirectory();
Directory::SetCurrentDirectory(dir->FullName);
auto name = Path::GetFileName(path);
Exporter^ exporter = gcnew Exporter(name, imported, allNodes, skins, castToBone, boneSize, scaleFactor, versionIndex, isAscii);
if (blendShape)
{
exporter->ExportMorphs();
}
if (animation)
{
exporter->ExportAnimations(eulerFilter, filterPrecision);
}
exporter->pExporter->Export(exporter->pScene);
delete exporter;
Directory::SetCurrentDirectory(currentDir);
}
Fbx::Exporter::Exporter(String^ name, IImported^ imported, bool allNodes, bool skins, bool castToBone, float boneSize, float scaleFactor, int versionIndex, bool isAscii)
{
this->imported = imported;
exportSkins = skins;
this->boneSize = boneSize;
cDest = NULL;
pSdkManager = NULL;
pScene = NULL;
pExporter = NULL;
pMaterials = NULL;
pTextures = NULL;
pin_ptr<FbxManager*> pSdkManagerPin = &pSdkManager;
pin_ptr<FbxScene*> pScenePin = &pScene;
Init(pSdkManagerPin, pScenePin);
IOS_REF.SetBoolProp(EXP_FBX_MATERIAL, true);
IOS_REF.SetBoolProp(EXP_FBX_TEXTURE, true);
IOS_REF.SetBoolProp(EXP_FBX_EMBEDDED, false);
IOS_REF.SetBoolProp(EXP_FBX_SHAPE, true);
IOS_REF.SetBoolProp(EXP_FBX_GOBO, true);
IOS_REF.SetBoolProp(EXP_FBX_ANIMATION, true);
IOS_REF.SetBoolProp(EXP_FBX_GLOBAL_SETTINGS, true);
FbxGlobalSettings& globalSettings = pScene->GetGlobalSettings();
globalSettings.SetSystemUnit(FbxSystemUnit(scaleFactor));
if (imported->AnimationList->Count > 0)
{
auto ani = imported->AnimationList[0];
if (ani->SampleRate == 60.0f)
{
globalSettings.SetTimeMode(FbxTime::eFrames60);
}
}
cDest = StringToUTF8(name);
pExporter = FbxExporter::Create(pScene, "");
int pFileFormat = 0;
if (versionIndex == 0)
{
pFileFormat = 3;
if (isAscii)
{
pFileFormat = 4;
}
}
else
{
pExporter->SetFileExportVersion(FBXVersion[versionIndex]);
if (isAscii)
{
pFileFormat = 1;
}
}
if (!pExporter->Initialize(cDest, pFileFormat, pSdkManager->GetIOSettings()))
{
throw gcnew Exception(gcnew String("Failed to initialize FbxExporter: ") + gcnew String(pExporter->GetStatus().GetErrorString()));
}
framePaths = nullptr;
if (!allNodes)
{
framePaths = SearchHierarchy();
if (!framePaths)
{
return;
}
}
pBindPose = FbxPose::Create(pScene, "BindPose");
pScene->AddPose(pBindPose);
frameToNode = gcnew Dictionary<ImportedFrame^, size_t>();
meshFrames = imported->MeshList != nullptr ? gcnew List<ImportedFrame^>() : nullptr;
ExportFrame(pScene->GetRootNode(), imported->RootFrame);
if (imported->MeshList != nullptr)
{
SetJointsFromImportedMeshes(castToBone);
pMaterials = new FbxArray<FbxSurfacePhong*>();
pTextures = new FbxArray<FbxFileTexture*>();
pMaterials->Reserve(imported->MaterialList->Count);
pTextures->Reserve(imported->TextureList->Count);
for (int i = 0; i < meshFrames->Count; i++)
{
auto meshFram = meshFrames[i];
FbxNode* meshNode = (FbxNode*)frameToNode[meshFram];
ImportedMesh^ mesh = ImportedHelpers::FindMesh(meshFram->Path, imported->MeshList);
ExportMesh(meshNode, mesh);
}
}
else
{
SetJointsNode(imported->RootFrame, nullptr, true);
}
}
Fbx::Exporter::~Exporter()
{
imported = nullptr;
if (framePaths != nullptr)
{
framePaths->Clear();
}
if (frameToNode != nullptr)
{
frameToNode->Clear();
}
if (meshFrames != nullptr)
{
meshFrames->Clear();
}
if (pMaterials != NULL)
{
delete pMaterials;
}
if (pTextures != NULL)
{
delete pTextures;
}
if (pExporter != NULL)
{
pExporter->Destroy();
}
if (pScene != NULL)
{
pScene->Destroy();
}
if (pSdkManager != NULL)
{
pSdkManager->Destroy();
}
if (cDest != NULL)
{
delete cDest;
}
}
void Fbx::Exporter::SetJointsNode(ImportedFrame^ frame, HashSet<String^>^ bonePaths, bool castToBone)
{
size_t pointer;
if (frameToNode->TryGetValue(frame, pointer))
{
auto pNode = (FbxNode*)pointer;
if (castToBone)
{
FbxSkeleton* pJoint = FbxSkeleton::Create(pScene, "");
pJoint->Size.Set(FbxDouble(boneSize));
pJoint->SetSkeletonType(FbxSkeleton::eLimbNode);
pNode->SetNodeAttribute(pJoint);
}
else if (bonePaths->Contains(frame->Path))
{
FbxSkeleton* pJoint = FbxSkeleton::Create(pScene, "");
pJoint->Size.Set(FbxDouble(boneSize));
pJoint->SetSkeletonType(FbxSkeleton::eLimbNode);
pNode->SetNodeAttribute(pJoint);
pJoint = FbxSkeleton::Create(pScene, "");
pJoint->Size.Set(FbxDouble(boneSize));
pJoint->SetSkeletonType(FbxSkeleton::eLimbNode);
pNode->GetParent()->SetNodeAttribute(pJoint);
}
else
{
FbxNull* pNull = FbxNull::Create(pScene, "");
if (pNode->GetChildCount() > 0)
{
pNull->Look.Set(FbxNull::eNone);
}
pNode->SetNodeAttribute(pNull);
}
}
for (int i = 0; i < frame->Count; i++)
{
SetJointsNode(frame[i], bonePaths, castToBone);
}
}
HashSet<String^>^ Fbx::Exporter::SearchHierarchy()
{
if (imported->MeshList == nullptr || imported->MeshList->Count == 0)
{
return nullptr;
}
HashSet<String^>^ exportFrames = gcnew HashSet<String^>();
SearchHierarchy(imported->RootFrame, exportFrames);
return exportFrames;
}
void Fbx::Exporter::SearchHierarchy(ImportedFrame^ frame, HashSet<String^>^ exportFrames)
{
ImportedMesh^ meshListSome = ImportedHelpers::FindMesh(frame->Path, imported->MeshList);
if (meshListSome != nullptr)
{
ImportedFrame^ parent = frame;
while (parent != nullptr)
{
exportFrames->Add(parent->Path);
parent = parent->Parent;
}
List<ImportedBone^>^ boneList = meshListSome->BoneList;
if (boneList != nullptr)
{
for (int i = 0; i < boneList->Count; i++)
{
if (!exportFrames->Contains(boneList[i]->Path))
{
ImportedFrame^ boneParent = imported->RootFrame->FindFrameByPath(boneList[i]->Path);
while (boneParent != nullptr)
{
exportFrames->Add(boneParent->Path);
boneParent = boneParent->Parent;
}
}
}
}
}
for (int i = 0; i < frame->Count; i++)
{
SearchHierarchy(frame[i], exportFrames);
}
}
void Fbx::Exporter::SetJointsFromImportedMeshes(bool castToBone)
{
if (!exportSkins)
{
return;
}
HashSet<String^>^ bonePaths = gcnew HashSet<String^>();
for (int i = 0; i < imported->MeshList->Count; i++)
{
ImportedMesh^ meshList = imported->MeshList[i];
List<ImportedBone^>^ boneList = meshList->BoneList;
if (boneList != nullptr)
{
for (int j = 0; j < boneList->Count; j++)
{
ImportedBone^ bone = boneList[j];
bonePaths->Add(bone->Path);
}
}
}
SetJointsNode(imported->RootFrame, bonePaths, castToBone);
}
void Fbx::Exporter::ExportFrame(FbxNode* pParentNode, ImportedFrame^ frame)
{
if (framePaths == nullptr || framePaths->Contains(frame->Path))
{
FbxNode* pFrameNode;
WITH_MARSHALLED_STRING
(
pName,
frame->Name,
pFrameNode = FbxNode::Create(pScene, pName);
);
pFrameNode->LclScaling.Set(FbxDouble3(frame->LocalScale.X, frame->LocalScale.Y, frame->LocalScale.Z));
pFrameNode->LclRotation.Set(FbxDouble3(frame->LocalRotation.X, frame->LocalRotation.Y, frame->LocalRotation.Z));
pFrameNode->LclTranslation.Set(FbxDouble3(frame->LocalPosition.X, frame->LocalPosition.Y, frame->LocalPosition.Z));
pFrameNode->SetPreferedAngle(pFrameNode->LclRotation.Get());
pParentNode->AddChild(pFrameNode);
pBindPose->Add(pFrameNode, pFrameNode->EvaluateGlobalTransform());
if (imported->MeshList != nullptr && ImportedHelpers::FindMesh(frame->Path, imported->MeshList) != nullptr)
{
meshFrames->Add(frame);
}
frameToNode->Add(frame, (size_t)pFrameNode);
for (int i = 0; i < frame->Count; i++)
{
ExportFrame(pFrameNode, frame[i]);
}
}
}
void Fbx::Exporter::ExportMesh(FbxNode* pFrameNode, ImportedMesh^ iMesh)
{
List<ImportedBone^>^ boneList = iMesh->BoneList;
bool hasBones;
if (exportSkins && boneList != nullptr)
{
hasBones = boneList->Count > 0;
}
else
{
hasBones = false;
}
FbxArray<FbxCluster*>* pClusterArray = nullptr;
try
{
if (hasBones)
{
pClusterArray = new FbxArray<FbxCluster*>(boneList->Count);
for (int i = 0; i < boneList->Count; i++)
{
auto bone = boneList[i];
if (bone->Path != nullptr)
{
auto frame = imported->RootFrame->FindFrameByPath(bone->Path);
auto boneNode = (FbxNode*)frameToNode[frame];
FbxString lClusterName = boneNode->GetNameOnly() + FbxString("Cluster");
FbxCluster* pCluster = FbxCluster::Create(pScene, lClusterName.Buffer());
pCluster->SetLink(boneNode);
pCluster->SetLinkMode(FbxCluster::eTotalOne);
pClusterArray->Add(pCluster);
}
else
{
pClusterArray->Add(NULL);
}
}
}
FbxMesh* pMesh = FbxMesh::Create(pScene, pFrameNode->GetName());
pFrameNode->SetNodeAttribute(pMesh);
int vertexCount = 0;
for (int i = 0; i < iMesh->SubmeshList->Count; i++)
{
vertexCount += iMesh->SubmeshList[i]->VertexList->Count;
}
pMesh->InitControlPoints(vertexCount);
FbxVector4* pControlPoints = pMesh->GetControlPoints();
FbxGeometryElementNormal* lGeometryElementNormal = NULL;
if (iMesh->hasNormal)
{
lGeometryElementNormal = pMesh->CreateElementNormal();
lGeometryElementNormal->SetMappingMode(FbxGeometryElement::eByControlPoint);
lGeometryElementNormal->SetReferenceMode(FbxGeometryElement::eDirect);
}
if (iMesh->hasUV[0])
{
auto lGeometryElementUV = pMesh->CreateElementUV("UV0", FbxLayerElement::eTextureDiffuse);
lGeometryElementUV->SetMappingMode(FbxGeometryElement::eByControlPoint);
lGeometryElementUV->SetReferenceMode(FbxGeometryElement::eDirect);
}
if (iMesh->hasUV[1])
{
auto lGeometryElementUV = pMesh->CreateElementUV("UV1", FbxLayerElement::eTextureNormalMap);
lGeometryElementUV->SetMappingMode(FbxGeometryElement::eByControlPoint);
lGeometryElementUV->SetReferenceMode(FbxGeometryElement::eDirect);
}
/*for (int uv = 0; uv < 8; uv++)
{
if (iMesh->hasUV[uv])
{
auto lGeometryElementUV = pMesh->CreateElementUV(FbxString("UV") + FbxString(uv));
lGeometryElementUV->SetMappingMode(FbxGeometryElement::eByControlPoint);
lGeometryElementUV->SetReferenceMode(FbxGeometryElement::eDirect);
}
}*/
FbxGeometryElementTangent* lGeometryElementTangent = NULL;
if (iMesh->hasTangent)
{
lGeometryElementTangent = pMesh->CreateElementTangent();
lGeometryElementTangent->SetMappingMode(FbxGeometryElement::eByControlPoint);
lGeometryElementTangent->SetReferenceMode(FbxGeometryElement::eDirect);
}
FbxGeometryElementVertexColor* lGeometryElementVertexColor = NULL;
if (iMesh->hasColor)
{
lGeometryElementVertexColor = pMesh->CreateElementVertexColor();
lGeometryElementVertexColor->SetMappingMode(FbxGeometryElement::eByControlPoint);
lGeometryElementVertexColor->SetReferenceMode(FbxGeometryElement::eDirect);
}
FbxGeometryElementMaterial* lGeometryElementMaterial = pMesh->CreateElementMaterial();
lGeometryElementMaterial->SetMappingMode(FbxGeometryElement::eByPolygon);
lGeometryElementMaterial->SetReferenceMode(FbxGeometryElement::eIndexToDirect);
int firstVertex = 0;
for (int i = 0; i < iMesh->SubmeshList->Count; i++)
{
ImportedSubmesh^ meshObj = iMesh->SubmeshList[i];
List<ImportedVertex^>^ vertexList = meshObj->VertexList;
List<ImportedFace^>^ faceList = meshObj->FaceList;
int materialIndex = 0;
ImportedMaterial^ mat = ImportedHelpers::FindMaterial(meshObj->Material, imported->MaterialList);
if (mat != nullptr)
{
char* pMatName = NULL;
try
{
pMatName = StringToUTF8(mat->Name);
int foundMat = -1;
for (int j = 0; j < pMaterials->GetCount(); j++)
{
FbxSurfacePhong* pMatTemp = pMaterials->GetAt(j);
if (strcmp(pMatTemp->GetName(), pMatName) == 0)
{
foundMat = j;
break;
}
}
FbxSurfacePhong* pMat;
if (foundMat >= 0)
{
pMat = pMaterials->GetAt(foundMat);
}
else
{
FbxString lShadingName = "Phong";
Color diffuse = mat->Diffuse;
Color ambient = mat->Ambient;
Color emissive = mat->Emissive;
Color specular = mat->Specular;
Color reflection = mat->Reflection;
pMat = FbxSurfacePhong::Create(pScene, pMatName);
pMat->Diffuse.Set(FbxDouble3(diffuse.R, diffuse.G, diffuse.B));
//pMat->DiffuseFactor.Set(FbxDouble(diffuse.A));
pMat->Ambient.Set(FbxDouble3(ambient.R, ambient.G, ambient.B));
//pMat->AmbientFactor.Set(FbxDouble(ambient.A));
pMat->Emissive.Set(FbxDouble3(emissive.R, emissive.G, emissive.B));
//pMat->EmissiveFactor.Set(FbxDouble(emissive.A));
pMat->Specular.Set(FbxDouble3(specular.R, specular.G, specular.B));
//pMat->SpecularFactor.Set(FbxDouble(specular.A));
pMat->Reflection.Set(FbxDouble3(reflection.R, reflection.G, reflection.B));
//pMat->ReflectionFactor.Set(FbxDouble(reflection.A));
pMat->Shininess.Set(FbxDouble(mat->Shininess));
pMat->TransparencyFactor.Set(FbxDouble(mat->Transparency));
pMat->ShadingModel.Set(lShadingName);
pMaterials->Add(pMat);
}
materialIndex = pFrameNode->AddMaterial(pMat);
bool hasTexture = false;
for each (ImportedMaterialTexture ^ texture in mat->Textures)
{
auto pTexture = ExportTexture(ImportedHelpers::FindTexture(texture->Name, imported->TextureList));
if (pTexture != NULL)
{
if (texture->Dest == 0)
{
LinkTexture(texture, pTexture, pMat->Diffuse);
hasTexture = true;
}
else if (texture->Dest == 1)
{
LinkTexture(texture, pTexture, pMat->NormalMap);
hasTexture = true;
}
else if (texture->Dest == 2)
{
LinkTexture(texture, pTexture, pMat->Specular);
hasTexture = true;
}
else if (texture->Dest == 3)
{
LinkTexture(texture, pTexture, pMat->Bump);
hasTexture = true;
}
}
}
if (hasTexture)
{
pFrameNode->SetShadingMode(FbxNode::eTextureShading);
}
}
finally
{
delete pMatName;
}
}
for (int j = 0; j < vertexList->Count; j++)
{
ImportedVertex^ iVertex = vertexList[j];
Vector3 vertex = iVertex->Vertex;
pControlPoints[j + firstVertex] = FbxVector4(vertex.X, vertex.Y, vertex.Z, 0);
if (iMesh->hasNormal)
{
Vector3 normal = iVertex->Normal;
lGeometryElementNormal->GetDirectArray().Add(FbxVector4(normal.X, normal.Y, normal.Z, 0));
}
//for (int uv = 0; uv < 8; uv++)
for (int uv = 0; uv < 2; uv++)
{
if (iMesh->hasUV[uv])
{
auto m_UV = iVertex->UV[uv];
auto lGeometryElementUV = pMesh->GetElementUV(uv);
lGeometryElementUV->GetDirectArray().Add(FbxVector2(m_UV[0], m_UV[1]));
}
}
if (iMesh->hasTangent)
{
Vector4 tangent = iVertex->Tangent;
lGeometryElementTangent->GetDirectArray().Add(FbxVector4(tangent.X, tangent.Y, tangent.Z, tangent.W));
}
if (iMesh->hasColor)
{
auto color = iVertex->Color;
lGeometryElementVertexColor->GetDirectArray().Add(FbxColor(color.R, color.G, color.B, color.A));
}
if (hasBones && iVertex->BoneIndices != nullptr)
{
auto boneIndices = iVertex->BoneIndices;
auto weights4 = iVertex->Weights;
for (int k = 0; k < 4; k++)
{
if (boneIndices[k] < boneList->Count && weights4[k] > 0)
{
FbxCluster* pCluster = pClusterArray->GetAt(boneIndices[k]);
if (pCluster)
{
pCluster->AddControlPointIndex(j + firstVertex, weights4[k]);
}
}
}
}
}
for (int j = 0; j < faceList->Count; j++)
{
ImportedFace^ face = faceList[j];
pMesh->BeginPolygon(materialIndex);
pMesh->AddPolygon(face->VertexIndices[0] + firstVertex);
pMesh->AddPolygon(face->VertexIndices[1] + firstVertex);
pMesh->AddPolygon(face->VertexIndices[2] + firstVertex);
pMesh->EndPolygon();
}
firstVertex += vertexList->Count;
}
if (hasBones)
{
FbxSkin* pSkin = FbxSkin::Create(pScene, "");
FbxAMatrix lMeshMatrix = pFrameNode->EvaluateGlobalTransform();
for (int j = 0; j < boneList->Count; j++)
{
FbxCluster* pCluster = pClusterArray->GetAt(j);
if (pCluster)
{
auto boneMatrix = boneList[j]->Matrix;
FbxAMatrix lBoneMatrix;
for (int m = 0; m < 4; m++)
{
for (int n = 0; n < 4; n++)
{
lBoneMatrix.mData[m][n] = boneMatrix[m, n];
}
}
pCluster->SetTransformMatrix(lMeshMatrix);
pCluster->SetTransformLinkMatrix(lMeshMatrix * lBoneMatrix.Inverse());
pSkin->AddCluster(pCluster);
}
}
if (pSkin->GetClusterCount() > 0)
{
pMesh->AddDeformer(pSkin);
}
}
}
finally
{
if (pClusterArray != NULL)
{
delete pClusterArray;
}
}
}
FbxFileTexture* Fbx::Exporter::ExportTexture(ImportedTexture^ matTex)
{
FbxFileTexture* pTex = NULL;
if (matTex != nullptr)
{
String^ matTexName = matTex->Name;
char* pTexName = NULL;
try
{
pTexName = StringToUTF8(matTexName);
int foundTex = -1;
for (int i = 0; i < pTextures->GetCount(); i++)
{
FbxFileTexture* pTexTemp = pTextures->GetAt(i);
if (strcmp(pTexTemp->GetName(), pTexName) == 0)
{
foundTex = i;
break;
}
}
if (foundTex >= 0)
{
pTex = pTextures->GetAt(foundTex);
}
else
{
pTex = FbxFileTexture::Create(pScene, pTexName);
pTex->SetFileName(pTexName);
pTex->SetTextureUse(FbxTexture::eStandard);
pTex->SetMappingType(FbxTexture::eUV);
pTex->SetMaterialUse(FbxFileTexture::eModelMaterial);
pTex->SetSwapUV(false);
pTex->SetTranslation(0.0, 0.0);
pTex->SetScale(1.0, 1.0);
pTex->SetRotation(0.0, 0.0);
pTextures->Add(pTex);
FileInfo^ file = gcnew FileInfo(matTex->Name);
BinaryWriter^ writer = gcnew BinaryWriter(file->Create());
writer->Write(matTex->Data);
writer->Close();
}
}
finally
{
delete pTexName;
}
}
return pTex;
}
void Fbx::Exporter::LinkTexture(ImportedMaterialTexture^ texture, FbxFileTexture* pTexture, FbxProperty& prop)
{
pTexture->SetTranslation(texture->Offset.X, texture->Offset.Y);
pTexture->SetScale(texture->Scale.X, texture->Scale.Y);
prop.ConnectSrcObject(pTexture);
}
void Fbx::Exporter::ExportAnimations(bool eulerFilter, float filterPrecision)
{
auto importedAnimationList = imported->AnimationList;
if (importedAnimationList == nullptr)
{
return;
}
FbxAnimCurveFilterUnroll* lFilter = eulerFilter ? new FbxAnimCurveFilterUnroll() : NULL;
for (int i = 0; i < importedAnimationList->Count; i++)
{
auto importedAnimation = importedAnimationList[i];
FbxString kTakeName;
if (importedAnimation->Name)
{
WITH_MARSHALLED_STRING
(
pClipName,
importedAnimation->Name,
kTakeName = FbxString(pClipName);
);
}
else
{
kTakeName = FbxString("Take") + FbxString(i);
}
ExportKeyframedAnimation(importedAnimation, kTakeName, lFilter, filterPrecision);
}
}
void Fbx::Exporter::ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* eulerFilter, float filterPrecision)
{
List<ImportedAnimationKeyframedTrack^>^ pAnimationList = parser->TrackList;
char* lTakeName = kTakeName.Buffer();
FbxAnimStack* lAnimStack = FbxAnimStack::Create(pScene, lTakeName);
FbxAnimLayer* lAnimLayer = FbxAnimLayer::Create(pScene, "Base Layer");
lAnimStack->AddMember(lAnimLayer);
for (int j = 0; j < pAnimationList->Count; j++)
{
ImportedAnimationKeyframedTrack^ keyframeList = pAnimationList[j];
if (keyframeList->Path == nullptr)
{
continue;
}
auto frame = imported->RootFrame->FindFrameByPath(keyframeList->Path);
if (frame != nullptr)
{
FbxNode* pNode = (FbxNode*)frameToNode[frame];
FbxAnimCurve* lCurveSX = pNode->LclScaling.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_X, true);
FbxAnimCurve* lCurveSY = pNode->LclScaling.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y, true);
FbxAnimCurve* lCurveSZ = pNode->LclScaling.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z, true);
FbxAnimCurve* lCurveRX = pNode->LclRotation.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_X, true);
FbxAnimCurve* lCurveRY = pNode->LclRotation.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y, true);
FbxAnimCurve* lCurveRZ = pNode->LclRotation.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z, true);
FbxAnimCurve* lCurveTX = pNode->LclTranslation.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_X, true);
FbxAnimCurve* lCurveTY = pNode->LclTranslation.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y, true);
FbxAnimCurve* lCurveTZ = pNode->LclTranslation.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z, true);
lCurveSX->KeyModifyBegin();
lCurveSY->KeyModifyBegin();
lCurveSZ->KeyModifyBegin();
lCurveRX->KeyModifyBegin();
lCurveRY->KeyModifyBegin();
lCurveRZ->KeyModifyBegin();
lCurveTX->KeyModifyBegin();
lCurveTY->KeyModifyBegin();
lCurveTZ->KeyModifyBegin();
FbxTime lTime;
for each (auto Scaling in keyframeList->Scalings)
{
lTime.SetSecondDouble(Scaling->time);
lCurveSX->KeySet(lCurveSX->KeyAdd(lTime), lTime, Scaling->value.X);
lCurveSY->KeySet(lCurveSY->KeyAdd(lTime), lTime, Scaling->value.Y);
lCurveSZ->KeySet(lCurveSZ->KeyAdd(lTime), lTime, Scaling->value.Z);
}
for each (auto Rotation in keyframeList->Rotations)
{
lTime.SetSecondDouble(Rotation->time);
lCurveRX->KeySet(lCurveRX->KeyAdd(lTime), lTime, Rotation->value.X);
lCurveRY->KeySet(lCurveRY->KeyAdd(lTime), lTime, Rotation->value.Y);
lCurveRZ->KeySet(lCurveRZ->KeyAdd(lTime), lTime, Rotation->value.Z);
}
for each (auto Translation in keyframeList->Translations)
{
lTime.SetSecondDouble(Translation->time);
lCurveTX->KeySet(lCurveTX->KeyAdd(lTime), lTime, Translation->value.X);
lCurveTY->KeySet(lCurveTY->KeyAdd(lTime), lTime, Translation->value.Y);
lCurveTZ->KeySet(lCurveTZ->KeyAdd(lTime), lTime, Translation->value.Z);
}
lCurveSX->KeyModifyEnd();
lCurveSY->KeyModifyEnd();
lCurveSZ->KeyModifyEnd();
lCurveRX->KeyModifyEnd();
lCurveRY->KeyModifyEnd();
lCurveRZ->KeyModifyEnd();
lCurveTX->KeyModifyEnd();
lCurveTY->KeyModifyEnd();
lCurveTZ->KeyModifyEnd();
if (eulerFilter)
{
FbxAnimCurve* lCurve[3];
lCurve[0] = lCurveRX;
lCurve[1] = lCurveRY;
lCurve[2] = lCurveRZ;
eulerFilter->Reset();
eulerFilter->SetQualityTolerance(filterPrecision);
eulerFilter->Apply(lCurve, 3);
}
//BlendShape
if (keyframeList->BlendShape != nullptr)
{
FbxString channelName;
WITH_MARSHALLED_STRING
(
pClipName,
keyframeList->BlendShape->ChannelName,
channelName = FbxString(pClipName);
);
auto lGeometry = (FbxGeometry*)pNode->GetNodeAttribute();
int lBlendShapeDeformerCount = lGeometry->GetDeformerCount(FbxDeformer::eBlendShape);
if (lBlendShapeDeformerCount > 0)
{
FbxBlendShape* lBlendShape = (FbxBlendShape*)lGeometry->GetDeformer(0, FbxDeformer::eBlendShape);
int lBlendShapeChannelCount = lBlendShape->GetBlendShapeChannelCount();
for (int lChannelIndex = 0; lChannelIndex < lBlendShapeChannelCount; ++lChannelIndex)
{
FbxBlendShapeChannel* lChannel = lBlendShape->GetBlendShapeChannel(lChannelIndex);
FbxString lChannelName = lChannel->GetNameOnly();
if (lChannelName == channelName)
{
FbxAnimCurve* lAnimCurve = lGeometry->GetShapeChannel(0, lChannelIndex, lAnimLayer, true);
lAnimCurve->KeyModifyBegin();
for each (auto keyframe in keyframeList->BlendShape->Keyframes)
{
lTime.SetSecondDouble(keyframe->time);
int lKeyIndex = lAnimCurve->KeyAdd(lTime);
lAnimCurve->KeySetValue(lKeyIndex, keyframe->value);
lAnimCurve->KeySetInterpolation(lKeyIndex, FbxAnimCurveDef::eInterpolationCubic);
}
lAnimCurve->KeyModifyEnd();
}
}
}
}
}
}
}
void Fbx::Exporter::ExportMorphs()
{
if (imported->MeshList == nullptr)
{
return;
}
for each (ImportedMorph ^ morph in imported->MorphList)
{
auto frame = imported->RootFrame->FindFrameByPath(morph->Path);
if (frame != nullptr)
{
FbxNode* pNode = (FbxNode*)frameToNode[frame];
FbxMesh* pMesh = pNode->GetMesh();
FbxBlendShape* lBlendShape = FbxBlendShape::Create(pScene, pMesh->GetNameOnly() + FbxString("BlendShape"));
pMesh->AddDeformer(lBlendShape);
for (int i = 0; i < morph->Channels->Count; i++)
{
auto channel = morph->Channels[i];
FbxBlendShapeChannel* lBlendShapeChannel;
WITH_MARSHALLED_STRING
(
pChannelName,
channel->Name,
lBlendShapeChannel = FbxBlendShapeChannel::Create(pScene, pChannelName);
);
lBlendShape->AddBlendShapeChannel(lBlendShapeChannel);
for each (ImportedMorphKeyframe ^ keyframe in channel->KeyframeList)
{
FbxShape* lShape = FbxShape::Create(pScene, FbxString(keyframe->Weight));
lBlendShapeChannel->AddTargetShape(lShape, keyframe->Weight);
auto vectorCount = pMesh->GetControlPointsCount();
FbxVector4* orilVector4 = pMesh->GetControlPoints();
lShape->InitControlPoints(vectorCount);
FbxVector4* lVector4 = lShape->GetControlPoints();
for (int j = 0; j < vectorCount; j++)
{
auto vertex = orilVector4[j];
lVector4[j] = FbxVector4(vertex);
}
for (int j = 0; j < keyframe->VertexList->Count; j++)
{
auto index = keyframe->VertexList[j]->Index;
auto vertex = keyframe->VertexList[j]->Vertex->Vertex;
lVector4[index] = FbxVector4(vertex.X, vertex.Y, vertex.Z, 0);
}
}
}
}
}
}
}

View File

@@ -1,99 +0,0 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Language neutral resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
#pragma code_page(65001)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "000004b0"
BEGIN
VALUE "FileDescription", "AssetStudioFBXNative"
VALUE "FileVersion", "1.0.0.1"
VALUE "InternalName", "AssetStudioFBXNative.dll"
VALUE "LegalCopyright", "Copyright (C) Perfare 2018-2020; Copyright (C) hozuki 2020"
VALUE "OriginalFilename", "AssetStudioFBXNative.dll"
VALUE "ProductName", "AssetStudioFBXNative"
VALUE "ProductVersion", "1.0.0.1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1200
END
END
#endif // Language neutral resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -1,74 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="源文件">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="头文件">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="资源文件">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="utils.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="api.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="asfbx_context.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="asfbx_skin_context.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="asfbx_anim_context.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="asfbx_morph_context.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="dllexport.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="api.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="utils.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="bool32_t.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="asfbx_context.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="asfbx_skin_context.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="asfbx_anim_context.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="asfbx_morph_context.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="AssetStudioFBXNative.rc">
<Filter>资源文件</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

View File

@@ -1,161 +0,0 @@
#pragma once
#include "dllexport.h"
#include "bool32_t.h"
namespace fbxsdk
{
class FbxNode;
class FbxFileTexture;
template<typename T, const int Alignment = 16>
class FbxArray;
class FbxCluster;
class FbxMesh;
class FbxSurfacePhong;
}
struct AsFbxContext;
struct AsFbxSkinContext;
struct AsFbxAnimContext;
struct AsFbxMorphContext;
AS_API(void) AsUtilQuaternionToEuler(float qx, float qy, float qz, float qw, float* vx, float* vy, float* vz);
AS_API(void) AsUtilEulerToQuaternion(float vx, float vy, float vz, float* qx, float* qy, float* qz, float* qw);
// All strings ([const] char *) in this header are UTF-8 strings.
AS_API(AsFbxContext*) AsFbxCreateContext();
// Do not free pErrMsg
AS_API(bool32_t) AsFbxInitializeContext(AsFbxContext* pContext, const char* pFileName, float scaleFactor, int32_t versionIndex, bool32_t isAscii, bool32_t is60Fps, const char** pErrMsg);
AS_API(void) AsFbxDisposeContext(AsFbxContext** ppContext);
AS_API(void) AsFbxSetFramePaths(AsFbxContext* pContext, const char* ppPaths[], int32_t count);
AS_API(void) AsFbxExportScene(AsFbxContext* pContext);
AS_API(fbxsdk::FbxNode*) AsFbxGetSceneRootNode(AsFbxContext* pContext);
AS_API(fbxsdk::FbxNode*) AsFbxExportSingleFrame(AsFbxContext* pContext, fbxsdk::FbxNode* pParentNode, const char* pFramePath, const char* pFrameName, float localPositionX, float localPositionY, float localPositionZ, float localRotationX, float localRotationY, float localRotationZ, float localScaleX, float localScaleY, float localScaleZ);
AS_API(void) AsFbxSetJointsNode_CastToBone(AsFbxContext* pContext, fbxsdk::FbxNode* pNode, float boneSize);
AS_API(void) AsFbxSetJointsNode_BoneInPath(AsFbxContext* pContext, fbxsdk::FbxNode* pNode, float boneSize);
AS_API(void) AsFbxSetJointsNode_Generic(AsFbxContext* pContext, fbxsdk::FbxNode* pNode);
AS_API(void) AsFbxPrepareMaterials(AsFbxContext* pContext, int32_t materialCount, int32_t textureCount);
AS_API(fbxsdk::FbxFileTexture*) AsFbxCreateTexture(AsFbxContext* pContext, const char* pMatTexName);
AS_API(void) AsFbxLinkTexture(int32_t dest, fbxsdk::FbxFileTexture* pTexture, fbxsdk::FbxSurfacePhong* pMaterial, float offsetX, float offsetY, float scaleX, float scaleY);
AS_API(fbxsdk::FbxArray<fbxsdk::FbxCluster*>*) AsFbxMeshCreateClusterArray(int32_t boneCount);
AS_API(void) AsFbxMeshDisposeClusterArray(fbxsdk::FbxArray<fbxsdk::FbxCluster*>** ppArray);
AS_API(fbxsdk::FbxCluster*) AsFbxMeshCreateCluster(AsFbxContext* pContext, fbxsdk::FbxNode* pBoneNode);
AS_API(void) AsFbxMeshAddCluster(fbxsdk::FbxArray<fbxsdk::FbxCluster*>* pArray, /* CanBeNull */ fbxsdk::FbxCluster* pCluster);
AS_API(fbxsdk::FbxMesh*) AsFbxMeshCreateMesh(AsFbxContext* pContext, fbxsdk::FbxNode* pFrameNode);
AS_API(void) AsFbxMeshInitControlPoints(fbxsdk::FbxMesh* pMesh, int32_t vertexCount);
AS_API(void) AsFbxMeshCreateElementNormal(fbxsdk::FbxMesh* pMesh);
AS_API(void) AsFbxMeshCreateDiffuseUV(fbxsdk::FbxMesh* pMesh, int32_t uv);
AS_API(void) AsFbxMeshCreateNormalMapUV(fbxsdk::FbxMesh* pMesh, int32_t uv);
AS_API(void) AsFbxMeshCreateElementTangent(fbxsdk::FbxMesh* pMesh);
AS_API(void) AsFbxMeshCreateElementVertexColor(fbxsdk::FbxMesh* pMesh);
AS_API(void) AsFbxMeshCreateElementMaterial(fbxsdk::FbxMesh* pMesh);
AS_API(fbxsdk::FbxSurfacePhong*) AsFbxCreateMaterial(AsFbxContext* pContext, const char* pMatName,
float diffuseR, float diffuseG, float diffuseB,
float ambientR, float ambientG, float ambientB,
float emissiveR, float emissiveG, float emissiveB,
float specularR, float specularG, float specularB,
float reflectR, float reflectG, float reflectB,
float shininess, float transparency);
AS_API(int32_t) AsFbxAddMaterialToFrame(fbxsdk::FbxNode* pFrameNode, fbxsdk::FbxSurfacePhong* pMaterial);
AS_API(void) AsFbxSetFrameShadingModeToTextureShading(fbxsdk::FbxNode* pFrameNode);
AS_API(void) AsFbxMeshSetControlPoint(fbxsdk::FbxMesh* pMesh, int32_t index, float x, float y, float z);
AS_API(void) AsFbxMeshAddPolygon(fbxsdk::FbxMesh* pMesh, int32_t materialIndex, int32_t index0, int32_t index1, int32_t index2);
AS_API(void) AsFbxMeshElementNormalAdd(fbxsdk::FbxMesh* pMesh, int32_t elementIndex, float x, float y, float z);
AS_API(void) AsFbxMeshElementUVAdd(fbxsdk::FbxMesh* pMesh, int32_t elementIndex, float u, float v);
AS_API(void) AsFbxMeshElementTangentAdd(fbxsdk::FbxMesh* pMesh, int32_t elementIndex, float x, float y, float z, float w);
AS_API(void) AsFbxMeshElementVertexColorAdd(fbxsdk::FbxMesh* pMesh, int32_t elementIndex, float r, float g, float b, float a);
AS_API(void) AsFbxMeshSetBoneWeight(fbxsdk::FbxArray<fbxsdk::FbxCluster*>* pClusterArray, int32_t boneIndex, int32_t vertexIndex, float weight);
AS_API(AsFbxSkinContext*) AsFbxMeshCreateSkinContext(AsFbxContext* pContext, fbxsdk::FbxNode* pFrameNode);
AS_API(void) AsFbxMeshDisposeSkinContext(AsFbxSkinContext** ppSkinContext);
AS_API(bool32_t) FbxClusterArray_HasItemAt(fbxsdk::FbxArray<fbxsdk::FbxCluster*>* pClusterArray, int32_t index);
AS_API(void) AsFbxMeshSkinAddCluster(AsFbxSkinContext* pSkinContext, fbxsdk::FbxArray<fbxsdk::FbxCluster*>* pClusterArray, int32_t index, float pBoneMatrix[16]);
AS_API(void) AsFbxMeshAddDeformer(AsFbxSkinContext* pSkinContext, fbxsdk::FbxMesh* pMesh);
AS_API(AsFbxAnimContext*) AsFbxAnimCreateContext(bool32_t eulerFilter);
AS_API(void) AsFbxAnimDisposeContext(AsFbxAnimContext** ppAnimContext);
AS_API(void) AsFbxAnimPrepareStackAndLayer(AsFbxContext* pContext, AsFbxAnimContext* pAnimContext, const char* pTakeName);
AS_API(void) AsFbxAnimLoadCurves(fbxsdk::FbxNode* pNode, AsFbxAnimContext* pAnimContext);
AS_API(void) AsFbxAnimBeginKeyModify(AsFbxAnimContext* pAnimContext);
AS_API(void) AsFbxAnimEndKeyModify(AsFbxAnimContext* pAnimContext);
AS_API(void) AsFbxAnimAddScalingKey(AsFbxAnimContext* pAnimContext, float time, float x, float y, float z);
AS_API(void) AsFbxAnimAddRotationKey(AsFbxAnimContext* pAnimContext, float time, float x, float y, float z);
AS_API(void) AsFbxAnimAddTranslationKey(AsFbxAnimContext* pAnimContext, float time, float x, float y, float z);
AS_API(void) AsFbxAnimApplyEulerFilter(AsFbxAnimContext* pAnimContext, float filterPrecision);
AS_API(int32_t) AsFbxAnimGetCurrentBlendShapeChannelCount(AsFbxAnimContext* pAnimContext, fbxsdk::FbxNode* pNode);
AS_API(bool32_t) AsFbxAnimIsBlendShapeChannelMatch(AsFbxAnimContext* pAnimContext, int32_t channelIndex, const char* channelName);
AS_API(void) AsFbxAnimBeginBlendShapeAnimCurve(AsFbxAnimContext* pAnimContext, int32_t channelIndex);
AS_API(void) AsFbxAnimEndBlendShapeAnimCurve(AsFbxAnimContext* pAnimContext);
AS_API(void) AsFbxAnimAddBlendShapeKeyframe(AsFbxAnimContext* pAnimContext, float time, float value);
AS_API(AsFbxMorphContext*) AsFbxMorphCreateContext();
AS_API(void) AsFbxMorphInitializeContext(AsFbxContext* pContext, AsFbxMorphContext* pMorphContext, fbxsdk::FbxNode* pNode);
AS_API(void) AsFbxMorphDisposeContext(AsFbxMorphContext** ppMorphContext);
AS_API(void) AsFbxMorphAddBlendShapeChannel(AsFbxContext* pContext, AsFbxMorphContext* pMorphContext, const char* channelName);
AS_API(void) AsFbxMorphAddBlendShapeChannelShape(AsFbxContext* pContext, AsFbxMorphContext* pMorphContext, float weight, const char* shapeName);
AS_API(void) AsFbxMorphCopyBlendShapeControlPoints(AsFbxMorphContext* pMorphContext);
AS_API(void) AsFbxMorphSetBlendShapeVertex(AsFbxMorphContext* pMorphContext, uint32_t index, float x, float y, float z);
AS_API(void) AsFbxMorphCopyBlendShapeControlPointsNormal(AsFbxMorphContext* pMorphContext);
AS_API(void) AsFbxMorphSetBlendShapeVertexNormal(AsFbxMorphContext* pMorphContext, uint32_t index, float x, float y, float z);

View File

@@ -1,27 +0,0 @@
#include "asfbx_anim_context.h"
AsFbxAnimContext::AsFbxAnimContext(bool32_t eulerFilter)
: lFilter(nullptr)
{
if (eulerFilter)
{
lFilter = new FbxAnimCurveFilterUnroll();
}
lAnimStack = nullptr;
lAnimLayer = nullptr;
lCurveSX = nullptr;
lCurveSY = nullptr;
lCurveSZ = nullptr;
lCurveRX = nullptr;
lCurveRY = nullptr;
lCurveRZ = nullptr;
lCurveTX = nullptr;
lCurveTY = nullptr;
lCurveTZ = nullptr;
pMesh = nullptr;
lBlendShape = nullptr;
lAnimCurve = nullptr;
}

View File

@@ -1,32 +0,0 @@
#pragma once
#include <fbxsdk.h>
#include "bool32_t.h"
struct AsFbxAnimContext
{
FbxAnimCurveFilterUnroll* lFilter;
FbxAnimStack* lAnimStack;
FbxAnimLayer* lAnimLayer;
FbxAnimCurve* lCurveSX;
FbxAnimCurve* lCurveSY;
FbxAnimCurve* lCurveSZ;
FbxAnimCurve* lCurveRX;
FbxAnimCurve* lCurveRY;
FbxAnimCurve* lCurveRZ;
FbxAnimCurve* lCurveTX;
FbxAnimCurve* lCurveTY;
FbxAnimCurve* lCurveTZ;
FbxMesh* pMesh;
FbxBlendShape* lBlendShape;
FbxAnimCurve* lAnimCurve;
AsFbxAnimContext(bool32_t eulerFilter);
~AsFbxAnimContext() = default;
};

View File

@@ -1,33 +0,0 @@
#include <fbxsdk.h>
#include "asfbx_context.h"
AsFbxContext::AsFbxContext()
{
pSdkManager = nullptr;
pScene = nullptr;
pTextures = nullptr;
pMaterials = nullptr;
pExporter = nullptr;
pBindPose = nullptr;
}
AsFbxContext::~AsFbxContext()
{
framePaths.clear();
delete pMaterials;
delete pTextures;
if (pExporter != nullptr) {
pExporter->Destroy();
}
if (pScene != nullptr) {
pScene->Destroy();
}
if (pSdkManager != nullptr) {
pSdkManager->Destroy();
}
}

View File

@@ -1,21 +0,0 @@
#pragma once
#include <cstdint>
#include <string>
#include <unordered_set>
struct AsFbxContext
{
fbxsdk::FbxManager* pSdkManager;
fbxsdk::FbxScene* pScene;
fbxsdk::FbxArray<fbxsdk::FbxFileTexture*>* pTextures;
fbxsdk::FbxArray<fbxsdk::FbxSurfacePhong*>* pMaterials;
fbxsdk::FbxExporter* pExporter;
fbxsdk::FbxPose* pBindPose;
std::unordered_set<std::string> framePaths;
AsFbxContext();
~AsFbxContext();
};

View File

@@ -1,9 +0,0 @@
#include "asfbx_morph_context.h"
AsFbxMorphContext::AsFbxMorphContext()
{
pMesh = nullptr;
lBlendShape = nullptr;
lBlendShapeChannel = nullptr;
lShape = nullptr;
}

View File

@@ -1,16 +0,0 @@
#pragma once
#include <fbxsdk.h>
struct AsFbxMorphContext
{
FbxMesh* pMesh;
FbxBlendShape* lBlendShape;
FbxBlendShapeChannel* lBlendShapeChannel;
FbxShape* lShape;
AsFbxMorphContext();
~AsFbxMorphContext() = default;
};

View File

@@ -1,16 +0,0 @@
#include "asfbx_skin_context.h"
#include "asfbx_context.h"
AsFbxSkinContext::AsFbxSkinContext(AsFbxContext* pContext, FbxNode* pFrameNode)
: pSkin(nullptr)
{
if (pContext != nullptr && pContext->pScene != nullptr)
{
pSkin = FbxSkin::Create(pContext->pScene, "");
}
if (pFrameNode != nullptr)
{
lMeshMatrix = pFrameNode->EvaluateGlobalTransform();
}
}

View File

@@ -1,16 +0,0 @@
#pragma once
#include <fbxsdk.h>
struct AsFbxContext;
struct AsFbxSkinContext
{
FbxSkin* pSkin;
FbxAMatrix lMeshMatrix;
AsFbxSkinContext(AsFbxContext* pContext, FbxNode* pFrameNode);
~AsFbxSkinContext() = default;
};

View File

@@ -1,5 +0,0 @@
#pragma once
#include <cstdint>
typedef uint32_t bool32_t;

View File

@@ -1 +0,0 @@
#define AS_API(ret_type)

View File

@@ -1,56 +0,0 @@
#pragma once
#if defined(_MSC_VER)
#if _MSC_VER < 1910 // MSVC 2017-
#error MSVC 2017 or later is required.
#endif
#endif
#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW__)
#ifdef _AS_DLL
#ifdef __GNUC__
#define _AS_EXPORT __attribute__ ((dllexport))
#else
#define _AS_EXPORT __declspec(dllexport)
#endif
#else
#ifdef __GNUC__
#define _AS_EXPORT __attribute__ ((dllimport))
#else
#define _AS_EXPORT __declspec(dllimport)
#endif
#endif
#define _AS_LOCAL
#else
#if __GNUC__ >= 4
#define _AS_EXPORT __attribute__ ((visibility ("default")))
#define _AS_LOCAL __attribute__ ((visibility ("hidden")))
#else
#define _AS_EXPORT
#define _AS_LOCAL
#endif
#endif
#ifdef __cplusplus
#ifndef _EXTERN_C_STMT
#define _EXTERN_C_STMT extern "C"
#endif
#else
#ifndef _EXTERN_C_STMT
#define _EXTERN_C_STMT
#endif
#endif
#ifndef _AS_CALL
#if defined(WIN32) || defined(_WIN32)
#define _AS_CALL __stdcall
#else
#define _AS_CALL /* __cdecl */
#endif
#endif
#if defined(_MSC_VER)
#define AS_API(ret_type) _EXTERN_C_STMT _AS_EXPORT ret_type _AS_CALL
#else
#define AS_API(ret_type) _EXTERN_C_STMT _AS_EXPORT _AS_CALL ret_type
#endif

View File

@@ -1,14 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by AssetStudioFBXNative.rc
// <20><EFBFBD><C2B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>Ĭ<EFBFBD><C4AC>ֵ
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -1,43 +0,0 @@
#include <fbxsdk.h>
#include <cassert>
#include "utils.h"
Vector3::Vector3()
: X(0), Y(0), Z(0)
{
}
Vector3::Vector3(float x, float y, float z)
: X(x), Y(y), Z(z)
{
}
Quaternion::Quaternion()
: X(0), Y(0), Z(0), W(1)
{
}
Quaternion::Quaternion(float x, float y, float z)
: X(x), Y(y), Z(z), W(1)
{
}
Quaternion::Quaternion(float x, float y, float z, float w)
: X(x), Y(y), Z(z), W(w)
{
}
Vector3 QuaternionToEuler(Quaternion q) {
FbxAMatrix lMatrixRot;
lMatrixRot.SetQ(FbxQuaternion(q.X, q.Y, q.Z, q.W));
FbxVector4 lEuler = lMatrixRot.GetR();
return Vector3((float)lEuler[0], (float)lEuler[1], (float)lEuler[2]);
}
Quaternion EulerToQuaternion(Vector3 v) {
FbxAMatrix lMatrixRot;
lMatrixRot.SetR(FbxVector4(v.X, v.Y, v.Z));
FbxQuaternion lQuaternion = lMatrixRot.GetQ();
return Quaternion((float)lQuaternion[0], (float)lQuaternion[1], (float)lQuaternion[2], (float)lQuaternion[3]);
}

View File

@@ -1,29 +0,0 @@
#pragma once
struct Vector3 {
float X;
float Y;
float Z;
Vector3();
Vector3(float x, float y, float z);
};
struct Quaternion {
float X;
float Y;
float Z;
float W;
Quaternion();
Quaternion(float x, float y, float z);
Quaternion(float x, float y, float z, float w);
};
Vector3 QuaternionToEuler(Quaternion q);
Quaternion EulerToQuaternion(Vector3 v);

View File

@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>0.16.8.1</Version>
<AssemblyVersion>0.16.8.1</AssemblyVersion>
<FileVersion>0.16.8.1</FileVersion>
<Copyright>Copyright © Perfare 2018-2021; Copyright © hozuki 2020</Copyright>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net472|AnyCPU'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\AssetStudio.PInvoke\AssetStudio.PInvoke.csproj" />
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,16 +0,0 @@
using System.Runtime.InteropServices;
using AssetStudio.FbxInterop;
namespace AssetStudio
{
partial class Fbx
{
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsUtilQuaternionToEuler(float qx, float qy, float qz, float qw, out float vx, out float vy, out float vz);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsUtilEulerToQuaternion(float vx, float vy, float vz, out float qx, out float qy, out float qz, out float qw);
}
}

View File

@@ -1,58 +0,0 @@
using AssetStudio.FbxInterop;
using AssetStudio.PInvoke;
using System.IO;
namespace AssetStudio
{
public static partial class Fbx
{
static Fbx()
{
DllLoader.PreloadDll(FbxDll.DllName);
}
public static Vector3 QuaternionToEuler(Quaternion q)
{
AsUtilQuaternionToEuler(q.X, q.Y, q.Z, q.W, out var x, out var y, out var z);
return new Vector3(x, y, z);
}
public static Quaternion EulerToQuaternion(Vector3 v)
{
AsUtilEulerToQuaternion(v.X, v.Y, v.Z, out var x, out var y, out var z, out var w);
return new Quaternion(x, y, z, w);
}
public static class Exporter
{
public static void Export(string path, IImported imported, bool eulerFilter, float filterPrecision,
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, bool exportAllUvsAsDiffuseMaps, float scaleFactor, int versionIndex, bool isAscii)
{
var file = new FileInfo(path);
var dir = file.Directory;
if (!dir.Exists)
{
dir.Create();
}
var currentDir = Directory.GetCurrentDirectory();
Directory.SetCurrentDirectory(dir.FullName);
var name = Path.GetFileName(path);
using (var exporter = new FbxExporter(name, imported, allNodes, skins, castToBone, boneSize, exportAllUvsAsDiffuseMaps, scaleFactor, versionIndex, isAscii))
{
exporter.Initialize();
exporter.ExportAll(blendShape, animation, eulerFilter, filterPrecision);
}
Directory.SetCurrentDirectory(currentDir);
}
}
}
}

View File

@@ -1,10 +0,0 @@
namespace AssetStudio.FbxInterop
{
internal static class FbxDll
{
internal const string DllName = "AssetStudioFBXNative";
internal const string FbxsdkDllName = "libfbxsdk";
}
}

View File

@@ -1,244 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace AssetStudio.FbxInterop
{
internal sealed class FbxExporter : IDisposable
{
private FbxExporterContext _context;
private readonly string _fileName;
private readonly IImported _imported;
private readonly bool _allNodes;
private readonly bool _exportSkins;
private readonly bool _castToBone;
private readonly float _boneSize;
private readonly bool _exportAllUvsAsDiffuseMaps;
private readonly float _scaleFactor;
private readonly int _versionIndex;
private readonly bool _isAscii;
internal FbxExporter(string fileName, IImported imported, bool allNodes, bool exportSkins, bool castToBone, float boneSize, bool exportAllUvsAsDiffuseMaps, float scaleFactor, int versionIndex, bool isAscii)
{
_context = new FbxExporterContext();
_fileName = fileName;
_imported = imported;
_allNodes = allNodes;
_exportSkins = exportSkins;
_castToBone = castToBone;
_boneSize = boneSize;
_exportAllUvsAsDiffuseMaps = exportAllUvsAsDiffuseMaps;
_scaleFactor = scaleFactor;
_versionIndex = versionIndex;
_isAscii = isAscii;
}
~FbxExporter()
{
Dispose(false);
}
public void Dispose()
{
if (IsDisposed)
{
return;
}
Dispose(true);
GC.SuppressFinalize(this);
}
public bool IsDisposed { get; private set; }
private void Dispose(bool disposing)
{
if (disposing)
{
_context.Dispose();
}
IsDisposed = true;
}
internal void Initialize()
{
var is60Fps = _imported.AnimationList.Count > 0 && _imported.AnimationList[0].SampleRate.Equals(60.0f);
_context.Initialize(_fileName, _scaleFactor, _versionIndex, _isAscii, is60Fps);
if (!_allNodes)
{
var framePaths = SearchHierarchy();
_context.SetFramePaths(framePaths);
}
}
internal void ExportAll(bool blendShape, bool animation, bool eulerFilter, float filterPrecision)
{
var meshFrames = new List<ImportedFrame>();
ExportRootFrame(meshFrames);
if (_imported.MeshList != null)
{
SetJointsFromImportedMeshes();
PrepareMaterials();
ExportMeshFrames(_imported.RootFrame, meshFrames);
}
else
{
SetJointsNode(_imported.RootFrame, null, true);
}
if (blendShape)
{
ExportMorphs();
}
if (animation)
{
ExportAnimations(eulerFilter, filterPrecision);
}
ExportScene();
}
private void ExportMorphs()
{
_context.ExportMorphs(_imported.RootFrame, _imported.MorphList);
}
private void ExportAnimations(bool eulerFilter, float filterPrecision)
{
_context.ExportAnimations(_imported.RootFrame, _imported.AnimationList, eulerFilter, filterPrecision);
}
private void ExportRootFrame(List<ImportedFrame> meshFrames)
{
_context.ExportFrame(_imported.MeshList, meshFrames, _imported.RootFrame);
}
private void ExportScene()
{
_context.ExportScene();
}
private void SetJointsFromImportedMeshes()
{
if (!_exportSkins)
{
return;
}
Debug.Assert(_imported.MeshList != null);
var bonePaths = new HashSet<string>();
foreach (var mesh in _imported.MeshList)
{
var boneList = mesh.BoneList;
if (boneList != null)
{
foreach (var bone in boneList)
{
bonePaths.Add(bone.Path);
}
}
}
SetJointsNode(_imported.RootFrame, bonePaths, _castToBone);
}
private void SetJointsNode(ImportedFrame rootFrame, HashSet<string> bonePaths, bool castToBone)
{
_context.SetJointsNode(rootFrame, bonePaths, castToBone, _boneSize);
}
private void PrepareMaterials()
{
_context.PrepareMaterials(_imported.MaterialList.Count, _imported.TextureList.Count);
}
private void ExportMeshFrames(ImportedFrame rootFrame, List<ImportedFrame> meshFrames)
{
foreach (var meshFrame in meshFrames)
{
_context.ExportMeshFromFrame(rootFrame, meshFrame, _imported.MeshList, _imported.MaterialList, _imported.TextureList, _exportSkins, _exportAllUvsAsDiffuseMaps);
}
}
private HashSet<string> SearchHierarchy()
{
if (_imported.MeshList == null || _imported.MeshList.Count == 0)
{
return null;
}
var exportFrames = new HashSet<string>();
SearchHierarchy(_imported.RootFrame, _imported.MeshList, exportFrames);
return exportFrames;
}
private static void SearchHierarchy(ImportedFrame rootFrame, List<ImportedMesh> meshList, HashSet<string> exportFrames)
{
var frameStack = new Stack<ImportedFrame>();
frameStack.Push(rootFrame);
while (frameStack.Count > 0)
{
var frame = frameStack.Pop();
var meshListSome = ImportedHelpers.FindMesh(frame.Path, meshList);
if (meshListSome != null)
{
var parent = frame;
while (parent != null)
{
exportFrames.Add(parent.Path);
parent = parent.Parent;
}
var boneList = meshListSome.BoneList;
if (boneList != null)
{
foreach (var bone in boneList)
{
if (!exportFrames.Contains(bone.Path))
{
var boneParent = rootFrame.FindFrameByPath(bone.Path);
while (boneParent != null)
{
exportFrames.Add(boneParent.Path);
boneParent = boneParent.Parent;
}
}
}
}
}
for (var i = frame.Count - 1; i >= 0; i -= 1)
{
frameStack.Push(frame[i]);
}
}
}
}
}

View File

@@ -1,325 +0,0 @@
using System;
using System.Runtime.InteropServices;
using AssetStudio.PInvoke;
namespace AssetStudio.FbxInterop
{
partial class FbxExporterContext
{
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern IntPtr AsFbxCreateContext();
private static bool AsFbxInitializeContext(IntPtr context, string fileName, float scaleFactor, int versionIndex, bool isAscii, bool is60Fps, out string errorMessage)
{
bool b;
IntPtr pErrMsg;
using (var fileNameUtf8 = new Utf8StringHandle(fileName))
{
b = AsFbxInitializeContext(context, fileNameUtf8.DangerousGetHandle(), scaleFactor, versionIndex, isAscii, is60Fps, out pErrMsg);
}
errorMessage = Utf8StringHandle.ReadUtf8StringFromPointer(pErrMsg);
return b;
}
// Do not free the pointer strErrorMessage
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AsFbxInitializeContext(IntPtr context, IntPtr strFileName, float scaleFactor, int versionIndex, [MarshalAs(UnmanagedType.Bool)] bool isAscii, [MarshalAs(UnmanagedType.Bool)] bool is60Fps, out IntPtr strErrorMessage);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxDisposeContext(ref IntPtr ppContext);
private static void AsFbxSetFramePaths(IntPtr context, string[] framePaths)
{
var framePathCount = framePaths.Length;
if (framePathCount == 0)
{
AsFbxSetFramePaths(context, Array.Empty<IntPtr>(), 0);
}
else
{
var utf8Paths = new Utf8StringHandle[framePathCount];
try
{
for (var i = 0; i < framePathCount; i += 1)
{
utf8Paths[i] = new Utf8StringHandle(framePaths[i]);
}
var pathPointers = new IntPtr[framePathCount];
for (var i = 0; i < framePathCount; i += 1)
{
pathPointers[i] = utf8Paths[i].DangerousGetHandle();
}
AsFbxSetFramePaths(context, pathPointers, framePathCount);
}
finally
{
foreach (var path in utf8Paths)
{
path?.Dispose();
}
}
}
}
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxSetFramePaths(IntPtr context, [MarshalAs(UnmanagedType.LPArray)] IntPtr[] strFramePaths, int count);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxExportScene(IntPtr context);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern IntPtr AsFbxGetSceneRootNode(IntPtr context);
private static IntPtr AsFbxExportSingleFrame(IntPtr context, IntPtr parentNode, string framePath, string frameName, in Vector3 localPosition, in Vector3 localRotation, in Vector3 localScale)
{
using (var framePathUtf8 = new Utf8StringHandle(framePath))
{
using (var frameNameUtf8 = new Utf8StringHandle(frameName))
{
return AsFbxExportSingleFrame(context, parentNode, framePathUtf8.DangerousGetHandle(), frameNameUtf8.DangerousGetHandle(), localPosition.X, localPosition.Y, localPosition.Z, localRotation.X, localRotation.Y, localRotation.Z, localScale.X, localScale.Y, localScale.Z);
}
}
}
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern IntPtr AsFbxExportSingleFrame(IntPtr context, IntPtr parentNode, IntPtr strFramePath, IntPtr strFrameName, float localPositionX, float localPositionY, float localPositionZ, float localRotationX, float localRotationY, float localRotationZ, float localScaleX, float localScaleY, float localScaleZ);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxSetJointsNode_CastToBone(IntPtr context, IntPtr node, float boneSize);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxSetJointsNode_BoneInPath(IntPtr context, IntPtr node, float boneSize);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxSetJointsNode_Generic(IntPtr context, IntPtr node);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxPrepareMaterials(IntPtr context, int materialCount, int textureCount);
private static IntPtr AsFbxCreateTexture(IntPtr context, string matTexName)
{
using (var matTexNameUtf8 = new Utf8StringHandle(matTexName))
{
return AsFbxCreateTexture(context, matTexNameUtf8.DangerousGetHandle());
}
}
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern IntPtr AsFbxCreateTexture(IntPtr context, IntPtr strMatTexName);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxLinkTexture(int dest, IntPtr texture, IntPtr material, float offsetX, float offsetY, float scaleX, float scaleY);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern IntPtr AsFbxMeshCreateClusterArray(int boneCount);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshDisposeClusterArray(ref IntPtr ppArray);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern IntPtr AsFbxMeshCreateCluster(IntPtr context, IntPtr boneNode);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshAddCluster(IntPtr array, IntPtr cluster);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern IntPtr AsFbxMeshCreateMesh(IntPtr context, IntPtr frameNode);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshInitControlPoints(IntPtr mesh, int vertexCount);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshCreateElementNormal(IntPtr mesh);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshCreateDiffuseUV(IntPtr mesh, int uv);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshCreateNormalMapUV(IntPtr mesh, int uv);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshCreateElementTangent(IntPtr mesh);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshCreateElementVertexColor(IntPtr mesh);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshCreateElementMaterial(IntPtr mesh);
private static IntPtr AsFbxCreateMaterial(IntPtr pContext, string matName, in Color diffuse, in Color ambient, in Color emissive, in Color specular, in Color reflection, float shininess, float transparency)
{
using (var matNameUtf8 = new Utf8StringHandle(matName))
{
return AsFbxCreateMaterial(pContext, matNameUtf8.DangerousGetHandle(), diffuse.R, diffuse.G, diffuse.B, ambient.R, ambient.G, ambient.B, emissive.R, emissive.G, emissive.B, specular.R, specular.G, specular.B, reflection.R, reflection.G, reflection.B, shininess, transparency);
}
}
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern IntPtr AsFbxCreateMaterial(IntPtr pContext, IntPtr pMatName,
float diffuseR, float diffuseG, float diffuseB,
float ambientR, float ambientG, float ambientB,
float emissiveR, float emissiveG, float emissiveB,
float specularR, float specularG, float specularB,
float reflectR, float reflectG, float reflectB,
float shininess, float transparency);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern int AsFbxAddMaterialToFrame(IntPtr frameNode, IntPtr material);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxSetFrameShadingModeToTextureShading(IntPtr frameNode);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshSetControlPoint(IntPtr mesh, int index, float x, float y, float z);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshAddPolygon(IntPtr mesh, int materialIndex, int index0, int index1, int index2);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshElementNormalAdd(IntPtr mesh, int elementIndex, float x, float y, float z);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshElementUVAdd(IntPtr mesh, int elementIndex, float u, float v);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshElementTangentAdd(IntPtr mesh, int elementIndex, float x, float y, float z, float w);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshElementVertexColorAdd(IntPtr mesh, int elementIndex, float r, float g, float b, float a);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshSetBoneWeight(IntPtr pClusterArray, int boneIndex, int vertexIndex, float weight);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern IntPtr AsFbxMeshCreateSkinContext(IntPtr context, IntPtr frameNode);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshDisposeSkinContext(ref IntPtr ppSkinContext);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FbxClusterArray_HasItemAt(IntPtr pClusterArray, int index);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private unsafe static extern void AsFbxMeshSkinAddCluster(IntPtr pSkinContext, IntPtr pClusterArray, int index, float* pBoneMatrix);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMeshAddDeformer(IntPtr pSkinContext, IntPtr pMesh);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern IntPtr AsFbxAnimCreateContext([MarshalAs(UnmanagedType.Bool)] bool eulerFilter);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxAnimDisposeContext(ref IntPtr ppAnimContext);
private static void AsFbxAnimPrepareStackAndLayer(IntPtr pContext, IntPtr pAnimContext, string takeName)
{
using (var takeNameUtf8 = new Utf8StringHandle(takeName))
{
AsFbxAnimPrepareStackAndLayer(pContext, pAnimContext, takeNameUtf8.DangerousGetHandle());
}
}
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxAnimPrepareStackAndLayer(IntPtr pContext, IntPtr pAnimContext, IntPtr strTakeName);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxAnimLoadCurves(IntPtr pNode, IntPtr pAnimContext);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxAnimBeginKeyModify(IntPtr pAnimContext);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxAnimEndKeyModify(IntPtr pAnimContext);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxAnimAddScalingKey(IntPtr pAnimContext, float time, float x, float y, float z);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxAnimAddRotationKey(IntPtr pAnimContext, float time, float x, float y, float z);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxAnimAddTranslationKey(IntPtr pAnimContext, float time, float x, float y, float z);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxAnimApplyEulerFilter(IntPtr pAnimContext, float filterPrecision);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern int AsFbxAnimGetCurrentBlendShapeChannelCount(IntPtr pAnimContext, IntPtr pNode);
private static bool AsFbxAnimIsBlendShapeChannelMatch(IntPtr pAnimContext, int channelIndex, string channelName)
{
using (var channelNameUtf8 = new Utf8StringHandle(channelName))
{
return AsFbxAnimIsBlendShapeChannelMatch(pAnimContext, channelIndex, channelNameUtf8.DangerousGetHandle());
}
}
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AsFbxAnimIsBlendShapeChannelMatch(IntPtr pAnimContext, int channelIndex, IntPtr strChannelName);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxAnimBeginBlendShapeAnimCurve(IntPtr pAnimContext, int channelIndex);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxAnimEndBlendShapeAnimCurve(IntPtr pAnimContext);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxAnimAddBlendShapeKeyframe(IntPtr pAnimContext, float time, float value);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern IntPtr AsFbxMorphCreateContext();
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMorphInitializeContext(IntPtr pContext, IntPtr pMorphContext, IntPtr pNode);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMorphDisposeContext(ref IntPtr ppMorphContext);
private static void AsFbxMorphAddBlendShapeChannel(IntPtr pContext, IntPtr pMorphContext, string channelName)
{
using (var channelNameUtf8 = new Utf8StringHandle(channelName))
{
AsFbxMorphAddBlendShapeChannel(pContext, pMorphContext, channelNameUtf8.DangerousGetHandle());
}
}
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMorphAddBlendShapeChannel(IntPtr pContext, IntPtr pMorphContext, IntPtr strChannelName);
private static void AsFbxMorphAddBlendShapeChannelShape(IntPtr pContext, IntPtr pMorphContext, float weight, string shapeName)
{
using (var shapeNameUtf8 = new Utf8StringHandle(shapeName))
{
AsFbxMorphAddBlendShapeChannelShape(pContext, pMorphContext, weight, shapeNameUtf8.DangerousGetHandle());
}
}
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMorphAddBlendShapeChannelShape(IntPtr pContext, IntPtr pMorphContext, float weight, IntPtr strShapeName);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMorphCopyBlendShapeControlPoints(IntPtr pMorphContext);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMorphSetBlendShapeVertex(IntPtr pMorphContext, uint index, float x, float y, float z);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMorphCopyBlendShapeControlPointsNormal(IntPtr pMorphContext);
[DllImport(FbxDll.DllName, CallingConvention = CallingConvention.Winapi)]
private static extern void AsFbxMorphSetBlendShapeVertexNormal(IntPtr pMorphContext, uint index, float x, float y, float z);
}
}

View File

@@ -1,643 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
namespace AssetStudio.FbxInterop
{
internal sealed partial class FbxExporterContext : IDisposable
{
private IntPtr _pContext;
private readonly Dictionary<ImportedFrame, IntPtr> _frameToNode;
private readonly List<KeyValuePair<string, IntPtr>> _createdMaterials;
private readonly Dictionary<string, IntPtr> _createdTextures;
public FbxExporterContext()
{
_pContext = AsFbxCreateContext();
_frameToNode = new Dictionary<ImportedFrame, IntPtr>();
_createdMaterials = new List<KeyValuePair<string, IntPtr>>();
_createdTextures = new Dictionary<string, IntPtr>();
}
~FbxExporterContext()
{
Dispose(false);
}
public void Dispose()
{
if (IsDisposed)
{
return;
}
Dispose(true);
GC.SuppressFinalize(this);
}
public bool IsDisposed { get; private set; }
private void Dispose(bool disposing)
{
IsDisposed = true;
_frameToNode.Clear();
_createdMaterials.Clear();
_createdTextures.Clear();
AsFbxDisposeContext(ref _pContext);
}
private void EnsureNotDisposed()
{
if (IsDisposed)
{
throw new ObjectDisposedException(nameof(FbxExporterContext));
}
}
internal void Initialize(string fileName, float scaleFactor, int versionIndex, bool isAscii, bool is60Fps)
{
EnsureNotDisposed();
var b = AsFbxInitializeContext(_pContext, fileName, scaleFactor, versionIndex, isAscii, is60Fps, out var errorMessage);
if (!b)
{
var fullMessage = $"Failed to initialize FbxExporter: {errorMessage}";
throw new ApplicationException(fullMessage);
}
}
internal void SetFramePaths(HashSet<string> framePaths)
{
EnsureNotDisposed();
if (framePaths == null || framePaths.Count == 0)
{
return;
}
var framePathList = new List<string>(framePaths);
var framePathArray = framePathList.ToArray();
AsFbxSetFramePaths(_pContext, framePathArray);
}
internal void ExportScene()
{
EnsureNotDisposed();
AsFbxExportScene(_pContext);
}
internal void ExportFrame(List<ImportedMesh> meshList, List<ImportedFrame> meshFrames, ImportedFrame rootFrame)
{
var rootNode = AsFbxGetSceneRootNode(_pContext);
Debug.Assert(rootNode != IntPtr.Zero);
var nodeStack = new Stack<IntPtr>();
var frameStack = new Stack<ImportedFrame>();
nodeStack.Push(rootNode);
frameStack.Push(rootFrame);
while (nodeStack.Count > 0)
{
var parentNode = nodeStack.Pop();
var frame = frameStack.Pop();
var childNode = AsFbxExportSingleFrame(_pContext, parentNode, frame.Path, frame.Name, frame.LocalPosition, frame.LocalRotation, frame.LocalScale);
if (meshList != null && ImportedHelpers.FindMesh(frame.Path, meshList) != null)
{
meshFrames.Add(frame);
}
_frameToNode.Add(frame, childNode);
for (var i = frame.Count - 1; i >= 0; i -= 1)
{
nodeStack.Push(childNode);
frameStack.Push(frame[i]);
}
}
}
internal void SetJointsNode(ImportedFrame rootFrame, HashSet<string> bonePaths, bool castToBone, float boneSize)
{
var frameStack = new Stack<ImportedFrame>();
frameStack.Push(rootFrame);
while (frameStack.Count > 0)
{
var frame = frameStack.Pop();
if (_frameToNode.TryGetValue(frame, out var node))
{
Debug.Assert(node != IntPtr.Zero);
if (castToBone)
{
AsFbxSetJointsNode_CastToBone(_pContext, node, boneSize);
}
else
{
Debug.Assert(bonePaths != null);
if (bonePaths.Contains(frame.Path))
{
AsFbxSetJointsNode_BoneInPath(_pContext, node, boneSize);
}
else
{
AsFbxSetJointsNode_Generic(_pContext, node);
}
}
}
for (var i = frame.Count - 1; i >= 0; i -= 1)
{
frameStack.Push(frame[i]);
}
}
}
internal void PrepareMaterials(int materialCount, int textureCount)
{
AsFbxPrepareMaterials(_pContext, materialCount, textureCount);
}
internal void ExportMeshFromFrame(ImportedFrame rootFrame, ImportedFrame meshFrame, List<ImportedMesh> meshList, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, bool exportSkins, bool exportAllUvsAsDiffuseMaps)
{
var meshNode = _frameToNode[meshFrame];
var mesh = ImportedHelpers.FindMesh(meshFrame.Path, meshList);
ExportMesh(rootFrame, materialList, textureList, meshNode, mesh, exportSkins, exportAllUvsAsDiffuseMaps);
}
private IntPtr ExportTexture(ImportedTexture texture)
{
if (texture == null)
{
return IntPtr.Zero;
}
if (_createdTextures.ContainsKey(texture.Name))
{
return _createdTextures[texture.Name];
}
var pTex = AsFbxCreateTexture(_pContext, texture.Name);
_createdTextures.Add(texture.Name, pTex);
var file = new FileInfo(texture.Name);
using (var writer = new BinaryWriter(file.Create()))
{
writer.Write(texture.Data);
}
return pTex;
}
private void ExportMesh(ImportedFrame rootFrame, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, IntPtr frameNode, ImportedMesh importedMesh, bool exportSkins, bool exportAllUvsAsDiffuseMaps)
{
var boneList = importedMesh.BoneList;
var totalBoneCount = 0;
var hasBones = false;
if (exportSkins && boneList?.Count > 0)
{
totalBoneCount = boneList.Count;
hasBones = true;
}
var pClusterArray = IntPtr.Zero;
try
{
if (hasBones)
{
pClusterArray = AsFbxMeshCreateClusterArray(totalBoneCount);
foreach (var bone in boneList)
{
if (bone.Path != null)
{
var frame = rootFrame.FindFrameByPath(bone.Path);
var boneNode = _frameToNode[frame];
var cluster = AsFbxMeshCreateCluster(_pContext, boneNode);
AsFbxMeshAddCluster(pClusterArray, cluster);
}
else
{
AsFbxMeshAddCluster(pClusterArray, IntPtr.Zero);
}
}
}
var mesh = AsFbxMeshCreateMesh(_pContext, frameNode);
AsFbxMeshInitControlPoints(mesh, importedMesh.VertexList.Count);
if (importedMesh.hasNormal)
{
AsFbxMeshCreateElementNormal(mesh);
}
for (int i = 0; i < importedMesh.hasUV.Length; i++)
{
if (!importedMesh.hasUV[i]) { continue; }
if (i == 1 && !exportAllUvsAsDiffuseMaps)
{
AsFbxMeshCreateNormalMapUV(mesh, 1);
}
else
{
AsFbxMeshCreateDiffuseUV(mesh, i);
}
}
if (importedMesh.hasTangent)
{
AsFbxMeshCreateElementTangent(mesh);
}
if (importedMesh.hasColor)
{
AsFbxMeshCreateElementVertexColor(mesh);
}
AsFbxMeshCreateElementMaterial(mesh);
foreach (var meshObj in importedMesh.SubmeshList)
{
var materialIndex = 0;
var mat = ImportedHelpers.FindMaterial(meshObj.Material, materialList);
if (mat != null)
{
var foundMat = _createdMaterials.FindIndex(kv => kv.Key == mat.Name);
IntPtr pMat;
if (foundMat >= 0)
{
pMat = _createdMaterials[foundMat].Value;
}
else
{
var diffuse = mat.Diffuse;
var ambient = mat.Ambient;
var emissive = mat.Emissive;
var specular = mat.Specular;
var reflection = mat.Reflection;
pMat = AsFbxCreateMaterial(_pContext, mat.Name, in diffuse, in ambient, in emissive, in specular, in reflection, mat.Shininess, mat.Transparency);
_createdMaterials.Add(new KeyValuePair<string, IntPtr>(mat.Name, pMat));
}
materialIndex = AsFbxAddMaterialToFrame(frameNode, pMat);
var hasTexture = false;
foreach (var texture in mat.Textures)
{
var tex = ImportedHelpers.FindTexture(texture.Name, textureList);
var pTexture = ExportTexture(tex);
if (pTexture != IntPtr.Zero)
{
switch (texture.Dest)
{
case 0:
case 1:
case 2:
case 3:
{
AsFbxLinkTexture(texture.Dest, pTexture, pMat, texture.Offset.X, texture.Offset.Y, texture.Scale.X, texture.Scale.Y);
hasTexture = true;
break;
}
default:
break;
}
}
}
if (hasTexture)
{
AsFbxSetFrameShadingModeToTextureShading(frameNode);
}
}
foreach (var face in meshObj.FaceList)
{
var index0 = face.VertexIndices[0] + meshObj.BaseVertex;
var index1 = face.VertexIndices[1] + meshObj.BaseVertex;
var index2 = face.VertexIndices[2] + meshObj.BaseVertex;
AsFbxMeshAddPolygon(mesh, materialIndex, index0, index1, index2);
}
}
var vertexList = importedMesh.VertexList;
var vertexCount = vertexList.Count;
for (var j = 0; j < vertexCount; j += 1)
{
var importedVertex = vertexList[j];
var vertex = importedVertex.Vertex;
AsFbxMeshSetControlPoint(mesh, j, vertex.X, vertex.Y, vertex.Z);
if (importedMesh.hasNormal)
{
var normal = importedVertex.Normal;
AsFbxMeshElementNormalAdd(mesh, 0, normal.X, normal.Y, normal.Z);
}
for (var uvIndex = 0; uvIndex < importedMesh.hasUV.Length; uvIndex += 1)
{
if (importedMesh.hasUV[uvIndex])
{
var uv = importedVertex.UV[uvIndex];
AsFbxMeshElementUVAdd(mesh, uvIndex, uv[0], uv[1]);
}
}
if (importedMesh.hasTangent)
{
var tangent = importedVertex.Tangent;
AsFbxMeshElementTangentAdd(mesh, 0, tangent.X, tangent.Y, tangent.Z, tangent.W);
}
if (importedMesh.hasColor)
{
var color = importedVertex.Color;
AsFbxMeshElementVertexColorAdd(mesh, 0, color.R, color.G, color.B, color.A);
}
if (hasBones && importedVertex.BoneIndices != null)
{
var boneIndices = importedVertex.BoneIndices;
var boneWeights = importedVertex.Weights;
for (var k = 0; k < 4; k += 1)
{
if (boneIndices[k] < totalBoneCount && boneWeights[k] > 0)
{
AsFbxMeshSetBoneWeight(pClusterArray, boneIndices[k], j, boneWeights[k]);
}
}
}
}
if (hasBones)
{
IntPtr pSkinContext = IntPtr.Zero;
try
{
pSkinContext = AsFbxMeshCreateSkinContext(_pContext, frameNode);
unsafe
{
var boneMatrix = stackalloc float[16];
for (var j = 0; j < totalBoneCount; j += 1)
{
if (!FbxClusterArray_HasItemAt(pClusterArray, j))
{
continue;
}
var m = boneList[j].Matrix;
CopyMatrix4x4(in m, boneMatrix);
AsFbxMeshSkinAddCluster(pSkinContext, pClusterArray, j, boneMatrix);
}
}
AsFbxMeshAddDeformer(pSkinContext, mesh);
}
finally
{
AsFbxMeshDisposeSkinContext(ref pSkinContext);
}
}
}
finally
{
AsFbxMeshDisposeClusterArray(ref pClusterArray);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe void CopyMatrix4x4(in Matrix4x4 matrix, float* buffer)
{
for (var m = 0; m < 4; m += 1)
{
for (var n = 0; n < 4; n += 1)
{
var index = IndexFrom4x4(m, n);
buffer[index] = matrix[m, n];
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int IndexFrom4x4(int m, int n)
{
return 4 * m + n;
}
internal void ExportAnimations(ImportedFrame rootFrame, List<ImportedKeyframedAnimation> animationList, bool eulerFilter, float filterPrecision)
{
if (animationList == null || animationList.Count == 0)
{
return;
}
var pAnimContext = IntPtr.Zero;
try
{
pAnimContext = AsFbxAnimCreateContext(eulerFilter);
for (int i = 0; i < animationList.Count; i++)
{
var importedAnimation = animationList[i];
string takeName;
if (importedAnimation.Name != null)
{
takeName = importedAnimation.Name;
}
else
{
takeName = $"Take{i.ToString()}";
}
AsFbxAnimPrepareStackAndLayer(_pContext, pAnimContext, takeName);
ExportKeyframedAnimation(rootFrame, importedAnimation, pAnimContext, filterPrecision);
}
}
finally
{
AsFbxAnimDisposeContext(ref pAnimContext);
}
}
private void ExportKeyframedAnimation(ImportedFrame rootFrame, ImportedKeyframedAnimation parser, IntPtr pAnimContext, float filterPrecision)
{
foreach (var track in parser.TrackList)
{
if (track.Path == null)
{
continue;
}
var frame = rootFrame.FindFrameByPath(track.Path);
if (frame == null)
{
continue;
}
var pNode = _frameToNode[frame];
AsFbxAnimLoadCurves(pNode, pAnimContext);
AsFbxAnimBeginKeyModify(pAnimContext);
foreach (var scaling in track.Scalings)
{
var value = scaling.value;
AsFbxAnimAddScalingKey(pAnimContext, scaling.time, value.X, value.Y, value.Z);
}
foreach (var rotation in track.Rotations)
{
var value = rotation.value;
AsFbxAnimAddRotationKey(pAnimContext, rotation.time, value.X, value.Y, value.Z);
}
foreach (var translation in track.Translations)
{
var value = translation.value;
AsFbxAnimAddTranslationKey(pAnimContext, translation.time, value.X, value.Y, value.Z);
}
AsFbxAnimEndKeyModify(pAnimContext);
AsFbxAnimApplyEulerFilter(pAnimContext, filterPrecision);
var blendShape = track.BlendShape;
if (blendShape != null)
{
var channelCount = AsFbxAnimGetCurrentBlendShapeChannelCount(pAnimContext, pNode);
if (channelCount > 0)
{
for (var channelIndex = 0; channelIndex < channelCount; channelIndex += 1)
{
if (!AsFbxAnimIsBlendShapeChannelMatch(pAnimContext, channelIndex, blendShape.ChannelName))
{
continue;
}
AsFbxAnimBeginBlendShapeAnimCurve(pAnimContext, channelIndex);
foreach (var keyframe in blendShape.Keyframes)
{
AsFbxAnimAddBlendShapeKeyframe(pAnimContext, keyframe.time, keyframe.value);
}
AsFbxAnimEndBlendShapeAnimCurve(pAnimContext);
}
}
}
}
}
internal void ExportMorphs(ImportedFrame rootFrame, List<ImportedMorph> morphList)
{
if (morphList == null || morphList.Count == 0)
{
return;
}
foreach (var morph in morphList)
{
var frame = rootFrame.FindFrameByPath(morph.Path);
if (frame == null)
{
continue;
}
var pNode = _frameToNode[frame];
var pMorphContext = IntPtr.Zero;
try
{
pMorphContext = AsFbxMorphCreateContext();
AsFbxMorphInitializeContext(_pContext, pMorphContext, pNode);
foreach (var channel in morph.Channels)
{
AsFbxMorphAddBlendShapeChannel(_pContext, pMorphContext, channel.Name);
for (var i = 0; i < channel.KeyframeList.Count; i++)
{
var keyframe = channel.KeyframeList[i];
AsFbxMorphAddBlendShapeChannelShape(_pContext, pMorphContext, keyframe.Weight, i == 0 ? channel.Name : $"{channel.Name}_{i + 1}");
AsFbxMorphCopyBlendShapeControlPoints(pMorphContext);
foreach (var vertex in keyframe.VertexList)
{
var v = vertex.Vertex.Vertex;
AsFbxMorphSetBlendShapeVertex(pMorphContext, vertex.Index, v.X, v.Y, v.Z);
}
if (keyframe.hasNormals)
{
AsFbxMorphCopyBlendShapeControlPointsNormal(pMorphContext);
foreach (var vertex in keyframe.VertexList)
{
var v = vertex.Vertex.Normal;
AsFbxMorphSetBlendShapeVertexNormal(pMorphContext, vertex.Index, v.X, v.Y, v.Z);
}
}
}
}
}
finally
{
AsFbxMorphDisposeContext(ref pMorphContext);
}
}
}
}
}

View File

@@ -1,72 +1,179 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net472</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<ApplicationIcon>Resources\as.ico</ApplicationIcon>
<AssemblyTitle>AssetStudio Mod by VaDiM</AssemblyTitle>
<Version>0.16.8.1</Version>
<AssemblyVersion>0.16.8.1</AssemblyVersion>
<FileVersion>0.16.8.1</FileVersion>
<Copyright>Copyright © Perfare 2018-2021</Copyright>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</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>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="OpenTK" Version="3.1.0" />
<PackageReference Include="OpenTK.GLControl" Version="3.1.0" />
</ItemGroup>
<Target Name="CustomAfterBuild" 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>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>AssetStudioGUI</RootNamespace>
<AssemblyName>AssetStudioGUI</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>none</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>none</DebugType>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Resources\as.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="OpenTK, Version=3.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>..\packages\OpenTK.3.1.0\lib\net20\OpenTK.dll</HintPath>
</Reference>
<Reference Include="OpenTK.GLControl, Version=3.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>..\packages\OpenTK.GLControl.3.1.0\lib\net20\OpenTK.GLControl.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssetStudioGUIForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="AssetStudioGUIForm.designer.cs">
<DependentUpon>AssetStudioGUIForm.cs</DependentUpon>
</Compile>
<Compile Include="Components\AssetItem.cs" />
<Compile Include="Components\GameObjectTreeNode.cs" />
<Compile Include="Components\GOHierarchy.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Components\OpenFolderDialog.cs" />
<Compile Include="Components\TreeViewExtensions.cs" />
<Compile Include="Components\TypeTreeItem.cs" />
<Compile Include="Exporter.cs" />
<Compile Include="ExportOptions.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="ExportOptions.designer.cs">
<DependentUpon>ExportOptions.cs</DependentUpon>
</Compile>
<Compile Include="GUILogger.cs" />
<Compile Include="GUIProgress.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Studio.cs" />
<Compile Include="TGASharpLib.cs" />
<EmbeddedResource Include="AssetStudioGUIForm.resx">
<DependentUpon>AssetStudioGUIForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ExportOptions.resx">
<DependentUpon>ExportOptions.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="OpenTK.dll.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\preview.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\as.ico" />
</ItemGroup>
<ItemGroup Condition="'$(Platform)' == 'x86'">
<ContentWithTargetPath Include="Libraries\x86\fmod.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>fmod.dll</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Libraries\x86\libfbxsdk.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>libfbxsdk.dll</TargetPath>
</ContentWithTargetPath>
</ItemGroup>
<ItemGroup Condition="'$(Platform)' == 'x64'">
<ContentWithTargetPath Include="Libraries\x64\fmod.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>fmod.dll</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Libraries\x64\libfbxsdk.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>libfbxsdk.dll</TargetPath>
</ContentWithTargetPath>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AssetStudioUtility\AssetStudioUtility.csproj">
<Project>{80aec261-21ee-4e4f-a93b-7a744dc84888}</Project>
<Name>AssetStudioUtility</Name>
</ProjectReference>
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj">
<Project>{7662f8c2-7bfd-442e-a948-a43b4f7eb06e}</Project>
<Name>AssetStudio</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -41,8 +41,6 @@
this.displayAll = new System.Windows.Forms.ToolStripMenuItem();
this.enablePreview = new System.Windows.Forms.ToolStripMenuItem();
this.displayInfo = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem14 = new System.Windows.Forms.ToolStripMenuItem();
this.specifyUnityVersion = new System.Windows.Forms.ToolStripTextBox();
this.showExpOpt = new System.Windows.Forms.ToolStripMenuItem();
this.modelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exportAllObjectssplitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
@@ -66,15 +64,9 @@
this.toolStripMenuItem7 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem8 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem9 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripMenuItem10 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem11 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem12 = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem13 = new System.Windows.Forms.ToolStripMenuItem();
this.filterTypeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.allToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.debugMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem15 = new System.Windows.Forms.ToolStripMenuItem();
this.exportClassStructuresMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.tabControl1 = new System.Windows.Forms.TabControl();
@@ -95,8 +87,6 @@
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.progressbarPanel = new System.Windows.Forms.Panel();
this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.tabControl2 = new System.Windows.Forms.TabControl();
this.tabPage4 = new System.Windows.Forms.TabPage();
this.previewPanel = new System.Windows.Forms.Panel();
this.assetInfoLabel = new System.Windows.Forms.Label();
this.FMODpanel = new System.Windows.Forms.Panel();
@@ -111,20 +101,20 @@
this.FMODpauseButton = new System.Windows.Forms.Button();
this.FMODplayButton = new System.Windows.Forms.Button();
this.fontPreviewBox = new System.Windows.Forms.RichTextBox();
this.glControl1 = new OpenTK.GLControl();
this.textPreviewBox = new System.Windows.Forms.TextBox();
this.glControl1 = new OpenTK.GLControl();
this.classPreviewPanel = new System.Windows.Forms.Panel();
this.classTextBox = new System.Windows.Forms.TextBox();
this.tabPage5 = new System.Windows.Forms.TabPage();
this.dumpTextBox = new System.Windows.Forms.TextBox();
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
this.timer = new System.Windows.Forms.Timer(this.components);
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.copyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exportSelectedAssetsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exportAnimatorwithselectedAnimationClipMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.dumpSelectedAssetsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exportAnimatorwithselectedAnimationClipMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.goToSceneHierarchyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.showOriginalFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menuStrip1.SuspendLayout();
@@ -137,13 +127,11 @@
this.tabPage2.SuspendLayout();
this.tabPage3.SuspendLayout();
this.progressbarPanel.SuspendLayout();
this.tabControl2.SuspendLayout();
this.tabPage4.SuspendLayout();
this.previewPanel.SuspendLayout();
this.FMODpanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.FMODprogressBar)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.FMODvolumeBar)).BeginInit();
this.tabPage5.SuspendLayout();
this.classPreviewPanel.SuspendLayout();
this.statusStrip1.SuspendLayout();
this.contextMenuStrip1.SuspendLayout();
this.SuspendLayout();
@@ -214,7 +202,6 @@
this.displayAll,
this.enablePreview,
this.displayInfo,
this.toolStripMenuItem14,
this.showExpOpt});
this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
this.optionsToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
@@ -254,20 +241,6 @@
"t, audio bitrate, etc.";
this.displayInfo.CheckedChanged += new System.EventHandler(this.displayAssetInfo_Check);
//
// toolStripMenuItem14
//
this.toolStripMenuItem14.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.specifyUnityVersion});
this.toolStripMenuItem14.Name = "toolStripMenuItem14";
this.toolStripMenuItem14.Size = new System.Drawing.Size(207, 22);
this.toolStripMenuItem14.Text = "Specify Unity version";
//
// specifyUnityVersion
//
this.specifyUnityVersion.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F);
this.specifyUnityVersion.Name = "specifyUnityVersion";
this.specifyUnityVersion.Size = new System.Drawing.Size(100, 23);
//
// showExpOpt
//
this.showExpOpt.Name = "showExpOpt";
@@ -338,9 +311,7 @@
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem,
this.toolStripSeparator4,
this.toolStripMenuItem2,
this.toolStripMenuItem3,
this.toolStripSeparator2,
this.toolStripMenuItem10});
this.toolStripMenuItem3});
this.exportToolStripMenuItem.Name = "exportToolStripMenuItem";
this.exportToolStripMenuItem.Size = new System.Drawing.Size(53, 20);
this.exportToolStripMenuItem.Text = "Export";
@@ -445,42 +416,6 @@
this.toolStripMenuItem9.Text = "Filtered assets";
this.toolStripMenuItem9.Click += new System.EventHandler(this.toolStripMenuItem9_Click);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(263, 6);
//
// toolStripMenuItem10
//
this.toolStripMenuItem10.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItem11,
this.toolStripMenuItem12,
this.toolStripMenuItem13});
this.toolStripMenuItem10.Name = "toolStripMenuItem10";
this.toolStripMenuItem10.Size = new System.Drawing.Size(266, 22);
this.toolStripMenuItem10.Text = "Asset list to XML";
//
// toolStripMenuItem11
//
this.toolStripMenuItem11.Name = "toolStripMenuItem11";
this.toolStripMenuItem11.Size = new System.Drawing.Size(152, 22);
this.toolStripMenuItem11.Text = "All assets";
this.toolStripMenuItem11.Click += new System.EventHandler(this.toolStripMenuItem11_Click);
//
// toolStripMenuItem12
//
this.toolStripMenuItem12.Name = "toolStripMenuItem12";
this.toolStripMenuItem12.Size = new System.Drawing.Size(152, 22);
this.toolStripMenuItem12.Text = "Selected assets";
this.toolStripMenuItem12.Click += new System.EventHandler(this.toolStripMenuItem12_Click);
//
// toolStripMenuItem13
//
this.toolStripMenuItem13.Name = "toolStripMenuItem13";
this.toolStripMenuItem13.Size = new System.Drawing.Size(152, 22);
this.toolStripMenuItem13.Text = "Filtered assets";
this.toolStripMenuItem13.Click += new System.EventHandler(this.toolStripMenuItem13_Click);
//
// filterTypeToolStripMenuItem
//
this.filterTypeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -502,24 +437,15 @@
// debugMenuItem
//
this.debugMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItem15,
this.exportClassStructuresMenuItem});
this.debugMenuItem.Name = "debugMenuItem";
this.debugMenuItem.Size = new System.Drawing.Size(54, 20);
this.debugMenuItem.Text = "Debug";
//
// toolStripMenuItem15
//
this.toolStripMenuItem15.CheckOnClick = true;
this.toolStripMenuItem15.Name = "toolStripMenuItem15";
this.toolStripMenuItem15.Size = new System.Drawing.Size(200, 22);
this.toolStripMenuItem15.Text = "Show all error messages";
this.toolStripMenuItem15.Click += new System.EventHandler(this.toolStripMenuItem15_Click);
//
// exportClassStructuresMenuItem
//
this.exportClassStructuresMenuItem.Name = "exportClassStructuresMenuItem";
this.exportClassStructuresMenuItem.Size = new System.Drawing.Size(200, 22);
this.exportClassStructuresMenuItem.Size = new System.Drawing.Size(191, 22);
this.exportClassStructuresMenuItem.Text = "Export class structures";
this.exportClassStructuresMenuItem.Click += new System.EventHandler(this.exportClassStructuresMenuItem_Click);
//
@@ -538,7 +464,8 @@
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.tabControl2);
this.splitContainer1.Panel2.Controls.Add(this.previewPanel);
this.splitContainer1.Panel2.Controls.Add(this.classPreviewPanel);
this.splitContainer1.Panel2.Controls.Add(this.statusStrip1);
this.splitContainer1.Panel2MinSize = 400;
this.splitContainer1.Size = new System.Drawing.Size(1264, 657);
@@ -603,7 +530,7 @@
this.tabPage2.Controls.Add(this.listSearch);
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Size = new System.Drawing.Size(472, 607);
this.tabPage2.Size = new System.Drawing.Size(472, 664);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Asset List";
this.tabPage2.UseVisualStyleBackColor = true;
@@ -622,7 +549,7 @@
this.assetListView.HideSelection = false;
this.assetListView.Location = new System.Drawing.Point(0, 20);
this.assetListView.Name = "assetListView";
this.assetListView.Size = new System.Drawing.Size(472, 587);
this.assetListView.Size = new System.Drawing.Size(472, 644);
this.assetListView.TabIndex = 1;
this.assetListView.UseCompatibleStateImageBehavior = false;
this.assetListView.View = System.Windows.Forms.View.Details;
@@ -630,8 +557,6 @@
this.assetListView.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.assetListView_ColumnClick);
this.assetListView.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.selectAsset);
this.assetListView.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.assetListView_RetrieveVirtualItem);
this.assetListView.SelectedIndexChanged += new System.EventHandler(this.assetListView_SelectedIndexChanged);
this.assetListView.VirtualItemsSelectionRangeChanged += new System.Windows.Forms.ListViewVirtualItemsSelectionRangeChangedEventHandler(this.assetListView_VirtualItemsSelectionRangeChanged);
this.assetListView.MouseClick += new System.Windows.Forms.MouseEventHandler(this.assetListView_MouseClick);
//
// columnHeaderName
@@ -676,7 +601,7 @@
this.tabPage3.Controls.Add(this.classesListView);
this.tabPage3.Location = new System.Drawing.Point(4, 22);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Size = new System.Drawing.Size(472, 607);
this.tabPage3.Size = new System.Drawing.Size(472, 664);
this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "Asset Classes";
this.tabPage3.UseVisualStyleBackColor = true;
@@ -692,7 +617,7 @@
this.classesListView.Location = new System.Drawing.Point(0, 0);
this.classesListView.MultiSelect = false;
this.classesListView.Name = "classesListView";
this.classesListView.Size = new System.Drawing.Size(472, 607);
this.classesListView.Size = new System.Drawing.Size(472, 664);
this.classesListView.TabIndex = 0;
this.classesListView.UseCompatibleStateImageBehavior = false;
this.classesListView.View = System.Windows.Forms.View.Details;
@@ -729,28 +654,6 @@
this.progressBar1.Step = 1;
this.progressBar1.TabIndex = 1;
//
// tabControl2
//
this.tabControl2.Controls.Add(this.tabPage4);
this.tabControl2.Controls.Add(this.tabPage5);
this.tabControl2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControl2.Location = new System.Drawing.Point(0, 0);
this.tabControl2.Name = "tabControl2";
this.tabControl2.SelectedIndex = 0;
this.tabControl2.Size = new System.Drawing.Size(776, 633);
this.tabControl2.TabIndex = 4;
this.tabControl2.SelectedIndexChanged += new System.EventHandler(this.tabControl2_SelectedIndexChanged);
//
// tabPage4
//
this.tabPage4.Controls.Add(this.previewPanel);
this.tabPage4.Location = new System.Drawing.Point(4, 22);
this.tabPage4.Name = "tabPage4";
this.tabPage4.Size = new System.Drawing.Size(768, 607);
this.tabPage4.TabIndex = 0;
this.tabPage4.Text = "Preview";
this.tabPage4.UseVisualStyleBackColor = true;
//
// previewPanel
//
this.previewPanel.BackColor = System.Drawing.SystemColors.ControlDark;
@@ -759,13 +662,12 @@
this.previewPanel.Controls.Add(this.assetInfoLabel);
this.previewPanel.Controls.Add(this.FMODpanel);
this.previewPanel.Controls.Add(this.fontPreviewBox);
this.previewPanel.Controls.Add(this.glControl1);
this.previewPanel.Controls.Add(this.textPreviewBox);
this.previewPanel.Controls.Add(this.classTextBox);
this.previewPanel.Controls.Add(this.glControl1);
this.previewPanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.previewPanel.Location = new System.Drawing.Point(0, 0);
this.previewPanel.Name = "previewPanel";
this.previewPanel.Size = new System.Drawing.Size(768, 607);
this.previewPanel.Size = new System.Drawing.Size(776, 633);
this.previewPanel.TabIndex = 1;
this.previewPanel.Resize += new System.EventHandler(this.preview_Resize);
//
@@ -795,7 +697,7 @@
this.FMODpanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.FMODpanel.Location = new System.Drawing.Point(0, 0);
this.FMODpanel.Name = "FMODpanel";
this.FMODpanel.Size = new System.Drawing.Size(768, 607);
this.FMODpanel.Size = new System.Drawing.Size(776, 633);
this.FMODpanel.TabIndex = 2;
this.FMODpanel.Visible = false;
//
@@ -803,7 +705,7 @@
//
this.FMODcopyright.AutoSize = true;
this.FMODcopyright.ForeColor = System.Drawing.SystemColors.ControlLight;
this.FMODcopyright.Location = new System.Drawing.Point(214, 365);
this.FMODcopyright.Location = new System.Drawing.Point(232, 379);
this.FMODcopyright.Name = "FMODcopyright";
this.FMODcopyright.Size = new System.Drawing.Size(283, 13);
this.FMODcopyright.TabIndex = 9;
@@ -813,7 +715,7 @@
//
this.FMODinfoLabel.AutoSize = true;
this.FMODinfoLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight;
this.FMODinfoLabel.Location = new System.Drawing.Point(269, 255);
this.FMODinfoLabel.Location = new System.Drawing.Point(287, 269);
this.FMODinfoLabel.Name = "FMODinfoLabel";
this.FMODinfoLabel.Size = new System.Drawing.Size(0, 13);
this.FMODinfoLabel.TabIndex = 8;
@@ -821,7 +723,7 @@
// FMODtimerLabel
//
this.FMODtimerLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight;
this.FMODtimerLabel.Location = new System.Drawing.Point(404, 255);
this.FMODtimerLabel.Location = new System.Drawing.Point(422, 269);
this.FMODtimerLabel.Name = "FMODtimerLabel";
this.FMODtimerLabel.Size = new System.Drawing.Size(155, 13);
this.FMODtimerLabel.TabIndex = 7;
@@ -831,7 +733,7 @@
// FMODstatusLabel
//
this.FMODstatusLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight;
this.FMODstatusLabel.Location = new System.Drawing.Point(213, 255);
this.FMODstatusLabel.Location = new System.Drawing.Point(231, 269);
this.FMODstatusLabel.Name = "FMODstatusLabel";
this.FMODstatusLabel.Size = new System.Drawing.Size(50, 13);
this.FMODstatusLabel.TabIndex = 6;
@@ -840,7 +742,7 @@
// FMODprogressBar
//
this.FMODprogressBar.AutoSize = false;
this.FMODprogressBar.Location = new System.Drawing.Point(213, 274);
this.FMODprogressBar.Location = new System.Drawing.Point(231, 288);
this.FMODprogressBar.Maximum = 1000;
this.FMODprogressBar.Name = "FMODprogressBar";
this.FMODprogressBar.Size = new System.Drawing.Size(350, 24);
@@ -853,7 +755,7 @@
// FMODvolumeBar
//
this.FMODvolumeBar.LargeChange = 2;
this.FMODvolumeBar.Location = new System.Drawing.Point(460, 303);
this.FMODvolumeBar.Location = new System.Drawing.Point(478, 317);
this.FMODvolumeBar.Name = "FMODvolumeBar";
this.FMODvolumeBar.Size = new System.Drawing.Size(104, 45);
this.FMODvolumeBar.TabIndex = 4;
@@ -864,7 +766,7 @@
// FMODloopButton
//
this.FMODloopButton.Appearance = System.Windows.Forms.Appearance.Button;
this.FMODloopButton.Location = new System.Drawing.Point(399, 303);
this.FMODloopButton.Location = new System.Drawing.Point(417, 317);
this.FMODloopButton.Name = "FMODloopButton";
this.FMODloopButton.Size = new System.Drawing.Size(55, 46);
this.FMODloopButton.TabIndex = 3;
@@ -875,7 +777,7 @@
//
// FMODstopButton
//
this.FMODstopButton.Location = new System.Drawing.Point(338, 303);
this.FMODstopButton.Location = new System.Drawing.Point(356, 317);
this.FMODstopButton.Name = "FMODstopButton";
this.FMODstopButton.Size = new System.Drawing.Size(55, 46);
this.FMODstopButton.TabIndex = 2;
@@ -885,7 +787,7 @@
//
// FMODpauseButton
//
this.FMODpauseButton.Location = new System.Drawing.Point(277, 303);
this.FMODpauseButton.Location = new System.Drawing.Point(295, 317);
this.FMODpauseButton.Name = "FMODpauseButton";
this.FMODpauseButton.Size = new System.Drawing.Size(55, 46);
this.FMODpauseButton.TabIndex = 1;
@@ -895,7 +797,7 @@
//
// FMODplayButton
//
this.FMODplayButton.Location = new System.Drawing.Point(216, 303);
this.FMODplayButton.Location = new System.Drawing.Point(234, 317);
this.FMODplayButton.Name = "FMODplayButton";
this.FMODplayButton.Size = new System.Drawing.Size(55, 46);
this.FMODplayButton.TabIndex = 0;
@@ -910,29 +812,12 @@
this.fontPreviewBox.Location = new System.Drawing.Point(0, 0);
this.fontPreviewBox.Name = "fontPreviewBox";
this.fontPreviewBox.ReadOnly = true;
this.fontPreviewBox.Size = new System.Drawing.Size(768, 607);
this.fontPreviewBox.Size = new System.Drawing.Size(776, 633);
this.fontPreviewBox.TabIndex = 0;
this.fontPreviewBox.Text = resources.GetString("fontPreviewBox.Text");
this.fontPreviewBox.Visible = false;
this.fontPreviewBox.WordWrap = false;
//
// glControl1
//
this.glControl1.BackColor = System.Drawing.SystemColors.ControlDarkDark;
this.glControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.glControl1.Location = new System.Drawing.Point(0, 0);
this.glControl1.Name = "glControl1";
this.glControl1.Size = new System.Drawing.Size(768, 607);
this.glControl1.TabIndex = 4;
this.glControl1.Visible = false;
this.glControl1.VSync = false;
this.glControl1.Load += new System.EventHandler(this.glControl1_Load);
this.glControl1.Paint += new System.Windows.Forms.PaintEventHandler(this.glControl1_Paint);
this.glControl1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseDown);
this.glControl1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseMove);
this.glControl1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseUp);
this.glControl1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseWheel);
//
// textPreviewBox
//
this.textPreviewBox.Dock = System.Windows.Forms.DockStyle.Fill;
@@ -942,11 +827,38 @@
this.textPreviewBox.Name = "textPreviewBox";
this.textPreviewBox.ReadOnly = true;
this.textPreviewBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.textPreviewBox.Size = new System.Drawing.Size(768, 607);
this.textPreviewBox.Size = new System.Drawing.Size(776, 633);
this.textPreviewBox.TabIndex = 2;
this.textPreviewBox.Visible = false;
this.textPreviewBox.WordWrap = false;
//
// glControl1
//
this.glControl1.BackColor = System.Drawing.SystemColors.ControlDarkDark;
this.glControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.glControl1.Location = new System.Drawing.Point(0, 0);
this.glControl1.Name = "glControl1";
this.glControl1.Size = new System.Drawing.Size(776, 633);
this.glControl1.TabIndex = 4;
this.glControl1.Visible = false;
this.glControl1.VSync = false;
this.glControl1.Load += new System.EventHandler(this.glControl1_Load);
this.glControl1.Paint += new System.Windows.Forms.PaintEventHandler(this.glControl1_Paint);
this.glControl1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseDown);
this.glControl1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseMove);
this.glControl1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseUp);
this.glControl1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseWheel);
//
// classPreviewPanel
//
this.classPreviewPanel.Controls.Add(this.classTextBox);
this.classPreviewPanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.classPreviewPanel.Location = new System.Drawing.Point(0, 0);
this.classPreviewPanel.Name = "classPreviewPanel";
this.classPreviewPanel.Size = new System.Drawing.Size(776, 633);
this.classPreviewPanel.TabIndex = 3;
this.classPreviewPanel.Visible = false;
//
// classTextBox
//
this.classTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
@@ -955,33 +867,10 @@
this.classTextBox.Name = "classTextBox";
this.classTextBox.ReadOnly = true;
this.classTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.classTextBox.Size = new System.Drawing.Size(768, 607);
this.classTextBox.Size = new System.Drawing.Size(776, 633);
this.classTextBox.TabIndex = 3;
this.classTextBox.Visible = false;
this.classTextBox.WordWrap = false;
//
// tabPage5
//
this.tabPage5.Controls.Add(this.dumpTextBox);
this.tabPage5.Location = new System.Drawing.Point(4, 22);
this.tabPage5.Name = "tabPage5";
this.tabPage5.Size = new System.Drawing.Size(768, 607);
this.tabPage5.TabIndex = 1;
this.tabPage5.Text = "Dump";
this.tabPage5.UseVisualStyleBackColor = true;
//
// dumpTextBox
//
this.dumpTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.dumpTextBox.Location = new System.Drawing.Point(0, 0);
this.dumpTextBox.Multiline = true;
this.dumpTextBox.Name = "dumpTextBox";
this.dumpTextBox.ReadOnly = true;
this.dumpTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.dumpTextBox.Size = new System.Drawing.Size(768, 607);
this.dumpTextBox.TabIndex = 0;
this.dumpTextBox.WordWrap = false;
//
// statusStrip1
//
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -1013,24 +902,29 @@
this.openFileDialog1.Multiselect = true;
this.openFileDialog1.RestoreDirectory = true;
//
// saveFileDialog1
//
this.saveFileDialog1.Filter = "FBX file|*.fbx";
this.saveFileDialog1.RestoreDirectory = true;
//
// contextMenuStrip1
//
this.contextMenuStrip1.ImageScalingSize = new System.Drawing.Size(20, 20);
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.copyToolStripMenuItem,
this.exportSelectedAssetsToolStripMenuItem,
this.exportAnimatorwithselectedAnimationClipMenuItem,
this.dumpSelectedAssetsToolStripMenuItem,
this.exportAnimatorwithselectedAnimationClipMenuItem,
this.goToSceneHierarchyToolStripMenuItem,
this.showOriginalFileToolStripMenuItem});
this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.Size = new System.Drawing.Size(304, 158);
this.contextMenuStrip1.Size = new System.Drawing.Size(304, 136);
//
// copyToolStripMenuItem
//
this.copyToolStripMenuItem.Name = "copyToolStripMenuItem";
this.copyToolStripMenuItem.Size = new System.Drawing.Size(303, 22);
this.copyToolStripMenuItem.Text = "Copy text";
this.copyToolStripMenuItem.Text = "Copy";
this.copyToolStripMenuItem.Click += new System.EventHandler(this.copyToolStripMenuItem_Click);
//
// exportSelectedAssetsToolStripMenuItem
@@ -1040,6 +934,13 @@
this.exportSelectedAssetsToolStripMenuItem.Text = "Export selected assets";
this.exportSelectedAssetsToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedAssetsToolStripMenuItem_Click);
//
// dumpSelectedAssetsToolStripMenuItem
//
this.dumpSelectedAssetsToolStripMenuItem.Name = "dumpSelectedAssetsToolStripMenuItem";
this.dumpSelectedAssetsToolStripMenuItem.Size = new System.Drawing.Size(303, 22);
this.dumpSelectedAssetsToolStripMenuItem.Text = "Dump selected assets";
this.dumpSelectedAssetsToolStripMenuItem.Click += new System.EventHandler(this.dumpSelectedAssetsToolStripMenuItem_Click);
//
// exportAnimatorwithselectedAnimationClipMenuItem
//
this.exportAnimatorwithselectedAnimationClipMenuItem.Name = "exportAnimatorwithselectedAnimationClipMenuItem";
@@ -1048,13 +949,6 @@
this.exportAnimatorwithselectedAnimationClipMenuItem.Visible = false;
this.exportAnimatorwithselectedAnimationClipMenuItem.Click += new System.EventHandler(this.exportAnimatorwithAnimationClipMenuItem_Click);
//
// dumpSelectedAssetsToolStripMenuItem
//
this.dumpSelectedAssetsToolStripMenuItem.Name = "dumpSelectedAssetsToolStripMenuItem";
this.dumpSelectedAssetsToolStripMenuItem.Size = new System.Drawing.Size(303, 22);
this.dumpSelectedAssetsToolStripMenuItem.Text = "Dump selected assets";
this.dumpSelectedAssetsToolStripMenuItem.Click += new System.EventHandler(this.dumpSelectedAssetsToolStripMenuItem_Click);
//
// goToSceneHierarchyToolStripMenuItem
//
this.goToSceneHierarchyToolStripMenuItem.Name = "goToSceneHierarchyToolStripMenuItem";
@@ -1073,7 +967,6 @@
//
// AssetStudioGUIForm
//
this.AllowDrop = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1264, 681);
@@ -1086,8 +979,6 @@
this.Name = "AssetStudioGUIForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "AssetStudioGUI";
this.DragDrop += new System.Windows.Forms.DragEventHandler(this.AssetStudioGUIForm_DragDrop);
this.DragEnter += new System.Windows.Forms.DragEventHandler(this.AssetStudioGUIForm_DragEnter);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.AssetStudioForm_KeyDown);
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
@@ -1103,16 +994,14 @@
this.tabPage2.PerformLayout();
this.tabPage3.ResumeLayout(false);
this.progressbarPanel.ResumeLayout(false);
this.tabControl2.ResumeLayout(false);
this.tabPage4.ResumeLayout(false);
this.previewPanel.ResumeLayout(false);
this.previewPanel.PerformLayout();
this.FMODpanel.ResumeLayout(false);
this.FMODpanel.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.FMODprogressBar)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.FMODvolumeBar)).EndInit();
this.tabPage5.ResumeLayout(false);
this.tabPage5.PerformLayout();
this.classPreviewPanel.ResumeLayout(false);
this.classPreviewPanel.PerformLayout();
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
this.contextMenuStrip1.ResumeLayout(false);
@@ -1169,6 +1058,7 @@
private System.Windows.Forms.ToolStripMenuItem extractFileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem extractFolderToolStripMenuItem;
private System.Windows.Forms.OpenFileDialog openFileDialog1;
private System.Windows.Forms.SaveFileDialog saveFileDialog1;
private System.Windows.Forms.ToolStripMenuItem showExpOpt;
private GOHierarchy sceneTreeView;
private System.Windows.Forms.ToolStripMenuItem debugMenuItem;
@@ -1176,6 +1066,7 @@
private System.Windows.Forms.ListView classesListView;
private System.Windows.Forms.ColumnHeader columnHeader2;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.Panel classPreviewPanel;
private System.Windows.Forms.TextBox classTextBox;
private System.Windows.Forms.ToolStripMenuItem exportClassStructuresMenuItem;
private System.Windows.Forms.Label FMODcopyright;
@@ -1207,18 +1098,6 @@
private System.Windows.Forms.ColumnHeader columnHeaderContainer;
private System.Windows.Forms.ColumnHeader columnHeaderPathID;
private System.Windows.Forms.ToolStripMenuItem copyToolStripMenuItem;
private System.Windows.Forms.TabControl tabControl2;
private System.Windows.Forms.TabPage tabPage4;
private System.Windows.Forms.TabPage tabPage5;
private System.Windows.Forms.TextBox dumpTextBox;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem10;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem11;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem12;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem13;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem14;
private System.Windows.Forms.ToolStripTextBox specifyUnityVersion;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem15;
private System.Windows.Forms.ToolStripMenuItem dumpSelectedAssetsToolStripMenuItem;
}
}

View File

@@ -1,5 +1,4 @@
using AssetStudio;
using Newtonsoft.Json;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using System;
@@ -19,7 +18,6 @@ using System.Timers;
using System.Windows.Forms;
using static AssetStudioGUI.Studio;
using Font = AssetStudio.Font;
using ImageFormat = AssetStudio.ImageFormat;
using PixelFormat = System.Drawing.Imaging.PixelFormat;
using Vector3 = OpenTK.Vector3;
using Vector4 = OpenTK.Vector4;
@@ -29,6 +27,7 @@ namespace AssetStudioGUI
partial class AssetStudioGUIForm : Form
{
private AssetItem lastSelectedItem;
private AssetItem lastLoadedAsset;
private Bitmap imageTexture;
private string tempClipboard;
@@ -73,7 +72,6 @@ namespace AssetStudioGUI
//asset list sorting
private int sortColumn = -1;
private bool reverseSort;
private AlphanumComparatorFast alphanumComparator = new AlphanumComparatorFast();
//asset list filter
private System.Timers.Timer delayTimer;
@@ -83,11 +81,6 @@ namespace AssetStudioGUI
private int nextGObject;
private List<TreeNode> treeSrcResults = new List<TreeNode>();
private string openDirectoryBackup = string.Empty;
private string saveDirectoryBackup = string.Empty;
private GUILogger logger;
[DllImport("gdi32.dll")]
private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts);
@@ -103,27 +96,27 @@ namespace AssetStudioGUI
enablePreview.Checked = Properties.Settings.Default.enablePreview;
FMODinit();
logger = new GUILogger(StatusStripUpdate);
Logger.Default = logger;
Logger.Default = new GUILogger(StatusStripUpdate);
Progress.Default = new GUIProgress(SetProgressBarValue);
Studio.StatusStripUpdate = StatusStripUpdate;
this.AllowDrop = true;
this.DragEnter += AssetStudioGUIForm_DragEnter;
this.DragDrop += AssetStudioGUIForm_DragDrop;
}
private void AssetStudioGUIForm_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Move;
}
if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Move;
}
private async void AssetStudioGUIForm_DragDrop(object sender, DragEventArgs e)
{
var paths = (string[])e.Data.GetData(DataFormats.FileDrop);
string[] paths = (string[])e.Data.GetData(DataFormats.FileDrop);
if (paths.Length > 0)
{
ResetForm();
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
if (paths.Length == 1 && Directory.Exists(paths[0]))
{
await Task.Run(() => assetsManager.LoadFolder(paths[0]));
@@ -132,18 +125,16 @@ namespace AssetStudioGUI
{
await Task.Run(() => assetsManager.LoadFiles(paths));
}
BuildAssetStructures();
}
}
private async void loadFile_Click(object sender, EventArgs e)
{
openFileDialog1.InitialDirectory = openDirectoryBackup;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
ResetForm();
openDirectoryBackup = Path.GetDirectoryName(openFileDialog1.FileNames[0]);
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
await Task.Run(() => assetsManager.LoadFiles(openFileDialog1.FileNames));
BuildAssetStructures();
}
@@ -152,47 +143,29 @@ namespace AssetStudioGUI
private async void loadFolder_Click(object sender, EventArgs e)
{
var openFolderDialog = new OpenFolderDialog();
openFolderDialog.InitialFolder = openDirectoryBackup;
if (openFolderDialog.ShowDialog(this) == DialogResult.OK)
{
ResetForm();
openDirectoryBackup = openFolderDialog.Folder;
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
await Task.Run(() => assetsManager.LoadFolder(openFolderDialog.Folder));
BuildAssetStructures();
}
}
private async void extractFileToolStripMenuItem_Click(object sender, EventArgs e)
private void extractFileToolStripMenuItem_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.Title = "Select the save folder";
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
{
var fileNames = openFileDialog1.FileNames;
var savePath = saveFolderDialog.Folder;
var extractedCount = await Task.Run(() => ExtractFile(fileNames, savePath));
StatusStripUpdate($"Finished extracting {extractedCount} files.");
}
ExtractFile(openFileDialog1.FileNames);
}
}
private async void extractFolderToolStripMenuItem_Click(object sender, EventArgs e)
private void extractFolderToolStripMenuItem_Click(object sender, EventArgs e)
{
var openFolderDialog = new OpenFolderDialog();
if (openFolderDialog.ShowDialog(this) == DialogResult.OK)
var openFolderDialog1 = new OpenFolderDialog();
if (openFolderDialog1.ShowDialog(this) == DialogResult.OK)
{
var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.Title = "Select the save folder";
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
{
var path = openFolderDialog.Folder;
var savePath = saveFolderDialog.Folder;
var extractedCount = await Task.Run(() => ExtractFolder(path, savePath));
StatusStripUpdate($"Finished extracting {extractedCount} files.");
}
var files = Directory.GetFiles(openFolderDialog1.Folder, "*.*", SearchOption.AllDirectories);
ExtractFile(files);
}
}
@@ -200,7 +173,7 @@ namespace AssetStudioGUI
{
if (assetsManager.assetsFileList.Count == 0)
{
StatusStripUpdate("No Unity file can be loaded.");
StatusStripUpdate("No file was loaded.");
return;
}
@@ -315,31 +288,31 @@ namespace AssetStudioGUI
{
if (e.Control)
{
var need = false;
bool dirty = false;
switch (e.KeyCode)
{
case Keys.B:
textureChannels[0] = !textureChannels[0];
need = true;
dirty = true;
break;
case Keys.G:
textureChannels[1] = !textureChannels[1];
need = true;
dirty = true;
break;
case Keys.R:
textureChannels[2] = !textureChannels[2];
need = true;
dirty = true;
break;
case Keys.A:
textureChannels[3] = !textureChannels[3];
need = true;
dirty = true;
break;
}
if (need)
if (dirty)
{
if (lastSelectedItem != null)
PreviewAsset(lastLoadedAsset);
if (lastSelectedItem != null && assetInfoLabel.Text != null)
{
PreviewAsset(lastSelectedItem);
assetInfoLabel.Text = lastSelectedItem.InfoText;
}
}
@@ -360,10 +333,10 @@ namespace AssetStudioGUI
Progress.Reset();
foreach (TypeTreeItem item in classesListView.Items)
{
var versionPath = Path.Combine(savePath, item.Group.Header);
var versionPath = savePath + "\\" + item.Group.Header;
Directory.CreateDirectory(versionPath);
var saveFile = $"{versionPath}{Path.DirectorySeparatorChar}{item.SubItems[1].Text} {item.Text}.txt";
var saveFile = $"{versionPath}\\{item.SubItems[1].Text} {item.Text}.txt";
File.WriteAllText(saveFile, item.ToString());
Progress.Report(++i, count);
@@ -382,9 +355,9 @@ namespace AssetStudioGUI
private void enablePreview_Check(object sender, EventArgs e)
{
if (lastSelectedItem != null)
if (lastLoadedAsset != null)
{
switch (lastSelectedItem.Type)
switch (lastLoadedAsset.Type)
{
case ClassIDType.Texture2D:
case ClassIDType.Sprite:
@@ -423,7 +396,7 @@ namespace AssetStudioGUI
}
else if (FMODpanel.Visible)
{
PreviewAsset(lastSelectedItem);
PreviewAsset(lastLoadedAsset);
}
break;
@@ -434,7 +407,8 @@ namespace AssetStudioGUI
}
else if (lastSelectedItem != null && enablePreview.Checked)
{
PreviewAsset(lastSelectedItem);
lastLoadedAsset = lastSelectedItem;
PreviewAsset(lastLoadedAsset);
}
Properties.Settings.Default.enablePreview = enablePreview.Checked;
@@ -475,8 +449,14 @@ namespace AssetStudioGUI
treeSearch.Select();
break;
case 1:
classPreviewPanel.Visible = false;
previewPanel.Visible = true;
listSearch.Select();
break;
case 2:
previewPanel.Visible = false;
classPreviewPanel.Visible = true;
break;
}
}
@@ -491,7 +471,7 @@ namespace AssetStudioGUI
private void treeSearch_Leave(object sender, EventArgs e)
{
if (treeSearch.Text == "")
if (string.IsNullOrEmpty(treeSearch.Text))
{
treeSearch.Text = " Search ";
treeSearch.ForeColor = SystemColors.GrayText;
@@ -561,7 +541,7 @@ namespace AssetStudioGUI
private void listSearch_Leave(object sender, EventArgs e)
{
if (listSearch.Text == "")
if (string.IsNullOrEmpty(listSearch.Text))
{
enableFiltering = false;
listSearch.Text = " Filter ";
@@ -622,15 +602,6 @@ namespace AssetStudioGUI
return reverseSort ? pathID_Y.CompareTo(pathID_X) : pathID_X.CompareTo(pathID_Y);
});
}
else if (sortColumn == 0) // Name
{
visibleAssets.Sort((a, b) =>
{
var at = a.SubItems[sortColumn].Text;
var bt = b.SubItems[sortColumn].Text;
return reverseSort ? alphanumComparator.Compare(bt, at) : alphanumComparator.Compare(at, bt);
});
}
else
{
visibleAssets.Sort((a, b) =>
@@ -647,13 +618,13 @@ namespace AssetStudioGUI
{
previewPanel.BackgroundImage = Properties.Resources.preview;
previewPanel.BackgroundImageLayout = ImageLayout.Center;
classTextBox.Visible = false;
assetInfoLabel.Visible = false;
assetInfoLabel.Text = null;
textPreviewBox.Visible = false;
fontPreviewBox.Visible = false;
FMODpanel.Visible = false;
glControl1.Visible = false;
lastLoadedAsset = null;
StatusStripUpdate("");
FMODreset();
@@ -662,32 +633,21 @@ namespace AssetStudioGUI
if (e.IsSelected)
{
if (tabControl2.SelectedIndex == 1)
{
dumpTextBox.Text = DumpAsset(lastSelectedItem.Asset);
}
if (enablePreview.Checked)
{
PreviewAsset(lastSelectedItem);
if (displayInfo.Checked && lastSelectedItem.InfoText != null)
{
assetInfoLabel.Text = lastSelectedItem.InfoText;
assetInfoLabel.Visible = true;
}
lastLoadedAsset = lastSelectedItem;
PreviewAsset(lastLoadedAsset);
}
if (displayInfo.Checked && assetInfoLabel.Text != null)//only display the label if asset has info text
{
assetInfoLabel.Text = lastSelectedItem.InfoText;
assetInfoLabel.Visible = true;
}
}
}
private void classesListView_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
classTextBox.Visible = true;
assetInfoLabel.Visible = false;
assetInfoLabel.Text = null;
textPreviewBox.Visible = false;
fontPreviewBox.Visible = false;
FMODpanel.Visible = false;
glControl1.Visible = false;
StatusStripUpdate("");
if (e.IsSelected)
{
classTextBox.Text = ((TypeTreeItem)classesListView.SelectedItems[0]).ToString();
@@ -921,15 +881,10 @@ namespace AssetStudioGUI
var result = system.createSound(m_AudioData, FMOD.MODE.OPENMEMORY | loopMode, ref exinfo, out sound);
if (ERRCHECK(result)) return;
sound.getNumSubSounds(out var numsubsounds);
if (numsubsounds > 0)
result = sound.getSubSound(0, out var subsound);
if (result == FMOD.RESULT.OK)
{
result = sound.getSubSound(0, out var subsound);
if (result == FMOD.RESULT.OK)
{
sound = subsound;
}
sound = subsound;
}
result = sound.getLength(out FMODlenms, FMOD.TIMEUNIT.MS);
@@ -956,20 +911,12 @@ namespace AssetStudioGUI
private void PreviewTextAsset(TextAsset m_TextAsset)
{
var text = Encoding.UTF8.GetString(m_TextAsset.m_Script);
text = text.Replace("\n", "\r\n").Replace("\0", "");
PreviewText(text);
PreviewText(text.Replace("\n", "\r\n"));
}
private void PreviewMonoBehaviour(MonoBehaviour m_MonoBehaviour)
{
var obj = m_MonoBehaviour.ToType();
if (obj == null)
{
var type = MonoBehaviourToTypeTree(m_MonoBehaviour);
obj = m_MonoBehaviour.ToType(type);
}
var str = JsonConvert.SerializeObject(obj, Formatting.Indented);
PreviewText(str);
PreviewText(m_MonoBehaviour.Dump() ?? GetScriptString(m_MonoBehaviour.reader));
}
private void PreviewFont(Font m_Font)
@@ -1177,6 +1124,7 @@ namespace AssetStudioGUI
if (bitmap != null)
{
assetItem.InfoText = $"Width: {bitmap.Width}\nHeight: {bitmap.Height}\n";
PreviewTexture(bitmap);
}
else
@@ -1230,7 +1178,6 @@ namespace AssetStudioGUI
{
Text = $"AssetStudioGUI v{Application.ProductVersion}";
assetsManager.Clear();
assemblyLoader.Clear();
exportableAssets.Clear();
visibleAssets.Clear();
sceneTreeView.Nodes.Clear();
@@ -1247,6 +1194,7 @@ namespace AssetStudioGUI
fontPreviewBox.Visible = false;
glControl1.Visible = false;
lastSelectedItem = null;
lastLoadedAsset = null;
sortColumn = -1;
reverseSort = false;
enableFiltering = false;
@@ -1261,6 +1209,12 @@ namespace AssetStudioGUI
}
FMODreset();
if (scriptDumper != null)
{
scriptDumper.Dispose();
scriptDumper = null;
}
}
private void assetListView_MouseClick(object sender, MouseEventArgs e)
@@ -1285,10 +1239,7 @@ namespace AssetStudioGUI
}
}
var selectedElement = assetListView.HitTest(new Point(e.X, e.Y));
var subItemIndex = selectedElement.Item.SubItems.IndexOf(selectedElement.SubItem);
tempClipboard = selectedElement.SubItem.Text;
copyToolStripMenuItem.Text = $"Copy {assetListView.Columns[subItemIndex].Text}";
tempClipboard = assetListView.HitTest(new Point(e.X, e.Y)).SubItem.Text;
contextMenuStrip1.Show(assetListView, e.X, e.Y);
}
}
@@ -1300,12 +1251,12 @@ namespace AssetStudioGUI
private void exportSelectedAssetsToolStripMenuItem_Click(object sender, EventArgs e)
{
ExportAssets(ExportFilter.Selected, ExportType.Convert);
ExportAssets(2, ExportType.Convert);
}
private void dumpSelectedAssetsToolStripMenuItem_Click(object sender, EventArgs e)
{
ExportAssets(ExportFilter.Selected, ExportType.Dump);
ExportAssets(2, ExportType.Dump);
}
private void showOriginalFileToolStripMenuItem_Click(object sender, EventArgs e)
@@ -1335,12 +1286,10 @@ namespace AssetStudioGUI
if (animator != null)
{
var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
var saveFolderDialog1 = new OpenFolderDialog();
if (saveFolderDialog1.ShowDialog(this) == DialogResult.OK)
{
saveDirectoryBackup = saveFolderDialog.Folder;
var exportPath = Path.Combine(saveFolderDialog.Folder, "Animator") + Path.DirectorySeparatorChar;
var exportPath = saveFolderDialog1.Folder + "\\Animator\\";
ExportAnimatorWithAnimationClip(animator, animationList, exportPath);
}
}
@@ -1360,12 +1309,10 @@ namespace AssetStudioGUI
{
if (sceneTreeView.Nodes.Count > 0)
{
var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
var saveFolderDialog1 = new OpenFolderDialog();
if (saveFolderDialog1.ShowDialog(this) == DialogResult.OK)
{
saveDirectoryBackup = saveFolderDialog.Folder;
var exportPath = Path.Combine(saveFolderDialog.Folder, "GameObject") + Path.DirectorySeparatorChar;
var exportPath = saveFolderDialog1.Folder + "\\GameObject\\";
List<AssetItem> animationList = null;
if (animation)
{
@@ -1404,10 +1351,8 @@ namespace AssetStudioGUI
saveFileDialog.FileName = gameObjects[0].m_Name + " (merge).fbx";
saveFileDialog.AddExtension = false;
saveFileDialog.Filter = "Fbx file (*.fbx)|*.fbx";
saveFileDialog.InitialDirectory = saveDirectoryBackup;
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
saveDirectoryBackup = Path.GetDirectoryName(saveFileDialog.FileName);
var exportPath = saveFileDialog.FileName;
List<AssetItem> animationList = null;
if (animation)
@@ -1435,74 +1380,57 @@ namespace AssetStudioGUI
private void exportAllAssetsMenuItem_Click(object sender, EventArgs e)
{
ExportAssets(ExportFilter.All, ExportType.Convert);
ExportAssets(1, ExportType.Convert);
}
private void exportSelectedAssetsMenuItem_Click(object sender, EventArgs e)
{
ExportAssets(ExportFilter.Selected, ExportType.Convert);
ExportAssets(2, ExportType.Convert);
}
private void exportFilteredAssetsMenuItem_Click(object sender, EventArgs e)
{
ExportAssets(ExportFilter.Filtered, ExportType.Convert);
ExportAssets(3, ExportType.Convert);
}
private void toolStripMenuItem4_Click(object sender, EventArgs e)
{
ExportAssets(ExportFilter.All, ExportType.Raw);
ExportAssets(1, ExportType.Raw);
}
private void toolStripMenuItem5_Click(object sender, EventArgs e)
{
ExportAssets(ExportFilter.Selected, ExportType.Raw);
ExportAssets(2, ExportType.Raw);
}
private void toolStripMenuItem6_Click(object sender, EventArgs e)
{
ExportAssets(ExportFilter.Filtered, ExportType.Raw);
ExportAssets(3, ExportType.Raw);
}
private void toolStripMenuItem7_Click(object sender, EventArgs e)
{
ExportAssets(ExportFilter.All, ExportType.Dump);
ExportAssets(1, ExportType.Dump);
}
private void toolStripMenuItem8_Click(object sender, EventArgs e)
{
ExportAssets(ExportFilter.Selected, ExportType.Dump);
ExportAssets(2, ExportType.Dump);
}
private void toolStripMenuItem9_Click(object sender, EventArgs e)
{
ExportAssets(ExportFilter.Filtered, ExportType.Dump);
}
private void toolStripMenuItem11_Click(object sender, EventArgs e)
{
ExportAssetsList(ExportFilter.All);
}
private void toolStripMenuItem12_Click(object sender, EventArgs e)
{
ExportAssetsList(ExportFilter.Selected);
}
private void toolStripMenuItem13_Click(object sender, EventArgs e)
{
ExportAssetsList(ExportFilter.Filtered);
ExportAssets(3, ExportType.Dump);
}
private void exportAllObjectssplitToolStripMenuItem1_Click(object sender, EventArgs e)
{
if (sceneTreeView.Nodes.Count > 0)
{
var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
var saveFolderDialog1 = new OpenFolderDialog();
if (saveFolderDialog1.ShowDialog(this) == DialogResult.OK)
{
saveDirectoryBackup = saveFolderDialog.Folder;
var savePath = saveFolderDialog.Folder + Path.DirectorySeparatorChar;
var savePath = saveFolderDialog1.Folder + "\\";
ExportSplitObjects(savePath, sceneTreeView.Nodes);
}
}
@@ -1512,18 +1440,6 @@ namespace AssetStudioGUI
}
}
private void assetListView_SelectedIndexChanged(object sender, EventArgs e)
{
if (assetListView.SelectedIndices.Count > 1)
StatusStripUpdate($"Selected {assetListView.SelectedIndices.Count} assets.");
}
private void assetListView_VirtualItemsSelectionRangeChanged(object sender, ListViewVirtualItemsSelectionRangeChangedEventArgs e)
{
if (assetListView.SelectedIndices.Count > 1)
StatusStripUpdate($"Selected {assetListView.SelectedIndices.Count} assets.");
}
private List<AssetItem> GetSelectedAssets()
{
var selectedAssets = new List<AssetItem>(assetListView.SelectedIndices.Count);
@@ -1567,64 +1483,29 @@ namespace AssetStudioGUI
assetListView.EndUpdate();
}
private void ExportAssets(ExportFilter type, ExportType exportType)
private void ExportAssets(int type, ExportType exportType)
{
if (exportableAssets.Count > 0)
{
var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
var saveFolderDialog1 = new OpenFolderDialog();
if (saveFolderDialog1.ShowDialog(this) == DialogResult.OK)
{
timer.Stop();
saveDirectoryBackup = saveFolderDialog.Folder;
List<AssetItem> toExportAssets = null;
switch (type)
{
case ExportFilter.All:
case 1: //All Assets
toExportAssets = exportableAssets;
break;
case ExportFilter.Selected:
case 2: //Selected Assets
toExportAssets = GetSelectedAssets();
break;
case ExportFilter.Filtered:
case 3: //Filtered Assets
toExportAssets = visibleAssets;
break;
}
Studio.ExportAssets(saveFolderDialog.Folder, toExportAssets, exportType);
}
}
else
{
StatusStripUpdate("No exportable assets loaded");
}
}
private void ExportAssetsList(ExportFilter type)
{
// XXX: Only exporting as XML for now, but would JSON(/CSV/other) be useful too?
if (exportableAssets.Count > 0)
{
var saveFolderDialog = new OpenFolderDialog();
saveFolderDialog.InitialFolder = saveDirectoryBackup;
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
{
timer.Stop();
saveDirectoryBackup = saveFolderDialog.Folder;
List<AssetItem> toExportAssets = null;
switch (type)
{
case ExportFilter.All:
toExportAssets = exportableAssets;
break;
case ExportFilter.Selected:
toExportAssets = GetSelectedAssets();
break;
case ExportFilter.Filtered:
toExportAssets = visibleAssets;
break;
}
Studio.ExportAssetsList(saveFolderDialog.Folder, toExportAssets, ExportListType.XML);
Studio.ExportAssets(saveFolderDialog1.Folder, toExportAssets, exportType);
}
}
else
@@ -1649,7 +1530,7 @@ namespace AssetStudioGUI
Application.Exit();
}
result = system.init(2, FMOD.INITFLAGS.NORMAL, IntPtr.Zero);
result = system.init(1, FMOD.INITFLAGS.NORMAL, IntPtr.Zero);
if (ERRCHECK(result)) { return; }
result = system.getMasterSoundGroup(out masterSoundGroup);
@@ -2061,19 +1942,6 @@ namespace AssetStudioGUI
glControl1.SwapBuffers();
}
private void tabControl2_SelectedIndexChanged(object sender, EventArgs e)
{
if (tabControl2.SelectedIndex == 1 && lastSelectedItem != null)
{
dumpTextBox.Text = DumpAsset(lastSelectedItem.Asset);
}
}
private void toolStripMenuItem15_Click(object sender, EventArgs e)
{
logger.ShowErrorMessage = toolStripMenuItem15.Checked;
}
private void glControl1_MouseWheel(object sender, MouseEventArgs e)
{
if (glControl1.Visible)

View File

@@ -147,6 +147,9 @@ The quick brown fox jumps over the lazy dog. 1234567890</value>
<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="saveFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>784, 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>

View File

@@ -1,96 +0,0 @@
// This code developed by Dot Net Perls
using System.Collections;
namespace AssetStudioGUI
{
internal class AlphanumComparatorFast : IComparer
{
public int Compare(object x, object y)
{
if (!(x is string s1))
{
return 0;
}
if (!(y is string s2))
{
return 0;
}
int len1 = s1.Length;
int len2 = s2.Length;
int marker1 = 0;
int marker2 = 0;
// Walk through two the strings with two markers.
while (marker1 < len1 && marker2 < len2)
{
char ch1 = s1[marker1];
char ch2 = s2[marker2];
// Some buffers we can build up characters in for each chunk.
char[] space1 = new char[len1];
int loc1 = 0;
char[] space2 = new char[len2];
int loc2 = 0;
// Walk through all following characters that are digits or
// characters in BOTH strings starting at the appropriate marker.
// Collect char arrays.
do
{
space1[loc1++] = ch1;
marker1++;
if (marker1 < len1)
{
ch1 = s1[marker1];
}
else
{
break;
}
} while (char.IsDigit(ch1) == char.IsDigit(space1[0]));
do
{
space2[loc2++] = ch2;
marker2++;
if (marker2 < len2)
{
ch2 = s2[marker2];
}
else
{
break;
}
} while (char.IsDigit(ch2) == char.IsDigit(space2[0]));
// If we have collected numbers, compare them numerically.
// Otherwise, if we have strings, compare them alphabetically.
string str1 = new string(space1);
string str2 = new string(space2);
int result;
if (char.IsDigit(space1[0]) && char.IsDigit(space2[0]))
{
int thisNumericChunk = int.Parse(str1);
int thatNumericChunk = int.Parse(str2);
result = thisNumericChunk.CompareTo(thatNumericChunk);
}
else
{
result = str1.CompareTo(str2);
}
if (result != 0)
{
return result;
}
}
return len1 - len2;
}
}
}

View File

@@ -29,11 +29,9 @@ namespace AssetStudioGUI
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))
{
if (Title != null)
frm.SetTitle(Title);
}
if (!string.IsNullOrEmpty(InitialFolder))
if (InitialFolder != null)
{
var riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem
if (NativeMethods.SHCreateItemFromParsingName(InitialFolder, IntPtr.Zero, ref riid, out var directoryShellItem) == NativeMethods.S_OK)
@@ -41,7 +39,7 @@ namespace AssetStudioGUI
frm.SetFolder(directoryShellItem);
}
}
if (!string.IsNullOrEmpty(DefaultFolder))
if (DefaultFolder != null)
{
var riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem
if (NativeMethods.SHCreateItemFromParsingName(DefaultFolder, IntPtr.Zero, ref riid, out var directoryShellItem) == NativeMethods.S_OK)

View File

@@ -40,7 +40,7 @@ namespace AssetStudioGUI
hItem = node.Handle,
mask = TVIF_STATE,
stateMask = TVIS_STATEIMAGEMASK,
state = TVIS_STATEIMAGEMASK //temp bugfix for an issue with getting stuck during the "Building tree structure" step
state = node.StateImageIndex //freeze bugfix (no)
};
SendMessage(node.TreeView.Handle, TVM_SETITEM, IntPtr.Zero, ref tvi);
}

View File

@@ -7,19 +7,19 @@ namespace AssetStudioGUI
{
internal class TypeTreeItem : ListViewItem
{
private TypeTree m_Type;
private List<TypeTreeNode> m_Nodes;
public TypeTreeItem(int typeID, TypeTree m_Type)
public TypeTreeItem(int typeID, List<TypeTreeNode> m_Nodes)
{
this.m_Type = m_Type;
Text = m_Type.m_Nodes[0].m_Type + " " + m_Type.m_Nodes[0].m_Name;
this.m_Nodes = m_Nodes;
Text = m_Nodes[0].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)
foreach (var i in 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);
}

View File

@@ -28,10 +28,11 @@
/// </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.pathIDAsDumpName = new System.Windows.Forms.CheckBox();
this.pathIDAsImageName = 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();
@@ -44,7 +45,6 @@
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();
@@ -61,7 +61,6 @@
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.groupBox1.SuspendLayout();
this.panel1.SuspendLayout();
this.groupBox2.SuspendLayout();
@@ -72,7 +71,7 @@
//
// OKbutton
//
this.OKbutton.Location = new System.Drawing.Point(318, 380);
this.OKbutton.Location = new System.Drawing.Point(308, 347);
this.OKbutton.Name = "OKbutton";
this.OKbutton.Size = new System.Drawing.Size(75, 23);
this.OKbutton.TabIndex = 6;
@@ -83,7 +82,7 @@
// Cancel
//
this.Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.Cancel.Location = new System.Drawing.Point(399, 380);
this.Cancel.Location = new System.Drawing.Point(389, 347);
this.Cancel.Name = "Cancel";
this.Cancel.Size = new System.Drawing.Size(75, 23);
this.Cancel.TabIndex = 7;
@@ -94,6 +93,8 @@
// groupBox1
//
this.groupBox1.AutoSize = true;
this.groupBox1.Controls.Add(this.pathIDAsDumpName);
this.groupBox1.Controls.Add(this.pathIDAsImageName);
this.groupBox1.Controls.Add(this.openAfterExport);
this.groupBox1.Controls.Add(this.restoreExtensionName);
this.groupBox1.Controls.Add(this.assetGroupOptions);
@@ -103,11 +104,35 @@
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, 362);
this.groupBox1.Size = new System.Drawing.Size(246, 327);
this.groupBox1.TabIndex = 9;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Export";
//
// pathIDAsDumpName
//
this.pathIDAsDumpName.AutoSize = true;
this.pathIDAsDumpName.Checked = true;
this.pathIDAsDumpName.CheckState = System.Windows.Forms.CheckState.Checked;
this.pathIDAsDumpName.Location = new System.Drawing.Point(6, 217);
this.pathIDAsDumpName.Name = "pathIDAsDumpName";
this.pathIDAsDumpName.Size = new System.Drawing.Size(201, 17);
this.pathIDAsDumpName.TabIndex = 12;
this.pathIDAsDumpName.Text = "Dump assets with PathID as filename";
this.pathIDAsDumpName.UseVisualStyleBackColor = true;
//
// pathIDAsImageName
//
this.pathIDAsImageName.AutoSize = true;
this.pathIDAsImageName.Checked = true;
this.pathIDAsImageName.CheckState = System.Windows.Forms.CheckState.Checked;
this.pathIDAsImageName.Location = new System.Drawing.Point(6, 196);
this.pathIDAsImageName.Name = "pathIDAsImageName";
this.pathIDAsImageName.Size = new System.Drawing.Size(234, 17);
this.pathIDAsImageName.TabIndex = 11;
this.pathIDAsImageName.Text = "Export image assets with PathID as filename";
this.pathIDAsImageName.UseVisualStyleBackColor = true;
//
// openAfterExport
//
this.openAfterExport.AutoSize = true;
@@ -183,9 +208,9 @@
this.totga.AutoSize = true;
this.totga.Location = new System.Drawing.Point(150, 7);
this.totga.Name = "totga";
this.totga.Size = new System.Drawing.Size(44, 17);
this.totga.Size = new System.Drawing.Size(47, 17);
this.totga.TabIndex = 2;
this.totga.Text = "Tga";
this.totga.Text = "TGA";
this.totga.UseVisualStyleBackColor = true;
//
// tojpg
@@ -193,9 +218,9 @@
this.tojpg.AutoSize = true;
this.tojpg.Location = new System.Drawing.Point(97, 7);
this.tojpg.Name = "tojpg";
this.tojpg.Size = new System.Drawing.Size(48, 17);
this.tojpg.Size = new System.Drawing.Size(52, 17);
this.tojpg.TabIndex = 4;
this.tojpg.Text = "Jpeg";
this.tojpg.Text = "JPEG";
this.tojpg.UseVisualStyleBackColor = true;
//
// topng
@@ -204,10 +229,10 @@
this.topng.Checked = true;
this.topng.Location = new System.Drawing.Point(50, 7);
this.topng.Name = "topng";
this.topng.Size = new System.Drawing.Size(44, 17);
this.topng.Size = new System.Drawing.Size(48, 17);
this.topng.TabIndex = 3;
this.topng.TabStop = true;
this.topng.Text = "Png";
this.topng.Text = "PNG";
this.topng.UseVisualStyleBackColor = true;
//
// tobmp
@@ -215,9 +240,9 @@
this.tobmp.AutoSize = true;
this.tobmp.Location = new System.Drawing.Point(3, 7);
this.tobmp.Name = "tobmp";
this.tobmp.Size = new System.Drawing.Size(46, 17);
this.tobmp.Size = new System.Drawing.Size(48, 17);
this.tobmp.TabIndex = 2;
this.tobmp.Text = "Bmp";
this.tobmp.Text = "BMP";
this.tobmp.UseVisualStyleBackColor = true;
//
// converttexture
@@ -235,7 +260,6 @@
// 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);
@@ -252,26 +276,13 @@
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.Location = new System.Drawing.Point(258, 13);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(224, 362);
this.groupBox2.Size = new System.Drawing.Size(206, 327);
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;
@@ -304,7 +315,7 @@
0,
0,
131072});
this.scaleFactor.Location = new System.Drawing.Point(83, 243);
this.scaleFactor.Location = new System.Drawing.Point(83, 219);
this.scaleFactor.Name = "scaleFactor";
this.scaleFactor.Size = new System.Drawing.Size(60, 20);
this.scaleFactor.TabIndex = 20;
@@ -318,7 +329,7 @@
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(6, 245);
this.label5.Location = new System.Drawing.Point(6, 221);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(64, 13);
this.label5.TabIndex = 19;
@@ -331,7 +342,7 @@
this.fbxFormat.Items.AddRange(new object[] {
"Binary",
"Ascii"});
this.fbxFormat.Location = new System.Drawing.Point(77, 275);
this.fbxFormat.Location = new System.Drawing.Point(77, 252);
this.fbxFormat.Name = "fbxFormat";
this.fbxFormat.Size = new System.Drawing.Size(61, 21);
this.fbxFormat.TabIndex = 18;
@@ -339,7 +350,7 @@
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(6, 280);
this.label4.Location = new System.Drawing.Point(6, 256);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(59, 13);
this.label4.TabIndex = 17;
@@ -356,7 +367,7 @@
"7.3",
"7.4",
"7.5"});
this.fbxVersion.Location = new System.Drawing.Point(77, 308);
this.fbxVersion.Location = new System.Drawing.Point(77, 284);
this.fbxVersion.Name = "fbxVersion";
this.fbxVersion.Size = new System.Drawing.Size(47, 21);
this.fbxVersion.TabIndex = 16;
@@ -364,7 +375,7 @@
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(6, 311);
this.label3.Location = new System.Drawing.Point(6, 287);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(62, 13);
this.label3.TabIndex = 15;
@@ -372,7 +383,7 @@
//
// boneSize
//
this.boneSize.Location = new System.Drawing.Point(65, 213);
this.boneSize.Location = new System.Drawing.Point(65, 190);
this.boneSize.Name = "boneSize";
this.boneSize.Size = new System.Drawing.Size(46, 20);
this.boneSize.TabIndex = 11;
@@ -385,7 +396,7 @@
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(6, 216);
this.label2.Location = new System.Drawing.Point(6, 192);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(52, 13);
this.label2.TabIndex = 10;
@@ -470,16 +481,16 @@
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.ClientSize = new System.Drawing.Size(477, 380);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.Cancel);
this.Controls.Add(this.OKbutton);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
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;
@@ -529,7 +540,7 @@
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 pathIDAsImageName;
private System.Windows.Forms.CheckBox pathIDAsDumpName;
}
}

View File

@@ -1,5 +1,4 @@
using AssetStudio;
using System;
using System;
using System.Windows.Forms;
namespace AssetStudioGUI
@@ -13,7 +12,7 @@ namespace AssetStudioGUI
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();
var str = Properties.Settings.Default.convertType;
foreach (Control c in panel1.Controls)
{
if (c.Text == str)
@@ -30,12 +29,12 @@ namespace AssetStudioGUI
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;
pathIDAsImageName.Checked = Properties.Settings.Default.pathIDAsImageName;
pathIDAsDumpName.Checked = Properties.Settings.Default.pathIDAsDumpName;
}
private void OKbutton_Click(object sender, EventArgs e)
@@ -48,7 +47,7 @@ namespace AssetStudioGUI
{
if (((RadioButton)c).Checked)
{
Properties.Settings.Default.convertType = (ImageFormat)Enum.Parse(typeof(ImageFormat), c.Text);
Properties.Settings.Default.convertType = c.Text;
break;
}
}
@@ -60,11 +59,12 @@ namespace AssetStudioGUI
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.pathIDAsImageName = pathIDAsImageName.Checked;
Properties.Settings.Default.pathIDAsDumpName = pathIDAsDumpName.Checked;
Properties.Settings.Default.Save();
DialogResult = DialogResult.OK;
Close();
@@ -75,6 +75,5 @@ namespace AssetStudioGUI
DialogResult = DialogResult.Cancel;
Close();
}
}
}

View File

@@ -117,10 +117,4 @@
<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>
<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>

View File

@@ -1,36 +1,67 @@
using AssetStudio;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using AssetStudio;
using TGASharpLib;
namespace AssetStudioGUI
{
internal static class Exporter
{
public static bool ExportTexture2D(AssetItem item, string exportPath)
public static bool ExportTexture2D(AssetItem item, string exportPathName)
{
string exportFullName;
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))
var bitmap = m_Texture2D.ConvertToBitmap(true);
if (bitmap == null)
return false;
var stream = m_Texture2D.ConvertToStream(type, true);
if (stream == null)
return false;
using (stream)
ImageFormat format = null;
var ext = Properties.Settings.Default.convertType;
bool tga = false;
switch (ext)
{
File.WriteAllBytes(exportFullPath, stream.ToArray());
return true;
case "BMP":
format = ImageFormat.Bmp;
break;
case "PNG":
format = ImageFormat.Png;
break;
case "JPEG":
format = ImageFormat.Jpeg;
break;
case "TGA":
tga = true;
break;
}
if (Properties.Settings.Default.pathIDAsImageName)
exportFullName = exportPathName + item.m_PathID.ToString() + "." + ext.ToLower();
else
exportFullName = exportPathName + item.Text + "." + ext.ToLower();
if (ExportFileExists(exportFullName))
return false;
if (tga)
{
var file = new TGA(bitmap);
file.Save(exportFullName);
}
else
bitmap.Save(exportFullName, format);
bitmap.Dispose();
return true;
}
else
{
if (!TryExportFile(exportPath, item, ".tex", out var exportFullPath))
if (Properties.Settings.Default.pathIDAsImageName)
exportFullName = exportPathName + item.m_PathID.ToString() + ".tex";
else
exportFullName = exportPathName + item.Text + ".tex";
if (ExportFileExists(exportFullName))
return false;
File.WriteAllBytes(exportFullPath, m_Texture2D.image_data.GetData());
File.WriteAllBytes(exportFullName, m_Texture2D.image_data.GetData());
return true;
}
}
@@ -44,29 +75,44 @@ namespace AssetStudioGUI
var converter = new AudioClipConverter(m_AudioClip);
if (Properties.Settings.Default.convertAudio && converter.IsSupport)
{
if (!TryExportFile(exportPath, item, ".wav", out var exportFullPath))
var exportFullName = exportPath + item.Text + ".wav";
if (ExportFileExists(exportFullName))
return false;
var buffer = converter.ConvertToWav();
if (buffer == null)
return false;
File.WriteAllBytes(exportFullPath, buffer);
File.WriteAllBytes(exportFullName, buffer);
}
else
{
if (!TryExportFile(exportPath, item, converter.GetExtensionName(), out var exportFullPath))
var exportFullName = exportPath + item.Text + converter.GetExtensionName();
if (ExportFileExists(exportFullName))
return false;
File.WriteAllBytes(exportFullPath, m_AudioData);
File.WriteAllBytes(exportFullName, m_AudioData);
}
return true;
}
public static bool ExportShader(AssetItem item, string exportPath)
{
if (!TryExportFile(exportPath, item, ".shader", out var exportFullPath))
var exportFullName = exportPath + item.Text + ".shader";
if (ExportFileExists(exportFullName))
return false;
var m_Shader = (Shader)item.Asset;
var str = m_Shader.Convert();
File.WriteAllText(exportFullPath, str);
if (m_Shader.compressedBlob != null) //5.5 and up
{
var strs = ShaderConverter.ConvertMultiple(m_Shader);
for (int i = 0; i < strs.Length; i++)
{
var platformName = ShaderConverter.GetPlatformString(m_Shader.platforms[i]);
File.WriteAllText($"{exportPath}{item.Text}_{platformName}.shader", strs[i]);
}
}
else
{
var str = ShaderConverter.Convert(m_Shader);
File.WriteAllText(exportFullName, str);
}
return true;
}
@@ -81,25 +127,21 @@ namespace AssetStudioGUI
extension = Path.GetExtension(item.Container);
}
}
if (!TryExportFile(exportPath, item, extension, out var exportFullPath))
var exportFullName = exportPath + item.Text + extension;
if (ExportFileExists(exportFullName))
return false;
File.WriteAllBytes(exportFullPath, m_TextAsset.m_Script);
File.WriteAllBytes(exportFullName, m_TextAsset.m_Script);
return true;
}
public static bool ExportMonoBehaviour(AssetItem item, string exportPath)
{
if (!TryExportFile(exportPath, item, ".json", out var exportFullPath))
var exportFullName = exportPath + item.Text + ".txt";
if (ExportFileExists(exportFullName))
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);
var str = m_MonoBehaviour.Dump() ?? Studio.GetScriptString(item.Asset.reader);
File.WriteAllText(exportFullName, str);
return true;
}
@@ -113,9 +155,10 @@ namespace AssetStudioGUI
{
extension = ".otf";
}
if (!TryExportFile(exportPath, item, extension, out var exportFullPath))
var exportFullName = exportPath + item.Text + extension;
if (ExportFileExists(exportFullName))
return false;
File.WriteAllBytes(exportFullPath, m_Font.m_FontData);
File.WriteAllBytes(exportFullName, m_Font.m_FontData);
return true;
}
return false;
@@ -126,7 +169,8 @@ namespace AssetStudioGUI
var m_Mesh = (Mesh)item.Asset;
if (m_Mesh.m_VertexCount <= 0)
return false;
if (!TryExportFile(exportPath, item, ".obj", out var exportFullPath))
var exportFullName = exportPath + item.Text + ".obj";
if (ExportFileExists(exportFullName))
return false;
var sb = new StringBuilder();
sb.AppendLine("g " + m_Mesh.m_Name);
@@ -198,18 +242,20 @@ namespace AssetStudioGUI
#endregion
sb.Replace("NaN", "0");
File.WriteAllText(exportFullPath, sb.ToString());
File.WriteAllText(exportFullName, 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)
var m_VideoData = m_VideoClip.m_VideoData.GetData();
if (m_VideoData != null && m_VideoData.Length != 0)
{
if (!TryExportFile(exportPath, item, Path.GetExtension(m_VideoClip.m_OriginalPath), out var exportFullPath))
var exportFullName = exportPath + item.Text + Path.GetExtension(m_VideoClip.m_OriginalPath);
if (ExportFileExists(exportFullName))
return false;
m_VideoClip.m_VideoData.WriteData(exportFullPath);
File.WriteAllBytes(exportFullName, m_VideoData);
return true;
}
return false;
@@ -218,85 +264,95 @@ namespace AssetStudioGUI
public static bool ExportMovieTexture(AssetItem item, string exportPath)
{
var m_MovieTexture = (MovieTexture)item.Asset;
if (!TryExportFile(exportPath, item, ".ogv", out var exportFullPath))
var exportFullName = exportPath + item.Text + ".ogv";
if (ExportFileExists(exportFullName))
return false;
File.WriteAllBytes(exportFullPath, m_MovieTexture.m_MovieData);
File.WriteAllBytes(exportFullName, m_MovieTexture.m_MovieData);
return true;
}
public static bool ExportSprite(AssetItem item, string exportPath)
{
ImageFormat format = null;
string exportFullName;
var type = Properties.Settings.Default.convertType;
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
return false;
var stream = ((Sprite)item.Asset).GetImage(type);
if (stream != null)
bool tga = false;
switch (type)
{
using (stream)
case "BMP":
format = ImageFormat.Bmp;
break;
case "PNG":
format = ImageFormat.Png;
break;
case "JPEG":
format = ImageFormat.Jpeg;
break;
case "TGA":
tga = true;
break;
}
if (Properties.Settings.Default.pathIDAsImageName)
exportFullName = exportPath + item.m_PathID.ToString() + "." + type.ToLower();
else
exportFullName = exportPath + item.Text + "." + type.ToLower();
if (ExportFileExists(exportFullName))
return false;
var bitmap = ((Sprite)item.Asset).GetImage();
if (bitmap != null)
{
if (tga)
{
File.WriteAllBytes(exportFullPath, stream.ToArray());
return true;
var file = new TGA(bitmap);
file.Save(exportFullName);
}
else
bitmap.Save(exportFullName, format);
bitmap.Dispose();
return true;
}
return false;
}
public static bool ExportRawFile(AssetItem item, string exportPath)
{
if (!TryExportFile(exportPath, item, ".dat", out var exportFullPath))
var exportFullName = exportPath + item.Text + ".dat";
if (ExportFileExists(exportFullName))
return false;
File.WriteAllBytes(exportFullPath, item.Asset.GetRawData());
File.WriteAllBytes(exportFullName, item.Asset.GetRawData());
return true;
}
private static bool TryExportFile(string dir, AssetItem item, string extension, out string fullPath)
private static bool ExportFileExists(string filename)
{
var fileName = FixFileName(item.Text);
fullPath = Path.Combine(dir, fileName + extension);
if (!File.Exists(fullPath))
if (File.Exists(filename))
{
Directory.CreateDirectory(dir);
return true;
}
fullPath = Path.Combine(dir, fileName + item.UniqueID + extension);
if (!File.Exists(fullPath))
{
Directory.CreateDirectory(dir);
return true;
}
Directory.CreateDirectory(Path.GetDirectoryName(filename));
return false;
}
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, animationList.Select(x => (AnimationClip)x.Asset).ToArray())
: new ModelConverter(m_Animator, Properties.Settings.Default.convertType);
ExportFbx(convert, exportFullPath);
var convert = animationList != null ? new ModelConverter(m_Animator, animationList.Select(x => (AnimationClip)x.Asset).ToArray()) : new ModelConverter(m_Animator);
exportPath = $"{exportPath}{item.Text}\\{item.Text}.fbx";
ExportFbx(convert, exportPath);
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, animationList.Select(x => (AnimationClip)x.Asset).ToArray())
: new ModelConverter(gameObject, Properties.Settings.Default.convertType);
exportPath = exportPath + FixFileName(gameObject.m_Name) + ".fbx";
var convert = animationList != null ? new ModelConverter(gameObject, animationList.Select(x => (AnimationClip)x.Asset).ToArray()) : new ModelConverter(gameObject);
exportPath = exportPath + Studio.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, animationList.Select(x => (AnimationClip)x.Asset).ToArray())
: new ModelConverter(rootName, gameObject, Properties.Settings.Default.convertType);
var convert = animationList != null ? new ModelConverter(rootName, gameObject, animationList.Select(x => (AnimationClip)x.Asset).ToArray()) : new ModelConverter(rootName, gameObject);
ExportFbx(convert, exportPath);
}
@@ -310,27 +366,30 @@ namespace AssetStudioGUI
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);
exportAllNodes, exportSkins, exportAnimations, exportBlendShape, castToBone, boneSize, scaleFactor, fbxVersion, fbxFormat == 1);
}
public static bool ExportDumpFile(AssetItem item, string exportPath)
{
if (!TryExportFile(exportPath, item, ".txt", out var exportFullPath))
string exportFullName;
if (Properties.Settings.Default.pathIDAsDumpName)
{
exportFullName = exportPath + item.m_PathID.ToString() + ".txt";
}
else
{
exportFullName = exportPath + item.Text + ".txt";
}
if (ExportFileExists(exportFullName))
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);
File.WriteAllText(exportFullName, str);
return true;
}
return false;
@@ -368,11 +427,5 @@ namespace AssetStudioGUI
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, '_'));
}
}
}

View File

@@ -1,12 +1,13 @@
using AssetStudio;
using System;
using System.Windows.Forms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AssetStudio;
namespace AssetStudioGUI
{
class GUILogger : ILogger
{
public bool ShowErrorMessage = false;
private Action<string> action;
public GUILogger(Action<string> action)
@@ -16,19 +17,7 @@ namespace AssetStudioGUI
public void Log(LoggerEvent loggerEvent, string message)
{
switch (loggerEvent)
{
case LoggerEvent.Error:
if (ShowErrorMessage)
{
MessageBox.Show(message);
}
break;
default:
action(message);
break;
}
action(message);
}
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,25 @@
<configuration>
<dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
<dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
<dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
<dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
<dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
<dllmap os="linux" dll="libX11" target="libX11.so.6"/>
<dllmap os="linux" dll="libXi" target="libXi.so.6"/>
<dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/>
<dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv1_CM.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
<dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/>
<!-- XQuartz compatibility (X11 on Mac) -->
<dllmap os="osx" dll="libGL.so.1" target="/usr/X11/lib/libGL.dylib"/>
<dllmap os="osx" dll="libX11" target="/usr/X11/lib/libX11.dylib"/>
<dllmap os="osx" dll="libXcursor.so.1" target="/usr/X11/lib/libXcursor.dylib"/>
<dllmap os="osx" dll="libXi" target="/usr/X11/lib/libXi.dylib"/>
<dllmap os="osx" dll="libXinerama" target="/usr/X11/lib/libXinerama.dylib"/>
<dllmap os="osx" dll="libXrandr.so.2" target="/usr/X11/lib/libXrandr.dylib"/>
</configuration>

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@@ -9,14 +9,11 @@ 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());

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("AssetStudioGUI Mod by VaDiM")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssetStudioGUI")]
[assembly: AssemblyCopyright("Copyright © Perfare 2018-2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("52b196fb-4c8a-499b-b877-1a0eb4f33ec0")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.14.38.5")]
[assembly: AssemblyFileVersion("0.14.38.5")]

Some files were not shown because too many files have changed in this diff Show More