Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d07fc6d6f5 | ||
|
|
ee2976aaf1 | ||
|
|
f144037bc0 | ||
|
|
0e097bda04 | ||
|
|
9686eee3b7 | ||
|
|
b6318e6d9b | ||
|
|
e0d90d1b1e | ||
|
|
dd727758a8 | ||
|
|
d44ed315e3 | ||
|
|
e30b9e9e89 | ||
|
|
9632e88115 | ||
|
|
bb19dd5019 | ||
|
|
b6c6ceba1c | ||
|
|
7c0a6375b1 | ||
|
|
5c489c5f83 | ||
|
|
e90af43459 | ||
|
|
381a7d89ae | ||
|
|
572e3bf0d6 | ||
|
|
3d7d51b54f | ||
|
|
abbd27fde7 |
@@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows;net8.0;net8.0-windows</TargetFrameworks>
|
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows;net8.0;net8.0-windows</TargetFrameworks>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<Version>0.18.0.0</Version>
|
<Version>1.2.0</Version>
|
||||||
<Copyright>Copyright © Perfare 2020-2022; Copyright © hozuki 2020</Copyright>
|
<Copyright>Copyright © Perfare 2020-2022; Copyright © hozuki 2020</Copyright>
|
||||||
<DebugType>embedded</DebugType>
|
<DebugType>embedded</DebugType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -22,26 +22,26 @@ namespace SevenZip
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private uint _value = 0xFFFFFFFF;
|
uint _value = 0xFFFFFFFF;
|
||||||
|
|
||||||
public void Init() { _value = 0xFFFFFFFF; }
|
public void Init() { _value = 0xFFFFFFFF; }
|
||||||
|
|
||||||
public void UpdateByte(byte b)
|
public void UpdateByte(byte b)
|
||||||
{
|
{
|
||||||
_value = Table[(byte)_value ^ b] ^ (_value >> 8);
|
_value = Table[(((byte)(_value)) ^ b)] ^ (_value >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(byte[] data, uint offset, uint size)
|
public void Update(byte[] data, uint offset, uint size)
|
||||||
{
|
{
|
||||||
for (uint i = 0; i < size; i++)
|
for (uint i = 0; i < size; i++)
|
||||||
_value = Table[(byte)_value ^ data[offset + i]] ^ (_value >> 8);
|
_value = Table[(((byte)(_value)) ^ data[offset + i])] ^ (_value >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint GetDigest() { return _value ^ 0xFFFFFFFF; }
|
public uint GetDigest() { return _value ^ 0xFFFFFFFF; }
|
||||||
|
|
||||||
public static uint CalculateDigest(byte[] data, uint offset, uint size)
|
static uint CalculateDigest(byte[] data, uint offset, uint size)
|
||||||
{
|
{
|
||||||
var crc = new CRC();
|
CRC crc = new CRC();
|
||||||
// crc.Init();
|
// crc.Init();
|
||||||
crc.Update(data, offset, size);
|
crc.Update(data, offset, size);
|
||||||
return crc.GetDigest();
|
return crc.GetDigest();
|
||||||
@@ -49,7 +49,7 @@ namespace SevenZip
|
|||||||
|
|
||||||
static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size)
|
static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size)
|
||||||
{
|
{
|
||||||
return CalculateDigest(data, offset, size) == digest;
|
return (CalculateDigest(data, offset, size) == digest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,25 +2,18 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows;net8.0;net8.0-windows</TargetFrameworks>
|
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows;net8.0;net8.0-windows</TargetFrameworks>
|
||||||
<Version>0.18.0.0</Version>
|
<Version>1.2.0</Version>
|
||||||
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2023-2024</Copyright>
|
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2025</Copyright>
|
||||||
<DebugType>embedded</DebugType>
|
<DebugType>embedded</DebugType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' != 'net472' ">
|
<ItemGroup>
|
||||||
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.8" />
|
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.8" />
|
||||||
<PackageReference Include="ZstdSharp.Port" Version="0.7.6" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
|
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
|
||||||
<PackageReference Include="System.Memory" Version="4.5.5" />
|
<PackageReference Include="System.Memory" Version="4.5.5" />
|
||||||
<PackageReference Include="System.IO.Compression" Version="4.0.0" />
|
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
|
||||||
<PackageReference Include="K4os.Compression.LZ4" Version="1.1.11" />
|
|
||||||
<PackageReference Include="ZstdSharp.Port" Version="0.6.5" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
@@ -11,48 +10,18 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public class AssetsManager
|
public class AssetsManager
|
||||||
{
|
{
|
||||||
public bool ZstdEnabled = true;
|
public string SpecifyUnityVersion;
|
||||||
public bool LoadingViaTypeTreeEnabled = true;
|
|
||||||
public List<SerializedFile> assetsFileList = new List<SerializedFile>();
|
public List<SerializedFile> assetsFileList = new List<SerializedFile>();
|
||||||
|
private HashSet<ClassIDType> filteredAssetTypesList = new HashSet<ClassIDType>();
|
||||||
|
|
||||||
internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
||||||
internal ConcurrentDictionary<string, BinaryReader> resourceFileReaders = new ConcurrentDictionary<string, BinaryReader>(StringComparer.OrdinalIgnoreCase);
|
internal Dictionary<string, BinaryReader> resourceFileReaders = new Dictionary<string, BinaryReader>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
private UnityVersion specifiedUnityVersion;
|
|
||||||
private List<string> importFiles = new List<string>();
|
private List<string> importFiles = new List<string>();
|
||||||
private HashSet<ClassIDType> filteredAssetTypesList = new HashSet<ClassIDType>();
|
|
||||||
private HashSet<string> importFilesHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
private HashSet<string> importFilesHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
private HashSet<string> noexistFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
private HashSet<string> noexistFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
private HashSet<string> assetsFileListHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
private HashSet<string> assetsFileListHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
public UnityVersion SpecifyUnityVersion
|
|
||||||
{
|
|
||||||
get => specifiedUnityVersion;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (specifiedUnityVersion == value)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (value == null)
|
|
||||||
{
|
|
||||||
specifiedUnityVersion = null;
|
|
||||||
Logger.Info("Specified Unity version: None");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(value.BuildType))
|
|
||||||
{
|
|
||||||
throw new NotSupportedException("Specified Unity version is not in a correct format.\n" +
|
|
||||||
"Specify full Unity version, including letters at the end.\n" +
|
|
||||||
"Example: 2017.4.39f1");
|
|
||||||
}
|
|
||||||
|
|
||||||
specifiedUnityVersion = value;
|
|
||||||
Logger.Info($"Specified Unity version: {specifiedUnityVersion}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAssetFilter(params ClassIDType[] classIDTypes)
|
public void SetAssetFilter(params ClassIDType[] classIDTypes)
|
||||||
{
|
{
|
||||||
if (filteredAssetTypesList.Count == 0)
|
if (filteredAssetTypesList.Count == 0)
|
||||||
@@ -61,8 +30,6 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
ClassIDType.AssetBundle,
|
ClassIDType.AssetBundle,
|
||||||
ClassIDType.ResourceManager,
|
ClassIDType.ResourceManager,
|
||||||
ClassIDType.GameObject,
|
|
||||||
ClassIDType.Transform,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,10 +37,15 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
filteredAssetTypesList.Add(ClassIDType.MonoScript);
|
filteredAssetTypesList.Add(ClassIDType.MonoScript);
|
||||||
}
|
}
|
||||||
if (classIDTypes.Contains(ClassIDType.Sprite))
|
if (classIDTypes.Contains(ClassIDType.Sprite) || classIDTypes.Contains(ClassIDType.AkPortraitSprite))
|
||||||
{
|
{
|
||||||
filteredAssetTypesList.Add(ClassIDType.Texture2D);
|
filteredAssetTypesList.UnionWith(new HashSet<ClassIDType>
|
||||||
filteredAssetTypesList.Add(ClassIDType.SpriteAtlas);
|
{
|
||||||
|
ClassIDType.Texture2D,
|
||||||
|
ClassIDType.SpriteAtlas,
|
||||||
|
ClassIDType.MonoBehaviour,
|
||||||
|
ClassIDType.MonoScript
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
filteredAssetTypesList.UnionWith(classIDTypes);
|
filteredAssetTypesList.UnionWith(classIDTypes);
|
||||||
@@ -86,21 +58,21 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public void LoadFilesAndFolders(params string[] path)
|
public void LoadFilesAndFolders(params string[] path)
|
||||||
{
|
{
|
||||||
var pathList = new List<string>();
|
List<string> pathList = new List<string>();
|
||||||
pathList.AddRange(path);
|
pathList.AddRange(path);
|
||||||
LoadFilesAndFolders(out _, pathList);
|
LoadFilesAndFolders(out _, pathList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadFilesAndFolders(out string parentPath, params string[] path)
|
public void LoadFilesAndFolders(out string parentPath, params string[] path)
|
||||||
{
|
{
|
||||||
var pathList = new List<string>();
|
List<string> pathList = new List<string>();
|
||||||
pathList.AddRange(path);
|
pathList.AddRange(path);
|
||||||
LoadFilesAndFolders(out parentPath, pathList);
|
LoadFilesAndFolders(out parentPath, pathList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadFilesAndFolders(out string parentPath, List<string> pathList)
|
public void LoadFilesAndFolders(out string parentPath, List<string> pathList)
|
||||||
{
|
{
|
||||||
var fileList = new List<string>();
|
List<string> fileList = new List<string>();
|
||||||
bool filesInPath = false;
|
bool filesInPath = false;
|
||||||
parentPath = "";
|
parentPath = "";
|
||||||
foreach (var path in pathList)
|
foreach (var path in pathList)
|
||||||
@@ -146,14 +118,8 @@ namespace AssetStudio
|
|||||||
//use a for loop because list size can change
|
//use a for loop because list size can change
|
||||||
for (var i = 0; i < importFiles.Count; i++)
|
for (var i = 0; i < importFiles.Count; i++)
|
||||||
{
|
{
|
||||||
if (LoadFile(importFiles[i]))
|
LoadFile(importFiles[i]);
|
||||||
{
|
Progress.Report(i + 1, importFiles.Count);
|
||||||
Progress.Report(i + 1, importFiles.Count);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
importFiles.Clear();
|
importFiles.Clear();
|
||||||
@@ -165,20 +131,22 @@ namespace AssetStudio
|
|||||||
ProcessAssets();
|
ProcessAssets();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool LoadFile(string fullName)
|
private void LoadFile(string fullName)
|
||||||
{
|
{
|
||||||
var reader = new FileReader(fullName);
|
var reader = new FileReader(fullName);
|
||||||
return LoadFile(reader);
|
LoadFile(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool LoadFile(FileReader reader)
|
private void LoadFile(FileReader reader)
|
||||||
{
|
{
|
||||||
switch (reader?.FileType)
|
switch (reader?.FileType)
|
||||||
{
|
{
|
||||||
case FileType.AssetsFile:
|
case FileType.AssetsFile:
|
||||||
return LoadAssetsFile(reader);
|
LoadAssetsFile(reader);
|
||||||
|
break;
|
||||||
case FileType.BundleFile:
|
case FileType.BundleFile:
|
||||||
return LoadBundleFile(reader);
|
LoadBundleFile(reader);
|
||||||
|
break;
|
||||||
case FileType.WebFile:
|
case FileType.WebFile:
|
||||||
LoadWebFile(reader);
|
LoadWebFile(reader);
|
||||||
break;
|
break;
|
||||||
@@ -192,10 +160,9 @@ namespace AssetStudio
|
|||||||
LoadZipFile(reader);
|
LoadZipFile(reader);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool LoadAssetsFile(FileReader reader)
|
private void LoadAssetsFile(FileReader reader)
|
||||||
{
|
{
|
||||||
if (!assetsFileListHash.Contains(reader.FileName))
|
if (!assetsFileListHash.Contains(reader.FileName))
|
||||||
{
|
{
|
||||||
@@ -203,7 +170,6 @@ namespace AssetStudio
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var assetsFile = new SerializedFile(reader, this);
|
var assetsFile = new SerializedFile(reader, this);
|
||||||
var dirName = Path.GetDirectoryName(reader.FullPath);
|
|
||||||
CheckStrippedVersion(assetsFile);
|
CheckStrippedVersion(assetsFile);
|
||||||
assetsFileList.Add(assetsFile);
|
assetsFileList.Add(assetsFile);
|
||||||
assetsFileListHash.Add(assetsFile.fileName);
|
assetsFileListHash.Add(assetsFile.fileName);
|
||||||
@@ -214,12 +180,12 @@ namespace AssetStudio
|
|||||||
|
|
||||||
if (!importFilesHash.Contains(sharedFileName))
|
if (!importFilesHash.Contains(sharedFileName))
|
||||||
{
|
{
|
||||||
var sharedFilePath = Path.Combine(dirName, sharedFileName);
|
var sharedFilePath = Path.Combine(Path.GetDirectoryName(reader.FullPath), sharedFileName);
|
||||||
if (!noexistFiles.Contains(sharedFilePath))
|
if (!noexistFiles.Contains(sharedFilePath))
|
||||||
{
|
{
|
||||||
if (!File.Exists(sharedFilePath))
|
if (!File.Exists(sharedFilePath))
|
||||||
{
|
{
|
||||||
var findFiles = Directory.GetFiles(dirName, sharedFileName, SearchOption.AllDirectories);
|
var findFiles = Directory.GetFiles(Path.GetDirectoryName(reader.FullPath), sharedFileName, SearchOption.AllDirectories);
|
||||||
if (findFiles.Length > 0)
|
if (findFiles.Length > 0)
|
||||||
{
|
{
|
||||||
sharedFilePath = findFiles[0];
|
sharedFilePath = findFiles[0];
|
||||||
@@ -242,11 +208,10 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
Logger.Error(e.Message);
|
Logger.Error(e.Message);
|
||||||
reader.Dispose();
|
reader.Dispose();
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.Warning($"Failed to read assets file {reader.FullPath}\r\n{e}");
|
Logger.Warning($"Error while reading assets file {reader.FullPath}\r\n{e}");
|
||||||
reader.Dispose();
|
reader.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -255,10 +220,9 @@ namespace AssetStudio
|
|||||||
Logger.Info($"Skipping {reader.FullPath}");
|
Logger.Info($"Skipping {reader.FullPath}");
|
||||||
reader.Dispose();
|
reader.Dispose();
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool LoadAssetsFromMemory(FileReader reader, string originalPath, UnityVersion assetBundleUnityVer = null)
|
private void LoadAssetsFromMemory(FileReader reader, string originalPath, string unityVersion = null)
|
||||||
{
|
{
|
||||||
if (!assetsFileListHash.Contains(reader.FileName))
|
if (!assetsFileListHash.Contains(reader.FileName))
|
||||||
{
|
{
|
||||||
@@ -266,59 +230,52 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
var assetsFile = new SerializedFile(reader, this);
|
var assetsFile = new SerializedFile(reader, this);
|
||||||
assetsFile.originalPath = originalPath;
|
assetsFile.originalPath = originalPath;
|
||||||
if (assetBundleUnityVer != null && assetsFile.header.m_Version < SerializedFileFormatVersion.Unknown_7)
|
if (!string.IsNullOrEmpty(unityVersion) && assetsFile.header.m_Version < SerializedFileFormatVersion.Unknown_7)
|
||||||
{
|
{
|
||||||
assetsFile.SetVersion(assetBundleUnityVer);
|
assetsFile.SetVersion(unityVersion);
|
||||||
}
|
}
|
||||||
CheckStrippedVersion(assetsFile, assetBundleUnityVer);
|
CheckStrippedVersion(assetsFile);
|
||||||
assetsFileList.Add(assetsFile);
|
assetsFileList.Add(assetsFile);
|
||||||
assetsFileListHash.Add(assetsFile.fileName);
|
assetsFileListHash.Add(assetsFile.fileName);
|
||||||
}
|
}
|
||||||
catch (NotSupportedException e)
|
catch (NotSupportedException e)
|
||||||
{
|
{
|
||||||
Logger.Error(e.Message);
|
Logger.Error(e.Message);
|
||||||
resourceFileReaders.TryAdd(reader.FileName, reader);
|
resourceFileReaders.Add(reader.FileName, reader);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.Warning($"Failed to read assets file {reader.FullPath} from {Path.GetFileName(originalPath)}\r\n{e}");
|
Logger.Warning($"Error while reading assets file {reader.FullPath} from {Path.GetFileName(originalPath)}\r\n{e}");
|
||||||
resourceFileReaders.TryAdd(reader.FileName, reader);
|
resourceFileReaders.Add(reader.FileName, reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
Logger.Info($"Skipping {originalPath} ({reader.FileName})");
|
Logger.Info($"Skipping {originalPath} ({reader.FileName})");
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool LoadBundleFile(FileReader reader, string originalPath = null)
|
private void LoadBundleFile(FileReader reader, string originalPath = null)
|
||||||
{
|
{
|
||||||
Logger.Info("Loading " + reader.FullPath);
|
Logger.Info("Loading " + reader.FullPath);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var bundleFile = new BundleFile(reader, ZstdEnabled, specifiedUnityVersion);
|
var bundleFile = new BundleFile(reader, SpecifyUnityVersion);
|
||||||
foreach (var file in bundleFile.fileList)
|
foreach (var file in bundleFile.fileList)
|
||||||
{
|
{
|
||||||
var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), file.fileName);
|
var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), file.fileName);
|
||||||
var subReader = new FileReader(dummyPath, file.stream);
|
var subReader = new FileReader(dummyPath, file.stream);
|
||||||
if (subReader.FileType == FileType.AssetsFile)
|
if (subReader.FileType == FileType.AssetsFile)
|
||||||
{
|
{
|
||||||
if (!LoadAssetsFromMemory(subReader, originalPath ?? reader.FullPath, bundleFile.m_Header.unityRevision))
|
LoadAssetsFromMemory(subReader, originalPath ?? reader.FullPath, bundleFile.m_Header.unityRevision);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
else
|
else if (!resourceFileReaders.ContainsKey(file.fileName))
|
||||||
{
|
{
|
||||||
resourceFileReaders.TryAdd(file.fileName, subReader);
|
resourceFileReaders.Add(file.fileName, subReader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
catch (NotSupportedException e)
|
catch (NotSupportedException e)
|
||||||
{
|
{
|
||||||
Logger.Error(e.Message);
|
Logger.Error(e.Message);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -328,7 +285,6 @@ namespace AssetStudio
|
|||||||
str += $" from {Path.GetFileName(originalPath)}";
|
str += $" from {Path.GetFileName(originalPath)}";
|
||||||
}
|
}
|
||||||
Logger.Warning($"{str}\r\n{e}");
|
Logger.Warning($"{str}\r\n{e}");
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -453,7 +409,10 @@ namespace AssetStudio
|
|||||||
if (entryReader.FileType == FileType.ResourceFile)
|
if (entryReader.FileType == FileType.ResourceFile)
|
||||||
{
|
{
|
||||||
entryReader.Position = 0;
|
entryReader.Position = 0;
|
||||||
resourceFileReaders.TryAdd(entry.Name, entryReader);
|
if (!resourceFileReaders.ContainsKey(entry.Name))
|
||||||
|
{
|
||||||
|
resourceFileReaders.Add(entry.Name, entryReader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Progress.Report(++k, progressCount);
|
Progress.Report(++k, progressCount);
|
||||||
}
|
}
|
||||||
@@ -474,16 +433,13 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CheckStrippedVersion(SerializedFile assetsFile, UnityVersion bundleUnityVer = null)
|
public void CheckStrippedVersion(SerializedFile assetsFile)
|
||||||
{
|
{
|
||||||
if (assetsFile.version.IsStripped && specifiedUnityVersion == null)
|
if (assetsFile.IsVersionStripped && string.IsNullOrEmpty(SpecifyUnityVersion))
|
||||||
{
|
{
|
||||||
var msg = "The asset's Unity version has been stripped, please set the version in the options.";
|
throw new NotSupportedException("The Unity version has been stripped, please set the version in the options");
|
||||||
if (bundleUnityVer != null && !bundleUnityVer.IsStripped)
|
|
||||||
msg += $"\n\nAssumed Unity version based on asset bundle: {bundleUnityVer}";
|
|
||||||
throw new NotSupportedException(msg);
|
|
||||||
}
|
}
|
||||||
if (specifiedUnityVersion != null)
|
if (!string.IsNullOrEmpty(SpecifyUnityVersion))
|
||||||
{
|
{
|
||||||
assetsFile.SetVersion(SpecifyUnityVersion);
|
assetsFile.SetVersion(SpecifyUnityVersion);
|
||||||
}
|
}
|
||||||
@@ -532,9 +488,7 @@ namespace AssetStudio
|
|||||||
obj = new Animation(objectReader);
|
obj = new Animation(objectReader);
|
||||||
break;
|
break;
|
||||||
case ClassIDType.AnimationClip:
|
case ClassIDType.AnimationClip:
|
||||||
obj = objectReader.serializedType?.m_Type != null && LoadingViaTypeTreeEnabled
|
obj = new AnimationClip(objectReader);
|
||||||
? new AnimationClip(objectReader, TypeTreeHelper.ReadType(objectReader.serializedType.m_Type, objectReader))
|
|
||||||
: new AnimationClip(objectReader);
|
|
||||||
break;
|
break;
|
||||||
case ClassIDType.Animator:
|
case ClassIDType.Animator:
|
||||||
obj = new Animator(objectReader);
|
obj = new Animator(objectReader);
|
||||||
@@ -591,7 +545,7 @@ namespace AssetStudio
|
|||||||
obj = new RectTransform(objectReader);
|
obj = new RectTransform(objectReader);
|
||||||
break;
|
break;
|
||||||
case ClassIDType.Shader:
|
case ClassIDType.Shader:
|
||||||
if (objectReader.version < 2021)
|
if (objectReader.version[0] < 2021)
|
||||||
obj = new Shader(objectReader);
|
obj = new Shader(objectReader);
|
||||||
break;
|
break;
|
||||||
case ClassIDType.SkinnedMeshRenderer:
|
case ClassIDType.SkinnedMeshRenderer:
|
||||||
@@ -607,14 +561,7 @@ namespace AssetStudio
|
|||||||
obj = new TextAsset(objectReader);
|
obj = new TextAsset(objectReader);
|
||||||
break;
|
break;
|
||||||
case ClassIDType.Texture2D:
|
case ClassIDType.Texture2D:
|
||||||
obj = objectReader.serializedType?.m_Type != null && LoadingViaTypeTreeEnabled
|
obj = new Texture2D(objectReader);
|
||||||
? new Texture2D(objectReader, TypeTreeHelper.ReadType(objectReader.serializedType.m_Type, objectReader))
|
|
||||||
: new Texture2D(objectReader);
|
|
||||||
break;
|
|
||||||
case ClassIDType.Texture2DArray:
|
|
||||||
obj = objectReader.serializedType?.m_Type != null && LoadingViaTypeTreeEnabled
|
|
||||||
? new Texture2DArray(objectReader, TypeTreeHelper.ReadType(objectReader.serializedType.m_Type, objectReader))
|
|
||||||
: new Texture2DArray(objectReader);
|
|
||||||
break;
|
break;
|
||||||
case ClassIDType.Transform:
|
case ClassIDType.Transform:
|
||||||
obj = new Transform(objectReader);
|
obj = new Transform(objectReader);
|
||||||
@@ -630,9 +577,7 @@ namespace AssetStudio
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (obj != null)
|
if (obj != null)
|
||||||
{
|
|
||||||
assetsFile.AddObject(obj);
|
assetsFile.AddObject(obj);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,11 +4,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public static class BigArrayPool<T>
|
public static class BigArrayPool<T>
|
||||||
{
|
{
|
||||||
public static ArrayPool<T> Shared { get; }
|
private static readonly ArrayPool<T> s_shared = ArrayPool<T>.Create(64 * 1024 * 1024, 3);
|
||||||
|
public static ArrayPool<T> Shared => s_shared;
|
||||||
static BigArrayPool()
|
|
||||||
{
|
|
||||||
Shared = ArrayPool<T>.Create(256 * 1024 * 1024, 5);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using K4os.Compression.LZ4;
|
using K4os.Compression.LZ4;
|
||||||
using ZstdSharp;
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -36,8 +35,7 @@ namespace AssetStudio
|
|||||||
Lzma,
|
Lzma,
|
||||||
Lz4,
|
Lz4,
|
||||||
Lz4HC,
|
Lz4HC,
|
||||||
Lzham,
|
Lz4Inv,
|
||||||
Custom,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BundleFile
|
public class BundleFile
|
||||||
@@ -47,7 +45,7 @@ namespace AssetStudio
|
|||||||
public string signature;
|
public string signature;
|
||||||
public uint version;
|
public uint version;
|
||||||
public string unityVersion;
|
public string unityVersion;
|
||||||
public UnityVersion unityRevision;
|
public string unityRevision;
|
||||||
public long size;
|
public long size;
|
||||||
public uint compressedBlocksInfoSize;
|
public uint compressedBlocksInfoSize;
|
||||||
public uint uncompressedBlocksInfoSize;
|
public uint uncompressedBlocksInfoSize;
|
||||||
@@ -75,13 +73,13 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public StreamFile[] fileList;
|
public StreamFile[] fileList;
|
||||||
|
|
||||||
public BundleFile(FileReader reader, bool useZstd, UnityVersion specUnityVer = null)
|
public BundleFile(FileReader reader, string specUnityVer = "")
|
||||||
{
|
{
|
||||||
m_Header = new Header();
|
m_Header = new Header();
|
||||||
m_Header.signature = reader.ReadStringToNull();
|
m_Header.signature = reader.ReadStringToNull();
|
||||||
m_Header.version = reader.ReadUInt32();
|
m_Header.version = reader.ReadUInt32();
|
||||||
m_Header.unityVersion = reader.ReadStringToNull();
|
m_Header.unityVersion = reader.ReadStringToNull();
|
||||||
m_Header.unityRevision = new UnityVersion(reader.ReadStringToNull());
|
m_Header.unityRevision = reader.ReadStringToNull();
|
||||||
switch (m_Header.signature)
|
switch (m_Header.signature)
|
||||||
{
|
{
|
||||||
case "UnityArchive":
|
case "UnityArchive":
|
||||||
@@ -102,26 +100,16 @@ namespace AssetStudio
|
|||||||
case "UnityFS":
|
case "UnityFS":
|
||||||
ReadHeader(reader);
|
ReadHeader(reader);
|
||||||
|
|
||||||
var isUnityCnEnc = false;
|
bool isUnityCnEnc = false;
|
||||||
var unityVer = m_Header.unityRevision;
|
string unityVer = string.IsNullOrEmpty(specUnityVer) ? m_Header.unityRevision : specUnityVer;
|
||||||
if (specUnityVer != null)
|
int[] ver = new string(unityVer.SkipWhile(x => !char.IsDigit(x)).TakeWhile(x => char.IsDigit(x) || x == '.').ToArray()).Split('.').Select(x => int.Parse(x)).ToArray();
|
||||||
{
|
if (ver[0] != 0)
|
||||||
if (!unityVer.IsStripped && specUnityVer != unityVer)
|
|
||||||
{
|
|
||||||
Logger.Warning($"Detected Unity version is different from the specified one ({specUnityVer.FullVersion.Color(ColorConsole.BrightCyan)}).\n" +
|
|
||||||
$"Assets may load with errors.\n" +
|
|
||||||
$"It is recommended to specify the detected Unity version: {unityVer.FullVersion.Color(ColorConsole.BrightCyan)}");
|
|
||||||
}
|
|
||||||
unityVer = specUnityVer;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!unityVer.IsStripped)
|
|
||||||
{
|
{
|
||||||
// https://issuetracker.unity3d.com/issues/files-within-assetbundles-do-not-start-on-aligned-boundaries-breaking-patching-on-nintendo-switch
|
// https://issuetracker.unity3d.com/issues/files-within-assetbundles-do-not-start-on-aligned-boundaries-breaking-patching-on-nintendo-switch
|
||||||
if (unityVer < 2020
|
if (ver[0] < 2020 ||
|
||||||
|| unityVer.IsInRange(2020, (2020, 3, 34))
|
(ver[0] == 2020 && ver[1] <= 3 && ver[2] < 34) ||
|
||||||
|| unityVer.IsInRange(2021, (2021, 3, 2))
|
(ver[0] == 2021 && ver[1] <= 3 && ver[2] < 2) ||
|
||||||
|| unityVer.IsInRange(2022, (2022, 1, 1)))
|
(ver[0] == 2022 && ver[1] <= 1 && ver[2] < 1))
|
||||||
{
|
{
|
||||||
isUnityCnEnc = ((CnEncryptionFlags)m_Header.flags & CnEncryptionFlags.OldFlag) != 0;
|
isUnityCnEnc = ((CnEncryptionFlags)m_Header.flags & CnEncryptionFlags.OldFlag) != 0;
|
||||||
}
|
}
|
||||||
@@ -132,24 +120,20 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
if (isUnityCnEnc)
|
if (isUnityCnEnc)
|
||||||
{
|
{
|
||||||
var msg = "Unsupported bundle file. ";
|
throw new NotSupportedException("Unsupported bundle file. UnityCN encryption was detected.");
|
||||||
msg += specUnityVer != null
|
|
||||||
? "UnityCN encryption was detected or the specified Unity version is incorrect."
|
|
||||||
: "UnityCN encryption was detected.";
|
|
||||||
throw new NotSupportedException(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadBlocksInfoAndDirectory(reader, unityVer);
|
ReadBlocksInfoAndDirectory(reader, ver);
|
||||||
using (var blocksStream = CreateBlocksStream(reader.FullPath))
|
using (var blocksStream = CreateBlocksStream(reader.FullPath))
|
||||||
{
|
{
|
||||||
ReadBlocks(reader, blocksStream, useZstd);
|
ReadBlocks(reader, blocksStream);
|
||||||
ReadFiles(blocksStream, reader.FullPath);
|
ReadFiles(blocksStream, reader.FullPath);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadHeaderAndBlocksInfo(FileReader reader)
|
private void ReadHeaderAndBlocksInfo(EndianBinaryReader reader)
|
||||||
{
|
{
|
||||||
if (m_Header.version >= 4)
|
if (m_Header.version >= 4)
|
||||||
{
|
{
|
||||||
@@ -201,7 +185,7 @@ namespace AssetStudio
|
|||||||
return blocksStream;
|
return blocksStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadBlocksAndDirectory(FileReader reader, Stream blocksStream)
|
private void ReadBlocksAndDirectory(EndianBinaryReader reader, Stream blocksStream)
|
||||||
{
|
{
|
||||||
var isCompressed = m_Header.signature == "UnityWeb";
|
var isCompressed = m_Header.signature == "UnityWeb";
|
||||||
foreach (var blockInfo in m_BlocksInfo)
|
foreach (var blockInfo in m_BlocksInfo)
|
||||||
@@ -262,7 +246,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadHeader(FileReader reader)
|
private void ReadHeader(EndianBinaryReader reader)
|
||||||
{
|
{
|
||||||
m_Header.size = reader.ReadInt64();
|
m_Header.size = reader.ReadInt64();
|
||||||
m_Header.compressedBlocksInfoSize = reader.ReadUInt32();
|
m_Header.compressedBlocksInfoSize = reader.ReadUInt32();
|
||||||
@@ -274,7 +258,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadBlocksInfoAndDirectory(FileReader reader, UnityVersion unityVer)
|
private void ReadBlocksInfoAndDirectory(EndianBinaryReader reader, int[] unityVer)
|
||||||
{
|
{
|
||||||
byte[] blocksInfoBytes;
|
byte[] blocksInfoBytes;
|
||||||
|
|
||||||
@@ -282,7 +266,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
reader.AlignStream(16);
|
reader.AlignStream(16);
|
||||||
}
|
}
|
||||||
else if (unityVer >= (2019, 4) && m_Header.flags != ArchiveFlags.BlocksAndDirectoryInfoCombined)
|
else if (unityVer[0] >= 2019 && unityVer[1] >= 4)
|
||||||
{
|
{
|
||||||
//check if we need to align the reader
|
//check if we need to align the reader
|
||||||
//- align to 16 bytes and check if all are 0
|
//- align to 16 bytes and check if all are 0
|
||||||
@@ -306,44 +290,42 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
|
blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
|
||||||
}
|
}
|
||||||
MemoryStream blocksInfoUncompressedStream;
|
MemoryStream blocksInfoUncompresseddStream;
|
||||||
var uncompressedSize = m_Header.uncompressedBlocksInfoSize;
|
var uncompressedSize = m_Header.uncompressedBlocksInfoSize;
|
||||||
var compressionType = (CompressionType)(m_Header.flags & ArchiveFlags.CompressionTypeMask);
|
var compressionType = (CompressionType)(m_Header.flags & ArchiveFlags.CompressionTypeMask);
|
||||||
switch (compressionType)
|
switch (compressionType)
|
||||||
{
|
{
|
||||||
case CompressionType.None:
|
case CompressionType.None:
|
||||||
{
|
|
||||||
blocksInfoUncompressedStream = new MemoryStream(blocksInfoBytes);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CompressionType.Lzma:
|
|
||||||
{
|
|
||||||
blocksInfoUncompressedStream = new MemoryStream((int) (uncompressedSize));
|
|
||||||
using (var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes))
|
|
||||||
{
|
{
|
||||||
SevenZipHelper.StreamDecompress(blocksInfoCompressedStream, blocksInfoUncompressedStream,
|
blocksInfoUncompresseddStream = new MemoryStream(blocksInfoBytes);
|
||||||
m_Header.compressedBlocksInfoSize, m_Header.uncompressedBlocksInfoSize);
|
break;
|
||||||
|
}
|
||||||
|
case CompressionType.Lzma:
|
||||||
|
{
|
||||||
|
blocksInfoUncompresseddStream = new MemoryStream((int)(uncompressedSize));
|
||||||
|
using (var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes))
|
||||||
|
{
|
||||||
|
SevenZipHelper.StreamDecompress(blocksInfoCompressedStream, blocksInfoUncompresseddStream, m_Header.compressedBlocksInfoSize, m_Header.uncompressedBlocksInfoSize);
|
||||||
|
}
|
||||||
|
blocksInfoUncompresseddStream.Position = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
blocksInfoUncompressedStream.Position = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CompressionType.Lz4:
|
case CompressionType.Lz4:
|
||||||
case CompressionType.Lz4HC:
|
case CompressionType.Lz4HC:
|
||||||
{
|
|
||||||
var uncompressedBytes = new byte[uncompressedSize];
|
|
||||||
var numWrite = LZ4Codec.Decode(blocksInfoBytes, uncompressedBytes);
|
|
||||||
if (numWrite != uncompressedSize)
|
|
||||||
{
|
{
|
||||||
throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
|
var uncompressedBytes = new byte[uncompressedSize];
|
||||||
|
var numWrite = LZ4Codec.Decode(blocksInfoBytes, uncompressedBytes);
|
||||||
|
if (numWrite != uncompressedSize)
|
||||||
|
{
|
||||||
|
throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
|
||||||
|
}
|
||||||
|
blocksInfoUncompresseddStream = new MemoryStream(uncompressedBytes);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
blocksInfoUncompressedStream = new MemoryStream(uncompressedBytes);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
throw new IOException($"Unsupported block info compression type {compressionType}");
|
throw new IOException($"Unsupported compression type {compressionType}");
|
||||||
}
|
}
|
||||||
|
using (var blocksInfoReader = new EndianBinaryReader(blocksInfoUncompresseddStream))
|
||||||
using (var blocksInfoReader = new EndianBinaryReader(blocksInfoUncompressedStream))
|
|
||||||
{
|
{
|
||||||
var uncompressedDataHash = blocksInfoReader.ReadBytes(16);
|
var uncompressedDataHash = blocksInfoReader.ReadBytes(16);
|
||||||
var blocksInfoCount = blocksInfoReader.ReadInt32();
|
var blocksInfoCount = blocksInfoReader.ReadInt32();
|
||||||
@@ -377,72 +359,54 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadBlocks(FileReader reader, Stream blocksStream, bool useZstd)
|
private void ReadBlocks(EndianBinaryReader reader, Stream blocksStream)
|
||||||
{
|
{
|
||||||
var zstdCodec = new Decompressor();
|
|
||||||
var i = 0;
|
|
||||||
foreach (var blockInfo in m_BlocksInfo)
|
foreach (var blockInfo in m_BlocksInfo)
|
||||||
{
|
{
|
||||||
var compressionType = (CompressionType)(blockInfo.flags & StorageBlockFlags.CompressionTypeMask);
|
var compressionType = (CompressionType)(blockInfo.flags & StorageBlockFlags.CompressionTypeMask);
|
||||||
switch (compressionType)
|
switch (compressionType)
|
||||||
{
|
{
|
||||||
case CompressionType.None:
|
case CompressionType.None:
|
||||||
{
|
{
|
||||||
reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize);
|
reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CompressionType.Lzma:
|
case CompressionType.Lzma:
|
||||||
{
|
{
|
||||||
SevenZipHelper.StreamDecompress(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
|
SevenZipHelper.StreamDecompress(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CompressionType.Lz4:
|
case CompressionType.Lz4:
|
||||||
case CompressionType.Lz4HC:
|
case CompressionType.Lz4HC:
|
||||||
case CompressionType.Custom:
|
case CompressionType.Lz4Inv:
|
||||||
{
|
|
||||||
var compressedSize = (int)blockInfo.compressedSize;
|
|
||||||
var compressedBytes = BigArrayPool<byte>.Shared.Rent(compressedSize);
|
|
||||||
_ = reader.Read(compressedBytes, 0, compressedSize);
|
|
||||||
var uncompressedSize = (int)blockInfo.uncompressedSize;
|
|
||||||
var uncompressedBytes = BigArrayPool<byte>.Shared.Rent(uncompressedSize);
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var compTypeStr = compressionType.ToString();
|
var compressedSize = (int)blockInfo.compressedSize;
|
||||||
if (compressionType == CompressionType.Custom)
|
var compressedBytes = BigArrayPool<byte>.Shared.Rent(compressedSize);
|
||||||
|
_ = reader.Read(compressedBytes, 0, compressedSize);
|
||||||
|
var uncompressedSize = (int)blockInfo.uncompressedSize;
|
||||||
|
var uncompressedBytes = BigArrayPool<byte>.Shared.Rent(uncompressedSize);
|
||||||
|
try
|
||||||
{
|
{
|
||||||
compTypeStr = useZstd ? "Zstd" : "Lz4";
|
var compressedSpan = compressedBytes.AsSpan(0, compressedSize);
|
||||||
if (i == 0)
|
var uncompressedSpan = uncompressedBytes.AsSpan(0, uncompressedSize);
|
||||||
|
var numWrite = compressionType == CompressionType.Lz4Inv
|
||||||
|
? LZ4Inv.Instance.Decompress(compressedSpan, uncompressedSpan)
|
||||||
|
: LZ4Codec.Decode(compressedSpan, uncompressedSpan);
|
||||||
|
if (numWrite != uncompressedSize)
|
||||||
{
|
{
|
||||||
Logger.Debug($"Custom block compression type was detected. Trying to decompress as {compTypeStr} archive..");
|
throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
blocksStream.Write(uncompressedBytes, 0, uncompressedSize);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
int numWrite;
|
|
||||||
if (compressionType == CompressionType.Custom && useZstd)
|
|
||||||
{
|
{
|
||||||
numWrite = zstdCodec.Unwrap(compressedBytes, 0, compressedSize, uncompressedBytes, 0, uncompressedSize);
|
BigArrayPool<byte>.Shared.Return(compressedBytes);
|
||||||
|
BigArrayPool<byte>.Shared.Return(uncompressedBytes);
|
||||||
}
|
}
|
||||||
else
|
break;
|
||||||
{
|
|
||||||
numWrite = LZ4Codec.Decode(compressedBytes, 0, compressedSize, uncompressedBytes, 0, uncompressedSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numWrite != uncompressedSize)
|
|
||||||
{
|
|
||||||
throw new IOException($"{compTypeStr} block decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
|
|
||||||
}
|
|
||||||
blocksStream.Write(uncompressedBytes, 0, uncompressedSize);
|
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
BigArrayPool<byte>.Shared.Return(compressedBytes, clearArray: true);
|
|
||||||
BigArrayPool<byte>.Shared.Return(uncompressedBytes, clearArray: true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
throw new IOException($"Unsupported block compression type {compressionType}");
|
throw new IOException($"Unsupported compression type {compressionType}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
blocksStream.Position = 0;
|
blocksStream.Position = 0;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public enum ClassIDType
|
public enum ClassIDType
|
||||||
{
|
{
|
||||||
|
AkPortraitSprite = -2,
|
||||||
UnknownType = -1,
|
UnknownType = -1,
|
||||||
Object = 0,
|
Object = 0,
|
||||||
GameObject = 1,
|
GameObject = 1,
|
||||||
@@ -145,7 +146,6 @@ namespace AssetStudio
|
|||||||
ProceduralMaterial = 185,
|
ProceduralMaterial = 185,
|
||||||
ProceduralTexture = 186,
|
ProceduralTexture = 186,
|
||||||
Texture2DArray = 187,
|
Texture2DArray = 187,
|
||||||
Texture2DArrayImage = -187, //fake type
|
|
||||||
CubemapArray = 188,
|
CubemapArray = 188,
|
||||||
OffMeshLink = 191,
|
OffMeshLink = 191,
|
||||||
OcclusionArea = 192,
|
OcclusionArea = 192,
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using Newtonsoft.Json;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -17,15 +15,13 @@ namespace AssetStudio
|
|||||||
public T inWeight;
|
public T inWeight;
|
||||||
public T outWeight;
|
public T outWeight;
|
||||||
|
|
||||||
public Keyframe() { }
|
|
||||||
|
|
||||||
public Keyframe(ObjectReader reader, Func<T> readerFunc)
|
public Keyframe(ObjectReader reader, Func<T> readerFunc)
|
||||||
{
|
{
|
||||||
time = reader.ReadSingle();
|
time = reader.ReadSingle();
|
||||||
value = readerFunc();
|
value = readerFunc();
|
||||||
inSlope = readerFunc();
|
inSlope = readerFunc();
|
||||||
outSlope = readerFunc();
|
outSlope = readerFunc();
|
||||||
if (reader.version >= 2018) //2018 and up
|
if (reader.version[0] >= 2018) //2018 and up
|
||||||
{
|
{
|
||||||
weightedMode = reader.ReadInt32();
|
weightedMode = reader.ReadInt32();
|
||||||
inWeight = readerFunc();
|
inWeight = readerFunc();
|
||||||
@@ -41,8 +37,6 @@ namespace AssetStudio
|
|||||||
public int m_PostInfinity;
|
public int m_PostInfinity;
|
||||||
public int m_RotationOrder;
|
public int m_RotationOrder;
|
||||||
|
|
||||||
public AnimationCurve() { }
|
|
||||||
|
|
||||||
public AnimationCurve(ObjectReader reader, Func<T> readerFunc)
|
public AnimationCurve(ObjectReader reader, Func<T> readerFunc)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
@@ -55,7 +49,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
m_PreInfinity = reader.ReadInt32();
|
m_PreInfinity = reader.ReadInt32();
|
||||||
m_PostInfinity = reader.ReadInt32();
|
m_PostInfinity = reader.ReadInt32();
|
||||||
if (version >= (5, 3)) //5.3 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3))//5.3 and up
|
||||||
{
|
{
|
||||||
m_RotationOrder = reader.ReadInt32();
|
m_RotationOrder = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
@@ -67,8 +61,6 @@ namespace AssetStudio
|
|||||||
public AnimationCurve<Quaternion> curve;
|
public AnimationCurve<Quaternion> curve;
|
||||||
public string path;
|
public string path;
|
||||||
|
|
||||||
public QuaternionCurve() { }
|
|
||||||
|
|
||||||
public QuaternionCurve(ObjectReader reader)
|
public QuaternionCurve(ObjectReader reader)
|
||||||
{
|
{
|
||||||
curve = new AnimationCurve<Quaternion>(reader, reader.ReadQuaternion);
|
curve = new AnimationCurve<Quaternion>(reader, reader.ReadQuaternion);
|
||||||
@@ -84,8 +76,6 @@ namespace AssetStudio
|
|||||||
public byte[] m_Data;
|
public byte[] m_Data;
|
||||||
public byte m_BitSize;
|
public byte m_BitSize;
|
||||||
|
|
||||||
public PackedFloatVector() { }
|
|
||||||
|
|
||||||
public PackedFloatVector(ObjectReader reader)
|
public PackedFloatVector(ObjectReader reader)
|
||||||
{
|
{
|
||||||
m_NumItems = reader.ReadUInt32();
|
m_NumItems = reader.ReadUInt32();
|
||||||
@@ -145,8 +135,6 @@ namespace AssetStudio
|
|||||||
public byte[] m_Data;
|
public byte[] m_Data;
|
||||||
public byte m_BitSize;
|
public byte m_BitSize;
|
||||||
|
|
||||||
public PackedIntVector() { }
|
|
||||||
|
|
||||||
public PackedIntVector(ObjectReader reader)
|
public PackedIntVector(ObjectReader reader)
|
||||||
{
|
{
|
||||||
m_NumItems = reader.ReadUInt32();
|
m_NumItems = reader.ReadUInt32();
|
||||||
@@ -191,8 +179,6 @@ namespace AssetStudio
|
|||||||
public uint m_NumItems;
|
public uint m_NumItems;
|
||||||
public byte[] m_Data;
|
public byte[] m_Data;
|
||||||
|
|
||||||
public PackedQuatVector() { }
|
|
||||||
|
|
||||||
public PackedQuatVector(ObjectReader reader)
|
public PackedQuatVector(ObjectReader reader)
|
||||||
{
|
{
|
||||||
m_NumItems = reader.ReadUInt32();
|
m_NumItems = reader.ReadUInt32();
|
||||||
@@ -277,8 +263,6 @@ namespace AssetStudio
|
|||||||
public int m_PreInfinity;
|
public int m_PreInfinity;
|
||||||
public int m_PostInfinity;
|
public int m_PostInfinity;
|
||||||
|
|
||||||
public CompressedAnimationCurve() { }
|
|
||||||
|
|
||||||
public CompressedAnimationCurve(ObjectReader reader)
|
public CompressedAnimationCurve(ObjectReader reader)
|
||||||
{
|
{
|
||||||
m_Path = reader.ReadAlignedString();
|
m_Path = reader.ReadAlignedString();
|
||||||
@@ -295,8 +279,6 @@ namespace AssetStudio
|
|||||||
public AnimationCurve<Vector3> curve;
|
public AnimationCurve<Vector3> curve;
|
||||||
public string path;
|
public string path;
|
||||||
|
|
||||||
public Vector3Curve() { }
|
|
||||||
|
|
||||||
public Vector3Curve(ObjectReader reader)
|
public Vector3Curve(ObjectReader reader)
|
||||||
{
|
{
|
||||||
curve = new AnimationCurve<Vector3>(reader, reader.ReadVector3);
|
curve = new AnimationCurve<Vector3>(reader, reader.ReadVector3);
|
||||||
@@ -313,8 +295,6 @@ namespace AssetStudio
|
|||||||
public PPtr<MonoScript> script;
|
public PPtr<MonoScript> script;
|
||||||
public int flags;
|
public int flags;
|
||||||
|
|
||||||
public FloatCurve() { }
|
|
||||||
|
|
||||||
public FloatCurve(ObjectReader reader)
|
public FloatCurve(ObjectReader reader)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
@@ -323,7 +303,7 @@ namespace AssetStudio
|
|||||||
path = reader.ReadAlignedString();
|
path = reader.ReadAlignedString();
|
||||||
classID = (ClassIDType)reader.ReadInt32();
|
classID = (ClassIDType)reader.ReadInt32();
|
||||||
script = new PPtr<MonoScript>(reader);
|
script = new PPtr<MonoScript>(reader);
|
||||||
if (version >= (2022, 2)) //2022.2 and up
|
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 2)) //2022.2 and up
|
||||||
{
|
{
|
||||||
flags = reader.ReadInt32();
|
flags = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
@@ -335,8 +315,6 @@ namespace AssetStudio
|
|||||||
public float time;
|
public float time;
|
||||||
public PPtr<Object> value;
|
public PPtr<Object> value;
|
||||||
|
|
||||||
public PPtrKeyframe() { }
|
|
||||||
|
|
||||||
public PPtrKeyframe(ObjectReader reader)
|
public PPtrKeyframe(ObjectReader reader)
|
||||||
{
|
{
|
||||||
time = reader.ReadSingle();
|
time = reader.ReadSingle();
|
||||||
@@ -353,8 +331,6 @@ namespace AssetStudio
|
|||||||
public PPtr<MonoScript> script;
|
public PPtr<MonoScript> script;
|
||||||
public int flags;
|
public int flags;
|
||||||
|
|
||||||
public PPtrCurve() { }
|
|
||||||
|
|
||||||
public PPtrCurve(ObjectReader reader)
|
public PPtrCurve(ObjectReader reader)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
@@ -369,7 +345,7 @@ namespace AssetStudio
|
|||||||
path = reader.ReadAlignedString();
|
path = reader.ReadAlignedString();
|
||||||
classID = reader.ReadInt32();
|
classID = reader.ReadInt32();
|
||||||
script = new PPtr<MonoScript>(reader);
|
script = new PPtr<MonoScript>(reader);
|
||||||
if (version >= (2022, 2)) //2022.2 and up
|
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 2)) //2022.2 and up
|
||||||
{
|
{
|
||||||
flags = reader.ReadInt32();
|
flags = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
@@ -381,8 +357,6 @@ namespace AssetStudio
|
|||||||
public Vector3 m_Center;
|
public Vector3 m_Center;
|
||||||
public Vector3 m_Extent;
|
public Vector3 m_Extent;
|
||||||
|
|
||||||
public AABB() { }
|
|
||||||
|
|
||||||
public AABB(ObjectReader reader)
|
public AABB(ObjectReader reader)
|
||||||
{
|
{
|
||||||
m_Center = reader.ReadVector3();
|
m_Center = reader.ReadVector3();
|
||||||
@@ -396,14 +370,12 @@ namespace AssetStudio
|
|||||||
public Quaternion q;
|
public Quaternion q;
|
||||||
public Vector3 s;
|
public Vector3 s;
|
||||||
|
|
||||||
public xform() { }
|
|
||||||
|
|
||||||
public xform(ObjectReader reader)
|
public xform(ObjectReader reader)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
t = version >= (5, 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4();//5.4 and up
|
t = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4();//5.4 and up
|
||||||
q = reader.ReadQuaternion();
|
q = reader.ReadQuaternion();
|
||||||
s = version >= (5, 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4();//5.4 and up
|
s = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4();//5.4 and up
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,8 +388,6 @@ namespace AssetStudio
|
|||||||
public float m_InOut;
|
public float m_InOut;
|
||||||
public float m_Grab;
|
public float m_Grab;
|
||||||
|
|
||||||
public HandPose() { }
|
|
||||||
|
|
||||||
public HandPose(ObjectReader reader)
|
public HandPose(ObjectReader reader)
|
||||||
{
|
{
|
||||||
m_GrabX = new xform(reader);
|
m_GrabX = new xform(reader);
|
||||||
@@ -437,17 +407,15 @@ namespace AssetStudio
|
|||||||
public Vector3 m_HintT;
|
public Vector3 m_HintT;
|
||||||
public float m_HintWeightT;
|
public float m_HintWeightT;
|
||||||
|
|
||||||
public HumanGoal() { }
|
|
||||||
|
|
||||||
public HumanGoal(ObjectReader reader)
|
public HumanGoal(ObjectReader reader)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
m_X = new xform(reader);
|
m_X = new xform(reader);
|
||||||
m_WeightT = reader.ReadSingle();
|
m_WeightT = reader.ReadSingle();
|
||||||
m_WeightR = reader.ReadSingle();
|
m_WeightR = reader.ReadSingle();
|
||||||
if (version >= 5)//5.0 and up
|
if (version[0] >= 5)//5.0 and up
|
||||||
{
|
{
|
||||||
m_HintT = version >= (5, 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4();//5.4 and up
|
m_HintT = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4();//5.4 and up
|
||||||
m_HintWeightT = reader.ReadSingle();
|
m_HintWeightT = reader.ReadSingle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -464,13 +432,11 @@ namespace AssetStudio
|
|||||||
public float[] m_DoFArray;
|
public float[] m_DoFArray;
|
||||||
public Vector3[] m_TDoFArray;
|
public Vector3[] m_TDoFArray;
|
||||||
|
|
||||||
public HumanPose() { }
|
|
||||||
|
|
||||||
public HumanPose(ObjectReader reader)
|
public HumanPose(ObjectReader reader)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
m_RootX = new xform(reader);
|
m_RootX = new xform(reader);
|
||||||
m_LookAtPosition = version >= (5, 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4();//5.4 and up
|
m_LookAtPosition = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4();//5.4 and up
|
||||||
m_LookAtWeight = reader.ReadVector4();
|
m_LookAtWeight = reader.ReadVector4();
|
||||||
|
|
||||||
int numGoals = reader.ReadInt32();
|
int numGoals = reader.ReadInt32();
|
||||||
@@ -485,13 +451,13 @@ namespace AssetStudio
|
|||||||
|
|
||||||
m_DoFArray = reader.ReadSingleArray();
|
m_DoFArray = reader.ReadSingleArray();
|
||||||
|
|
||||||
if (version >= (5, 2))//5.2 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2))//5.2 and up
|
||||||
{
|
{
|
||||||
int numTDof = reader.ReadInt32();
|
int numTDof = reader.ReadInt32();
|
||||||
m_TDoFArray = new Vector3[numTDof];
|
m_TDoFArray = new Vector3[numTDof];
|
||||||
for (int i = 0; i < numTDof; i++)
|
for (int i = 0; i < numTDof; i++)
|
||||||
{
|
{
|
||||||
m_TDoFArray[i] = version >= (5, 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4();//5.4 and up
|
m_TDoFArray[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4();//5.4 and up
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -502,8 +468,6 @@ namespace AssetStudio
|
|||||||
public uint[] data;
|
public uint[] data;
|
||||||
public uint curveCount;
|
public uint curveCount;
|
||||||
|
|
||||||
public StreamedClip() { }
|
|
||||||
|
|
||||||
public StreamedClip(ObjectReader reader)
|
public StreamedClip(ObjectReader reader)
|
||||||
{
|
{
|
||||||
data = reader.ReadUInt32Array();
|
data = reader.ReadUInt32Array();
|
||||||
@@ -519,8 +483,6 @@ namespace AssetStudio
|
|||||||
public float outSlope;
|
public float outSlope;
|
||||||
public float inSlope;
|
public float inSlope;
|
||||||
|
|
||||||
public StreamedCurveKey() { }
|
|
||||||
|
|
||||||
public StreamedCurveKey(BinaryReader reader)
|
public StreamedCurveKey(BinaryReader reader)
|
||||||
{
|
{
|
||||||
index = reader.ReadInt32();
|
index = reader.ReadInt32();
|
||||||
@@ -552,8 +514,6 @@ namespace AssetStudio
|
|||||||
public float time;
|
public float time;
|
||||||
public StreamedCurveKey[] keyList;
|
public StreamedCurveKey[] keyList;
|
||||||
|
|
||||||
public StreamedFrame() { }
|
|
||||||
|
|
||||||
public StreamedFrame(BinaryReader reader)
|
public StreamedFrame(BinaryReader reader)
|
||||||
{
|
{
|
||||||
time = reader.ReadSingle();
|
time = reader.ReadSingle();
|
||||||
@@ -609,8 +569,6 @@ namespace AssetStudio
|
|||||||
public float m_BeginTime;
|
public float m_BeginTime;
|
||||||
public float[] m_SampleArray;
|
public float[] m_SampleArray;
|
||||||
|
|
||||||
public DenseClip() { }
|
|
||||||
|
|
||||||
public DenseClip(ObjectReader reader)
|
public DenseClip(ObjectReader reader)
|
||||||
{
|
{
|
||||||
m_FrameCount = reader.ReadInt32();
|
m_FrameCount = reader.ReadInt32();
|
||||||
@@ -625,8 +583,6 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public float[] data;
|
public float[] data;
|
||||||
|
|
||||||
public ConstantClip() { }
|
|
||||||
|
|
||||||
public ConstantClip(ObjectReader reader)
|
public ConstantClip(ObjectReader reader)
|
||||||
{
|
{
|
||||||
data = reader.ReadSingleArray();
|
data = reader.ReadSingleArray();
|
||||||
@@ -640,13 +596,11 @@ namespace AssetStudio
|
|||||||
public uint m_Type;
|
public uint m_Type;
|
||||||
public uint m_Index;
|
public uint m_Index;
|
||||||
|
|
||||||
public ValueConstant() { }
|
|
||||||
|
|
||||||
public ValueConstant(ObjectReader reader)
|
public ValueConstant(ObjectReader reader)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
m_ID = reader.ReadUInt32();
|
m_ID = reader.ReadUInt32();
|
||||||
if (version < (5, 5)) //5.5 down
|
if (version[0] < 5 || (version[0] == 5 && version[1] < 5))//5.5 down
|
||||||
{
|
{
|
||||||
m_TypeID = reader.ReadUInt32();
|
m_TypeID = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
@@ -659,8 +613,6 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public ValueConstant[] m_ValueArray;
|
public ValueConstant[] m_ValueArray;
|
||||||
|
|
||||||
public ValueArrayConstant() { }
|
|
||||||
|
|
||||||
public ValueArrayConstant(ObjectReader reader)
|
public ValueArrayConstant(ObjectReader reader)
|
||||||
{
|
{
|
||||||
int numVals = reader.ReadInt32();
|
int numVals = reader.ReadInt32();
|
||||||
@@ -672,18 +624,6 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class OffsetPtr
|
|
||||||
{
|
|
||||||
public Clip data;
|
|
||||||
|
|
||||||
public OffsetPtr() { }
|
|
||||||
|
|
||||||
public OffsetPtr(ObjectReader reader)
|
|
||||||
{
|
|
||||||
data = new Clip(reader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Clip
|
public class Clip
|
||||||
{
|
{
|
||||||
public StreamedClip m_StreamedClip;
|
public StreamedClip m_StreamedClip;
|
||||||
@@ -691,18 +631,16 @@ namespace AssetStudio
|
|||||||
public ConstantClip m_ConstantClip;
|
public ConstantClip m_ConstantClip;
|
||||||
public ValueArrayConstant m_Binding;
|
public ValueArrayConstant m_Binding;
|
||||||
|
|
||||||
public Clip() { }
|
|
||||||
|
|
||||||
public Clip(ObjectReader reader)
|
public Clip(ObjectReader reader)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
m_StreamedClip = new StreamedClip(reader);
|
m_StreamedClip = new StreamedClip(reader);
|
||||||
m_DenseClip = new DenseClip(reader);
|
m_DenseClip = new DenseClip(reader);
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
m_ConstantClip = new ConstantClip(reader);
|
m_ConstantClip = new ConstantClip(reader);
|
||||||
}
|
}
|
||||||
if (version < (2018, 3)) //2018.3 down
|
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 3)) //2018.3 down
|
||||||
{
|
{
|
||||||
m_Binding = new ValueArrayConstant(reader);
|
m_Binding = new ValueArrayConstant(reader);
|
||||||
}
|
}
|
||||||
@@ -758,8 +696,6 @@ namespace AssetStudio
|
|||||||
public float m_Start;
|
public float m_Start;
|
||||||
public float m_Stop;
|
public float m_Stop;
|
||||||
|
|
||||||
public ValueDelta() { }
|
|
||||||
|
|
||||||
public ValueDelta(ObjectReader reader)
|
public ValueDelta(ObjectReader reader)
|
||||||
{
|
{
|
||||||
m_Start = reader.ReadSingle();
|
m_Start = reader.ReadSingle();
|
||||||
@@ -777,7 +713,7 @@ namespace AssetStudio
|
|||||||
public xform m_MotionStartX;
|
public xform m_MotionStartX;
|
||||||
public xform m_MotionStopX;
|
public xform m_MotionStopX;
|
||||||
public Vector3 m_AverageSpeed;
|
public Vector3 m_AverageSpeed;
|
||||||
public OffsetPtr m_Clip;
|
public Clip m_Clip;
|
||||||
public float m_StartTime;
|
public float m_StartTime;
|
||||||
public float m_StopTime;
|
public float m_StopTime;
|
||||||
public float m_OrientationOffsetY;
|
public float m_OrientationOffsetY;
|
||||||
@@ -799,26 +735,24 @@ namespace AssetStudio
|
|||||||
public bool m_KeepOriginalPositionXZ;
|
public bool m_KeepOriginalPositionXZ;
|
||||||
public bool m_HeightFromFeet;
|
public bool m_HeightFromFeet;
|
||||||
|
|
||||||
public ClipMuscleConstant() { }
|
|
||||||
|
|
||||||
public ClipMuscleConstant(ObjectReader reader)
|
public ClipMuscleConstant(ObjectReader reader)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
m_DeltaPose = new HumanPose(reader);
|
m_DeltaPose = new HumanPose(reader);
|
||||||
m_StartX = new xform(reader);
|
m_StartX = new xform(reader);
|
||||||
if (version >= (5, 5)) //5.5 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5))//5.5 and up
|
||||||
{
|
{
|
||||||
m_StopX = new xform(reader);
|
m_StopX = new xform(reader);
|
||||||
}
|
}
|
||||||
m_LeftFootStartX = new xform(reader);
|
m_LeftFootStartX = new xform(reader);
|
||||||
m_RightFootStartX = new xform(reader);
|
m_RightFootStartX = new xform(reader);
|
||||||
if (version < 5)//5.0 down
|
if (version[0] < 5)//5.0 down
|
||||||
{
|
{
|
||||||
m_MotionStartX = new xform(reader);
|
m_MotionStartX = new xform(reader);
|
||||||
m_MotionStopX = new xform(reader);
|
m_MotionStopX = new xform(reader);
|
||||||
}
|
}
|
||||||
m_AverageSpeed = version >= (5, 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4();//5.4 and up
|
m_AverageSpeed = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4();//5.4 and up
|
||||||
m_Clip = new OffsetPtr(reader);
|
m_Clip = new Clip(reader);
|
||||||
m_StartTime = reader.ReadSingle();
|
m_StartTime = reader.ReadSingle();
|
||||||
m_StopTime = reader.ReadSingle();
|
m_StopTime = reader.ReadSingle();
|
||||||
m_OrientationOffsetY = reader.ReadSingle();
|
m_OrientationOffsetY = reader.ReadSingle();
|
||||||
@@ -827,7 +761,7 @@ namespace AssetStudio
|
|||||||
m_AverageAngularSpeed = reader.ReadSingle();
|
m_AverageAngularSpeed = reader.ReadSingle();
|
||||||
|
|
||||||
m_IndexArray = reader.ReadInt32Array();
|
m_IndexArray = reader.ReadInt32Array();
|
||||||
if (version < (4, 3)) //4.3 down
|
if (version[0] < 4 || (version[0] == 4 && version[1] < 3)) //4.3 down
|
||||||
{
|
{
|
||||||
var m_AdditionalCurveIndexArray = reader.ReadInt32Array();
|
var m_AdditionalCurveIndexArray = reader.ReadInt32Array();
|
||||||
}
|
}
|
||||||
@@ -837,13 +771,13 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
m_ValueArrayDelta[i] = new ValueDelta(reader);
|
m_ValueArrayDelta[i] = new ValueDelta(reader);
|
||||||
}
|
}
|
||||||
if (version >= (5, 3))//5.3 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3))//5.3 and up
|
||||||
{
|
{
|
||||||
m_ValueArrayReferencePose = reader.ReadSingleArray();
|
m_ValueArrayReferencePose = reader.ReadSingleArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Mirror = reader.ReadBoolean();
|
m_Mirror = reader.ReadBoolean();
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
m_LoopTime = reader.ReadBoolean();
|
m_LoopTime = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
@@ -851,7 +785,7 @@ namespace AssetStudio
|
|||||||
m_LoopBlendOrientation = reader.ReadBoolean();
|
m_LoopBlendOrientation = reader.ReadBoolean();
|
||||||
m_LoopBlendPositionY = reader.ReadBoolean();
|
m_LoopBlendPositionY = reader.ReadBoolean();
|
||||||
m_LoopBlendPositionXZ = reader.ReadBoolean();
|
m_LoopBlendPositionXZ = reader.ReadBoolean();
|
||||||
if (version >= (5, 5))//5.5 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5))//5.5 and up
|
||||||
{
|
{
|
||||||
m_StartAtOrigin = reader.ReadBoolean();
|
m_StartAtOrigin = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
@@ -881,7 +815,7 @@ namespace AssetStudio
|
|||||||
path = reader.ReadUInt32();
|
path = reader.ReadUInt32();
|
||||||
attribute = reader.ReadUInt32();
|
attribute = reader.ReadUInt32();
|
||||||
script = new PPtr<Object>(reader);
|
script = new PPtr<Object>(reader);
|
||||||
if (version >= (5, 6)) //5.6 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
|
||||||
{
|
{
|
||||||
typeID = (ClassIDType)reader.ReadInt32();
|
typeID = (ClassIDType)reader.ReadInt32();
|
||||||
}
|
}
|
||||||
@@ -891,7 +825,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
customType = reader.ReadByte();
|
customType = reader.ReadByte();
|
||||||
isPPtrCurve = reader.ReadByte();
|
isPPtrCurve = reader.ReadByte();
|
||||||
if (version >= (2022, 1)) //2022.1 and up
|
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 1)) //2022.1 and up
|
||||||
{
|
{
|
||||||
isIntCurve = reader.ReadByte();
|
isIntCurve = reader.ReadByte();
|
||||||
}
|
}
|
||||||
@@ -969,8 +903,6 @@ namespace AssetStudio
|
|||||||
public int intParameter;
|
public int intParameter;
|
||||||
public int messageOptions;
|
public int messageOptions;
|
||||||
|
|
||||||
public AnimationEvent() { }
|
|
||||||
|
|
||||||
public AnimationEvent(ObjectReader reader)
|
public AnimationEvent(ObjectReader reader)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
@@ -980,7 +912,7 @@ namespace AssetStudio
|
|||||||
data = reader.ReadAlignedString();
|
data = reader.ReadAlignedString();
|
||||||
objectReferenceParameter = new PPtr<Object>(reader);
|
objectReferenceParameter = new PPtr<Object>(reader);
|
||||||
floatParameter = reader.ReadSingle();
|
floatParameter = reader.ReadSingle();
|
||||||
if (version >= 3) //3 and up
|
if (version[0] >= 3) //3 and up
|
||||||
{
|
{
|
||||||
intParameter = reader.ReadInt32();
|
intParameter = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
@@ -1016,40 +948,13 @@ namespace AssetStudio
|
|||||||
public AnimationClipBindingConstant m_ClipBindingConstant;
|
public AnimationClipBindingConstant m_ClipBindingConstant;
|
||||||
public AnimationEvent[] m_Events;
|
public AnimationEvent[] m_Events;
|
||||||
|
|
||||||
public AnimationClip() { }
|
|
||||||
|
|
||||||
public AnimationClip(ObjectReader reader, IDictionary typeDict) : base(reader)
|
|
||||||
{
|
|
||||||
var parsedAnimClip = JsonConvert.DeserializeObject<AnimationClip>(JsonConvert.SerializeObject(typeDict));
|
|
||||||
m_AnimationType = parsedAnimClip.m_AnimationType;
|
|
||||||
m_Legacy = parsedAnimClip.m_Legacy;
|
|
||||||
m_Compressed = parsedAnimClip.m_Compressed;
|
|
||||||
m_UseHighQualityCurve = parsedAnimClip.m_UseHighQualityCurve;
|
|
||||||
m_RotationCurves = parsedAnimClip.m_RotationCurves;
|
|
||||||
m_CompressedRotationCurves = parsedAnimClip.m_CompressedRotationCurves;
|
|
||||||
m_EulerCurves = parsedAnimClip.m_EulerCurves;
|
|
||||||
m_PositionCurves = parsedAnimClip.m_PositionCurves;
|
|
||||||
m_ScaleCurves = parsedAnimClip.m_ScaleCurves;
|
|
||||||
m_FloatCurves = parsedAnimClip.m_FloatCurves;
|
|
||||||
m_PPtrCurves = parsedAnimClip.m_PPtrCurves;
|
|
||||||
m_SampleRate = parsedAnimClip.m_SampleRate;
|
|
||||||
m_WrapMode = parsedAnimClip.m_WrapMode;
|
|
||||||
m_Bounds = parsedAnimClip.m_Bounds;
|
|
||||||
m_MuscleClipSize = parsedAnimClip.m_MuscleClipSize;
|
|
||||||
m_MuscleClip = parsedAnimClip.m_MuscleClip;
|
|
||||||
m_ClipBindingConstant = parsedAnimClip.m_ClipBindingConstant;
|
|
||||||
m_Events = parsedAnimClip.m_Events;
|
|
||||||
|
|
||||||
typeDict.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AnimationClip(ObjectReader reader) : base(reader)
|
public AnimationClip(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
if (version >= 5)//5.0 and up
|
if (version[0] >= 5)//5.0 and up
|
||||||
{
|
{
|
||||||
m_Legacy = reader.ReadBoolean();
|
m_Legacy = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
else if (version >= 4)//4.0 and up
|
else if (version[0] >= 4)//4.0 and up
|
||||||
{
|
{
|
||||||
m_AnimationType = (AnimationType)reader.ReadInt32();
|
m_AnimationType = (AnimationType)reader.ReadInt32();
|
||||||
if (m_AnimationType == AnimationType.Legacy)
|
if (m_AnimationType == AnimationType.Legacy)
|
||||||
@@ -1060,7 +965,7 @@ namespace AssetStudio
|
|||||||
m_Legacy = true;
|
m_Legacy = true;
|
||||||
}
|
}
|
||||||
m_Compressed = reader.ReadBoolean();
|
m_Compressed = reader.ReadBoolean();
|
||||||
if (version >= (4, 3))//4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3))//4.3 and up
|
||||||
{
|
{
|
||||||
m_UseHighQualityCurve = reader.ReadBoolean();
|
m_UseHighQualityCurve = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
@@ -1079,7 +984,7 @@ namespace AssetStudio
|
|||||||
m_CompressedRotationCurves[i] = new CompressedAnimationCurve(reader);
|
m_CompressedRotationCurves[i] = new CompressedAnimationCurve(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (5, 3))//5.3 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3))//5.3 and up
|
||||||
{
|
{
|
||||||
int numEulerCurves = reader.ReadInt32();
|
int numEulerCurves = reader.ReadInt32();
|
||||||
m_EulerCurves = new Vector3Curve[numEulerCurves];
|
m_EulerCurves = new Vector3Curve[numEulerCurves];
|
||||||
@@ -1110,7 +1015,7 @@ namespace AssetStudio
|
|||||||
m_FloatCurves[i] = new FloatCurve(reader);
|
m_FloatCurves[i] = new FloatCurve(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
int numPtrCurves = reader.ReadInt32();
|
int numPtrCurves = reader.ReadInt32();
|
||||||
m_PPtrCurves = new PPtrCurve[numPtrCurves];
|
m_PPtrCurves = new PPtrCurve[numPtrCurves];
|
||||||
@@ -1122,20 +1027,20 @@ namespace AssetStudio
|
|||||||
|
|
||||||
m_SampleRate = reader.ReadSingle();
|
m_SampleRate = reader.ReadSingle();
|
||||||
m_WrapMode = reader.ReadInt32();
|
m_WrapMode = reader.ReadInt32();
|
||||||
if (version >= (3, 4)) //3.4 and up
|
if (version[0] > 3 || (version[0] == 3 && version[1] >= 4)) //3.4 and up
|
||||||
{
|
{
|
||||||
m_Bounds = new AABB(reader);
|
m_Bounds = new AABB(reader);
|
||||||
}
|
}
|
||||||
if (version >= 4)//4.0 and up
|
if (version[0] >= 4)//4.0 and up
|
||||||
{
|
{
|
||||||
m_MuscleClipSize = reader.ReadUInt32();
|
m_MuscleClipSize = reader.ReadUInt32();
|
||||||
m_MuscleClip = new ClipMuscleConstant(reader);
|
m_MuscleClip = new ClipMuscleConstant(reader);
|
||||||
}
|
}
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
m_ClipBindingConstant = new AnimationClipBindingConstant(reader);
|
m_ClipBindingConstant = new AnimationClipBindingConstant(reader);
|
||||||
}
|
}
|
||||||
if (version >= (2018, 3)) //2018.3 and up
|
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 3)) //2018.3 and up
|
||||||
{
|
{
|
||||||
var m_HasGenericRootTransform = reader.ReadBoolean();
|
var m_HasGenericRootTransform = reader.ReadBoolean();
|
||||||
var m_HasMotionFloatCurves = reader.ReadBoolean();
|
var m_HasMotionFloatCurves = reader.ReadBoolean();
|
||||||
@@ -1147,7 +1052,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
m_Events[i] = new AnimationEvent(reader);
|
m_Events[i] = new AnimationEvent(reader);
|
||||||
}
|
}
|
||||||
if (version >= 2017) //2017 and up
|
if (version[0] >= 2017) //2017 and up
|
||||||
{
|
{
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,47 +17,47 @@ namespace AssetStudio
|
|||||||
m_Controller = new PPtr<RuntimeAnimatorController>(reader);
|
m_Controller = new PPtr<RuntimeAnimatorController>(reader);
|
||||||
var m_CullingMode = reader.ReadInt32();
|
var m_CullingMode = reader.ReadInt32();
|
||||||
|
|
||||||
if (version >= (4, 5)) //4.5 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
|
||||||
{
|
{
|
||||||
var m_UpdateMode = reader.ReadInt32();
|
var m_UpdateMode = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
var m_ApplyRootMotion = reader.ReadBoolean();
|
var m_ApplyRootMotion = reader.ReadBoolean();
|
||||||
if (version == 4 && version.Minor >= 5) //4.5 and up - 5.0 down
|
if (version[0] == 4 && version[1] >= 5) //4.5 and up - 5.0 down
|
||||||
{
|
{
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 5) //5.0 and up
|
if (version[0] >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
var m_LinearVelocityBlending = reader.ReadBoolean();
|
var m_LinearVelocityBlending = reader.ReadBoolean();
|
||||||
if (version >= (2021, 2)) //2021.2 and up
|
if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 2)) //2021.2 and up
|
||||||
{
|
{
|
||||||
var m_StabilizeFeet = reader.ReadBoolean();
|
var m_StabilizeFeet = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version < (4, 5)) //4.5 down
|
if (version[0] < 4 || (version[0] == 4 && version[1] < 5)) //4.5 down
|
||||||
{
|
{
|
||||||
var m_AnimatePhysics = reader.ReadBoolean();
|
var m_AnimatePhysics = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
m_HasTransformHierarchy = reader.ReadBoolean();
|
m_HasTransformHierarchy = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (4, 5)) //4.5 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
|
||||||
{
|
{
|
||||||
var m_AllowConstantClipSamplingOptimization = reader.ReadBoolean();
|
var m_AllowConstantClipSamplingOptimization = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
if (version.IsInRange(5, 2018)) //5.0 and up - 2018 down
|
if (version[0] >= 5 && version[0] < 2018) //5.0 and up - 2018 down
|
||||||
{
|
{
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 2018) //2018 and up
|
if (version[0] >= 2018) //2018 and up
|
||||||
{
|
{
|
||||||
var m_KeepAnimatorControllerStateOnDisable = reader.ReadBoolean();
|
var m_KeepAnimatorControllerStateOnDisable = reader.ReadBoolean();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
word0 = reader.ReadUInt32();
|
word0 = reader.ReadUInt32();
|
||||||
word1 = reader.ReadUInt32();
|
word1 = reader.ReadUInt32();
|
||||||
if (version >= (5, 2)) //5.2 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up
|
||||||
{
|
{
|
||||||
word2 = reader.ReadUInt32();
|
word2 = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
@@ -73,12 +73,12 @@ namespace AssetStudio
|
|||||||
m_SkeletonMask = new SkeletonMask(reader);
|
m_SkeletonMask = new SkeletonMask(reader);
|
||||||
m_Binding = reader.ReadUInt32();
|
m_Binding = reader.ReadUInt32();
|
||||||
m_LayerBlendingMode = reader.ReadInt32();
|
m_LayerBlendingMode = reader.ReadInt32();
|
||||||
if (version >= (4, 2)) //4.2 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 2)) //4.2 and up
|
||||||
{
|
{
|
||||||
m_DefaultWeight = reader.ReadSingle();
|
m_DefaultWeight = reader.ReadSingle();
|
||||||
}
|
}
|
||||||
m_IKPass = reader.ReadBoolean();
|
m_IKPass = reader.ReadBoolean();
|
||||||
if (version >= (4, 2)) //4.2 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 2)) //4.2 and up
|
||||||
{
|
{
|
||||||
m_SyncedLayerAffectsTiming = reader.ReadBoolean();
|
m_SyncedLayerAffectsTiming = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_DestinationState = reader.ReadUInt32();
|
m_DestinationState = reader.ReadUInt32();
|
||||||
if (version >= 5) //5.0 and up
|
if (version[0] >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
m_FullPathID = reader.ReadUInt32();
|
m_FullPathID = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ namespace AssetStudio
|
|||||||
m_UserID = reader.ReadUInt32();
|
m_UserID = reader.ReadUInt32();
|
||||||
m_TransitionDuration = reader.ReadSingle();
|
m_TransitionDuration = reader.ReadSingle();
|
||||||
m_TransitionOffset = reader.ReadSingle();
|
m_TransitionOffset = reader.ReadSingle();
|
||||||
if (version >= 5) //5.0 and up
|
if (version[0] >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
m_ExitTime = reader.ReadSingle();
|
m_ExitTime = reader.ReadSingle();
|
||||||
m_HasExitTime = reader.ReadBoolean();
|
m_HasExitTime = reader.ReadBoolean();
|
||||||
@@ -154,7 +154,7 @@ namespace AssetStudio
|
|||||||
m_Atomic = reader.ReadBoolean();
|
m_Atomic = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (4, 5)) //4.5 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
|
||||||
{
|
{
|
||||||
m_CanTransitionToSelf = reader.ReadBoolean();
|
m_CanTransitionToSelf = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
@@ -252,41 +252,43 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
if (version >= (4, 1)) //4.1 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
|
||||||
{
|
{
|
||||||
m_BlendType = reader.ReadUInt32();
|
m_BlendType = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
m_BlendEventID = reader.ReadUInt32();
|
m_BlendEventID = reader.ReadUInt32();
|
||||||
if (version >= (4, 1)) //4.1 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
|
||||||
{
|
{
|
||||||
m_BlendEventYID = reader.ReadUInt32();
|
m_BlendEventYID = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
m_ChildIndices = reader.ReadUInt32Array();
|
m_ChildIndices = reader.ReadUInt32Array();
|
||||||
if (version < (4, 1)) //4.1 down
|
if (version[0] < 4 || (version[0] == 4 && version[1] < 1)) //4.1 down
|
||||||
{
|
{
|
||||||
m_ChildThresholdArray = reader.ReadSingleArray();
|
m_ChildThresholdArray = reader.ReadSingleArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (4, 1)) //4.1 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
|
||||||
{
|
{
|
||||||
m_Blend1dData = new Blend1dDataConstant(reader);
|
m_Blend1dData = new Blend1dDataConstant(reader);
|
||||||
m_Blend2dData = new Blend2dDataConstant(reader);
|
m_Blend2dData = new Blend2dDataConstant(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 5) //5.0 and up
|
if (version[0] >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
m_BlendDirectData = new BlendDirectDataConstant(reader);
|
m_BlendDirectData = new BlendDirectDataConstant(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ClipID = reader.ReadUInt32();
|
m_ClipID = reader.ReadUInt32();
|
||||||
if (version == 4 && version.Minor >= 5) //4.5 - 5.0
|
if (version[0] == 4 && version[1] >= 5) //4.5 - 5.0
|
||||||
{
|
{
|
||||||
m_ClipIndex = reader.ReadUInt32();
|
m_ClipIndex = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Duration = reader.ReadSingle();
|
m_Duration = reader.ReadSingle();
|
||||||
|
|
||||||
if (version >= (4, 1, 3)) //4.1.3 and up
|
if (version[0] > 4
|
||||||
|
|| (version[0] == 4 && version[1] > 1)
|
||||||
|
|| (version[0] == 4 && version[1] == 1 && version[2] >= 3)) //4.1.3 and up
|
||||||
{
|
{
|
||||||
m_CycleOffset = reader.ReadSingle();
|
m_CycleOffset = reader.ReadSingle();
|
||||||
m_Mirror = reader.ReadBoolean();
|
m_Mirror = reader.ReadBoolean();
|
||||||
@@ -311,7 +313,7 @@ namespace AssetStudio
|
|||||||
m_NodeArray[i] = new BlendTreeNodeConstant(reader);
|
m_NodeArray[i] = new BlendTreeNodeConstant(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version < (4, 5)) //4.5 down
|
if (version[0] < 4 || (version[0] == 4 && version[1] < 5)) //4.5 down
|
||||||
{
|
{
|
||||||
m_BlendEventArrayConstant = new ValueArrayConstant(reader);
|
m_BlendEventArrayConstant = new ValueArrayConstant(reader);
|
||||||
}
|
}
|
||||||
@@ -352,7 +354,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
m_BlendTreeConstantIndexArray = reader.ReadInt32Array();
|
m_BlendTreeConstantIndexArray = reader.ReadInt32Array();
|
||||||
|
|
||||||
if (version < (5, 2)) //5.2 down
|
if (version[0] < 5 || (version[0] == 5 && version[1] < 2)) //5.2 down
|
||||||
{
|
{
|
||||||
int numInfos = reader.ReadInt32();
|
int numInfos = reader.ReadInt32();
|
||||||
m_LeafInfoArray = new LeafInfoConstant[numInfos];
|
m_LeafInfoArray = new LeafInfoConstant[numInfos];
|
||||||
@@ -370,41 +372,41 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_NameID = reader.ReadUInt32();
|
m_NameID = reader.ReadUInt32();
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
m_PathID = reader.ReadUInt32();
|
m_PathID = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
if (version >= 5) //5.0 and up
|
if (version[0] >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
m_FullPathID = reader.ReadUInt32();
|
m_FullPathID = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_TagID = reader.ReadUInt32();
|
m_TagID = reader.ReadUInt32();
|
||||||
if (version >= (5, 1)) //5.1 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 1)) //5.1 and up
|
||||||
{
|
{
|
||||||
m_SpeedParamID = reader.ReadUInt32();
|
m_SpeedParamID = reader.ReadUInt32();
|
||||||
m_MirrorParamID = reader.ReadUInt32();
|
m_MirrorParamID = reader.ReadUInt32();
|
||||||
m_CycleOffsetParamID = reader.ReadUInt32();
|
m_CycleOffsetParamID = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (2017, 2)) //2017.2 and up
|
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
|
||||||
{
|
{
|
||||||
var m_TimeParamID = reader.ReadUInt32();
|
var m_TimeParamID = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Speed = reader.ReadSingle();
|
m_Speed = reader.ReadSingle();
|
||||||
if (version >= (4, 1)) //4.1 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
|
||||||
{
|
{
|
||||||
m_CycleOffset = reader.ReadSingle();
|
m_CycleOffset = reader.ReadSingle();
|
||||||
}
|
}
|
||||||
m_IKOnFeet = reader.ReadBoolean();
|
m_IKOnFeet = reader.ReadBoolean();
|
||||||
if (version >= 5) //5.0 and up
|
if (version[0] >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
m_WriteDefaultValues = reader.ReadBoolean();
|
m_WriteDefaultValues = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Loop = reader.ReadBoolean();
|
m_Loop = reader.ReadBoolean();
|
||||||
if (version >= (4, 1)) //4.1 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
|
||||||
{
|
{
|
||||||
m_Mirror = reader.ReadBoolean();
|
m_Mirror = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
@@ -478,7 +480,7 @@ namespace AssetStudio
|
|||||||
m_AnyStateTransitionConstantArray[i] = new TransitionConstant(reader);
|
m_AnyStateTransitionConstantArray[i] = new TransitionConstant(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 5) //5.0 and up
|
if (version[0] >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
int numSelectors = reader.ReadInt32();
|
int numSelectors = reader.ReadInt32();
|
||||||
m_SelectorStateConstantArray = new SelectorStateConstant[numSelectors];
|
m_SelectorStateConstantArray = new SelectorStateConstant[numSelectors];
|
||||||
@@ -507,7 +509,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
if (version < (5, 5)) //5.5 down
|
if (version[0] < 5 || (version[0] == 5 && version[1] < 5)) //5.5 down
|
||||||
{
|
{
|
||||||
m_BoolValues = reader.ReadBooleanArray();
|
m_BoolValues = reader.ReadBooleanArray();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
@@ -515,7 +517,7 @@ namespace AssetStudio
|
|||||||
m_FloatValues = reader.ReadSingleArray();
|
m_FloatValues = reader.ReadSingleArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version < (4, 3)) //4.3 down
|
if (version[0] < 4 || (version[0] == 4 && version[1] < 3)) //4.3 down
|
||||||
{
|
{
|
||||||
m_VectorValues = reader.ReadVector4Array();
|
m_VectorValues = reader.ReadVector4Array();
|
||||||
}
|
}
|
||||||
@@ -525,7 +527,7 @@ namespace AssetStudio
|
|||||||
m_PositionValues = new Vector3[numPosValues];
|
m_PositionValues = new Vector3[numPosValues];
|
||||||
for (int i = 0; i < numPosValues; i++)
|
for (int i = 0; i < numPosValues; i++)
|
||||||
{
|
{
|
||||||
m_PositionValues[i] = version >= (5, 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4(); //5.4 and up
|
m_PositionValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4(); //5.4 and up
|
||||||
}
|
}
|
||||||
|
|
||||||
m_QuaternionValues = reader.ReadVector4Array();
|
m_QuaternionValues = reader.ReadVector4Array();
|
||||||
@@ -534,10 +536,10 @@ namespace AssetStudio
|
|||||||
m_ScaleValues = new Vector3[numScaleValues];
|
m_ScaleValues = new Vector3[numScaleValues];
|
||||||
for (int i = 0; i < numScaleValues; i++)
|
for (int i = 0; i < numScaleValues; i++)
|
||||||
{
|
{
|
||||||
m_ScaleValues[i] = version >= (5, 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4(); //5.4 and up
|
m_ScaleValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4(); //5.4 and up
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (5, 5)) //5.5 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5)) //5.5 and up
|
||||||
{
|
{
|
||||||
m_FloatValues = reader.ReadSingleArray();
|
m_FloatValues = reader.ReadSingleArray();
|
||||||
m_IntValues = reader.ReadInt32Array();
|
m_IntValues = reader.ReadInt32Array();
|
||||||
|
|||||||
@@ -42,22 +42,12 @@ namespace AssetStudio
|
|||||||
|
|
||||||
var m_MainAsset = new AssetInfo(reader);
|
var m_MainAsset = new AssetInfo(reader);
|
||||||
|
|
||||||
if (version == (5, 4)) //5.4.x
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 2)) //4.2 and up
|
||||||
{
|
|
||||||
var m_ClassVersionMapSize = reader.ReadInt32();
|
|
||||||
for (var i = 0; i < m_ClassVersionMapSize; i++)
|
|
||||||
{
|
|
||||||
var first = reader.ReadInt32();
|
|
||||||
var second = reader.ReadInt32();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version >= (4, 2)) //4.2 and up
|
|
||||||
{
|
{
|
||||||
var m_RuntimeCompatibility = reader.ReadUInt32();
|
var m_RuntimeCompatibility = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 5) //5.0 and up
|
if (version[0] >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
m_AssetBundleName = reader.ReadAlignedString();
|
m_AssetBundleName = reader.ReadAlignedString();
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public AudioClip(ObjectReader reader) : base(reader)
|
public AudioClip(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
if (version < 5)
|
if (version[0] < 5)
|
||||||
{
|
{
|
||||||
m_Format = reader.ReadInt32();
|
m_Format = reader.ReadInt32();
|
||||||
m_Type = (FMODSoundType)reader.ReadInt32();
|
m_Type = (FMODSoundType)reader.ReadInt32();
|
||||||
@@ -41,7 +41,7 @@ namespace AssetStudio
|
|||||||
m_UseHardware = reader.ReadBoolean();
|
m_UseHardware = reader.ReadBoolean();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
|
||||||
if (version >= (3, 2)) //3.2.0 to 5
|
if (version[0] >= 4 || (version[0] == 3 && version[1] >= 2)) //3.2.0 to 5
|
||||||
{
|
{
|
||||||
int m_Stream = reader.ReadInt32();
|
int m_Stream = reader.ReadInt32();
|
||||||
m_Size = reader.ReadInt32();
|
m_Size = reader.ReadInt32();
|
||||||
@@ -95,7 +95,7 @@ namespace AssetStudio
|
|||||||
public enum FMODSoundType
|
public enum FMODSoundType
|
||||||
{
|
{
|
||||||
UNKNOWN = 0,
|
UNKNOWN = 0,
|
||||||
AAC = 1,
|
ACC = 1,
|
||||||
AIFF = 2,
|
AIFF = 2,
|
||||||
ASF = 3,
|
ASF = 3,
|
||||||
AT3 = 4,
|
AT3 = 4,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace AssetStudio
|
|||||||
public Limit(ObjectReader reader)
|
public Limit(ObjectReader reader)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
if (version >= (5, 4))//5.4 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4))//5.4 and up
|
||||||
{
|
{
|
||||||
m_Min = reader.ReadVector3();
|
m_Min = reader.ReadVector3();
|
||||||
m_Max = reader.ReadVector3();
|
m_Max = reader.ReadVector3();
|
||||||
@@ -50,7 +50,7 @@ namespace AssetStudio
|
|||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
m_PreQ = reader.ReadVector4();
|
m_PreQ = reader.ReadVector4();
|
||||||
m_PostQ = reader.ReadVector4();
|
m_PostQ = reader.ReadVector4();
|
||||||
if (version >= (5, 4)) //5.4 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4 and up
|
||||||
{
|
{
|
||||||
m_Sgn = reader.ReadVector3();
|
m_Sgn = reader.ReadVector3();
|
||||||
}
|
}
|
||||||
@@ -189,7 +189,7 @@ namespace AssetStudio
|
|||||||
m_LeftHand = new Hand(reader);
|
m_LeftHand = new Hand(reader);
|
||||||
m_RightHand = new Hand(reader);
|
m_RightHand = new Hand(reader);
|
||||||
|
|
||||||
if (version < (2018, 2)) //2018.2 down
|
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 2)) //2018.2 down
|
||||||
{
|
{
|
||||||
int numHandles = reader.ReadInt32();
|
int numHandles = reader.ReadInt32();
|
||||||
m_Handles = new Handle[numHandles];
|
m_Handles = new Handle[numHandles];
|
||||||
@@ -210,7 +210,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
m_HumanBoneMass = reader.ReadSingleArray();
|
m_HumanBoneMass = reader.ReadSingleArray();
|
||||||
|
|
||||||
if (version < (2018, 2)) //2018.2 down
|
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 2)) //2018.2 down
|
||||||
{
|
{
|
||||||
m_ColliderIndex = reader.ReadInt32Array();
|
m_ColliderIndex = reader.ReadInt32Array();
|
||||||
}
|
}
|
||||||
@@ -225,7 +225,7 @@ namespace AssetStudio
|
|||||||
m_FeetSpacing = reader.ReadSingle();
|
m_FeetSpacing = reader.ReadSingle();
|
||||||
m_HasLeftHand = reader.ReadBoolean();
|
m_HasLeftHand = reader.ReadBoolean();
|
||||||
m_HasRightHand = reader.ReadBoolean();
|
m_HasRightHand = reader.ReadBoolean();
|
||||||
if (version >= (5, 2)) //5.2 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up
|
||||||
{
|
{
|
||||||
m_HasTDoF = reader.ReadBoolean();
|
m_HasTDoF = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
@@ -254,7 +254,7 @@ namespace AssetStudio
|
|||||||
m_AvatarSkeleton = new Skeleton(reader);
|
m_AvatarSkeleton = new Skeleton(reader);
|
||||||
m_AvatarSkeletonPose = new SkeletonPose(reader);
|
m_AvatarSkeletonPose = new SkeletonPose(reader);
|
||||||
|
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
m_DefaultPose = new SkeletonPose(reader);
|
m_DefaultPose = new SkeletonPose(reader);
|
||||||
|
|
||||||
@@ -265,7 +265,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
m_HumanSkeletonIndexArray = reader.ReadInt32Array();
|
m_HumanSkeletonIndexArray = reader.ReadInt32Array();
|
||||||
|
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
m_HumanSkeletonReverseIndexArray = reader.ReadInt32Array();
|
m_HumanSkeletonReverseIndexArray = reader.ReadInt32Array();
|
||||||
}
|
}
|
||||||
@@ -273,7 +273,7 @@ namespace AssetStudio
|
|||||||
m_RootMotionBoneIndex = reader.ReadInt32();
|
m_RootMotionBoneIndex = reader.ReadInt32();
|
||||||
m_RootMotionBoneX = new xform(reader);
|
m_RootMotionBoneX = new xform(reader);
|
||||||
|
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
m_RootMotionSkeleton = new Skeleton(reader);
|
m_RootMotionSkeleton = new Skeleton(reader);
|
||||||
m_RootMotionSkeletonPose = new SkeletonPose(reader);
|
m_RootMotionSkeletonPose = new SkeletonPose(reader);
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public abstract class EditorExtension : Object
|
public abstract class EditorExtension : Object
|
||||||
{
|
{
|
||||||
protected EditorExtension() { }
|
|
||||||
|
|
||||||
protected EditorExtension(ObjectReader reader) : base(reader)
|
protected EditorExtension(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
if (platform == BuildTarget.NoTarget)
|
if (platform == BuildTarget.NoTarget)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public Font(ObjectReader reader) : base(reader)
|
public Font(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
if (version >= (5, 5))//5.5 and up
|
if ((version[0] == 5 && version[1] >= 5) || version[0] > 5)//5.5 and up
|
||||||
{
|
{
|
||||||
var m_LineSpacing = reader.ReadSingle();
|
var m_LineSpacing = reader.ReadSingle();
|
||||||
var m_DefaultMaterial = new PPtr<Material>(reader);
|
var m_DefaultMaterial = new PPtr<Material>(reader);
|
||||||
@@ -43,7 +43,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
int m_AsciiStartOffset = reader.ReadInt32();
|
int m_AsciiStartOffset = reader.ReadInt32();
|
||||||
|
|
||||||
if (version <= 3)
|
if (version[0] <= 3)
|
||||||
{
|
{
|
||||||
int m_FontCountX = reader.ReadInt32();
|
int m_FontCountX = reader.ReadInt32();
|
||||||
int m_FontCountY = reader.ReadInt32();
|
int m_FontCountY = reader.ReadInt32();
|
||||||
@@ -52,7 +52,7 @@ namespace AssetStudio
|
|||||||
float m_Kerning = reader.ReadSingle();
|
float m_Kerning = reader.ReadSingle();
|
||||||
float m_LineSpacing = reader.ReadSingle();
|
float m_LineSpacing = reader.ReadSingle();
|
||||||
|
|
||||||
if (version <= 3)
|
if (version[0] <= 3)
|
||||||
{
|
{
|
||||||
int m_PerCharacterKerning_size = reader.ReadInt32();
|
int m_PerCharacterKerning_size = reader.ReadInt32();
|
||||||
for (int i = 0; i < m_PerCharacterKerning_size; i++)
|
for (int i = 0; i < m_PerCharacterKerning_size; i++)
|
||||||
@@ -86,7 +86,7 @@ namespace AssetStudio
|
|||||||
float vertheight = reader.ReadSingle();
|
float vertheight = reader.ReadSingle();
|
||||||
float width = reader.ReadSingle();
|
float width = reader.ReadSingle();
|
||||||
|
|
||||||
if (version >= 4)
|
if (version[0] >= 4)
|
||||||
{
|
{
|
||||||
var flipped = reader.ReadBoolean();
|
var flipped = reader.ReadBoolean();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
@@ -103,7 +103,7 @@ namespace AssetStudio
|
|||||||
float second = reader.ReadSingle();
|
float second = reader.ReadSingle();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version <= 3)
|
if (version[0] <= 3)
|
||||||
{
|
{
|
||||||
var m_GridFont = reader.ReadBoolean();
|
var m_GridFont = reader.ReadBoolean();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
namespace AssetStudio
|
|
||||||
{
|
|
||||||
public class GLTextureSettings
|
|
||||||
{
|
|
||||||
public int m_FilterMode;
|
|
||||||
public int m_Aniso;
|
|
||||||
public float m_MipBias;
|
|
||||||
public int m_WrapMode;
|
|
||||||
|
|
||||||
public GLTextureSettings() { }
|
|
||||||
|
|
||||||
public GLTextureSettings(ObjectReader reader)
|
|
||||||
{
|
|
||||||
var version = reader.version;
|
|
||||||
|
|
||||||
m_FilterMode = reader.ReadInt32();
|
|
||||||
m_Aniso = reader.ReadInt32();
|
|
||||||
m_MipBias = reader.ReadSingle();
|
|
||||||
if (version >= 2017)//2017.x and up
|
|
||||||
{
|
|
||||||
m_WrapMode = reader.ReadInt32(); //m_WrapU
|
|
||||||
int m_WrapV = reader.ReadInt32();
|
|
||||||
int m_WrapW = reader.ReadInt32();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_WrapMode = reader.ReadInt32();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,7 +23,7 @@ namespace AssetStudio
|
|||||||
m_Components = new PPtr<Component>[m_Component_size];
|
m_Components = new PPtr<Component>[m_Component_size];
|
||||||
for (int i = 0; i < m_Component_size; i++)
|
for (int i = 0; i < m_Component_size; i++)
|
||||||
{
|
{
|
||||||
if (version < (5, 5)) //5.5 down
|
if ((version[0] == 5 && version[1] < 5) || version[0] < 5) //5.5 down
|
||||||
{
|
{
|
||||||
int first = reader.ReadInt32();
|
int first = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,711 +0,0 @@
|
|||||||
namespace AssetStudio
|
|
||||||
{
|
|
||||||
public enum GraphicsFormat
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The format is not specified.
|
|
||||||
/// </summary>
|
|
||||||
None,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 8-bit unsigned normalized format that has a single 8-bit R component stored with sRGB nonlinear encoding.
|
|
||||||
/// </summary>
|
|
||||||
R8_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 16-bit unsigned normalized format that has an 8-bit R component stored with sRGB nonlinear encoding in byte 0, and an 8-bit G component stored with sRGB nonlinear encoding in byte 1.
|
|
||||||
/// </summary>
|
|
||||||
R8G8_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 24-bit unsigned normalized format that has an 8-bit R component stored with sRGB nonlinear encoding in byte 0, an 8-bit G component stored with sRGB nonlinear encoding in byte 1, and an 8-bit B component stored with sRGB nonlinear encoding in byte 2.
|
|
||||||
/// </summary>
|
|
||||||
R8G8B8_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit unsigned normalized format that has an 8-bit R component stored with sRGB nonlinear encoding in byte 0, an 8-bit G component stored with sRGB nonlinear encoding in byte 1, an 8-bit B component stored with sRGB nonlinear encoding in byte 2, and an 8-bit A component in byte 3.
|
|
||||||
/// </summary>
|
|
||||||
R8G8B8A8_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 8-bit unsigned normalized format that has a single 8-bit R component.
|
|
||||||
/// </summary>
|
|
||||||
R8_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 16-bit unsigned normalized format that has an 8-bit R component stored with sRGB nonlinear encoding in byte 0, and an 8-bit G component stored with sRGB nonlinear encoding in byte 1.
|
|
||||||
/// </summary>
|
|
||||||
R8G8_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 24-bit unsigned normalized format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, and an 8-bit B component in byte 2.
|
|
||||||
/// </summary>
|
|
||||||
R8G8B8_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit unsigned normalized format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, an 8-bit B component in byte 2, and an 8-bit A component in byte 3.
|
|
||||||
/// </summary>
|
|
||||||
R8G8B8A8_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 8-bit signed normalized format that has a single 8-bit R component.
|
|
||||||
/// </summary>
|
|
||||||
R8_SNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 16-bit signed normalized format that has an 8-bit R component stored with sRGB nonlinear encoding in byte 0, and an 8-bit G component stored with sRGB nonlinear encoding in byte 1.
|
|
||||||
/// </summary>
|
|
||||||
R8G8_SNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 24-bit signed normalized format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, and an 8-bit B component in byte 2.
|
|
||||||
/// </summary>
|
|
||||||
R8G8B8_SNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit signed normalized format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, an 8-bit B component in byte 2, and an 8-bit A component in byte 3.
|
|
||||||
/// </summary>
|
|
||||||
R8G8B8A8_SNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 8-bit unsigned integer format that has a single 8-bit R component.
|
|
||||||
/// </summary>
|
|
||||||
R8_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 16-bit unsigned integer format that has an 8-bit R component in byte 0, and an 8-bit G component in byte 1.
|
|
||||||
/// </summary>
|
|
||||||
R8G8_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 24-bit unsigned integer format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, and an 8-bit B component in byte 2.
|
|
||||||
/// </summary>
|
|
||||||
R8G8B8_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit unsigned integer format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, an 8-bit B component in byte 2, and an 8-bit A component in byte 3.
|
|
||||||
/// </summary>
|
|
||||||
R8G8B8A8_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 8-bit signed integer format that has a single 8-bit R component.
|
|
||||||
/// </summary>
|
|
||||||
R8_SInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 16-bit signed integer format that has an 8-bit R component in byte 0, and an 8-bit G component in byte 1.
|
|
||||||
/// </summary>
|
|
||||||
R8G8_SInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 24-bit signed integer format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, and an 8-bit B component in byte 2.
|
|
||||||
/// </summary>
|
|
||||||
R8G8B8_SInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit signed integer format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, an 8-bit B component in byte 2, and an 8-bit A component in byte 3.
|
|
||||||
/// </summary>
|
|
||||||
R8G8B8A8_SInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 16-bit unsigned normalized format that has a single 16-bit R component.
|
|
||||||
/// </summary>
|
|
||||||
R16_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 32-bit unsigned normalized format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3.
|
|
||||||
/// </summary>
|
|
||||||
R16G16_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 48-bit unsigned normalized format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, and a 16-bit B component in bytes 4..5.
|
|
||||||
/// </summary>
|
|
||||||
R16G16B16_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 64-bit unsigned normalized format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, a 16-bit B component in bytes 4..5, and a 16-bit A component in bytes 6..7.
|
|
||||||
/// </summary>
|
|
||||||
R16G16B16A16_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 16-bit signed normalized format that has a single 16-bit R component.
|
|
||||||
/// </summary>
|
|
||||||
R16_SNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 32-bit signed normalized format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3.
|
|
||||||
/// </summary>
|
|
||||||
R16G16_SNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 48-bit signed normalized format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, and a 16-bit B component in bytes 4..5.
|
|
||||||
/// </summary>
|
|
||||||
R16G16B16_SNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 64-bit signed normalized format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, a 16-bit B component in bytes 4..5, and a 16-bit A component in bytes 6..7.
|
|
||||||
/// </summary>
|
|
||||||
R16G16B16A16_SNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 16-bit unsigned integer format that has a single 16-bit R component.
|
|
||||||
/// </summary>
|
|
||||||
R16_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 32-bit unsigned integer format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3.
|
|
||||||
/// </summary>
|
|
||||||
R16G16_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 48-bit unsigned integer format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, and a 16-bit B component in bytes 4..5.
|
|
||||||
/// </summary>
|
|
||||||
R16G16B16_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 64-bit unsigned integer format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, a 16-bit B component in bytes 4..5, and a 16-bit A component in bytes 6..7.
|
|
||||||
/// </summary>
|
|
||||||
R16G16B16A16_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 16-bit signed integer format that has a single 16-bit R component.
|
|
||||||
/// </summary>
|
|
||||||
R16_SInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 32-bit signed integer format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3.
|
|
||||||
/// </summary>
|
|
||||||
R16G16_SInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 48-bit signed integer format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, and a 16-bit B component in bytes 4..5.
|
|
||||||
/// </summary>
|
|
||||||
R16G16B16_SInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 64-bit signed integer format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, a 16-bit B component in bytes 4..5, and a 16-bit A component in bytes 6..7.
|
|
||||||
/// </summary>
|
|
||||||
R16G16B16A16_SInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 32-bit unsigned integer format that has a single 32-bit R component.
|
|
||||||
/// </summary>
|
|
||||||
R32_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 64-bit unsigned integer format that has a 32-bit R component in bytes 0..3, and a 32-bit G component in bytes 4..7.
|
|
||||||
/// </summary>
|
|
||||||
R32G32_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 96-bit unsigned integer format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, and a 32-bit B component in bytes 8..11.
|
|
||||||
/// </summary>
|
|
||||||
R32G32B32_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 128-bit unsigned integer format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, a 32-bit B component in bytes 8..11, and a 32-bit A component in bytes 12..15.
|
|
||||||
/// </summary>
|
|
||||||
R32G32B32A32_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 32-bit signed integer format that has a single 32-bit R component.
|
|
||||||
/// </summary>
|
|
||||||
R32_SInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 64-bit signed integer format that has a 32-bit R component in bytes 0..3, and a 32-bit G component in bytes 4..7.
|
|
||||||
/// </summary>
|
|
||||||
R32G32_SInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 96-bit signed integer format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, and a 32-bit B component in bytes 8..11.
|
|
||||||
/// </summary>
|
|
||||||
R32G32B32_SInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 128-bit signed integer format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, a 32-bit B component in bytes 8..11, and a 32-bit A component in bytes 12..15.
|
|
||||||
/// </summary>
|
|
||||||
R32G32B32A32_SInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 16-bit signed floating-point format that has a single 16-bit R component.
|
|
||||||
/// </summary>
|
|
||||||
R16_SFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 32-bit signed floating-point format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3.
|
|
||||||
/// </summary>
|
|
||||||
R16G16_SFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 48-bit signed floating-point format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, and a 16-bit B component in bytes 4..5.
|
|
||||||
/// </summary>
|
|
||||||
R16G16B16_SFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 64-bit signed floating-point format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, a 16-bit B component in bytes 4..5, and a 16-bit A component in bytes 6..7.
|
|
||||||
/// </summary>
|
|
||||||
R16G16B16A16_SFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 32-bit signed floating-point format that has a single 32-bit R component.
|
|
||||||
/// </summary>
|
|
||||||
R32_SFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 64-bit signed floating-point format that has a 32-bit R component in bytes 0..3, and a 32-bit G component in bytes 4..7.
|
|
||||||
/// </summary>
|
|
||||||
R32G32_SFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 96-bit signed floating-point format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, and a 32-bit B component in bytes 8..11.
|
|
||||||
/// </summary>
|
|
||||||
R32G32B32_SFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 128-bit signed floating-point format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, a 32-bit B component in bytes 8..11, and a 32-bit A component in bytes 12..15.
|
|
||||||
/// </summary>
|
|
||||||
R32G32B32A32_SFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 24-bit unsigned normalized format that has an 8-bit B component stored with sRGB nonlinear encoding in byte 0, an 8-bit G component stored with sRGB nonlinear encoding in byte 1, and an 8-bit R component stored with sRGB nonlinear encoding in byte 2.
|
|
||||||
/// </summary>
|
|
||||||
B8G8R8_SRGB = 56,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit unsigned normalized format that has an 8-bit B component stored with sRGB nonlinear encoding in byte 0, an 8-bit G component stored with sRGB nonlinear encoding in byte 1, an 8-bit R component stored with sRGB nonlinear encoding in byte 2, and an 8-bit A component in byte 3.
|
|
||||||
/// </summary>
|
|
||||||
B8G8R8A8_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 24-bit unsigned normalized format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, and an 8-bit R component in byte 2.
|
|
||||||
/// </summary>
|
|
||||||
B8G8R8_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit unsigned normalized format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, an 8-bit R component in byte 2, and an 8-bit A component in byte 3.
|
|
||||||
/// </summary>
|
|
||||||
B8G8R8A8_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 24-bit signed normalized format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, and an 8-bit R component in byte 2.
|
|
||||||
/// </summary>
|
|
||||||
B8G8R8_SNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit signed normalized format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, an 8-bit R component in byte 2, and an 8-bit A component in byte 3.
|
|
||||||
/// </summary>
|
|
||||||
B8G8R8A8_SNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 24-bit unsigned integer format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, and an 8-bit R component in byte 2
|
|
||||||
/// </summary>
|
|
||||||
B8G8R8_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit unsigned integer format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, an 8-bit R component in byte 2, and an 8-bit A component in byte 3.
|
|
||||||
/// </summary>
|
|
||||||
B8G8R8A8_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 24-bit signed integer format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, and an 8-bit R component in byte 2.
|
|
||||||
/// </summary>
|
|
||||||
B8G8R8_SInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit signed integer format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, an 8-bit R component in byte 2, and an 8-bit A component in byte 3.
|
|
||||||
/// </summary>
|
|
||||||
B8G8R8A8_SInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 16-bit packed unsigned normalized format that has a 4-bit R component in bits 12..15, a 4-bit G component in bits 8..11, a 4-bit B component in bits 4..7, and a 4-bit A component in bits 0..3.
|
|
||||||
/// </summary>
|
|
||||||
R4G4B4A4_UNormPack16,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 16-bit packed unsigned normalized format that has a 4-bit B component in bits 12..15, a 4-bit G component in bits 8..11, a 4-bit R component in bits 4..7, and a 4-bit A component in bits 0..3.
|
|
||||||
/// </summary>
|
|
||||||
B4G4R4A4_UNormPack16,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 16-bit packed unsigned normalized format that has a 5-bit R component in bits 11..15, a 6-bit G component in bits 5..10, and a 5-bit B component in bits 0..4.
|
|
||||||
/// </summary>
|
|
||||||
R5G6B5_UNormPack16,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 16-bit packed unsigned normalized format that has a 5-bit B component in bits 11..15, a 6-bit G component in bits 5..10, and a 5-bit R component in bits 0..4.
|
|
||||||
/// </summary>
|
|
||||||
B5G6R5_UNormPack16,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 16-bit packed unsigned normalized format that has a 5-bit R component in bits 11..15, a 5-bit G component in bits 6..10, a 5-bit B component in bits 1..5, and a 1-bit A component in bit 0.
|
|
||||||
/// </summary>
|
|
||||||
R5G5B5A1_UNormPack16,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 16-bit packed unsigned normalized format that has a 5-bit B component in bits 11..15, a 5-bit G component in bits 6..10, a 5-bit R component in bits 1..5, and a 1-bit A component in bit 0.
|
|
||||||
/// </summary>
|
|
||||||
B5G5R5A1_UNormPack16,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 16-bit packed unsigned normalized format that has a 1-bit A component in bit 15, a 5-bit R component in bits 10..14, a 5-bit G component in bits 5..9, and a 5-bit B component in bits 0..4.
|
|
||||||
/// </summary>
|
|
||||||
A1R5G5B5_UNormPack16,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 32-bit packed unsigned floating-point format that has a 5-bit shared exponent in bits 27..31, a 9-bit B component mantissa in bits 18..26, a 9-bit G component mantissa in bits 9..17, and a 9-bit R component mantissa in bits 0..8.
|
|
||||||
/// </summary>
|
|
||||||
E5B9G9R9_UFloatPack32,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, 32-bit packed unsigned floating-point format that has a 10-bit B component in bits 22..31, an 11-bit G component in bits 11..21, an 11-bit R component in bits 0..10.
|
|
||||||
/// </summary>
|
|
||||||
B10G11R11_UFloatPack32,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit packed unsigned normalized format that has a 2-bit A component in bits 30..31, a 10-bit B component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit R component in bits 0..9.
|
|
||||||
/// </summary>
|
|
||||||
A2B10G10R10_UNormPack32,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit packed unsigned integer format that has a 2-bit A component in bits 30..31, a 10-bit B component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit R component in bits 0..9.
|
|
||||||
/// </summary>
|
|
||||||
A2B10G10R10_UIntPack32,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit packed signed integer format that has a 2-bit A component in bits 30..31, a 10-bit B component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit R component in bits 0..9.
|
|
||||||
/// </summary>
|
|
||||||
A2B10G10R10_SIntPack32,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit packed unsigned normalized format that has a 2-bit A component in bits 30..31, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9.
|
|
||||||
/// </summary>
|
|
||||||
A2R10G10B10_UNormPack32,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit packed unsigned integer format that has a 2-bit A component in bits 30..31, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9.
|
|
||||||
/// </summary>
|
|
||||||
A2R10G10B10_UIntPack32,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit packed signed integer format that has a 2-bit A component in bits 30..31, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9.
|
|
||||||
/// </summary>
|
|
||||||
A2R10G10B10_SIntPack32,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit packed unsigned normalized format that has a 2-bit A component in bits 30..31, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are gamma encoded and their values range from -0.5271 to 1.66894. The alpha component is clamped to either 0.0 or 1.0 on sampling, rendering, and writing operations.
|
|
||||||
/// </summary>
|
|
||||||
A2R10G10B10_XRSRGBPack32,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit packed unsigned normalized format that has a 2-bit A component in bits 30..31, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are linearly encoded and their values range from -0.752941 to 1.25098 (pre-expansion). The alpha component is clamped to either 0.0 or 1.0 on sampling, rendering, and writing operations.
|
|
||||||
/// </summary>
|
|
||||||
A2R10G10B10_XRUNormPack32,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit packed unsigned normalized format that has a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are gamma encoded and their values range from -0.5271 to 1.66894. The alpha component is clamped to either 0.0 or 1.0 on sampling, rendering, and writing operations.
|
|
||||||
/// </summary>
|
|
||||||
R10G10B10_XRSRGBPack32,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 32-bit packed unsigned normalized format that has a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are linearly encoded and their values range from -0.752941 to 1.25098 (pre-expansion).
|
|
||||||
/// </summary>
|
|
||||||
R10G10B10_XRUNormPack32,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 64-bit packed unsigned normalized format that has a 10-bit A component in bits 30..39, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are gamma encoded and their values range from -0.5271 to 1.66894. The alpha component is clamped to either 0.0 or 1.0 on sampling, rendering, and writing operations.
|
|
||||||
/// </summary>
|
|
||||||
A10R10G10B10_XRSRGBPack32,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, 64-bit packed unsigned normalized format that has a 10-bit A component in bits 30..39, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are linearly encoded and their values range from -0.752941 to 1.25098 (pre-expansion). The alpha component is clamped to either 0.0 or 1.0 on sampling, rendering, and writing operations.
|
|
||||||
/// </summary>
|
|
||||||
A10R10G10B10_XRUNormPack32,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 16-bit unsigned normalized format that has a single 16-bit depth component.
|
|
||||||
/// </summary>
|
|
||||||
D16_UNorm = 90,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 32-bit format that has 24 unsigned normalized bits in the depth component and, optionally: 8 bits that are unused.
|
|
||||||
/// </summary>
|
|
||||||
D24_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 32-bit packed format that has 8 unsigned integer bits in the stencil component, and 24 unsigned normalized bits in the depth component.
|
|
||||||
/// </summary>
|
|
||||||
D24_UNorm_S8_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 32-bit signed floating-point format that has 32-bits in the depth component.
|
|
||||||
/// </summary>
|
|
||||||
D32_SFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component format that has 32 signed float bits in the depth component and 8 unsigned integer bits in the stencil component. There are optionally: 24-bits that are unused.
|
|
||||||
/// </summary>
|
|
||||||
D32_SFloat_S8_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, 8-bit unsigned integer format that has 8-bits in the stencil component.
|
|
||||||
/// </summary>
|
|
||||||
S8_UInt,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, block-compressed format (also known as BC1). Each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data with sRGB nonlinear encoding. This format has a 1 bit alpha channel.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_DXT1_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, block-compressed format (also known as BC1). Each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data. This format has a 1 bit alpha channel.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_DXT1_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, block-compressed format (also known as BC2) where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values with sRGB nonlinear encoding.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_DXT3_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, block-compressed format (also known as BC2) where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_DXT3_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, block-compressed format (also known as BC3) where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values with sRGB nonlinear encoding.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_DXT5_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, block-compressed format (also known as BC3) where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_DXT5_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, block-compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized red texel data.
|
|
||||||
/// </summary>
|
|
||||||
R_BC4_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, block-compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of signed normalized red texel data.
|
|
||||||
/// </summary>
|
|
||||||
R_BC4_SNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RG texel data with the first 64 bits encoding red values followed by 64 bits encoding green values.
|
|
||||||
/// </summary>
|
|
||||||
RG_BC5_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of signed normalized RG texel data with the first 64 bits encoding red values followed by 64 bits encoding green values.
|
|
||||||
/// </summary>
|
|
||||||
RG_BC5_SNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned floating-point RGB texel data.
|
|
||||||
/// </summary>
|
|
||||||
RGB_BC6H_UFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of signed floating-point RGB texel data.
|
|
||||||
/// </summary>
|
|
||||||
RGB_BC6H_SFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_BC7_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_BC7_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 8×4 rectangle of unsigned normalized RGB texel data with sRGB nonlinear encoding. This format has no alpha and is considered opaque.
|
|
||||||
/// </summary>
|
|
||||||
RGB_PVRTC_2Bpp_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 8×4 rectangle of unsigned normalized RGB texel data. This format has no alpha and is considered opaque.
|
|
||||||
/// </summary>
|
|
||||||
RGB_PVRTC_2Bpp_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data with sRGB nonlinear encoding. This format has no alpha and is considered opaque.
|
|
||||||
/// </summary>
|
|
||||||
RGB_PVRTC_4Bpp_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data. This format has no alpha and is considered opaque.
|
|
||||||
/// </summary>
|
|
||||||
RGB_PVRTC_4Bpp_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 8×4 rectangle of unsigned normalized RGBA texel data with the first 32 bits encoding alpha values followed by 32 bits encoding RGB values with sRGB nonlinear encoding applied.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_PVRTC_2Bpp_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 8×4 rectangle of unsigned normalized RGBA texel data with the first 32 bits encoding alpha values followed by 32 bits encoding RGB values.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_PVRTC_2Bpp_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 32 bits encoding alpha values followed by 32 bits encoding RGB values with sRGB nonlinear encoding applied.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_PVRTC_4Bpp_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 32 bits encoding alpha values followed by 32 bits encoding RGB values.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_PVRTC_4Bpp_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, ETC compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data. This format has no alpha and is considered opaque.
|
|
||||||
/// </summary>
|
|
||||||
RGB_ETC_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data with sRGB nonlinear encoding. This format has no alpha and is considered opaque.
|
|
||||||
/// </summary>
|
|
||||||
RGB_ETC2_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A three-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data. This format has no alpha and is considered opaque.
|
|
||||||
/// </summary>
|
|
||||||
RGB_ETC2_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data with sRGB nonlinear encoding, and provides 1 bit of alpha.
|
|
||||||
/// </summary>
|
|
||||||
RGB_A1_ETC2_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data, and provides 1 bit of alpha.
|
|
||||||
/// </summary>
|
|
||||||
RGB_A1_ETC2_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ETC2 compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values with sRGB nonlinear encoding applied.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ETC2_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ETC2 compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ETC2_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized red texel data.
|
|
||||||
/// </summary>
|
|
||||||
R_EAC_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A one-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of signed normalized red texel data.
|
|
||||||
/// </summary>
|
|
||||||
R_EAC_SNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, ETC2 compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RG texel data with the first 64 bits encoding red values followed by 64 bits encoding green values.
|
|
||||||
/// </summary>
|
|
||||||
RG_EAC_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, ETC2 compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of signed normalized RG texel data with the first 64 bits encoding red values followed by 64 bits encoding green values.
|
|
||||||
/// </summary>
|
|
||||||
RG_EAC_SNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC4X4_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC4X4_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 5×5 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC5X5_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 5×5 rectangle of unsigned normalized RGBA texel data.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC5X5_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 6×6 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC6X6_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 6×6 rectangle of unsigned normalized RGBA texel data.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC6X6_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes an 8×8 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC8X8_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes an 8×8 rectangle of unsigned normalized RGBA texel data.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC8X8_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 10×10 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC10X10_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 10×10 rectangle of unsigned normalized RGBA texel data.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC10X10_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 12×12 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC12X12_SRGB,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 12×12 rectangle of unsigned normalized RGBA texel data.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC12X12_UNorm,
|
|
||||||
/// <summary>
|
|
||||||
/// YUV 4:2:2 Video resource format.
|
|
||||||
/// </summary>
|
|
||||||
YUV2,
|
|
||||||
/// <summary>
|
|
||||||
/// GraphicsFormat.YUV2.
|
|
||||||
/// </summary>
|
|
||||||
VideoAuto = 144,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of float RGBA texel data.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC4X4_UFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 5×5 rectangle of float RGBA texel data.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC5X5_UFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 6×6 rectangle of float RGBA texel data.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC6X6_UFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes an 8×8 rectangle of float RGBA texel data.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC8X8_UFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 10×10 rectangle of float RGBA texel data.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC10X10_UFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 12×12 rectangle of float RGBA texel data.
|
|
||||||
/// </summary>
|
|
||||||
RGBA_ASTC12X12_UFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A two-component, 24-bit format that has 16 unsigned normalized bits in the depth component and 8 unsigned integer bits in the stencil component. Most platforms do not support this format.
|
|
||||||
/// </summary>
|
|
||||||
D16_UNorm_S8_UInt,
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class GraphicsFormatExtension
|
|
||||||
{
|
|
||||||
public static TextureFormat ToTextureFormat(this GraphicsFormat graphicsFormat)
|
|
||||||
{
|
|
||||||
switch (graphicsFormat)
|
|
||||||
{
|
|
||||||
case GraphicsFormat.R8_SRGB:
|
|
||||||
case GraphicsFormat.R8_UInt:
|
|
||||||
case GraphicsFormat.R8_UNorm:
|
|
||||||
return TextureFormat.R8;
|
|
||||||
case GraphicsFormat.R8G8_SRGB:
|
|
||||||
case GraphicsFormat.R8G8_UInt:
|
|
||||||
case GraphicsFormat.R8G8_UNorm:
|
|
||||||
return TextureFormat.RG16;
|
|
||||||
case GraphicsFormat.R8G8B8_SRGB:
|
|
||||||
case GraphicsFormat.R8G8B8_UInt:
|
|
||||||
case GraphicsFormat.R8G8B8_UNorm:
|
|
||||||
return TextureFormat.RGB24;
|
|
||||||
case GraphicsFormat.R8G8B8A8_SRGB:
|
|
||||||
case GraphicsFormat.R8G8B8A8_UInt:
|
|
||||||
case GraphicsFormat.R8G8B8A8_UNorm:
|
|
||||||
return TextureFormat.RGBA32;
|
|
||||||
case GraphicsFormat.R16_UInt:
|
|
||||||
case GraphicsFormat.R16_UNorm:
|
|
||||||
return TextureFormat.R16;
|
|
||||||
case GraphicsFormat.R16G16_UInt:
|
|
||||||
case GraphicsFormat.R16G16_UNorm:
|
|
||||||
return TextureFormat.RG32;
|
|
||||||
case GraphicsFormat.R16G16B16_UInt:
|
|
||||||
case GraphicsFormat.R16G16B16_UNorm:
|
|
||||||
return TextureFormat.RGB48;
|
|
||||||
case GraphicsFormat.R16G16B16A16_UInt:
|
|
||||||
case GraphicsFormat.R16G16B16A16_UNorm:
|
|
||||||
return TextureFormat.RGBA64;
|
|
||||||
case GraphicsFormat.R16_SFloat:
|
|
||||||
return TextureFormat.RHalf;
|
|
||||||
case GraphicsFormat.R16G16_SFloat:
|
|
||||||
return TextureFormat.RGHalf;
|
|
||||||
case GraphicsFormat.R16G16B16_SFloat: //?
|
|
||||||
case GraphicsFormat.R16G16B16A16_SFloat:
|
|
||||||
return TextureFormat.RGBAHalf;
|
|
||||||
case GraphicsFormat.R32_SFloat:
|
|
||||||
return TextureFormat.RFloat;
|
|
||||||
case GraphicsFormat.R32G32_SFloat:
|
|
||||||
return TextureFormat.RGFloat;
|
|
||||||
case GraphicsFormat.R32G32B32_SFloat: //?
|
|
||||||
case GraphicsFormat.R32G32B32A32_SFloat:
|
|
||||||
return TextureFormat.RGBAFloat;
|
|
||||||
case GraphicsFormat.B8G8R8A8_SRGB:
|
|
||||||
case GraphicsFormat.B8G8R8A8_UInt:
|
|
||||||
case GraphicsFormat.B8G8R8A8_UNorm:
|
|
||||||
return TextureFormat.BGRA32;
|
|
||||||
case GraphicsFormat.E5B9G9R9_UFloatPack32:
|
|
||||||
return TextureFormat.RGB9e5Float;
|
|
||||||
case GraphicsFormat.RGBA_DXT1_SRGB:
|
|
||||||
case GraphicsFormat.RGBA_DXT1_UNorm:
|
|
||||||
return TextureFormat.DXT1;
|
|
||||||
case GraphicsFormat.RGBA_DXT3_SRGB:
|
|
||||||
case GraphicsFormat.RGBA_DXT3_UNorm:
|
|
||||||
return TextureFormat.DXT3;
|
|
||||||
case GraphicsFormat.RGBA_DXT5_SRGB:
|
|
||||||
case GraphicsFormat.RGBA_DXT5_UNorm:
|
|
||||||
return TextureFormat.DXT5;
|
|
||||||
case GraphicsFormat.R_BC4_UNorm:
|
|
||||||
return TextureFormat.BC4;
|
|
||||||
case GraphicsFormat.RG_BC5_UNorm:
|
|
||||||
return TextureFormat.BC5;
|
|
||||||
case GraphicsFormat.RGB_BC6H_SFloat:
|
|
||||||
case GraphicsFormat.RGB_BC6H_UFloat:
|
|
||||||
return TextureFormat.BC6H;
|
|
||||||
case GraphicsFormat.RGBA_BC7_SRGB:
|
|
||||||
case GraphicsFormat.RGBA_BC7_UNorm:
|
|
||||||
return TextureFormat.BC7;
|
|
||||||
case GraphicsFormat.RGB_PVRTC_2Bpp_SRGB:
|
|
||||||
case GraphicsFormat.RGB_PVRTC_2Bpp_UNorm:
|
|
||||||
case GraphicsFormat.RGBA_PVRTC_2Bpp_SRGB:
|
|
||||||
case GraphicsFormat.RGBA_PVRTC_2Bpp_UNorm:
|
|
||||||
return TextureFormat.PVRTC_RGBA2;
|
|
||||||
case GraphicsFormat.RGB_PVRTC_4Bpp_SRGB:
|
|
||||||
case GraphicsFormat.RGB_PVRTC_4Bpp_UNorm:
|
|
||||||
case GraphicsFormat.RGBA_PVRTC_4Bpp_SRGB:
|
|
||||||
case GraphicsFormat.RGBA_PVRTC_4Bpp_UNorm:
|
|
||||||
return TextureFormat.PVRTC_RGBA4;
|
|
||||||
case GraphicsFormat.RGB_ETC_UNorm:
|
|
||||||
return TextureFormat.ETC_RGB4;
|
|
||||||
case GraphicsFormat.RGB_ETC2_SRGB:
|
|
||||||
case GraphicsFormat.RGB_ETC2_UNorm:
|
|
||||||
return TextureFormat.ETC2_RGB;
|
|
||||||
case GraphicsFormat.RGB_A1_ETC2_SRGB:
|
|
||||||
case GraphicsFormat.RGB_A1_ETC2_UNorm:
|
|
||||||
return TextureFormat.ETC2_RGBA1;
|
|
||||||
case GraphicsFormat.RGBA_ETC2_SRGB:
|
|
||||||
case GraphicsFormat.RGBA_ETC2_UNorm:
|
|
||||||
return TextureFormat.ETC2_RGBA8;
|
|
||||||
case GraphicsFormat.R_EAC_UNorm:
|
|
||||||
return TextureFormat.EAC_R;
|
|
||||||
case GraphicsFormat.R_EAC_SNorm:
|
|
||||||
return TextureFormat.EAC_R_SIGNED;
|
|
||||||
case GraphicsFormat.RG_EAC_UNorm:
|
|
||||||
return TextureFormat.EAC_RG;
|
|
||||||
case GraphicsFormat.RG_EAC_SNorm:
|
|
||||||
return TextureFormat.EAC_RG_SIGNED;
|
|
||||||
case GraphicsFormat.RGBA_ASTC4X4_SRGB:
|
|
||||||
case GraphicsFormat.RGBA_ASTC4X4_UNorm:
|
|
||||||
return TextureFormat.ASTC_RGBA_4x4;
|
|
||||||
case GraphicsFormat.RGBA_ASTC5X5_SRGB:
|
|
||||||
case GraphicsFormat.RGBA_ASTC5X5_UNorm:
|
|
||||||
return TextureFormat.ASTC_RGBA_5x5;
|
|
||||||
case GraphicsFormat.RGBA_ASTC6X6_SRGB:
|
|
||||||
case GraphicsFormat.RGBA_ASTC6X6_UNorm:
|
|
||||||
return TextureFormat.ASTC_RGBA_6x6;
|
|
||||||
case GraphicsFormat.RGBA_ASTC8X8_SRGB:
|
|
||||||
case GraphicsFormat.RGBA_ASTC8X8_UNorm:
|
|
||||||
return TextureFormat.ASTC_RGBA_8x8;
|
|
||||||
case GraphicsFormat.RGBA_ASTC10X10_SRGB:
|
|
||||||
case GraphicsFormat.RGBA_ASTC10X10_UNorm:
|
|
||||||
return TextureFormat.ASTC_RGBA_10x10;
|
|
||||||
case GraphicsFormat.RGBA_ASTC12X12_SRGB:
|
|
||||||
case GraphicsFormat.RGBA_ASTC12X12_UNorm:
|
|
||||||
return TextureFormat.ASTC_RGBA_12x12;
|
|
||||||
case GraphicsFormat.YUV2:
|
|
||||||
case GraphicsFormat.VideoAuto:
|
|
||||||
return TextureFormat.YUY2;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -34,7 +34,7 @@ namespace AssetStudio
|
|||||||
m_TexEnvs[i] = new KeyValuePair<string, UnityTexEnv>(reader.ReadAlignedString(), new UnityTexEnv(reader));
|
m_TexEnvs[i] = new KeyValuePair<string, UnityTexEnv>(reader.ReadAlignedString(), new UnityTexEnv(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 2021) //2021.1 and up
|
if (version[0] >= 2021) //2021.1 and up
|
||||||
{
|
{
|
||||||
int m_IntsSize = reader.ReadInt32();
|
int m_IntsSize = reader.ReadInt32();
|
||||||
m_Ints = new KeyValuePair<string, int>[m_IntsSize];
|
m_Ints = new KeyValuePair<string, int>[m_IntsSize];
|
||||||
@@ -69,39 +69,39 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
m_Shader = new PPtr<Shader>(reader);
|
m_Shader = new PPtr<Shader>(reader);
|
||||||
|
|
||||||
if (version == 4 && version.Minor >= 1) //4.x
|
if (version[0] == 4 && version[1] >= 1) //4.x
|
||||||
{
|
{
|
||||||
var m_ShaderKeywords = reader.ReadStringArray();
|
var m_ShaderKeywords = reader.ReadStringArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (2021, 3)) //2021.3 and up
|
if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 3)) //2021.3 and up
|
||||||
{
|
{
|
||||||
var m_ValidKeywords = reader.ReadStringArray();
|
var m_ValidKeywords = reader.ReadStringArray();
|
||||||
var m_InvalidKeywords = reader.ReadStringArray();
|
var m_InvalidKeywords = reader.ReadStringArray();
|
||||||
}
|
}
|
||||||
else if (version >= 5) //5.0 ~ 2021.2
|
else if (version[0] >= 5) //5.0 ~ 2021.2
|
||||||
{
|
{
|
||||||
var m_ShaderKeywords = reader.ReadAlignedString();
|
var m_ShaderKeywords = reader.ReadAlignedString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 5) //5.0 and up
|
if (version[0] >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
var m_LightmapFlags = reader.ReadUInt32();
|
var m_LightmapFlags = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (5, 6)) //5.6 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
|
||||||
{
|
{
|
||||||
var m_EnableInstancingVariants = reader.ReadBoolean();
|
var m_EnableInstancingVariants = reader.ReadBoolean();
|
||||||
//var m_DoubleSidedGI = a_Stream.ReadBoolean(); //2017 and up
|
//var m_DoubleSidedGI = a_Stream.ReadBoolean(); //2017 and up
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
var m_CustomRenderQueue = reader.ReadInt32();
|
var m_CustomRenderQueue = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (5, 1)) //5.1 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 1)) //5.1 and up
|
||||||
{
|
{
|
||||||
var stringTagMapSize = reader.ReadInt32();
|
var stringTagMapSize = reader.ReadInt32();
|
||||||
for (int i = 0; i < stringTagMapSize; i++)
|
for (int i = 0; i < stringTagMapSize; i++)
|
||||||
@@ -111,7 +111,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (5, 6)) //5.6 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
|
||||||
{
|
{
|
||||||
var disabledShaderPasses = reader.ReadStringArray();
|
var disabledShaderPasses = reader.ReadStringArray();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
m_Vertices = new PackedFloatVector(reader);
|
m_Vertices = new PackedFloatVector(reader);
|
||||||
m_UV = new PackedFloatVector(reader);
|
m_UV = new PackedFloatVector(reader);
|
||||||
if (version < 5)
|
if (version[0] < 5)
|
||||||
{
|
{
|
||||||
m_BindPoses = new PackedFloatVector(reader);
|
m_BindPoses = new PackedFloatVector(reader);
|
||||||
}
|
}
|
||||||
@@ -49,15 +49,15 @@ namespace AssetStudio
|
|||||||
m_Weights = new PackedIntVector(reader);
|
m_Weights = new PackedIntVector(reader);
|
||||||
m_NormalSigns = new PackedIntVector(reader);
|
m_NormalSigns = new PackedIntVector(reader);
|
||||||
m_TangentSigns = new PackedIntVector(reader);
|
m_TangentSigns = new PackedIntVector(reader);
|
||||||
if (version >= 5)
|
if (version[0] >= 5)
|
||||||
{
|
{
|
||||||
m_FloatColors = new PackedFloatVector(reader);
|
m_FloatColors = new PackedFloatVector(reader);
|
||||||
}
|
}
|
||||||
m_BoneIndices = new PackedIntVector(reader);
|
m_BoneIndices = new PackedIntVector(reader);
|
||||||
m_Triangles = new PackedIntVector(reader);
|
m_Triangles = new PackedIntVector(reader);
|
||||||
if (version >= (3, 5)) //3.5 and up
|
if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5 and up
|
||||||
{
|
{
|
||||||
if (version < 5)
|
if (version[0] < 5)
|
||||||
{
|
{
|
||||||
m_Colors = new PackedIntVector(reader);
|
m_Colors = new PackedIntVector(reader);
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ namespace AssetStudio
|
|||||||
channelMask = reader.ReadUInt32();
|
channelMask = reader.ReadUInt32();
|
||||||
offset = reader.ReadUInt32();
|
offset = reader.ReadUInt32();
|
||||||
|
|
||||||
if (version < 4) //4.0 down
|
if (version[0] < 4) //4.0 down
|
||||||
{
|
{
|
||||||
stride = reader.ReadUInt32();
|
stride = reader.ReadUInt32();
|
||||||
align = reader.ReadUInt32();
|
align = reader.ReadUInt32();
|
||||||
@@ -131,14 +131,14 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
if (version < 2018)//2018 down
|
if (version[0] < 2018)//2018 down
|
||||||
{
|
{
|
||||||
m_CurrentChannels = reader.ReadUInt32();
|
m_CurrentChannels = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_VertexCount = reader.ReadUInt32();
|
m_VertexCount = reader.ReadUInt32();
|
||||||
|
|
||||||
if (version >= 4) //4.0 and up
|
if (version[0] >= 4) //4.0 and up
|
||||||
{
|
{
|
||||||
var m_ChannelsSize = reader.ReadInt32();
|
var m_ChannelsSize = reader.ReadInt32();
|
||||||
m_Channels = new ChannelInfo[m_ChannelsSize];
|
m_Channels = new ChannelInfo[m_ChannelsSize];
|
||||||
@@ -148,9 +148,9 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version < 5) //5.0 down
|
if (version[0] < 5) //5.0 down
|
||||||
{
|
{
|
||||||
if (version < 4)
|
if (version[0] < 4)
|
||||||
{
|
{
|
||||||
m_Streams = new StreamInfo[4];
|
m_Streams = new StreamInfo[4];
|
||||||
}
|
}
|
||||||
@@ -164,7 +164,7 @@ namespace AssetStudio
|
|||||||
m_Streams[i] = new StreamInfo(reader);
|
m_Streams[i] = new StreamInfo(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version < 4) //4.0 down
|
if (version[0] < 4) //4.0 down
|
||||||
{
|
{
|
||||||
GetChannels(version);
|
GetChannels(version);
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ namespace AssetStudio
|
|||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GetStreams(UnityVersion version)
|
private void GetStreams(int[] version)
|
||||||
{
|
{
|
||||||
var streamCount = m_Channels.Max(x => x.stream) + 1;
|
var streamCount = m_Channels.Max(x => x.stream) + 1;
|
||||||
m_Streams = new StreamInfo[streamCount];
|
m_Streams = new StreamInfo[streamCount];
|
||||||
@@ -213,7 +213,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GetChannels(UnityVersion version)
|
private void GetChannels(int[] version)
|
||||||
{
|
{
|
||||||
m_Channels = new ChannelInfo[6];
|
m_Channels = new ChannelInfo[6];
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
@@ -305,20 +305,20 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
if (version < (4, 3)) //4.3 down
|
if (version[0] == 4 && version[1] < 3) //4.3 down
|
||||||
{
|
{
|
||||||
var name = reader.ReadAlignedString();
|
var name = reader.ReadAlignedString();
|
||||||
}
|
}
|
||||||
firstVertex = reader.ReadUInt32();
|
firstVertex = reader.ReadUInt32();
|
||||||
vertexCount = reader.ReadUInt32();
|
vertexCount = reader.ReadUInt32();
|
||||||
if (version < (4, 3)) //4.3 down
|
if (version[0] == 4 && version[1] < 3) //4.3 down
|
||||||
{
|
{
|
||||||
var aabbMinDelta = reader.ReadVector3();
|
var aabbMinDelta = reader.ReadVector3();
|
||||||
var aabbMaxDelta = reader.ReadVector3();
|
var aabbMaxDelta = reader.ReadVector3();
|
||||||
}
|
}
|
||||||
hasNormals = reader.ReadBoolean();
|
hasNormals = reader.ReadBoolean();
|
||||||
hasTangents = reader.ReadBoolean();
|
hasTangents = reader.ReadBoolean();
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
@@ -352,7 +352,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
int numVerts = reader.ReadInt32();
|
int numVerts = reader.ReadInt32();
|
||||||
vertices = new BlendShapeVertex[numVerts];
|
vertices = new BlendShapeVertex[numVerts];
|
||||||
@@ -425,17 +425,17 @@ namespace AssetStudio
|
|||||||
indexCount = reader.ReadUInt32();
|
indexCount = reader.ReadUInt32();
|
||||||
topology = (GfxPrimitiveType)reader.ReadInt32();
|
topology = (GfxPrimitiveType)reader.ReadInt32();
|
||||||
|
|
||||||
if (version < 4) //4.0 down
|
if (version[0] < 4) //4.0 down
|
||||||
{
|
{
|
||||||
triangleCount = reader.ReadUInt32();
|
triangleCount = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (2017, 3)) //2017.3 and up
|
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
|
||||||
{
|
{
|
||||||
baseVertex = reader.ReadUInt32();
|
baseVertex = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 3) //3.0 and up
|
if (version[0] >= 3) //3.0 and up
|
||||||
{
|
{
|
||||||
firstVertex = reader.ReadUInt32();
|
firstVertex = reader.ReadUInt32();
|
||||||
vertexCount = reader.ReadUInt32();
|
vertexCount = reader.ReadUInt32();
|
||||||
@@ -474,12 +474,12 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public Mesh(ObjectReader reader) : base(reader)
|
public Mesh(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
if (version < (3, 5)) //3.5 down
|
if (version[0] < 3 || (version[0] == 3 && version[1] < 5)) //3.5 down
|
||||||
{
|
{
|
||||||
m_Use16BitIndices = reader.ReadInt32() > 0;
|
m_Use16BitIndices = reader.ReadInt32() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version <= (2, 5)) //2.5 and down
|
if (version[0] == 2 && version[1] <= 5) //2.5 and down
|
||||||
{
|
{
|
||||||
int m_IndexBuffer_size = reader.ReadInt32();
|
int m_IndexBuffer_size = reader.ReadInt32();
|
||||||
|
|
||||||
@@ -505,21 +505,21 @@ namespace AssetStudio
|
|||||||
m_SubMeshes[i] = new SubMesh(reader);
|
m_SubMeshes[i] = new SubMesh(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (4, 1)) //4.1 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
|
||||||
{
|
{
|
||||||
m_Shapes = new BlendShapeData(reader);
|
m_Shapes = new BlendShapeData(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
m_BindPose = reader.ReadMatrixArray();
|
m_BindPose = reader.ReadMatrixArray();
|
||||||
m_BoneNameHashes = reader.ReadUInt32Array();
|
m_BoneNameHashes = reader.ReadUInt32Array();
|
||||||
var m_RootBoneNameHash = reader.ReadUInt32();
|
var m_RootBoneNameHash = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (2, 6)) //2.6.0 and up
|
if (version[0] > 2 || (version[0] == 2 && version[1] >= 6)) //2.6.0 and up
|
||||||
{
|
{
|
||||||
if (version >= 2019) //2019 and up
|
if (version[0] >= 2019) //2019 and up
|
||||||
{
|
{
|
||||||
var m_BonesAABBSize = reader.ReadInt32();
|
var m_BonesAABBSize = reader.ReadInt32();
|
||||||
var m_BonesAABB = new MinMaxAABB[m_BonesAABBSize];
|
var m_BonesAABB = new MinMaxAABB[m_BonesAABBSize];
|
||||||
@@ -532,9 +532,9 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
|
|
||||||
var m_MeshCompression = reader.ReadByte();
|
var m_MeshCompression = reader.ReadByte();
|
||||||
if (version >= 4)
|
if (version[0] >= 4)
|
||||||
{
|
{
|
||||||
if (version < 5)
|
if (version[0] < 5)
|
||||||
{
|
{
|
||||||
var m_StreamCompression = reader.ReadByte();
|
var m_StreamCompression = reader.ReadByte();
|
||||||
}
|
}
|
||||||
@@ -545,9 +545,9 @@ namespace AssetStudio
|
|||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
|
||||||
//Unity fixed it in 2017.3.1p1 and later versions
|
//Unity fixed it in 2017.3.1p1 and later versions
|
||||||
if (version >= (2017, 4) //2017.4
|
if ((version[0] > 2017 || (version[0] == 2017 && version[1] >= 4)) || //2017.4
|
||||||
|| version == (2017, 3, 1) && buildType.IsPatch //fixed after 2017.3.1px
|
((version[0] == 2017 && version[1] == 3 && version[2] == 1) && buildType.IsPatch) || //fixed after 2017.3.1px
|
||||||
|| version == (2017, 3) && m_MeshCompression == 0)//2017.3.xfx with no compression
|
((version[0] == 2017 && version[1] == 3) && m_MeshCompression == 0))//2017.3.xfx with no compression
|
||||||
{
|
{
|
||||||
var m_IndexFormat = reader.ReadInt32();
|
var m_IndexFormat = reader.ReadInt32();
|
||||||
m_Use16BitIndices = m_IndexFormat == 0;
|
m_Use16BitIndices = m_IndexFormat == 0;
|
||||||
@@ -569,7 +569,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version < (3, 5)) //3.4.2 and earlier
|
if (version[0] < 3 || (version[0] == 3 && version[1] < 5)) //3.4.2 and earlier
|
||||||
{
|
{
|
||||||
m_VertexCount = reader.ReadInt32();
|
m_VertexCount = reader.ReadInt32();
|
||||||
m_Vertices = reader.ReadSingleArray(m_VertexCount * 3); //Vector3
|
m_Vertices = reader.ReadSingleArray(m_VertexCount * 3); //Vector3
|
||||||
@@ -586,7 +586,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
m_UV1 = reader.ReadSingleArray(reader.ReadInt32() * 2); //Vector2
|
m_UV1 = reader.ReadSingleArray(reader.ReadInt32() * 2); //Vector2
|
||||||
|
|
||||||
if (version <= (2, 5)) //2.5 and down
|
if (version[0] == 2 && version[1] <= 5) //2.5 and down
|
||||||
{
|
{
|
||||||
int m_TangentSpace_size = reader.ReadInt32();
|
int m_TangentSpace_size = reader.ReadInt32();
|
||||||
m_Normals = new float[m_TangentSpace_size * 3];
|
m_Normals = new float[m_TangentSpace_size * 3];
|
||||||
@@ -611,7 +611,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (version < (2018, 2)) //2018.2 down
|
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 2)) //2018.2 down
|
||||||
{
|
{
|
||||||
m_Skin = new BoneWeights4[reader.ReadInt32()];
|
m_Skin = new BoneWeights4[reader.ReadInt32()];
|
||||||
for (int s = 0; s < m_Skin.Length; s++)
|
for (int s = 0; s < m_Skin.Length; s++)
|
||||||
@@ -620,7 +620,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version <= (4, 2)) //4.2 and down
|
if (version[0] == 3 || (version[0] == 4 && version[1] <= 2)) //4.2 and down
|
||||||
{
|
{
|
||||||
m_BindPose = reader.ReadMatrixArray();
|
m_BindPose = reader.ReadMatrixArray();
|
||||||
}
|
}
|
||||||
@@ -628,14 +628,14 @@ namespace AssetStudio
|
|||||||
m_VertexData = new VertexData(reader);
|
m_VertexData = new VertexData(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (2, 6)) //2.6.0 and later
|
if (version[0] > 2 || (version[0] == 2 && version[1] >= 6)) //2.6.0 and later
|
||||||
{
|
{
|
||||||
m_CompressedMesh = new CompressedMesh(reader);
|
m_CompressedMesh = new CompressedMesh(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.Position += 24; //AABB m_LocalAABB
|
reader.Position += 24; //AABB m_LocalAABB
|
||||||
|
|
||||||
if (version <= (3, 4)) //3.4.2 and earlier
|
if (version[0] < 3 || (version[0] == 3 && version[1] <= 4)) //3.4.2 and earlier
|
||||||
{
|
{
|
||||||
int m_Colors_size = reader.ReadInt32();
|
int m_Colors_size = reader.ReadInt32();
|
||||||
m_Colors = new float[m_Colors_size * 4];
|
m_Colors = new float[m_Colors_size * 4];
|
||||||
@@ -651,12 +651,12 @@ namespace AssetStudio
|
|||||||
|
|
||||||
int m_MeshUsageFlags = reader.ReadInt32();
|
int m_MeshUsageFlags = reader.ReadInt32();
|
||||||
|
|
||||||
if (version >= (2022, 1)) //2022.1 and up
|
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 1)) //2022.1 and up
|
||||||
{
|
{
|
||||||
int m_CookingOptions = reader.ReadInt32();
|
int m_CookingOptions = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 5) //5.0 and up
|
if (version[0] >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
var m_BakedConvexCollisionMesh = reader.ReadUInt8Array();
|
var m_BakedConvexCollisionMesh = reader.ReadUInt8Array();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
@@ -664,14 +664,14 @@ namespace AssetStudio
|
|||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (2018, 2)) //2018.2 and up
|
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
|
||||||
{
|
{
|
||||||
var m_MeshMetrics = new float[2];
|
var m_MeshMetrics = new float[2];
|
||||||
m_MeshMetrics[0] = reader.ReadSingle();
|
m_MeshMetrics[0] = reader.ReadSingle();
|
||||||
m_MeshMetrics[1] = reader.ReadSingle();
|
m_MeshMetrics[1] = reader.ReadSingle();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (2018, 3)) //2018.3 and up
|
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 3)) //2018.3 and up
|
||||||
{
|
{
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
m_StreamData = new StreamingInfo(reader);
|
m_StreamData = new StreamingInfo(reader);
|
||||||
@@ -690,12 +690,12 @@ namespace AssetStudio
|
|||||||
m_VertexData.m_DataSize = resourceReader.GetData();
|
m_VertexData.m_DataSize = resourceReader.GetData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (version >= (3, 5)) //3.5 and up
|
if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5 and up
|
||||||
{
|
{
|
||||||
ReadVertexData();
|
ReadVertexData();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (2, 6)) //2.6.0 and later
|
if (version[0] > 2 || (version[0] == 2 && version[1] >= 6)) //2.6.0 and later
|
||||||
{
|
{
|
||||||
DecompressCompressedMesh();
|
DecompressCompressedMesh();
|
||||||
}
|
}
|
||||||
@@ -716,7 +716,7 @@ namespace AssetStudio
|
|||||||
var channelMask = new BitArray(new[] { (int)m_Stream.channelMask });
|
var channelMask = new BitArray(new[] { (int)m_Stream.channelMask });
|
||||||
if (channelMask.Get(chn))
|
if (channelMask.Get(chn))
|
||||||
{
|
{
|
||||||
if (version < 2018 && chn == 2 && m_Channel.format == 2) //kShaderChannelColor && kChannelFormatColor
|
if (version[0] < 2018 && chn == 2 && m_Channel.format == 2) //kShaderChannelColor && kChannelFormatColor
|
||||||
{
|
{
|
||||||
m_Channel.dimension = 4;
|
m_Channel.dimension = 4;
|
||||||
}
|
}
|
||||||
@@ -752,7 +752,7 @@ namespace AssetStudio
|
|||||||
else
|
else
|
||||||
componentsFloatArray = MeshHelper.BytesToFloatArray(componentBytes, vertexFormat);
|
componentsFloatArray = MeshHelper.BytesToFloatArray(componentBytes, vertexFormat);
|
||||||
|
|
||||||
if (version >= 2018)
|
if (version[0] >= 2018)
|
||||||
{
|
{
|
||||||
switch (chn)
|
switch (chn)
|
||||||
{
|
{
|
||||||
@@ -841,7 +841,7 @@ namespace AssetStudio
|
|||||||
m_UV1 = componentsFloatArray;
|
m_UV1 = componentsFloatArray;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if (version >= 5) //kShaderChannelTexCoord2
|
if (version[0] >= 5) //kShaderChannelTexCoord2
|
||||||
{
|
{
|
||||||
m_UV2 = componentsFloatArray;
|
m_UV2 = componentsFloatArray;
|
||||||
}
|
}
|
||||||
@@ -906,7 +906,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//BindPose
|
//BindPose
|
||||||
if (version < 5)
|
if (version[0] < 5)
|
||||||
{
|
{
|
||||||
if (m_CompressedMesh.m_BindPoses.m_NumItems > 0)
|
if (m_CompressedMesh.m_BindPoses.m_NumItems > 0)
|
||||||
{
|
{
|
||||||
@@ -983,7 +983,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//FloatColor
|
//FloatColor
|
||||||
if (version >= 5)
|
if (version[0] >= 5)
|
||||||
{
|
{
|
||||||
if (m_CompressedMesh.m_FloatColors.m_NumItems > 0)
|
if (m_CompressedMesh.m_FloatColors.m_NumItems > 0)
|
||||||
{
|
{
|
||||||
@@ -1074,7 +1074,7 @@ namespace AssetStudio
|
|||||||
m_Indices.Add(m_IndexBuffer[firstIndex + i + 2]);
|
m_Indices.Add(m_IndexBuffer[firstIndex + i + 2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (version < 4 || topology == GfxPrimitiveType.TriangleStrip)
|
else if (version[0] < 4 || topology == GfxPrimitiveType.TriangleStrip)
|
||||||
{
|
{
|
||||||
// de-stripify :
|
// de-stripify :
|
||||||
uint triIndex = 0;
|
uint triIndex = 0;
|
||||||
@@ -1238,9 +1238,9 @@ namespace AssetStudio
|
|||||||
SInt32
|
SInt32
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VertexFormat ToVertexFormat(int format, UnityVersion version)
|
public static VertexFormat ToVertexFormat(int format, int[] version)
|
||||||
{
|
{
|
||||||
if (version < 2017)
|
if (version[0] < 2017)
|
||||||
{
|
{
|
||||||
switch ((VertexChannelFormat)format)
|
switch ((VertexChannelFormat)format)
|
||||||
{
|
{
|
||||||
@@ -1258,7 +1258,7 @@ namespace AssetStudio
|
|||||||
throw new ArgumentOutOfRangeException(nameof(format), format, null);
|
throw new ArgumentOutOfRangeException(nameof(format), format, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (version < 2019)
|
else if (version[0] < 2019)
|
||||||
{
|
{
|
||||||
switch ((VertexFormat2017)format)
|
switch ((VertexFormat2017)format)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public MonoScript(ObjectReader reader) : base(reader)
|
public MonoScript(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
if (version >= (3, 4)) //3.4 and up
|
if (version[0] > 3 || (version[0] == 3 && version[1] >= 4)) //3.4 and up
|
||||||
{
|
{
|
||||||
var m_ExecutionOrder = reader.ReadInt32();
|
var m_ExecutionOrder = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
if (version < 5) //5.0 down
|
if (version[0] < 5) //5.0 down
|
||||||
{
|
{
|
||||||
var m_PropertiesHash = reader.ReadUInt32();
|
var m_PropertiesHash = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
@@ -25,17 +25,17 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
var m_PropertiesHash = reader.ReadBytes(16);
|
var m_PropertiesHash = reader.ReadBytes(16);
|
||||||
}
|
}
|
||||||
if (version < 3) //3.0 down
|
if (version[0] < 3) //3.0 down
|
||||||
{
|
{
|
||||||
var m_PathName = reader.ReadAlignedString();
|
var m_PathName = reader.ReadAlignedString();
|
||||||
}
|
}
|
||||||
m_ClassName = reader.ReadAlignedString();
|
m_ClassName = reader.ReadAlignedString();
|
||||||
if (version >= 3) //3.0 and up
|
if (version[0] >= 3) //3.0 and up
|
||||||
{
|
{
|
||||||
m_Namespace = reader.ReadAlignedString();
|
m_Namespace = reader.ReadAlignedString();
|
||||||
}
|
}
|
||||||
m_AssemblyName = reader.ReadAlignedString();
|
m_AssemblyName = reader.ReadAlignedString();
|
||||||
if (version < (2018, 2)) //2018.2 down
|
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 2)) //2018.2 down
|
||||||
{
|
{
|
||||||
var m_IsEditorScript = reader.ReadBoolean();
|
var m_IsEditorScript = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public string m_Name;
|
public string m_Name;
|
||||||
|
|
||||||
protected NamedObject() { }
|
|
||||||
|
|
||||||
protected NamedObject(ObjectReader reader) : base(reader)
|
protected NamedObject(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
m_Name = reader.ReadAlignedString();
|
m_Name = reader.ReadAlignedString();
|
||||||
|
|||||||
@@ -1,27 +1,19 @@
|
|||||||
using Newtonsoft.Json;
|
using System.Collections.Specialized;
|
||||||
using System.Collections.Specialized;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
public class Object
|
public class Object
|
||||||
{
|
{
|
||||||
[JsonIgnore]
|
|
||||||
public SerializedFile assetsFile;
|
public SerializedFile assetsFile;
|
||||||
[JsonIgnore]
|
|
||||||
public ObjectReader reader;
|
public ObjectReader reader;
|
||||||
public long m_PathID;
|
public long m_PathID;
|
||||||
[JsonIgnore]
|
public int[] version;
|
||||||
public UnityVersion version;
|
|
||||||
protected BuildType buildType;
|
protected BuildType buildType;
|
||||||
[JsonIgnore]
|
|
||||||
public BuildTarget platform;
|
public BuildTarget platform;
|
||||||
public ClassIDType type;
|
public ClassIDType type;
|
||||||
[JsonIgnore]
|
|
||||||
public SerializedType serializedType;
|
public SerializedType serializedType;
|
||||||
public uint byteSize;
|
public uint byteSize;
|
||||||
|
|
||||||
public Object() { }
|
|
||||||
|
|
||||||
public Object(ObjectReader reader)
|
public Object(ObjectReader reader)
|
||||||
{
|
{
|
||||||
this.reader = reader;
|
this.reader = reader;
|
||||||
@@ -59,24 +51,6 @@ namespace AssetStudio
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string DumpObject()
|
|
||||||
{
|
|
||||||
string str = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
str = JsonConvert.SerializeObject(this, new JsonSerializerSettings
|
|
||||||
{
|
|
||||||
Formatting = Formatting.Indented,
|
|
||||||
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
|
|
||||||
}).Replace(" ", " ");
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
//ignore
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OrderedDictionary ToType()
|
public OrderedDictionary ToType()
|
||||||
{
|
{
|
||||||
if (serializedType?.m_Type != null)
|
if (serializedType?.m_Type != null)
|
||||||
|
|||||||
@@ -7,47 +7,45 @@ namespace AssetStudio
|
|||||||
public int m_FileID;
|
public int m_FileID;
|
||||||
public long m_PathID;
|
public long m_PathID;
|
||||||
|
|
||||||
private SerializedFile _assetsFile;
|
private SerializedFile assetsFile;
|
||||||
private int _index = -2; //-2 - Prepare, -1 - Missing
|
private int index = -2; //-2 - Prepare, -1 - Missing
|
||||||
|
|
||||||
public PPtr(ObjectReader reader)
|
public PPtr(ObjectReader reader)
|
||||||
{
|
{
|
||||||
m_FileID = reader.ReadInt32();
|
m_FileID = reader.ReadInt32();
|
||||||
m_PathID = reader.m_Version < SerializedFileFormatVersion.Unknown_14 ? reader.ReadInt32() : reader.ReadInt64();
|
m_PathID = reader.m_Version < SerializedFileFormatVersion.Unknown_14 ? reader.ReadInt32() : reader.ReadInt64();
|
||||||
_assetsFile = reader.assetsFile;
|
assetsFile = reader.assetsFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PPtr() { }
|
|
||||||
|
|
||||||
private bool TryGetAssetsFile(out SerializedFile result)
|
private bool TryGetAssetsFile(out SerializedFile result)
|
||||||
{
|
{
|
||||||
result = null;
|
result = null;
|
||||||
if (m_FileID == 0)
|
if (m_FileID == 0)
|
||||||
{
|
{
|
||||||
result = _assetsFile;
|
result = assetsFile;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_FileID > 0 && m_FileID - 1 < _assetsFile.m_Externals.Count)
|
if (m_FileID > 0 && m_FileID - 1 < assetsFile.m_Externals.Count)
|
||||||
{
|
{
|
||||||
var assetsManager = _assetsFile.assetsManager;
|
var assetsManager = assetsFile.assetsManager;
|
||||||
var assetsFileList = assetsManager.assetsFileList;
|
var assetsFileList = assetsManager.assetsFileList;
|
||||||
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
|
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
|
||||||
|
|
||||||
if (_index == -2)
|
if (index == -2)
|
||||||
{
|
{
|
||||||
var m_External = _assetsFile.m_Externals[m_FileID - 1];
|
var m_External = assetsFile.m_Externals[m_FileID - 1];
|
||||||
var name = m_External.fileName;
|
var name = m_External.fileName;
|
||||||
if (!assetsFileIndexCache.TryGetValue(name, out _index))
|
if (!assetsFileIndexCache.TryGetValue(name, out index))
|
||||||
{
|
{
|
||||||
_index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
|
index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||||
assetsFileIndexCache.Add(name, _index);
|
assetsFileIndexCache.Add(name, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_index >= 0)
|
if (index >= 0)
|
||||||
{
|
{
|
||||||
result = assetsFileList[_index];
|
result = assetsFileList[index];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,9 +53,8 @@ namespace AssetStudio
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGet(out T result, SerializedFile assetsFile = null)
|
public bool TryGet(out T result)
|
||||||
{
|
{
|
||||||
_assetsFile = _assetsFile ?? assetsFile;
|
|
||||||
if (TryGetAssetsFile(out var sourceFile))
|
if (TryGetAssetsFile(out var sourceFile))
|
||||||
{
|
{
|
||||||
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
|
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
|
||||||
@@ -74,9 +71,8 @@ namespace AssetStudio
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGet<T2>(out T2 result, SerializedFile assetsFile = null) where T2 : Object
|
public bool TryGet<T2>(out T2 result) where T2 : Object
|
||||||
{
|
{
|
||||||
_assetsFile = _assetsFile ?? assetsFile;
|
|
||||||
if (TryGetAssetsFile(out var sourceFile))
|
if (TryGetAssetsFile(out var sourceFile))
|
||||||
{
|
{
|
||||||
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
|
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
|
||||||
@@ -96,20 +92,20 @@ namespace AssetStudio
|
|||||||
public void Set(T m_Object)
|
public void Set(T m_Object)
|
||||||
{
|
{
|
||||||
var name = m_Object.assetsFile.fileName;
|
var name = m_Object.assetsFile.fileName;
|
||||||
if (string.Equals(_assetsFile.fileName, name, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(assetsFile.fileName, name, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
m_FileID = 0;
|
m_FileID = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_FileID = _assetsFile.m_Externals.FindIndex(x => string.Equals(x.fileName, name, StringComparison.OrdinalIgnoreCase));
|
m_FileID = assetsFile.m_Externals.FindIndex(x => string.Equals(x.fileName, name, StringComparison.OrdinalIgnoreCase));
|
||||||
if (m_FileID == -1)
|
if (m_FileID == -1)
|
||||||
{
|
{
|
||||||
_assetsFile.m_Externals.Add(new FileIdentifier
|
assetsFile.m_Externals.Add(new FileIdentifier
|
||||||
{
|
{
|
||||||
fileName = m_Object.assetsFile.fileName
|
fileName = m_Object.assetsFile.fileName
|
||||||
});
|
});
|
||||||
m_FileID = _assetsFile.m_Externals.Count;
|
m_FileID = assetsFile.m_Externals.Count;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -117,14 +113,14 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var assetsManager = _assetsFile.assetsManager;
|
var assetsManager = assetsFile.assetsManager;
|
||||||
var assetsFileList = assetsManager.assetsFileList;
|
var assetsFileList = assetsManager.assetsFileList;
|
||||||
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
|
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
|
||||||
|
|
||||||
if (!assetsFileIndexCache.TryGetValue(name, out _index))
|
if (!assetsFileIndexCache.TryGetValue(name, out index))
|
||||||
{
|
{
|
||||||
_index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
|
index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||||
assetsFileIndexCache.Add(name, _index);
|
assetsFileIndexCache.Add(name, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_PathID = m_Object.m_PathID;
|
m_PathID = m_Object.m_PathID;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public PlayerSettings(ObjectReader reader) : base(reader)
|
public PlayerSettings(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
if (version >= (5, 4)) //5.4.0 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4.0 nad up
|
||||||
{
|
{
|
||||||
var productGUID = reader.ReadBytes(16);
|
var productGUID = reader.ReadBytes(16);
|
||||||
}
|
}
|
||||||
@@ -23,12 +23,12 @@ namespace AssetStudio
|
|||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
int defaultScreenOrientation = reader.ReadInt32();
|
int defaultScreenOrientation = reader.ReadInt32();
|
||||||
int targetDevice = reader.ReadInt32();
|
int targetDevice = reader.ReadInt32();
|
||||||
if (version < (5, 3)) //5.3 down
|
if (version[0] < 5 || (version[0] == 5 && version[1] < 3)) //5.3 down
|
||||||
{
|
{
|
||||||
if (version < 5) //5.0 down
|
if (version[0] < 5) //5.0 down
|
||||||
{
|
{
|
||||||
int targetPlatform = reader.ReadInt32(); //4.0 and up targetGlesGraphics
|
int targetPlatform = reader.ReadInt32(); //4.0 and up targetGlesGraphics
|
||||||
if (version >= (4, 6)) //4.6 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 6)) //4.6 and up
|
||||||
{
|
{
|
||||||
var targetIOSGraphics = reader.ReadInt32();
|
var targetIOSGraphics = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,7 @@ namespace AssetStudio
|
|||||||
var useOnDemandResources = reader.ReadBoolean();
|
var useOnDemandResources = reader.ReadBoolean();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
if (version >= (3, 5)) //3.5 and up
|
if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5 and up
|
||||||
{
|
{
|
||||||
var accelerometerFrequency = reader.ReadInt32();
|
var accelerometerFrequency = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
protected Renderer(ObjectReader reader) : base(reader)
|
protected Renderer(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
if (version < 5) //5.0 down
|
if (version[0] < 5) //5.0 down
|
||||||
{
|
{
|
||||||
var m_Enabled = reader.ReadBoolean();
|
var m_Enabled = reader.ReadBoolean();
|
||||||
var m_CastShadows = reader.ReadBoolean();
|
var m_CastShadows = reader.ReadBoolean();
|
||||||
@@ -34,27 +34,27 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
else //5.0 and up
|
else //5.0 and up
|
||||||
{
|
{
|
||||||
if (version >= (5, 4)) //5.4 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4 and up
|
||||||
{
|
{
|
||||||
var m_Enabled = reader.ReadBoolean();
|
var m_Enabled = reader.ReadBoolean();
|
||||||
var m_CastShadows = reader.ReadByte();
|
var m_CastShadows = reader.ReadByte();
|
||||||
var m_ReceiveShadows = reader.ReadByte();
|
var m_ReceiveShadows = reader.ReadByte();
|
||||||
if (version >= (2017, 2)) //2017.2 and up
|
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
|
||||||
{
|
{
|
||||||
var m_DynamicOccludee = reader.ReadByte();
|
var m_DynamicOccludee = reader.ReadByte();
|
||||||
}
|
}
|
||||||
if (version >= 2021) //2021.1 and up
|
if (version[0] >= 2021) //2021.1 and up
|
||||||
{
|
{
|
||||||
var m_StaticShadowCaster = reader.ReadByte();
|
var m_StaticShadowCaster = reader.ReadByte();
|
||||||
}
|
}
|
||||||
var m_MotionVectors = reader.ReadByte();
|
var m_MotionVectors = reader.ReadByte();
|
||||||
var m_LightProbeUsage = reader.ReadByte();
|
var m_LightProbeUsage = reader.ReadByte();
|
||||||
var m_ReflectionProbeUsage = reader.ReadByte();
|
var m_ReflectionProbeUsage = reader.ReadByte();
|
||||||
if (version >= (2019, 3)) //2019.3 and up
|
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
|
||||||
{
|
{
|
||||||
var m_RayTracingMode = reader.ReadByte();
|
var m_RayTracingMode = reader.ReadByte();
|
||||||
}
|
}
|
||||||
if (version >= 2020) //2020.1 and up
|
if (version[0] >= 2020) //2020.1 and up
|
||||||
{
|
{
|
||||||
var m_RayTraceProcedural = reader.ReadByte();
|
var m_RayTraceProcedural = reader.ReadByte();
|
||||||
}
|
}
|
||||||
@@ -69,12 +69,12 @@ namespace AssetStudio
|
|||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 2018) //2018 and up
|
if (version[0] >= 2018) //2018 and up
|
||||||
{
|
{
|
||||||
var m_RenderingLayerMask = reader.ReadUInt32();
|
var m_RenderingLayerMask = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (2018, 3)) //2018.3 and up
|
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 3)) //2018.3 and up
|
||||||
{
|
{
|
||||||
var m_RendererPriority = reader.ReadInt32();
|
var m_RendererPriority = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
@@ -83,12 +83,12 @@ namespace AssetStudio
|
|||||||
var m_LightmapIndexDynamic = reader.ReadUInt16();
|
var m_LightmapIndexDynamic = reader.ReadUInt16();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 3) //3.0 and up
|
if (version[0] >= 3) //3.0 and up
|
||||||
{
|
{
|
||||||
var m_LightmapTilingOffset = reader.ReadVector4();
|
var m_LightmapTilingOffset = reader.ReadVector4();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 5) //5.0 and up
|
if (version[0] >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
var m_LightmapTilingOffsetDynamic = reader.ReadVector4();
|
var m_LightmapTilingOffsetDynamic = reader.ReadVector4();
|
||||||
}
|
}
|
||||||
@@ -100,13 +100,13 @@ namespace AssetStudio
|
|||||||
m_Materials[i] = new PPtr<Material>(reader);
|
m_Materials[i] = new PPtr<Material>(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version < 3) //3.0 down
|
if (version[0] < 3) //3.0 down
|
||||||
{
|
{
|
||||||
var m_LightmapTilingOffset = reader.ReadVector4();
|
var m_LightmapTilingOffset = reader.ReadVector4();
|
||||||
}
|
}
|
||||||
else //3.0 and up
|
else //3.0 and up
|
||||||
{
|
{
|
||||||
if (version >= (5, 5)) //5.5 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5)) //5.5 and up
|
||||||
{
|
{
|
||||||
m_StaticBatchInfo = new StaticBatchInfo(reader);
|
m_StaticBatchInfo = new StaticBatchInfo(reader);
|
||||||
}
|
}
|
||||||
@@ -118,17 +118,17 @@ namespace AssetStudio
|
|||||||
var m_StaticBatchRoot = new PPtr<Transform>(reader);
|
var m_StaticBatchRoot = new PPtr<Transform>(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (5, 4)) //5.4 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4 and up
|
||||||
{
|
{
|
||||||
var m_ProbeAnchor = new PPtr<Transform>(reader);
|
var m_ProbeAnchor = new PPtr<Transform>(reader);
|
||||||
var m_LightProbeVolumeOverride = new PPtr<GameObject>(reader);
|
var m_LightProbeVolumeOverride = new PPtr<GameObject>(reader);
|
||||||
}
|
}
|
||||||
else if (version >= (3, 5)) //3.5 - 5.3
|
else if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5 - 5.3
|
||||||
{
|
{
|
||||||
var m_UseLightProbes = reader.ReadBoolean();
|
var m_UseLightProbes = reader.ReadBoolean();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
|
||||||
if (version >= 5)//5.0 and up
|
if (version[0] >= 5)//5.0 and up
|
||||||
{
|
{
|
||||||
var m_ReflectionProbeUsage = reader.ReadInt32();
|
var m_ReflectionProbeUsage = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
@@ -136,9 +136,9 @@ namespace AssetStudio
|
|||||||
var m_LightProbeAnchor = new PPtr<Transform>(reader); //5.0 and up m_ProbeAnchor
|
var m_LightProbeAnchor = new PPtr<Transform>(reader); //5.0 and up m_ProbeAnchor
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
if (version == (4, 3)) //4.3
|
if (version[0] == 4 && version[1] == 3) //4.3
|
||||||
{
|
{
|
||||||
var m_SortingLayer = reader.ReadInt16();
|
var m_SortingLayer = reader.ReadInt16();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,14 +243,14 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
rtSeparateBlend = reader.ReadBoolean();
|
rtSeparateBlend = reader.ReadBoolean();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
if (version >= (2017, 2)) //2017.2 and up
|
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
|
||||||
{
|
{
|
||||||
zClip = new SerializedShaderFloatValue(reader);
|
zClip = new SerializedShaderFloatValue(reader);
|
||||||
}
|
}
|
||||||
zTest = new SerializedShaderFloatValue(reader);
|
zTest = new SerializedShaderFloatValue(reader);
|
||||||
zWrite = new SerializedShaderFloatValue(reader);
|
zWrite = new SerializedShaderFloatValue(reader);
|
||||||
culling = new SerializedShaderFloatValue(reader);
|
culling = new SerializedShaderFloatValue(reader);
|
||||||
if (version >= 2020) //2020.1 and up
|
if (version[0] >= 2020) //2020.1 and up
|
||||||
{
|
{
|
||||||
conservative = new SerializedShaderFloatValue(reader);
|
conservative = new SerializedShaderFloatValue(reader);
|
||||||
}
|
}
|
||||||
@@ -359,7 +359,7 @@ namespace AssetStudio
|
|||||||
m_NameIndex = reader.ReadInt32();
|
m_NameIndex = reader.ReadInt32();
|
||||||
m_Index = reader.ReadInt32();
|
m_Index = reader.ReadInt32();
|
||||||
m_SamplerIndex = reader.ReadInt32();
|
m_SamplerIndex = reader.ReadInt32();
|
||||||
if (version >= (2017, 3)) //2017.3 and up
|
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
|
||||||
{
|
{
|
||||||
var m_MultiSampled = reader.ReadBoolean();
|
var m_MultiSampled = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
@@ -380,7 +380,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
m_NameIndex = reader.ReadInt32();
|
m_NameIndex = reader.ReadInt32();
|
||||||
m_Index = reader.ReadInt32();
|
m_Index = reader.ReadInt32();
|
||||||
if (version >= 2020) //2020.1 and up
|
if (version[0] >= 2020) //2020.1 and up
|
||||||
{
|
{
|
||||||
m_ArraySize = reader.ReadInt32();
|
m_ArraySize = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
@@ -415,7 +415,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
m_VectorParams[i] = new VectorParameter(reader);
|
m_VectorParams[i] = new VectorParameter(reader);
|
||||||
}
|
}
|
||||||
if (version >= (2017, 3)) //2017.3 and up
|
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
|
||||||
{
|
{
|
||||||
int numStructParams = reader.ReadInt32();
|
int numStructParams = reader.ReadInt32();
|
||||||
m_StructParams = new StructParameter[numStructParams];
|
m_StructParams = new StructParameter[numStructParams];
|
||||||
@@ -426,8 +426,11 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
m_Size = reader.ReadInt32();
|
m_Size = reader.ReadInt32();
|
||||||
|
|
||||||
if (version.IsInRange((2020, 3, 2), 2021) //2020.3.2f1 and up
|
if ((version[0] == 2020 && version[1] > 3) ||
|
||||||
|| version >= (2021, 1, 4)) //2021.1.4f1 and up
|
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
|
||||||
|
(version[0] > 2021) ||
|
||||||
|
(version[0] == 2021 && version[1] > 1) ||
|
||||||
|
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 and up
|
||||||
{
|
{
|
||||||
m_IsPartialCB = reader.ReadBoolean();
|
m_IsPartialCB = reader.ReadBoolean();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
@@ -581,7 +584,7 @@ namespace AssetStudio
|
|||||||
m_BlobIndex = reader.ReadUInt32();
|
m_BlobIndex = reader.ReadUInt32();
|
||||||
m_Channels = new ParserBindChannels(reader);
|
m_Channels = new ParserBindChannels(reader);
|
||||||
|
|
||||||
if (version.IsInRange(2019, (2021, 2))) //2019 ~2021.1
|
if ((version[0] >= 2019 && version[0] < 2021) || (version[0] == 2021 && version[1] < 2)) //2019 ~2021.1
|
||||||
{
|
{
|
||||||
var m_GlobalKeywordIndices = reader.ReadUInt16Array();
|
var m_GlobalKeywordIndices = reader.ReadUInt16Array();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
@@ -591,7 +594,7 @@ namespace AssetStudio
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_KeywordIndices = reader.ReadUInt16Array();
|
m_KeywordIndices = reader.ReadUInt16Array();
|
||||||
if (version >= 2017) //2017 and up
|
if (version[0] >= 2017) //2017 and up
|
||||||
{
|
{
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
@@ -601,8 +604,11 @@ namespace AssetStudio
|
|||||||
m_GpuProgramType = (ShaderGpuProgramType)reader.ReadSByte();
|
m_GpuProgramType = (ShaderGpuProgramType)reader.ReadSByte();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
|
||||||
if (version.IsInRange((2020, 3, 2), 2021) //2020.3.2f1 and up
|
if ((version[0] == 2020 && version[1] > 3) ||
|
||||||
|| version >= (2021, 1, 1)) //2021.1.1f1 and up
|
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
|
||||||
|
(version[0] > 2021) ||
|
||||||
|
(version[0] == 2021 && version[1] > 1) ||
|
||||||
|
(version[0] == 2021 && version[1] == 1 && version[2] >= 1)) //2021.1.1f1 and up
|
||||||
{
|
{
|
||||||
m_Parameters = new SerializedProgramParameters(reader);
|
m_Parameters = new SerializedProgramParameters(reader);
|
||||||
}
|
}
|
||||||
@@ -657,7 +663,7 @@ namespace AssetStudio
|
|||||||
m_UAVParams[i] = new UAVParameter(reader);
|
m_UAVParams[i] = new UAVParameter(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 2017) //2017 and up
|
if (version[0] >= 2017) //2017 and up
|
||||||
{
|
{
|
||||||
int numSamplers = reader.ReadInt32();
|
int numSamplers = reader.ReadInt32();
|
||||||
m_Samplers = new SamplerParameter[numSamplers];
|
m_Samplers = new SamplerParameter[numSamplers];
|
||||||
@@ -668,9 +674,9 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (2017, 2)) //2017.2 and up
|
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
|
||||||
{
|
{
|
||||||
if (version >= 2021) //2021.1 and up
|
if (version[0] >= 2021) //2021.1 and up
|
||||||
{
|
{
|
||||||
var m_ShaderRequirements = reader.ReadInt64();
|
var m_ShaderRequirements = reader.ReadInt64();
|
||||||
}
|
}
|
||||||
@@ -699,13 +705,16 @@ namespace AssetStudio
|
|||||||
m_SubPrograms[i] = new SerializedSubProgram(reader);
|
m_SubPrograms[i] = new SerializedSubProgram(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version.IsInRange((2020, 3, 2), 2021) //2020.3.2f1 and up
|
if ((version[0] == 2020 && version[1] > 3) ||
|
||||||
|| version >= (2021, 1, 1)) //2021.1.1f1 and up
|
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
|
||||||
|
(version[0] > 2021) ||
|
||||||
|
(version[0] == 2021 && version[1] > 1) ||
|
||||||
|
(version[0] == 2021 && version[1] == 1 && version[2] >= 1)) //2021.1.1f1 and up
|
||||||
{
|
{
|
||||||
m_CommonParameters = new SerializedProgramParameters(reader);
|
m_CommonParameters = new SerializedProgramParameters(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (2022, 1)) //2022.1 and up
|
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 1)) //2022.1 and up
|
||||||
{
|
{
|
||||||
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
|
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
@@ -747,7 +756,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
if (version >= (2020, 2)) //2020.2 and up
|
if (version[0] > 2020 || (version[0] == 2020 && version[1] >= 2)) //2020.2 and up
|
||||||
{
|
{
|
||||||
int numEditorDataHash = reader.ReadInt32();
|
int numEditorDataHash = reader.ReadInt32();
|
||||||
m_EditorDataHash = new Hash128[numEditorDataHash];
|
m_EditorDataHash = new Hash128[numEditorDataHash];
|
||||||
@@ -758,7 +767,7 @@ namespace AssetStudio
|
|||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
m_Platforms = reader.ReadUInt8Array();
|
m_Platforms = reader.ReadUInt8Array();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
if (version <= (2021, 1)) //2021.1 and down
|
if (version[0] < 2021 || (version[0] == 2021 && version[1] < 2)) //2021.1 and down
|
||||||
{
|
{
|
||||||
m_LocalKeywordMask = reader.ReadUInt16Array();
|
m_LocalKeywordMask = reader.ReadUInt16Array();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
@@ -782,12 +791,12 @@ namespace AssetStudio
|
|||||||
progGeometry = new SerializedProgram(reader);
|
progGeometry = new SerializedProgram(reader);
|
||||||
progHull = new SerializedProgram(reader);
|
progHull = new SerializedProgram(reader);
|
||||||
progDomain = new SerializedProgram(reader);
|
progDomain = new SerializedProgram(reader);
|
||||||
if (version >= (2019, 3)) //2019.3 and up
|
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
|
||||||
{
|
{
|
||||||
progRayTracing = new SerializedProgram(reader);
|
progRayTracing = new SerializedProgram(reader);
|
||||||
}
|
}
|
||||||
m_HasInstancingVariant = reader.ReadBoolean();
|
m_HasInstancingVariant = reader.ReadBoolean();
|
||||||
if (version >= 2018) //2018 and up
|
if (version[0] >= 2018) //2018 and up
|
||||||
{
|
{
|
||||||
var m_HasProceduralInstancingVariant = reader.ReadBoolean();
|
var m_HasProceduralInstancingVariant = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
@@ -796,7 +805,7 @@ namespace AssetStudio
|
|||||||
m_Name = reader.ReadAlignedString();
|
m_Name = reader.ReadAlignedString();
|
||||||
m_TextureName = reader.ReadAlignedString();
|
m_TextureName = reader.ReadAlignedString();
|
||||||
m_Tags = new SerializedTagMap(reader);
|
m_Tags = new SerializedTagMap(reader);
|
||||||
if (version == 2021 && version.Minor >= 2) //2021.2 ~2021.x
|
if (version[0] == 2021 && version[1] >= 2) //2021.2 ~2021.x
|
||||||
{
|
{
|
||||||
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
|
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
@@ -889,7 +898,7 @@ namespace AssetStudio
|
|||||||
m_SubShaders[i] = new SerializedSubShader(reader);
|
m_SubShaders[i] = new SerializedSubShader(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (2021, 2)) //2021.2 and up
|
if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 2)) //2021.2 and up
|
||||||
{
|
{
|
||||||
m_KeywordNames = reader.ReadStringArray();
|
m_KeywordNames = reader.ReadStringArray();
|
||||||
m_KeywordFlags = reader.ReadUInt8Array();
|
m_KeywordFlags = reader.ReadUInt8Array();
|
||||||
@@ -907,7 +916,7 @@ namespace AssetStudio
|
|||||||
m_Dependencies[i] = new SerializedShaderDependency(reader);
|
m_Dependencies[i] = new SerializedShaderDependency(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 2021) //2021.1 and up
|
if (version[0] >= 2021) //2021.1 and up
|
||||||
{
|
{
|
||||||
int m_CustomEditorForRenderPipelinesSize = reader.ReadInt32();
|
int m_CustomEditorForRenderPipelinesSize = reader.ReadInt32();
|
||||||
m_CustomEditorForRenderPipelines = new SerializedCustomEditorForRenderPipeline[m_CustomEditorForRenderPipelinesSize];
|
m_CustomEditorForRenderPipelines = new SerializedCustomEditorForRenderPipeline[m_CustomEditorForRenderPipelinesSize];
|
||||||
@@ -968,11 +977,11 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public Shader(ObjectReader reader) : base(reader)
|
public Shader(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
if (version >= (5, 5)) //5.5 and up
|
if (version[0] == 5 && version[1] >= 5 || version[0] > 5) //5.5 and up
|
||||||
{
|
{
|
||||||
m_ParsedForm = new SerializedShader(reader);
|
m_ParsedForm = new SerializedShader(reader);
|
||||||
platforms = reader.ReadUInt32Array().Select(x => (ShaderCompilerPlatform)x).ToArray();
|
platforms = reader.ReadUInt32Array().Select(x => (ShaderCompilerPlatform)x).ToArray();
|
||||||
if (version >= (2019, 3)) //2019.3 and up
|
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
|
||||||
{
|
{
|
||||||
offsets = reader.ReadUInt32ArrayArray();
|
offsets = reader.ReadUInt32ArrayArray();
|
||||||
compressedLengths = reader.ReadUInt32ArrayArray();
|
compressedLengths = reader.ReadUInt32ArrayArray();
|
||||||
@@ -993,7 +1002,7 @@ namespace AssetStudio
|
|||||||
new PPtr<Shader>(reader);
|
new PPtr<Shader>(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 2018)
|
if (version[0] >= 2018)
|
||||||
{
|
{
|
||||||
var m_NonModifiableTexturesCount = reader.ReadInt32();
|
var m_NonModifiableTexturesCount = reader.ReadInt32();
|
||||||
for (int i = 0; i < m_NonModifiableTexturesCount; i++)
|
for (int i = 0; i < m_NonModifiableTexturesCount; i++)
|
||||||
@@ -1011,7 +1020,7 @@ namespace AssetStudio
|
|||||||
m_Script = reader.ReadUInt8Array();
|
m_Script = reader.ReadUInt8Array();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
var m_PathName = reader.ReadAlignedString();
|
var m_PathName = reader.ReadAlignedString();
|
||||||
if (version == 5 && version.Minor >= 3) //5.3 - 5.4
|
if (version[0] == 5 && version[1] >= 3) //5.3 - 5.4
|
||||||
{
|
{
|
||||||
decompressedSize = reader.ReadUInt32();
|
decompressedSize = reader.ReadUInt32();
|
||||||
m_SubProgramBlob = reader.ReadUInt8Array();
|
m_SubProgramBlob = reader.ReadUInt8Array();
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace AssetStudio
|
|||||||
var m_SkinNormals = reader.ReadBoolean(); //3.1.0 and below
|
var m_SkinNormals = reader.ReadBoolean(); //3.1.0 and below
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
|
||||||
if (version < (2, 6)) //2.6 down
|
if (version[0] == 2 && version[1] < 6) //2.6 down
|
||||||
{
|
{
|
||||||
var m_DisableAnimationWhenOffscreen = new PPtr<Animation>(reader);
|
var m_DisableAnimationWhenOffscreen = new PPtr<Animation>(reader);
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ namespace AssetStudio
|
|||||||
m_Bones[b] = new PPtr<Transform>(reader);
|
m_Bones[b] = new PPtr<Transform>(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
m_BlendShapeWeights = reader.ReadSingleArray();
|
m_BlendShapeWeights = reader.ReadSingleArray();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ namespace AssetStudio
|
|||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
pos = reader.ReadVector3();
|
pos = reader.ReadVector3();
|
||||||
if (version <= (4, 3)) //4.3 and down
|
if (version[0] < 4 || (version[0] == 4 && version[1] <= 3)) //4.3 and down
|
||||||
{
|
{
|
||||||
uv = reader.ReadVector2();
|
uv = reader.ReadVector2();
|
||||||
}
|
}
|
||||||
@@ -99,12 +99,12 @@ namespace AssetStudio
|
|||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
texture = new PPtr<Texture2D>(reader);
|
texture = new PPtr<Texture2D>(reader);
|
||||||
if (version >= (5, 2)) //5.2 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up
|
||||||
{
|
{
|
||||||
alphaTexture = new PPtr<Texture2D>(reader);
|
alphaTexture = new PPtr<Texture2D>(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 2019) //2019 and up
|
if (version[0] >= 2019) //2019 and up
|
||||||
{
|
{
|
||||||
var secondaryTexturesSize = reader.ReadInt32();
|
var secondaryTexturesSize = reader.ReadInt32();
|
||||||
secondaryTextures = new SecondarySpriteTexture[secondaryTexturesSize];
|
secondaryTextures = new SecondarySpriteTexture[secondaryTexturesSize];
|
||||||
@@ -114,7 +114,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (5, 6)) //5.6 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
|
||||||
{
|
{
|
||||||
var m_SubMeshesSize = reader.ReadInt32();
|
var m_SubMeshesSize = reader.ReadInt32();
|
||||||
m_SubMeshes = new SubMesh[m_SubMeshesSize];
|
m_SubMeshes = new SubMesh[m_SubMeshesSize];
|
||||||
@@ -141,11 +141,11 @@ namespace AssetStudio
|
|||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 2018) //2018 and up
|
if (version[0] >= 2018) //2018 and up
|
||||||
{
|
{
|
||||||
m_Bindpose = reader.ReadMatrixArray();
|
m_Bindpose = reader.ReadMatrixArray();
|
||||||
|
|
||||||
if (version < (2018, 2)) //2018.2 down
|
if (version[0] == 2018 && version[1] < 2) //2018.2 down
|
||||||
{
|
{
|
||||||
var m_SourceSkinSize = reader.ReadInt32();
|
var m_SourceSkinSize = reader.ReadInt32();
|
||||||
for (int i = 0; i < m_SourceSkinSize; i++)
|
for (int i = 0; i < m_SourceSkinSize; i++)
|
||||||
@@ -157,18 +157,18 @@ namespace AssetStudio
|
|||||||
|
|
||||||
textureRect = new Rectf(reader);
|
textureRect = new Rectf(reader);
|
||||||
textureRectOffset = reader.ReadVector2();
|
textureRectOffset = reader.ReadVector2();
|
||||||
if (version >= (5, 6)) //5.6 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
|
||||||
{
|
{
|
||||||
atlasRectOffset = reader.ReadVector2();
|
atlasRectOffset = reader.ReadVector2();
|
||||||
}
|
}
|
||||||
|
|
||||||
settingsRaw = new SpriteSettings(reader);
|
settingsRaw = new SpriteSettings(reader);
|
||||||
if (version >= (4, 5)) //4.5 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
|
||||||
{
|
{
|
||||||
uvTransform = reader.ReadVector4();
|
uvTransform = reader.ReadVector4();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 2017) //2017 and up
|
if (version[0] >= 2017) //2017 and up
|
||||||
{
|
{
|
||||||
downscaleMultiplier = reader.ReadSingle();
|
downscaleMultiplier = reader.ReadSingle();
|
||||||
}
|
}
|
||||||
@@ -182,6 +182,13 @@ namespace AssetStudio
|
|||||||
public float width;
|
public float width;
|
||||||
public float height;
|
public float height;
|
||||||
|
|
||||||
|
public Rectf(float x, float y, float w, float h) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
}
|
||||||
|
|
||||||
public Rectf(BinaryReader reader)
|
public Rectf(BinaryReader reader)
|
||||||
{
|
{
|
||||||
x = reader.ReadSingle();
|
x = reader.ReadSingle();
|
||||||
@@ -205,31 +212,34 @@ namespace AssetStudio
|
|||||||
public PPtr<SpriteAtlas> m_SpriteAtlas;
|
public PPtr<SpriteAtlas> m_SpriteAtlas;
|
||||||
public SpriteRenderData m_RD;
|
public SpriteRenderData m_RD;
|
||||||
public Vector2[][] m_PhysicsShape;
|
public Vector2[][] m_PhysicsShape;
|
||||||
|
public bool akSplitAlpha;
|
||||||
|
|
||||||
public Sprite(ObjectReader reader) : base(reader)
|
public Sprite(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
m_Rect = new Rectf(reader);
|
m_Rect = new Rectf(reader);
|
||||||
m_Offset = reader.ReadVector2();
|
m_Offset = reader.ReadVector2();
|
||||||
if (version >= (4, 5)) //4.5 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
|
||||||
{
|
{
|
||||||
m_Border = reader.ReadVector4();
|
m_Border = reader.ReadVector4();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_PixelsToUnits = reader.ReadSingle();
|
m_PixelsToUnits = reader.ReadSingle();
|
||||||
if (version >= (5, 4, 2)
|
if (version[0] > 5
|
||||||
|| version == (5, 4, 1) && buildType.IsPatch && version.Build >= 3) //5.4.1p3 and up
|
|| (version[0] == 5 && version[1] > 4)
|
||||||
|
|| (version[0] == 5 && version[1] == 4 && version[2] >= 2)
|
||||||
|
|| (version[0] == 5 && version[1] == 4 && version[2] == 1 && buildType.IsPatch && version[3] >= 3)) //5.4.1p3 and up
|
||||||
{
|
{
|
||||||
m_Pivot = reader.ReadVector2();
|
m_Pivot = reader.ReadVector2();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Extrude = reader.ReadUInt32();
|
m_Extrude = reader.ReadUInt32();
|
||||||
if (version >= (5, 3)) //5.3 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3)) //5.3 and up
|
||||||
{
|
{
|
||||||
m_IsPolygon = reader.ReadBoolean();
|
m_IsPolygon = reader.ReadBoolean();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 2017) //2017 and up
|
if (version[0] >= 2017) //2017 and up
|
||||||
{
|
{
|
||||||
var first = new Guid(reader.ReadBytes(16));
|
var first = new Guid(reader.ReadBytes(16));
|
||||||
var second = reader.ReadInt64();
|
var second = reader.ReadInt64();
|
||||||
@@ -242,7 +252,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
m_RD = new SpriteRenderData(reader);
|
m_RD = new SpriteRenderData(reader);
|
||||||
|
|
||||||
if (version >= 2017) //2017 and up
|
if (version[0] >= 2017) //2017 and up
|
||||||
{
|
{
|
||||||
var m_PhysicsShapeSize = reader.ReadInt32();
|
var m_PhysicsShapeSize = reader.ReadInt32();
|
||||||
m_PhysicsShape = new Vector2[m_PhysicsShapeSize][];
|
m_PhysicsShape = new Vector2[m_PhysicsShapeSize][];
|
||||||
@@ -252,6 +262,8 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
akSplitAlpha = false;
|
||||||
|
|
||||||
//vector m_Bones 2018 and up
|
//vector m_Bones 2018 and up
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ namespace AssetStudio
|
|||||||
alphaTexture = new PPtr<Texture2D>(reader);
|
alphaTexture = new PPtr<Texture2D>(reader);
|
||||||
textureRect = new Rectf(reader);
|
textureRect = new Rectf(reader);
|
||||||
textureRectOffset = reader.ReadVector2();
|
textureRectOffset = reader.ReadVector2();
|
||||||
if (version >= (2017, 2)) //2017.2 and up
|
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
|
||||||
{
|
{
|
||||||
atlasRectOffset = reader.ReadVector2();
|
atlasRectOffset = reader.ReadVector2();
|
||||||
}
|
}
|
||||||
uvTransform = reader.ReadVector4();
|
uvTransform = reader.ReadVector4();
|
||||||
downscaleMultiplier = reader.ReadSingle();
|
downscaleMultiplier = reader.ReadSingle();
|
||||||
settingsRaw = new SpriteSettings(reader);
|
settingsRaw = new SpriteSettings(reader);
|
||||||
if (version >= (2020, 2)) //2020.2 and up
|
if (version[0] > 2020 || (version[0] == 2020 && version[1] >= 2)) //2020.2 and up
|
||||||
{
|
{
|
||||||
var secondaryTexturesSize = reader.ReadInt32();
|
var secondaryTexturesSize = reader.ReadInt32();
|
||||||
secondaryTextures = new SecondarySpriteTexture[secondaryTexturesSize];
|
secondaryTextures = new SecondarySpriteTexture[secondaryTexturesSize];
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
namespace AssetStudio
|
|
||||||
{
|
|
||||||
public class StreamingInfo
|
|
||||||
{
|
|
||||||
public long offset; //ulong
|
|
||||||
public uint size;
|
|
||||||
public string path;
|
|
||||||
|
|
||||||
public StreamingInfo() { }
|
|
||||||
|
|
||||||
public StreamingInfo(ObjectReader reader)
|
|
||||||
{
|
|
||||||
var version = reader.version;
|
|
||||||
|
|
||||||
if (version >= 2020) //2020.1 and up
|
|
||||||
{
|
|
||||||
offset = reader.ReadInt64();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
offset = reader.ReadUInt32();
|
|
||||||
}
|
|
||||||
size = reader.ReadUInt32();
|
|
||||||
path = reader.ReadAlignedString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +1,19 @@
|
|||||||
namespace AssetStudio
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
public abstract class Texture : NamedObject
|
public abstract class Texture : NamedObject
|
||||||
{
|
{
|
||||||
protected Texture() { }
|
|
||||||
|
|
||||||
protected Texture(ObjectReader reader) : base(reader)
|
protected Texture(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
if (version >= (2017, 3)) //2017.3 and up
|
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
|
||||||
{
|
{
|
||||||
if (version < (2023, 2)) //2023.2 down
|
var m_ForcedFallbackFormat = reader.ReadInt32();
|
||||||
{
|
var m_DownscaleFallback = reader.ReadBoolean();
|
||||||
var m_ForcedFallbackFormat = reader.ReadInt32();
|
if (version[0] > 2020 || (version[0] == 2020 && version[1] >= 2)) //2020.2 and up
|
||||||
var m_DownscaleFallback = reader.ReadBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version >= (2020, 2)) //2020.2 and up
|
|
||||||
{
|
{
|
||||||
var m_IsAlphaChannelOptional = reader.ReadBoolean();
|
var m_IsAlphaChannelOptional = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,89 +1,79 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
|
public class StreamingInfo
|
||||||
|
{
|
||||||
|
public long offset; //ulong
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
size = reader.ReadUInt32();
|
||||||
|
path = reader.ReadAlignedString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GLTextureSettings
|
||||||
|
{
|
||||||
|
public int m_FilterMode;
|
||||||
|
public int m_Aniso;
|
||||||
|
public float m_MipBias;
|
||||||
|
public int m_WrapMode;
|
||||||
|
|
||||||
|
public GLTextureSettings(ObjectReader reader)
|
||||||
|
{
|
||||||
|
var version = reader.version;
|
||||||
|
|
||||||
|
m_FilterMode = reader.ReadInt32();
|
||||||
|
m_Aniso = reader.ReadInt32();
|
||||||
|
m_MipBias = reader.ReadSingle();
|
||||||
|
if (version[0] >= 2017)//2017.x and up
|
||||||
|
{
|
||||||
|
m_WrapMode = reader.ReadInt32(); //m_WrapU
|
||||||
|
int m_WrapV = reader.ReadInt32();
|
||||||
|
int m_WrapW = reader.ReadInt32();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_WrapMode = reader.ReadInt32();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public sealed class Texture2D : Texture
|
public sealed class Texture2D : Texture
|
||||||
{
|
{
|
||||||
public int m_Width;
|
public int m_Width;
|
||||||
public int m_Height;
|
public int m_Height;
|
||||||
public int m_CompleteImageSize;
|
|
||||||
public TextureFormat m_TextureFormat;
|
public TextureFormat m_TextureFormat;
|
||||||
public bool m_MipMap;
|
public bool m_MipMap;
|
||||||
public int m_MipCount;
|
public int m_MipCount;
|
||||||
public GLTextureSettings m_TextureSettings;
|
public GLTextureSettings m_TextureSettings;
|
||||||
public int m_ImageCount;
|
|
||||||
public byte[] m_PlatformBlob;
|
|
||||||
public ResourceReader image_data;
|
public ResourceReader image_data;
|
||||||
public StreamingInfo m_StreamData;
|
public StreamingInfo m_StreamData;
|
||||||
|
|
||||||
public Texture2D() { }
|
|
||||||
|
|
||||||
public Texture2D(Texture2DArray m_Texture2DArray, int layer) // Texture2DArrayImage
|
|
||||||
{
|
|
||||||
reader = m_Texture2DArray.reader;
|
|
||||||
assetsFile = m_Texture2DArray.assetsFile;
|
|
||||||
version = m_Texture2DArray.version;
|
|
||||||
platform = m_Texture2DArray.platform;
|
|
||||||
|
|
||||||
m_Name = $"{m_Texture2DArray.m_Name}_{layer + 1}";
|
|
||||||
type = ClassIDType.Texture2DArrayImage;
|
|
||||||
m_PathID = m_Texture2DArray.m_PathID;
|
|
||||||
|
|
||||||
m_Width = m_Texture2DArray.m_Width;
|
|
||||||
m_Height = m_Texture2DArray.m_Height;
|
|
||||||
m_TextureFormat = m_Texture2DArray.m_Format.ToTextureFormat();
|
|
||||||
m_MipCount = m_Texture2DArray.m_MipCount;
|
|
||||||
m_TextureSettings = m_Texture2DArray.m_TextureSettings;
|
|
||||||
m_StreamData = m_Texture2DArray.m_StreamData;
|
|
||||||
m_PlatformBlob = Array.Empty<byte>();
|
|
||||||
m_MipMap = m_MipCount > 1;
|
|
||||||
m_ImageCount = 1;
|
|
||||||
|
|
||||||
//var imgActualDataSize = GetImageDataSize(m_TextureFormat);
|
|
||||||
//var mipmapSize = (int)(m_Texture2DArray.m_DataSize / m_Texture2DArray.m_Depth - imgActualDataSize);
|
|
||||||
m_CompleteImageSize = (int)m_Texture2DArray.m_DataSize / m_Texture2DArray.m_Depth;
|
|
||||||
var offset = layer * m_CompleteImageSize + m_Texture2DArray.image_data.Offset;
|
|
||||||
|
|
||||||
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
|
||||||
? new ResourceReader(m_StreamData.path, assetsFile, offset, m_CompleteImageSize)
|
|
||||||
: new ResourceReader(reader, offset, m_CompleteImageSize);
|
|
||||||
|
|
||||||
byteSize = (uint)(m_Width * m_Height) * 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Texture2D(ObjectReader reader, IDictionary typeDict) : base(reader)
|
|
||||||
{
|
|
||||||
var parsedTex2d = JsonConvert.DeserializeObject<Texture2D>(JsonConvert.SerializeObject(typeDict));
|
|
||||||
m_Width = parsedTex2d.m_Width;
|
|
||||||
m_Height = parsedTex2d.m_Height;
|
|
||||||
m_CompleteImageSize = parsedTex2d.m_CompleteImageSize;
|
|
||||||
m_TextureFormat = parsedTex2d.m_TextureFormat;
|
|
||||||
m_MipMap = parsedTex2d.m_MipMap;
|
|
||||||
m_MipCount = parsedTex2d.m_MipCount;
|
|
||||||
m_ImageCount = parsedTex2d.m_ImageCount;
|
|
||||||
m_TextureSettings = parsedTex2d.m_TextureSettings;
|
|
||||||
m_StreamData = parsedTex2d.m_StreamData;
|
|
||||||
m_PlatformBlob = parsedTex2d.m_PlatformBlob ?? Array.Empty<byte>();
|
|
||||||
|
|
||||||
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
|
||||||
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
|
|
||||||
: new ResourceReader(reader, parsedTex2d.image_data.Offset, parsedTex2d.image_data.Size);
|
|
||||||
typeDict.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Texture2D(ObjectReader reader) : base(reader)
|
public Texture2D(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
m_Width = reader.ReadInt32();
|
m_Width = reader.ReadInt32();
|
||||||
m_Height = reader.ReadInt32();
|
m_Height = reader.ReadInt32();
|
||||||
m_CompleteImageSize = reader.ReadInt32();
|
var m_CompleteImageSize = reader.ReadInt32();
|
||||||
if (version >= 2020) //2020.1 and up
|
if (version[0] >= 2020) //2020.1 and up
|
||||||
{
|
{
|
||||||
var m_MipsStripped = reader.ReadInt32();
|
var m_MipsStripped = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
m_TextureFormat = (TextureFormat)reader.ReadInt32();
|
m_TextureFormat = (TextureFormat)reader.ReadInt32();
|
||||||
if (version < (5, 2)) //5.2 down
|
if (version[0] < 5 || (version[0] == 5 && version[1] < 2)) //5.2 down
|
||||||
{
|
{
|
||||||
m_MipMap = reader.ReadBoolean();
|
m_MipMap = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
@@ -91,132 +81,152 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
m_MipCount = reader.ReadInt32();
|
m_MipCount = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
if (version >= (2, 6)) //2.6.0 and up
|
if (version[0] > 2 || (version[0] == 2 && version[1] >= 6)) //2.6.0 and up
|
||||||
{
|
{
|
||||||
var m_IsReadable = reader.ReadBoolean();
|
var m_IsReadable = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
if (version >= 2020) //2020.1 and up
|
if (version[0] >= 2020) //2020.1 and up
|
||||||
{
|
{
|
||||||
var m_IsPreProcessed = reader.ReadBoolean();
|
var m_IsPreProcessed = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
if (version >= (2019, 3)) //2019.3 and up
|
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
|
||||||
{
|
{
|
||||||
if (version >= (2022, 2)) //2022.2 and up
|
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 2)) //2022.2 and up
|
||||||
{
|
{
|
||||||
var m_IgnoreMipmapLimit = reader.ReadBoolean();
|
var m_IgnoreMipmapLimit = reader.ReadBoolean();
|
||||||
reader.AlignStream();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var m_IgnoreMasterTextureLimit = reader.ReadBoolean();
|
var m_IgnoreMasterTextureLimit = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (version.IsInRange(3, (5, 5))) //3.0.0 - 5.4
|
if (version[0] >= 3) //3.0.0 - 5.4
|
||||||
{
|
{
|
||||||
var m_ReadAllowed = reader.ReadBoolean();
|
if (version[0] < 5 || (version[0] == 5 && version[1] <= 4))
|
||||||
|
{
|
||||||
|
var m_ReadAllowed = reader.ReadBoolean();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (version >= (2022, 2)) //2022.2 and up
|
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 2)) //2022.2 and up
|
||||||
{
|
{
|
||||||
var m_MipmapLimitGroupName = reader.ReadAlignedString();
|
var m_MipmapLimitGroupName = reader.ReadAlignedString();
|
||||||
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
if (version >= (2018, 2)) //2018.2 and up
|
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
|
||||||
{
|
{
|
||||||
var m_StreamingMipmaps = reader.ReadBoolean();
|
var m_StreamingMipmaps = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
if (version >= (2018, 2)) //2018.2 and up
|
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
|
||||||
{
|
{
|
||||||
var m_StreamingMipmapsPriority = reader.ReadInt32();
|
var m_StreamingMipmapsPriority = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
m_ImageCount = reader.ReadInt32();
|
var m_ImageCount = reader.ReadInt32();
|
||||||
var m_TextureDimension = reader.ReadInt32();
|
var m_TextureDimension = reader.ReadInt32();
|
||||||
m_TextureSettings = new GLTextureSettings(reader);
|
m_TextureSettings = new GLTextureSettings(reader);
|
||||||
if (version >= 3) //3.0 and up
|
if (version[0] >= 3) //3.0 and up
|
||||||
{
|
{
|
||||||
var m_LightmapFormat = reader.ReadInt32();
|
var m_LightmapFormat = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
if (version >= (3, 5)) //3.5.0 and up
|
if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5.0 and up
|
||||||
{
|
{
|
||||||
var m_ColorSpace = reader.ReadInt32();
|
var m_ColorSpace = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
if (version >= (2020, 2)) //2020.2 and up
|
if (version[0] > 2020 || (version[0] == 2020 && version[1] >= 2)) //2020.2 and up
|
||||||
{
|
{
|
||||||
m_PlatformBlob = reader.ReadUInt8Array();
|
var m_PlatformBlob = reader.ReadUInt8Array();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
m_PlatformBlob = Array.Empty<byte>();
|
|
||||||
}
|
|
||||||
var image_data_size = reader.ReadInt32();
|
var image_data_size = reader.ReadInt32();
|
||||||
if (image_data_size == 0 && version >= (5, 3))//5.3.0 and up
|
if (image_data_size == 0 && ((version[0] == 5 && version[1] >= 3) || version[0] > 5))//5.3.0 and up
|
||||||
{
|
{
|
||||||
m_StreamData = new StreamingInfo(reader);
|
m_StreamData = new StreamingInfo(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
ResourceReader resourceReader;
|
||||||
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
|
if (!string.IsNullOrEmpty(m_StreamData?.path))
|
||||||
: new ResourceReader(reader, reader.BaseStream.Position, image_data_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://docs.unity3d.com/2023.3/Documentation/Manual/class-TextureImporterOverride.html
|
|
||||||
private int GetImageDataSize(TextureFormat textureFormat)
|
|
||||||
{
|
|
||||||
var imgDataSize = m_Width * m_Height;
|
|
||||||
switch (textureFormat)
|
|
||||||
{
|
{
|
||||||
case TextureFormat.ASTC_RGBA_5x5:
|
resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size);
|
||||||
// https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/
|
|
||||||
imgDataSize = (int)(Math.Floor((m_Width + 4) / 5f) * Math.Floor((m_Height + 4) / 5f) * 16);
|
|
||||||
break;
|
|
||||||
case TextureFormat.ASTC_RGBA_6x6:
|
|
||||||
imgDataSize = (int)(Math.Floor((m_Width + 5) / 6f) * Math.Floor((m_Height + 5) / 6f) * 16);
|
|
||||||
break;
|
|
||||||
case TextureFormat.ASTC_RGBA_8x8:
|
|
||||||
imgDataSize = (int)(Math.Floor((m_Width + 7) / 8f) * Math.Floor((m_Height + 7) / 8f) * 16);
|
|
||||||
break;
|
|
||||||
case TextureFormat.ASTC_RGBA_10x10:
|
|
||||||
imgDataSize = (int)(Math.Floor((m_Width + 9) / 10f) * Math.Floor((m_Height + 9) / 10f) * 16);
|
|
||||||
break;
|
|
||||||
case TextureFormat.ASTC_RGBA_12x12:
|
|
||||||
imgDataSize = (int)(Math.Floor((m_Width + 11) / 12f) * Math.Floor((m_Height + 11) / 12f) * 16);
|
|
||||||
break;
|
|
||||||
case TextureFormat.DXT1:
|
|
||||||
case TextureFormat.EAC_R:
|
|
||||||
case TextureFormat.EAC_R_SIGNED:
|
|
||||||
case TextureFormat.ATC_RGB4:
|
|
||||||
case TextureFormat.ETC_RGB4:
|
|
||||||
case TextureFormat.ETC2_RGB:
|
|
||||||
case TextureFormat.ETC2_RGBA1:
|
|
||||||
case TextureFormat.PVRTC_RGBA4:
|
|
||||||
imgDataSize /= 2;
|
|
||||||
break;
|
|
||||||
case TextureFormat.PVRTC_RGBA2:
|
|
||||||
imgDataSize /= 4;
|
|
||||||
break;
|
|
||||||
case TextureFormat.R16:
|
|
||||||
case TextureFormat.RGB565:
|
|
||||||
imgDataSize *= 2;
|
|
||||||
break;
|
|
||||||
case TextureFormat.RGB24:
|
|
||||||
imgDataSize *= 3;
|
|
||||||
break;
|
|
||||||
case TextureFormat.RG32:
|
|
||||||
case TextureFormat.RGBA32:
|
|
||||||
case TextureFormat.ARGB32:
|
|
||||||
case TextureFormat.BGRA32:
|
|
||||||
case TextureFormat.RGB9e5Float:
|
|
||||||
imgDataSize *= 4;
|
|
||||||
break;
|
|
||||||
case TextureFormat.RGB48:
|
|
||||||
imgDataSize *= 6;
|
|
||||||
break;
|
|
||||||
case TextureFormat.RGBAHalf:
|
|
||||||
case TextureFormat.RGBA64:
|
|
||||||
imgDataSize *= 8;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return imgDataSize;
|
else
|
||||||
|
{
|
||||||
|
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, image_data_size);
|
||||||
|
}
|
||||||
|
image_data = resourceReader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum TextureFormat
|
||||||
|
{
|
||||||
|
Alpha8 = 1,
|
||||||
|
ARGB4444,
|
||||||
|
RGB24,
|
||||||
|
RGBA32,
|
||||||
|
ARGB32,
|
||||||
|
ARGBFloat,
|
||||||
|
RGB565,
|
||||||
|
BGR24,
|
||||||
|
R16,
|
||||||
|
DXT1,
|
||||||
|
DXT3,
|
||||||
|
DXT5,
|
||||||
|
RGBA4444,
|
||||||
|
BGRA32,
|
||||||
|
RHalf,
|
||||||
|
RGHalf,
|
||||||
|
RGBAHalf,
|
||||||
|
RFloat,
|
||||||
|
RGFloat,
|
||||||
|
RGBAFloat,
|
||||||
|
YUY2,
|
||||||
|
RGB9e5Float,
|
||||||
|
RGBFloat,
|
||||||
|
BC6H,
|
||||||
|
BC7,
|
||||||
|
BC4,
|
||||||
|
BC5,
|
||||||
|
DXT1Crunched,
|
||||||
|
DXT5Crunched,
|
||||||
|
PVRTC_RGB2,
|
||||||
|
PVRTC_RGBA2,
|
||||||
|
PVRTC_RGB4,
|
||||||
|
PVRTC_RGBA4,
|
||||||
|
ETC_RGB4,
|
||||||
|
ATC_RGB4,
|
||||||
|
ATC_RGBA8,
|
||||||
|
EAC_R = 41,
|
||||||
|
EAC_R_SIGNED,
|
||||||
|
EAC_RG,
|
||||||
|
EAC_RG_SIGNED,
|
||||||
|
ETC2_RGB,
|
||||||
|
ETC2_RGBA1,
|
||||||
|
ETC2_RGBA8,
|
||||||
|
ASTC_RGB_4x4,
|
||||||
|
ASTC_RGB_5x5,
|
||||||
|
ASTC_RGB_6x6,
|
||||||
|
ASTC_RGB_8x8,
|
||||||
|
ASTC_RGB_10x10,
|
||||||
|
ASTC_RGB_12x12,
|
||||||
|
ASTC_RGBA_4x4,
|
||||||
|
ASTC_RGBA_5x5,
|
||||||
|
ASTC_RGBA_6x6,
|
||||||
|
ASTC_RGBA_8x8,
|
||||||
|
ASTC_RGBA_10x10,
|
||||||
|
ASTC_RGBA_12x12,
|
||||||
|
ETC_RGB4_3DS,
|
||||||
|
ETC_RGBA8_3DS,
|
||||||
|
RG16,
|
||||||
|
R8,
|
||||||
|
ETC_RGB4Crunched,
|
||||||
|
ETC2_RGBA8Crunched,
|
||||||
|
ASTC_HDR_4x4,
|
||||||
|
ASTC_HDR_5x5,
|
||||||
|
ASTC_HDR_6x6,
|
||||||
|
ASTC_HDR_8x8,
|
||||||
|
ASTC_HDR_10x10,
|
||||||
|
ASTC_HDR_12x12,
|
||||||
|
RG32,
|
||||||
|
RGB48,
|
||||||
|
RGBA64
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
|
||||||
public sealed class Texture2DArray : Texture
|
|
||||||
{
|
|
||||||
public int m_Width;
|
|
||||||
public int m_Height;
|
|
||||||
public int m_Depth;
|
|
||||||
public GraphicsFormat m_Format;
|
|
||||||
public int m_MipCount;
|
|
||||||
public uint m_DataSize;
|
|
||||||
public GLTextureSettings m_TextureSettings;
|
|
||||||
public int m_ColorSpace;
|
|
||||||
public ResourceReader image_data;
|
|
||||||
public StreamingInfo m_StreamData;
|
|
||||||
public List<Texture2D> TextureList;
|
|
||||||
|
|
||||||
public Texture2DArray() { }
|
|
||||||
|
|
||||||
public Texture2DArray(ObjectReader reader) : base(reader)
|
|
||||||
{
|
|
||||||
m_ColorSpace = reader.ReadInt32();
|
|
||||||
m_Format = (GraphicsFormat)reader.ReadInt32();
|
|
||||||
m_Width = reader.ReadInt32();
|
|
||||||
m_Height = reader.ReadInt32();
|
|
||||||
m_Depth = reader.ReadInt32();
|
|
||||||
m_MipCount = reader.ReadInt32();
|
|
||||||
m_DataSize = reader.ReadUInt32();
|
|
||||||
m_TextureSettings = new GLTextureSettings(reader);
|
|
||||||
if (version >= (2020, 2)) //2020.2 and up
|
|
||||||
{
|
|
||||||
var m_UsageMode = reader.ReadInt32();
|
|
||||||
}
|
|
||||||
var m_IsReadable = reader.ReadBoolean();
|
|
||||||
reader.AlignStream();
|
|
||||||
|
|
||||||
var image_data_size = reader.ReadInt32();
|
|
||||||
if (image_data_size == 0)
|
|
||||||
{
|
|
||||||
m_StreamData = new StreamingInfo(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
|
||||||
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, (int)m_StreamData.size)
|
|
||||||
: new ResourceReader(reader, reader.BaseStream.Position, image_data_size);
|
|
||||||
|
|
||||||
TextureList = new List<Texture2D>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Texture2DArray(ObjectReader reader, IDictionary typeDict) : base(reader)
|
|
||||||
{
|
|
||||||
var parsedTex2dArray = JsonConvert.DeserializeObject<Texture2DArray>(JsonConvert.SerializeObject(typeDict));
|
|
||||||
m_Width = parsedTex2dArray.m_Width;
|
|
||||||
m_Height = parsedTex2dArray.m_Height;
|
|
||||||
m_Depth = parsedTex2dArray.m_Depth;
|
|
||||||
m_Format = parsedTex2dArray.m_Format;
|
|
||||||
m_MipCount = parsedTex2dArray.m_MipCount;
|
|
||||||
m_DataSize = parsedTex2dArray.m_DataSize;
|
|
||||||
m_TextureSettings = parsedTex2dArray.m_TextureSettings;
|
|
||||||
m_StreamData = parsedTex2dArray.m_StreamData;
|
|
||||||
|
|
||||||
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
|
||||||
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
|
|
||||||
: new ResourceReader(reader, parsedTex2dArray.image_data.Offset, parsedTex2dArray.image_data.Size);
|
|
||||||
typeDict.Clear();
|
|
||||||
|
|
||||||
TextureList = new List<Texture2D>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,282 +0,0 @@
|
|||||||
namespace AssetStudio
|
|
||||||
{
|
|
||||||
public enum TextureFormat
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Alpha-only texture format, 8 bit integer.
|
|
||||||
/// </summary>
|
|
||||||
Alpha8 = 1,
|
|
||||||
/// <summary>
|
|
||||||
/// A 16 bits/pixel texture format. Texture stores color with an alpha channel.
|
|
||||||
/// </summary>
|
|
||||||
ARGB4444,
|
|
||||||
/// <summary>
|
|
||||||
/// Three channel (RGB) texture format, 8-bits unsigned integer per channel.
|
|
||||||
/// </summary>
|
|
||||||
RGB24,
|
|
||||||
/// <summary>
|
|
||||||
/// Four channel (RGBA) texture format, 8-bits unsigned integer per channel.
|
|
||||||
/// </summary>
|
|
||||||
RGBA32,
|
|
||||||
/// <summary>
|
|
||||||
/// Color with alpha texture format, 8-bits per channel.
|
|
||||||
/// </summary>
|
|
||||||
ARGB32,
|
|
||||||
/// <summary>
|
|
||||||
/// </summary>
|
|
||||||
ARGBFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A 16 bit color texture format.
|
|
||||||
/// </summary>
|
|
||||||
RGB565,
|
|
||||||
/// <summary>
|
|
||||||
/// </summary>
|
|
||||||
BGR24,
|
|
||||||
/// <summary>
|
|
||||||
/// Single channel (R) texture format, 16 bit integer.
|
|
||||||
/// </summary>
|
|
||||||
R16,
|
|
||||||
/// <summary>
|
|
||||||
/// Compressed color texture format.
|
|
||||||
/// </summary>
|
|
||||||
DXT1,
|
|
||||||
/// <summary>
|
|
||||||
/// </summary>
|
|
||||||
DXT3,
|
|
||||||
/// <summary>
|
|
||||||
/// Compressed color with alpha channel texture format.
|
|
||||||
/// </summary>
|
|
||||||
DXT5,
|
|
||||||
/// <summary>
|
|
||||||
/// Color and alpha texture format, 4 bit per channel.
|
|
||||||
/// </summary>
|
|
||||||
RGBA4444,
|
|
||||||
/// <summary>
|
|
||||||
/// Color with alpha texture format, 8-bits per channel.
|
|
||||||
/// </summary>
|
|
||||||
BGRA32,
|
|
||||||
/// <summary>
|
|
||||||
/// Scalar (R) texture format, 16 bit floating point.
|
|
||||||
/// </summary>
|
|
||||||
RHalf,
|
|
||||||
/// <summary>
|
|
||||||
/// Two color (RG) texture format, 16 bit floating point per channel.
|
|
||||||
/// </summary>
|
|
||||||
RGHalf,
|
|
||||||
/// <summary>
|
|
||||||
/// RGB color and alpha texture format, 16 bit floating point per channel.
|
|
||||||
/// </summary>
|
|
||||||
RGBAHalf,
|
|
||||||
/// <summary>
|
|
||||||
/// Scalar (R) texture format, 32 bit floating point.
|
|
||||||
/// </summary>
|
|
||||||
RFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// Two color (RG) texture format, 32 bit floating point per channel.
|
|
||||||
/// </summary>
|
|
||||||
RGFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// RGB color and alpha texture format, 32-bit floats per channel.
|
|
||||||
/// </summary>
|
|
||||||
RGBAFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// A format that uses the YUV color space and is often used for video encoding or playback.
|
|
||||||
/// </summary>
|
|
||||||
YUY2,
|
|
||||||
/// <summary>
|
|
||||||
/// RGB HDR format, with 9 bit mantissa per channel and a 5 bit shared exponent.
|
|
||||||
/// </summary>
|
|
||||||
RGB9e5Float,
|
|
||||||
/// <summary>
|
|
||||||
/// </summary>
|
|
||||||
RGBFloat,
|
|
||||||
/// <summary>
|
|
||||||
/// HDR compressed color texture format.
|
|
||||||
/// </summary>
|
|
||||||
BC6H,
|
|
||||||
/// <summary>
|
|
||||||
/// High quality compressed color texture format.
|
|
||||||
/// </summary>
|
|
||||||
BC7,
|
|
||||||
/// <summary>
|
|
||||||
/// Compressed one channel (R) texture format.
|
|
||||||
/// </summary>
|
|
||||||
BC4,
|
|
||||||
/// <summary>
|
|
||||||
/// Compressed two-channel (RG) texture format.
|
|
||||||
/// </summary>
|
|
||||||
BC5,
|
|
||||||
/// <summary>
|
|
||||||
/// Compressed color texture format with Crunch compression for smaller storage sizes.
|
|
||||||
/// </summary>
|
|
||||||
DXT1Crunched,
|
|
||||||
/// <summary>
|
|
||||||
/// Compressed color with alpha channel texture format with Crunch compression for smaller storage sizes.
|
|
||||||
/// </summary>
|
|
||||||
DXT5Crunched,
|
|
||||||
/// <summary>
|
|
||||||
/// PowerVR (iOS) 2 bits/pixel compressed color texture format.
|
|
||||||
/// </summary>
|
|
||||||
PVRTC_RGB2,
|
|
||||||
/// <summary>
|
|
||||||
/// PowerVR (iOS) 2 bits/pixel compressed with alpha channel texture format.
|
|
||||||
/// </summary>
|
|
||||||
PVRTC_RGBA2,
|
|
||||||
/// <summary>
|
|
||||||
/// PowerVR (iOS) 4 bits/pixel compressed color texture format.
|
|
||||||
/// </summary>
|
|
||||||
PVRTC_RGB4,
|
|
||||||
/// <summary>
|
|
||||||
/// PowerVR (iOS) 4 bits/pixel compressed with alpha channel texture format.
|
|
||||||
/// </summary>
|
|
||||||
PVRTC_RGBA4,
|
|
||||||
/// <summary>
|
|
||||||
/// ETC (GLES2.0) 4 bits/pixel compressed RGB texture format.
|
|
||||||
/// </summary>
|
|
||||||
ETC_RGB4,
|
|
||||||
/// <summary>
|
|
||||||
/// ATC (ATITC) 4 bits/pixel compressed RGB texture format.
|
|
||||||
/// </summary>
|
|
||||||
ATC_RGB4,
|
|
||||||
/// <summary>
|
|
||||||
/// ATC (ATITC) 8 bits/pixel compressed RGB texture format.
|
|
||||||
/// </summary>
|
|
||||||
ATC_RGBA8,
|
|
||||||
/// <summary>
|
|
||||||
/// ETC2 / EAC (GL ES 3.0) 4 bits/pixel compressed unsigned single-channel texture format.
|
|
||||||
/// </summary>
|
|
||||||
EAC_R = 41,
|
|
||||||
/// <summary>
|
|
||||||
/// ETC2 / EAC (GL ES 3.0) 4 bits/pixel compressed signed single-channel texture format.
|
|
||||||
/// </summary>
|
|
||||||
EAC_R_SIGNED,
|
|
||||||
/// <summary>
|
|
||||||
/// ETC2 / EAC (GL ES 3.0) 8 bits/pixel compressed unsigned dual-channel (RG) texture format.
|
|
||||||
/// </summary>
|
|
||||||
EAC_RG,
|
|
||||||
/// <summary>
|
|
||||||
/// ETC2 / EAC (GL ES 3.0) 8 bits/pixel compressed signed dual-channel (RG) texture format.
|
|
||||||
/// </summary>
|
|
||||||
EAC_RG_SIGNED,
|
|
||||||
/// <summary>
|
|
||||||
/// ETC2 (GL ES 3.0) 4 bits/pixel compressed RGB texture format.
|
|
||||||
/// </summary>
|
|
||||||
ETC2_RGB,
|
|
||||||
/// <summary>
|
|
||||||
/// ETC2 (GL ES 3.0) 4 bits/pixel RGB+1-bit alpha texture format.
|
|
||||||
/// </summary>
|
|
||||||
ETC2_RGBA1,
|
|
||||||
/// <summary>
|
|
||||||
/// ETC2 (GL ES 3.0) 8 bits/pixel compressed RGBA texture format.
|
|
||||||
/// </summary>
|
|
||||||
ETC2_RGBA8,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (4x4 pixel block in 128 bits) compressed RGB texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_RGB_4x4,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (5x5 pixel block in 128 bits) compressed RGB texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_RGB_5x5,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (6x6 pixel block in 128 bits) compressed RGB texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_RGB_6x6,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (8x8 pixel block in 128 bits) compressed RGB texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_RGB_8x8,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (10x10 pixel block in 128 bits) compressed RGB texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_RGB_10x10,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (12x12 pixel block in 128 bits) compressed RGB texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_RGB_12x12,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (4x4 pixel block in 128 bits) compressed RGBA texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_RGBA_4x4,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (5x5 pixel block in 128 bits) compressed RGBA texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_RGBA_5x5,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (6x6 pixel block in 128 bits) compressed RGBA texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_RGBA_6x6,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (8x8 pixel block in 128 bits) compressed RGBA texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_RGBA_8x8,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (10x10 pixel block in 128 bits) compressed RGBA texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_RGBA_10x10,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (12x12 pixel block in 128 bits) compressed RGBA texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_RGBA_12x12,
|
|
||||||
/// <summary>
|
|
||||||
/// ETC 4 bits/pixel compressed RGB texture format.
|
|
||||||
/// </summary>
|
|
||||||
ETC_RGB4_3DS,
|
|
||||||
/// <summary>
|
|
||||||
/// ETC 4 bits/pixel RGB + 4 bits/pixel Alpha compressed texture format.
|
|
||||||
/// </summary>
|
|
||||||
ETC_RGBA8_3DS,
|
|
||||||
/// <summary>
|
|
||||||
/// Two color (RG) texture format, 8-bits per channel.
|
|
||||||
/// </summary>
|
|
||||||
RG16,
|
|
||||||
/// <summary>
|
|
||||||
/// Single channel (R) texture format, 8 bit integer.
|
|
||||||
/// </summary>
|
|
||||||
R8,
|
|
||||||
/// <summary>
|
|
||||||
/// Compressed color texture format with Crunch compression for smaller storage sizes.
|
|
||||||
/// </summary>
|
|
||||||
ETC_RGB4Crunched,
|
|
||||||
/// <summary>
|
|
||||||
/// Compressed color with alpha channel texture format using Crunch compression for smaller storage sizes.
|
|
||||||
/// </summary>
|
|
||||||
ETC2_RGBA8Crunched,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (4x4 pixel block in 128 bits) compressed RGB(A) HDR texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_HDR_4x4,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (5x5 pixel block in 128 bits) compressed RGB(A) HDR texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_HDR_5x5,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (6x6 pixel block in 128 bits) compressed RGB(A) HDR texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_HDR_6x6,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (8x8 pixel block in 128 bits) compressed RGB(A) texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_HDR_8x8,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (10x10 pixel block in 128 bits) compressed RGB(A) HDR texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_HDR_10x10,
|
|
||||||
/// <summary>
|
|
||||||
/// ASTC (12x12 pixel block in 128 bits) compressed RGB(A) HDR texture format.
|
|
||||||
/// </summary>
|
|
||||||
ASTC_HDR_12x12,
|
|
||||||
/// <summary>
|
|
||||||
/// Two channel (RG) texture format, 16-bits unsigned integer per channel.
|
|
||||||
/// </summary>
|
|
||||||
RG32,
|
|
||||||
/// <summary>
|
|
||||||
/// Three channel (RGB) texture format, 16-bits unsigned integer per channel.
|
|
||||||
/// </summary>
|
|
||||||
RGB48,
|
|
||||||
/// <summary>
|
|
||||||
/// Four channel (RGBA) texture format, 16-bits unsigned integer per channel.
|
|
||||||
/// </summary>
|
|
||||||
RGBA64,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -34,7 +34,7 @@ namespace AssetStudio
|
|||||||
var m_ProxyHeight = reader.ReadUInt32();
|
var m_ProxyHeight = reader.ReadUInt32();
|
||||||
Width = reader.ReadUInt32();
|
Width = reader.ReadUInt32();
|
||||||
Height = reader.ReadUInt32();
|
Height = reader.ReadUInt32();
|
||||||
if (version >= (2017, 2)) //2017.2 and up
|
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
|
||||||
{
|
{
|
||||||
var m_PixelAspecRatioNum = reader.ReadUInt32();
|
var m_PixelAspecRatioNum = reader.ReadUInt32();
|
||||||
var m_PixelAspecRatioDen = reader.ReadUInt32();
|
var m_PixelAspecRatioDen = reader.ReadUInt32();
|
||||||
@@ -46,7 +46,7 @@ namespace AssetStudio
|
|||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
var m_AudioSampleRate = reader.ReadUInt32Array();
|
var m_AudioSampleRate = reader.ReadUInt32Array();
|
||||||
var m_AudioLanguage = reader.ReadStringArray();
|
var m_AudioLanguage = reader.ReadStringArray();
|
||||||
if (version >= 2020) //2020.1 and up
|
if (version[0] >= 2020) //2020.1 and up
|
||||||
{
|
{
|
||||||
var m_VideoShadersSize = reader.ReadInt32();
|
var m_VideoShadersSize = reader.ReadInt32();
|
||||||
var m_VideoShaders = new PPtr<Shader>[m_VideoShadersSize];
|
var m_VideoShaders = new PPtr<Shader>[m_VideoShadersSize];
|
||||||
@@ -57,7 +57,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
m_ExternalResources = new StreamedResource(reader);
|
m_ExternalResources = new StreamedResource(reader);
|
||||||
m_HasSplitAlpha = reader.ReadBoolean();
|
m_HasSplitAlpha = reader.ReadBoolean();
|
||||||
if (version >= 2020) //2020.1 and up
|
if (version[0] >= 2020) //2020.1 and up
|
||||||
{
|
{
|
||||||
var m_sRGB = reader.ReadBoolean();
|
var m_sRGB = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,149 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
using static AssetStudio.EndianSpanReader;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
|
||||||
public enum CubismSDKVersion : byte
|
|
||||||
{
|
|
||||||
V30 = 1,
|
|
||||||
V33,
|
|
||||||
V40,
|
|
||||||
V42,
|
|
||||||
V50
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class CubismModel : IDisposable
|
|
||||||
{
|
|
||||||
public CubismSDKVersion Version { get; }
|
|
||||||
public string VersionDescription { get; }
|
|
||||||
public float CanvasWidth { get; }
|
|
||||||
public float CanvasHeight { get; }
|
|
||||||
public float CentralPosX { get; }
|
|
||||||
public float CentralPosY { get; }
|
|
||||||
public float PixelPerUnit { get; }
|
|
||||||
public uint PartCount { get; }
|
|
||||||
public uint ParamCount { get; }
|
|
||||||
public HashSet<string> PartNames { get; }
|
|
||||||
public HashSet<string> ParamNames { get; }
|
|
||||||
|
|
||||||
private byte[] modelData;
|
|
||||||
private int modelDataSize;
|
|
||||||
private bool isBigEndian;
|
|
||||||
|
|
||||||
public CubismModel(MonoBehaviour moc)
|
|
||||||
{
|
|
||||||
var reader = moc.reader;
|
|
||||||
reader.Reset();
|
|
||||||
reader.Position += 28; //PPtr<GameObject> m_GameObject, m_Enabled, PPtr<MonoScript>
|
|
||||||
reader.ReadAlignedString(); //m_Name
|
|
||||||
modelDataSize = (int)reader.ReadUInt32();
|
|
||||||
modelData = BigArrayPool<byte>.Shared.Rent(modelDataSize);
|
|
||||||
_ = reader.Read(modelData, 0, modelDataSize);
|
|
||||||
|
|
||||||
var sdkVer = modelData[4];
|
|
||||||
if (Enum.IsDefined(typeof(CubismSDKVersion), sdkVer))
|
|
||||||
{
|
|
||||||
Version = (CubismSDKVersion)sdkVer;
|
|
||||||
VersionDescription = ParseVersion();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var msg = $"Unknown SDK version ({sdkVer})";
|
|
||||||
VersionDescription = msg;
|
|
||||||
Version = 0;
|
|
||||||
Logger.Warning($"Live2D model \"{moc.m_Name}\": " + msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
isBigEndian = BitConverter.ToBoolean(modelData, 5);
|
|
||||||
|
|
||||||
//offsets
|
|
||||||
var countInfoTableOffset = (int)SpanToUint32(modelData, 64, isBigEndian);
|
|
||||||
var canvasInfoOffset = (int)SpanToUint32(modelData, 68, isBigEndian);
|
|
||||||
var partIdsOffset = SpanToUint32(modelData, 76, isBigEndian);
|
|
||||||
var parameterIdsOffset = SpanToUint32(modelData, 264, isBigEndian);
|
|
||||||
|
|
||||||
//canvas
|
|
||||||
PixelPerUnit = ToSingle(modelData, canvasInfoOffset, isBigEndian);
|
|
||||||
CentralPosX = ToSingle(modelData, canvasInfoOffset + 4, isBigEndian);
|
|
||||||
CentralPosY = ToSingle(modelData, canvasInfoOffset + 8, isBigEndian);
|
|
||||||
CanvasWidth = ToSingle(modelData, canvasInfoOffset + 12, isBigEndian);
|
|
||||||
CanvasHeight = ToSingle(modelData, canvasInfoOffset + 16, isBigEndian);
|
|
||||||
|
|
||||||
//model
|
|
||||||
PartCount = SpanToUint32(modelData, countInfoTableOffset, isBigEndian);
|
|
||||||
ParamCount = SpanToUint32(modelData, countInfoTableOffset + 20, isBigEndian);
|
|
||||||
PartNames = ReadMocStringHashSet(modelData, (int)partIdsOffset, (int)PartCount);
|
|
||||||
ParamNames = ReadMocStringHashSet(modelData, (int)parameterIdsOffset, (int)ParamCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveMoc3(string savePath)
|
|
||||||
{
|
|
||||||
if (!savePath.EndsWith(".moc3"))
|
|
||||||
savePath += ".moc3";
|
|
||||||
|
|
||||||
using (var file = File.OpenWrite(savePath))
|
|
||||||
{
|
|
||||||
file.Write(modelData, 0, modelDataSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string ParseVersion()
|
|
||||||
{
|
|
||||||
switch (Version)
|
|
||||||
{
|
|
||||||
case CubismSDKVersion.V30:
|
|
||||||
return "SDK3.0/Cubism3.0(3.2)";
|
|
||||||
case CubismSDKVersion.V33:
|
|
||||||
return "SDK3.3/Cubism3.3";
|
|
||||||
case CubismSDKVersion.V40:
|
|
||||||
return "SDK4.0/Cubism4.0";
|
|
||||||
case CubismSDKVersion.V42:
|
|
||||||
return "SDK4.2/Cubism4.2";
|
|
||||||
case CubismSDKVersion.V50:
|
|
||||||
return "SDK5.0/Cubism5.0";
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static float ToSingle(ReadOnlySpan<byte> data, int index, bool isBigEndian) //net framework ver
|
|
||||||
{
|
|
||||||
var bytes = data.Slice(index, index + 4).ToArray();
|
|
||||||
if ((isBigEndian && BitConverter.IsLittleEndian) || (!isBigEndian && !BitConverter.IsLittleEndian))
|
|
||||||
(bytes[0], bytes[1], bytes[2], bytes[3]) = (bytes[3], bytes[2], bytes[1], bytes[0]);
|
|
||||||
|
|
||||||
return BitConverter.ToSingle(bytes, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static HashSet<string> ReadMocStringHashSet(ReadOnlySpan<byte> data, int index, int count)
|
|
||||||
{
|
|
||||||
const int strLen = 64;
|
|
||||||
var strHashSet = new HashSet<string>();
|
|
||||||
for (var i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
if (index + i * strLen <= data.Length)
|
|
||||||
{
|
|
||||||
var buff = data.Slice(index + i * strLen, strLen);
|
|
||||||
strHashSet.Add(Encoding.UTF8.GetString(buff.ToArray()).TrimEnd('\0'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return strHashSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
BigArrayPool<byte>.Shared.Return(modelData, clearArray: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Dispose(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Buffers.Binary;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
|
||||||
public static class EndianSpanReader
|
|
||||||
{
|
|
||||||
public static uint SpanToUint32(Span<byte> data, int start, bool isBigEndian)
|
|
||||||
{
|
|
||||||
return isBigEndian
|
|
||||||
? BinaryPrimitives.ReadUInt32BigEndian(data.Slice(start))
|
|
||||||
: BinaryPrimitives.ReadUInt32LittleEndian(data.Slice(start));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static uint SpanToUint16(Span<byte> data, int start, bool isBigEndian)
|
|
||||||
{
|
|
||||||
return isBigEndian
|
|
||||||
? BinaryPrimitives.ReadUInt16BigEndian(data.Slice(start))
|
|
||||||
: BinaryPrimitives.ReadUInt16LittleEndian(data.Slice(start));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long SpanToInt64(Span<byte> data, int start, bool isBigEndian)
|
|
||||||
{
|
|
||||||
return isBigEndian
|
|
||||||
? BinaryPrimitives.ReadInt64BigEndian(data.Slice(start))
|
|
||||||
: BinaryPrimitives.ReadInt64LittleEndian(data.Slice(start));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -40,7 +40,7 @@ namespace AssetStudio
|
|||||||
if (encoding?.CodePage == 1200) //Unicode (UTF-16LE)
|
if (encoding?.CodePage == 1200) //Unicode (UTF-16LE)
|
||||||
return reader.ReadUnicodeStringToNull(maxLength * 2);
|
return reader.ReadUnicodeStringToNull(maxLength * 2);
|
||||||
|
|
||||||
Span<byte> bytes = stackalloc byte[maxLength];
|
var bytes = new List<byte>();
|
||||||
var count = 0;
|
var count = 0;
|
||||||
while (reader.BaseStream.Position != reader.BaseStream.Length && count < maxLength)
|
while (reader.BaseStream.Position != reader.BaseStream.Length && count < maxLength)
|
||||||
{
|
{
|
||||||
@@ -49,10 +49,9 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bytes[count] = b;
|
bytes.Add(b);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
bytes = bytes.Slice(0, count);
|
|
||||||
return encoding?.GetString(bytes.ToArray()) ?? Encoding.UTF8.GetString(bytes.ToArray());
|
return encoding?.GetString(bytes.ToArray()) ?? Encoding.UTF8.GetString(bytes.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System.IO;
|
||||||
using System.IO;
|
using System.Linq;
|
||||||
using static AssetStudio.EndianSpanReader;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -38,69 +37,66 @@ namespace AssetStudio
|
|||||||
case "UnityWebData1.0":
|
case "UnityWebData1.0":
|
||||||
return FileType.WebFile;
|
return FileType.WebFile;
|
||||||
default:
|
default:
|
||||||
{
|
|
||||||
var buff = ReadBytes(40).AsSpan();
|
|
||||||
var magic = Span<byte>.Empty;
|
|
||||||
Position = 0;
|
|
||||||
|
|
||||||
magic = buff.Length > 2 ? buff.Slice(0, 2) : magic;
|
|
||||||
if (magic.SequenceEqual(gzipMagic))
|
|
||||||
{
|
{
|
||||||
return FileType.GZipFile;
|
byte[] 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;
|
||||||
|
}
|
||||||
|
magic = ReadBytes(4);
|
||||||
|
Position = 0;
|
||||||
|
if (zipMagic.SequenceEqual(magic) || zipSpannedMagic.SequenceEqual(magic))
|
||||||
|
return FileType.ZipFile;
|
||||||
|
return FileType.ResourceFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
magic = buff.Length > 38 ? buff.Slice(32, 6) : magic;
|
|
||||||
if (magic.SequenceEqual(brotliMagic))
|
|
||||||
{
|
|
||||||
return FileType.BrotliFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsSerializedFile(buff))
|
|
||||||
{
|
|
||||||
return FileType.AssetsFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
magic = buff.Length > 4 ? buff.Slice(0, 4): magic;
|
|
||||||
if (magic.SequenceEqual(zipMagic) || magic.SequenceEqual(zipSpannedMagic))
|
|
||||||
{
|
|
||||||
return FileType.ZipFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FileType.ResourceFile;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsSerializedFile(Span<byte> buff)
|
private bool IsSerializedFile()
|
||||||
{
|
{
|
||||||
var fileSize = BaseStream.Length;
|
var fileSize = BaseStream.Length;
|
||||||
if (fileSize < 20)
|
if (fileSize < 20)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var isBigEndian = Endian == EndianType.BigEndian;
|
var m_MetadataSize = ReadUInt32();
|
||||||
|
long m_FileSize = ReadUInt32();
|
||||||
//var m_MetadataSize = SpanToUint32(buff, 0, isBigEndian);
|
var m_Version = ReadUInt32();
|
||||||
long m_FileSize = SpanToUint32(buff, 4, isBigEndian);
|
long m_DataOffset = ReadUInt32();
|
||||||
var m_Version = SpanToUint32(buff, 8, isBigEndian);
|
var m_Endianess = ReadByte();
|
||||||
long m_DataOffset = SpanToUint32(buff, 12, isBigEndian);
|
var m_Reserved = ReadBytes(3);
|
||||||
//var m_Endianess = buff[16];
|
|
||||||
//var m_Reserved = buff.Slice(17, 3);
|
|
||||||
if (m_Version >= 22)
|
if (m_Version >= 22)
|
||||||
{
|
{
|
||||||
if (fileSize < 48)
|
if (fileSize < 48)
|
||||||
{
|
{
|
||||||
|
Position = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//m_MetadataSize = SpanToUint32(buff, 20, isBigEndian);
|
m_MetadataSize = ReadUInt32();
|
||||||
m_FileSize = SpanToInt64(buff, 24, isBigEndian);
|
m_FileSize = ReadInt64();
|
||||||
m_DataOffset = SpanToInt64(buff, 32, isBigEndian);
|
m_DataOffset = ReadInt64();
|
||||||
}
|
}
|
||||||
if (m_FileSize != fileSize || m_DataOffset > fileSize)
|
Position = 0;
|
||||||
|
if (m_FileSize != fileSize)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (m_DataOffset > fileSize)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
75
AssetStudio/LZ4/LZ4.cs
Normal file
75
AssetStudio/LZ4/LZ4.cs
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
|
{
|
||||||
|
public class LZ4
|
||||||
|
{
|
||||||
|
public static LZ4 Instance => new LZ4();
|
||||||
|
|
||||||
|
public virtual int Decompress(ReadOnlySpan<byte> cmp, Span<byte> dec)
|
||||||
|
{
|
||||||
|
int cmpPos = 0;
|
||||||
|
int decPos = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
var (encCount, litCount) = GetLiteralToken(cmp, ref cmpPos);
|
||||||
|
|
||||||
|
//Copy literal chunk
|
||||||
|
litCount = GetLength(litCount, cmp, ref cmpPos);
|
||||||
|
|
||||||
|
cmp.Slice(cmpPos, litCount).CopyTo(dec.Slice(decPos));
|
||||||
|
|
||||||
|
cmpPos += litCount;
|
||||||
|
decPos += litCount;
|
||||||
|
|
||||||
|
if (cmpPos >= cmp.Length)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Copy compressed chunk
|
||||||
|
int back = GetChunkEnd(cmp, ref cmpPos);
|
||||||
|
|
||||||
|
encCount = GetLength(encCount, cmp, ref cmpPos) + 4;
|
||||||
|
|
||||||
|
int encPos = decPos - back;
|
||||||
|
|
||||||
|
if (encCount <= back)
|
||||||
|
{
|
||||||
|
dec.Slice(encPos, encCount).CopyTo(dec.Slice(decPos));
|
||||||
|
decPos += encCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (encCount-- > 0)
|
||||||
|
{
|
||||||
|
dec[decPos++] = dec[encPos++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (cmpPos < cmp.Length && decPos < dec.Length);
|
||||||
|
|
||||||
|
return decPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual (int encCount, int litCount) GetLiteralToken(ReadOnlySpan<byte> cmp, ref int cmpPos) =>
|
||||||
|
((cmp[cmpPos] >> 0) & 0xf, (cmp[cmpPos++] >> 4) & 0xf);
|
||||||
|
|
||||||
|
protected virtual int GetChunkEnd(ReadOnlySpan<byte> cmp, ref int cmpPos) =>
|
||||||
|
cmp[cmpPos++] << 0 | cmp[cmpPos++] << 8;
|
||||||
|
|
||||||
|
protected virtual int GetLength(int length, ReadOnlySpan<byte> cmp, ref int cmpPos)
|
||||||
|
{
|
||||||
|
byte sum;
|
||||||
|
|
||||||
|
if (length == 0xf)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
length += sum = cmp[cmpPos++];
|
||||||
|
} while (sum == 0xff);
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
AssetStudio/LZ4/LZ4Inv.cs
Normal file
15
AssetStudio/LZ4/LZ4Inv.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
|
{
|
||||||
|
public class LZ4Inv : LZ4
|
||||||
|
{
|
||||||
|
public new static LZ4Inv Instance => new LZ4Inv();
|
||||||
|
|
||||||
|
protected override (int encCount, int litCount) GetLiteralToken(ReadOnlySpan<byte> cmp, ref int cmpPos) =>
|
||||||
|
((cmp[cmpPos] >> 4) & 0xf, (cmp[cmpPos++] >> 0) & 0xf);
|
||||||
|
|
||||||
|
protected override int GetChunkEnd(ReadOnlySpan<byte> cmp, ref int cmpPos) =>
|
||||||
|
cmp[cmpPos++] << 8 | cmp[cmpPos++] << 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ namespace AssetStudio
|
|||||||
public BuildTarget platform;
|
public BuildTarget platform;
|
||||||
public SerializedFileFormatVersion m_Version;
|
public SerializedFileFormatVersion m_Version;
|
||||||
|
|
||||||
public UnityVersion version => assetsFile.version;
|
public int[] version => assetsFile.version;
|
||||||
public BuildType buildType => assetsFile.buildType;
|
public BuildType buildType => assetsFile.buildType;
|
||||||
|
|
||||||
public ObjectReader(EndianBinaryReader reader, SerializedFile assetsFile, ObjectInfo objectInfo) : base(reader.BaseStream, reader.Endian)
|
public ObjectReader(EndianBinaryReader reader, SerializedFile assetsFile, ObjectInfo objectInfo) : base(reader.BaseStream, reader.Endian)
|
||||||
|
|||||||
@@ -7,31 +7,25 @@ namespace AssetStudio
|
|||||||
private bool needSearch;
|
private bool needSearch;
|
||||||
private string path;
|
private string path;
|
||||||
private SerializedFile assetsFile;
|
private SerializedFile assetsFile;
|
||||||
|
private long offset;
|
||||||
private long size;
|
private long size;
|
||||||
private BinaryReader reader;
|
private BinaryReader reader;
|
||||||
|
|
||||||
public int Size
|
public int Size { get => (int)size; }
|
||||||
{
|
|
||||||
get => (int)size;
|
|
||||||
set => size = value;
|
|
||||||
}
|
|
||||||
public long Offset { get; set; }
|
|
||||||
|
|
||||||
public ResourceReader() { }
|
|
||||||
|
|
||||||
public ResourceReader(string path, SerializedFile assetsFile, long offset, long size)
|
public ResourceReader(string path, SerializedFile assetsFile, long offset, long size)
|
||||||
{
|
{
|
||||||
needSearch = true;
|
needSearch = true;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.assetsFile = assetsFile;
|
this.assetsFile = assetsFile;
|
||||||
this.Offset = offset;
|
this.offset = offset;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceReader(BinaryReader reader, long offset, long size)
|
public ResourceReader(BinaryReader reader, long offset, long size)
|
||||||
{
|
{
|
||||||
this.reader = reader;
|
this.reader = reader;
|
||||||
this.Offset = offset;
|
this.offset = offset;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,12 +52,8 @@ namespace AssetStudio
|
|||||||
if (File.Exists(resourceFilePath))
|
if (File.Exists(resourceFilePath))
|
||||||
{
|
{
|
||||||
needSearch = false;
|
needSearch = false;
|
||||||
if (assetsFile.assetsManager.resourceFileReaders.TryGetValue(resourceFileName, out reader))
|
|
||||||
{
|
|
||||||
return reader;
|
|
||||||
}
|
|
||||||
reader = new BinaryReader(File.OpenRead(resourceFilePath));
|
reader = new BinaryReader(File.OpenRead(resourceFilePath));
|
||||||
assetsFile.assetsManager.resourceFileReaders.TryAdd(resourceFileName, reader);
|
assetsFile.assetsManager.resourceFileReaders.Add(resourceFileName, reader);
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
throw new FileNotFoundException($"Can't find the resource file {resourceFileName}");
|
throw new FileNotFoundException($"Can't find the resource file {resourceFileName}");
|
||||||
@@ -77,27 +67,21 @@ namespace AssetStudio
|
|||||||
public byte[] GetData()
|
public byte[] GetData()
|
||||||
{
|
{
|
||||||
var binaryReader = GetReader();
|
var binaryReader = GetReader();
|
||||||
lock (binaryReader)
|
binaryReader.BaseStream.Position = offset;
|
||||||
{
|
return binaryReader.ReadBytes((int)size);
|
||||||
binaryReader.BaseStream.Position = Offset;
|
|
||||||
return binaryReader.ReadBytes((int) size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GetData(byte[] buff)
|
public void GetData(byte[] buff)
|
||||||
{
|
{
|
||||||
var binaryReader = GetReader();
|
var binaryReader = GetReader();
|
||||||
lock (binaryReader)
|
binaryReader.BaseStream.Position = offset;
|
||||||
{
|
binaryReader.Read(buff, 0, (int)size);
|
||||||
binaryReader.BaseStream.Position = Offset;
|
|
||||||
binaryReader.Read(buff, 0, (int) size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteData(string path)
|
public void WriteData(string path)
|
||||||
{
|
{
|
||||||
var binaryReader = GetReader();
|
var binaryReader = GetReader();
|
||||||
binaryReader.BaseStream.Position = Offset;
|
binaryReader.BaseStream.Position = offset;
|
||||||
using (var writer = File.OpenWrite(path))
|
using (var writer = File.OpenWrite(path))
|
||||||
{
|
{
|
||||||
binaryReader.BaseStream.CopyTo(writer, size);
|
binaryReader.BaseStream.CopyTo(writer, size);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace AssetStudio
|
|||||||
public string fullName;
|
public string fullName;
|
||||||
public string originalPath;
|
public string originalPath;
|
||||||
public string fileName;
|
public string fileName;
|
||||||
public UnityVersion version = new UnityVersion();
|
public int[] version = { 0, 0, 0, 0 };
|
||||||
public BuildType buildType;
|
public BuildType buildType;
|
||||||
public List<Object> Objects;
|
public List<Object> Objects;
|
||||||
public Dictionary<long, Object> ObjectsDic;
|
public Dictionary<long, Object> ObjectsDic;
|
||||||
@@ -73,7 +73,7 @@ namespace AssetStudio
|
|||||||
if (header.m_Version >= SerializedFileFormatVersion.Unknown_7)
|
if (header.m_Version >= SerializedFileFormatVersion.Unknown_7)
|
||||||
{
|
{
|
||||||
unityVersion = reader.ReadStringToNull();
|
unityVersion = reader.ReadStringToNull();
|
||||||
SetVersion(new UnityVersion(unityVersion));
|
SetVersion(unityVersion);
|
||||||
}
|
}
|
||||||
if (header.m_Version >= SerializedFileFormatVersion.Unknown_8)
|
if (header.m_Version >= SerializedFileFormatVersion.Unknown_8)
|
||||||
{
|
{
|
||||||
@@ -217,13 +217,19 @@ namespace AssetStudio
|
|||||||
//reader.AlignStream(16);
|
//reader.AlignStream(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVersion(UnityVersion unityVer)
|
public void SetVersion(string stringVersion)
|
||||||
{
|
{
|
||||||
if (unityVer != null && !unityVer.IsStripped)
|
if (stringVersion != strippedVersion)
|
||||||
{
|
{
|
||||||
unityVersion = unityVer.FullVersion;
|
unityVersion = stringVersion;
|
||||||
buildType = new BuildType(unityVer.BuildType);
|
var buildSplit = Regex.Replace(stringVersion, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
version = unityVer;
|
if (buildSplit.Length == 0)
|
||||||
|
throw new NotSupportedException("Specified Unity version is not in a correct format.\n" +
|
||||||
|
"Specify full Unity version, including letters at the end.\n" +
|
||||||
|
"Example: 2017.4.39f1");
|
||||||
|
buildType = new BuildType(buildSplit[0]);
|
||||||
|
var versionSplit = Regex.Replace(stringVersion, @"\D", ".").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
version = versionSplit.Select(int.Parse).ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,5 +377,9 @@ namespace AssetStudio
|
|||||||
Objects.Add(obj);
|
Objects.Add(obj);
|
||||||
ObjectsDic.Add(obj.m_PathID, obj);
|
ObjectsDic.Add(obj.m_PathID, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsVersionStripped => unityVersion == strippedVersion;
|
||||||
|
|
||||||
|
private const string strippedVersion = "0.0.0";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace AssetStudio
|
|||||||
var readed = reader.Position - reader.byteStart;
|
var readed = reader.Position - reader.byteStart;
|
||||||
if (readed != reader.byteSize)
|
if (readed != reader.byteSize)
|
||||||
{
|
{
|
||||||
Logger.Info($"Failed to read type, read {readed} bytes but expected {reader.byteSize} bytes");
|
Logger.Info($"Error while read type, read {readed} bytes but expected {reader.byteSize} bytes");
|
||||||
}
|
}
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
append = false;
|
append = false;
|
||||||
var size = reader.ReadInt32();
|
var size = reader.ReadInt32();
|
||||||
reader.BaseStream.Position += size;
|
reader.ReadBytes(size);
|
||||||
i += 2;
|
i += 2;
|
||||||
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr);
|
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr);
|
||||||
sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), "int", "size", size);
|
sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), "int", "size", size);
|
||||||
@@ -171,13 +171,13 @@ namespace AssetStudio
|
|||||||
for (int i = 1; i < m_Nodes.Count; i++)
|
for (int i = 1; i < m_Nodes.Count; i++)
|
||||||
{
|
{
|
||||||
var m_Node = m_Nodes[i];
|
var m_Node = m_Nodes[i];
|
||||||
var varNameStr = m_Node.m_Name.Replace("image data", "image_data");
|
var varNameStr = m_Node.m_Name;
|
||||||
obj[varNameStr] = ReadValue(m_Nodes, reader, ref i);
|
obj[varNameStr] = ReadValue(m_Nodes, reader, ref i);
|
||||||
}
|
}
|
||||||
var readed = reader.Position - reader.byteStart;
|
var readed = reader.Position - reader.byteStart;
|
||||||
if (readed != reader.byteSize)
|
if (readed != reader.byteSize)
|
||||||
{
|
{
|
||||||
Logger.Info($"Failed to read type, read {readed} bytes but expected {reader.byteSize} bytes");
|
Logger.Info($"Error while read type, read {readed} bytes but expected {reader.byteSize} bytes");
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@@ -262,13 +262,7 @@ namespace AssetStudio
|
|||||||
case "TypelessData":
|
case "TypelessData":
|
||||||
{
|
{
|
||||||
var size = reader.ReadInt32();
|
var size = reader.ReadInt32();
|
||||||
var dic = new OrderedDictionary
|
value = reader.ReadBytes(size);
|
||||||
{
|
|
||||||
{ "Offset", reader.BaseStream.Position },
|
|
||||||
{ "Size", size }
|
|
||||||
};
|
|
||||||
value = dic;
|
|
||||||
reader.BaseStream.Position += size;
|
|
||||||
i += 2;
|
i += 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,449 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
|
||||||
public class UnityVersion : IComparable
|
|
||||||
{
|
|
||||||
public int Major { get; }
|
|
||||||
public int Minor { get; }
|
|
||||||
public int Patch { get; }
|
|
||||||
public int Build { get; }
|
|
||||||
public string BuildType { get; }
|
|
||||||
public string FullVersion { get; }
|
|
||||||
|
|
||||||
public bool IsStripped => this == (0, 0, 0);
|
|
||||||
|
|
||||||
public UnityVersion(string version)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(version))
|
|
||||||
throw new ArgumentException("Unity version cannot be empty.");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int[] ver = Regex.Matches(version, @"\d+").Cast<Match>().Select(x => int.Parse(x.Value)).ToArray();
|
|
||||||
(Major, Minor, Patch) = (ver[0], ver[1], ver[2]);
|
|
||||||
if (ver.Length == 4)
|
|
||||||
Build = ver[3];
|
|
||||||
FullVersion = version;
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException($"Failed to parse Unity version: \"{version}\".");
|
|
||||||
}
|
|
||||||
|
|
||||||
string[] build = Regex.Matches(version, @"\D+").Cast<Match>().Select(x => x.Value).ToArray();
|
|
||||||
if (build.Length > 2)
|
|
||||||
{
|
|
||||||
BuildType = build[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public UnityVersion(int major = 0, int minor = 0, int patch = 0)
|
|
||||||
{
|
|
||||||
(Major, Minor, Patch) = (major, minor, patch);
|
|
||||||
FullVersion = $"{Major}.{Minor}.{Patch}";
|
|
||||||
if (!IsStripped)
|
|
||||||
{
|
|
||||||
Build = 1;
|
|
||||||
BuildType = "f";
|
|
||||||
FullVersion += $"{BuildType}{Build}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region UnityVer, UnityVer
|
|
||||||
public static bool operator ==(UnityVersion left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return Equals(left, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=(UnityVersion left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return !Equals(left, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >(UnityVersion left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return left?.CompareTo(right) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <(UnityVersion left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return left?.CompareTo(right) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >=(UnityVersion left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return left == right || left > right;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <=(UnityVersion left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return left == right || left < right;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region UnityVer, int
|
|
||||||
public static bool operator ==(UnityVersion left, int right)
|
|
||||||
{
|
|
||||||
return left?.Major == right;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=(UnityVersion left, int right)
|
|
||||||
{
|
|
||||||
return left?.Major != right;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >(UnityVersion left, int right)
|
|
||||||
{
|
|
||||||
return left?.Major > right;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <(UnityVersion left, int right)
|
|
||||||
{
|
|
||||||
return left?.Major < right;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >=(UnityVersion left, int right)
|
|
||||||
{
|
|
||||||
return left?.Major >= right;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <=(UnityVersion left, int right)
|
|
||||||
{
|
|
||||||
return left?.Major <= right;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region UnityVer, (int, int)
|
|
||||||
public static bool operator ==(UnityVersion left, (int, int) right)
|
|
||||||
{
|
|
||||||
return (left?.Major, left?.Minor) == (right.Item1, right.Item2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=(UnityVersion left, (int, int) right)
|
|
||||||
{
|
|
||||||
return (left?.Major, left?.Minor) != (right.Item1, right.Item2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >(UnityVersion left, (int, int) right)
|
|
||||||
{
|
|
||||||
return left?.CompareTo(right) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <(UnityVersion left, (int, int) right)
|
|
||||||
{
|
|
||||||
return left?.CompareTo(right) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >=(UnityVersion left, (int, int) right)
|
|
||||||
{
|
|
||||||
return left == right || left > right;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <=(UnityVersion left, (int, int) right)
|
|
||||||
{
|
|
||||||
return left == right || left < right;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region UnityVer, (int, int, int)
|
|
||||||
public static bool operator ==(UnityVersion left, (int, int, int) right)
|
|
||||||
{
|
|
||||||
return (left?.Major, left?.Minor, left?.Patch) == (right.Item1, right.Item2, right.Item3);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=(UnityVersion left, (int, int, int) right)
|
|
||||||
{
|
|
||||||
return (left?.Major, left?.Minor, left?.Patch) != (right.Item1, right.Item2, right.Item3);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >(UnityVersion left, (int, int, int) right)
|
|
||||||
{
|
|
||||||
return left?.CompareTo(right) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <(UnityVersion left, (int, int, int) right)
|
|
||||||
{
|
|
||||||
return left?.CompareTo(right) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >=(UnityVersion left, (int, int, int) right)
|
|
||||||
{
|
|
||||||
return left == right || left > right;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <=(UnityVersion left, (int, int, int) right)
|
|
||||||
{
|
|
||||||
return left == right || left < right;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region int, UnityVer
|
|
||||||
public static bool operator ==(int left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return left == right?.Major;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=(int left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return left != right?.Major;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >(int left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return left > right?.Major;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <(int left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return left < right?.Major;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >=(int left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return left >= right?.Major;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <=(int left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return left <= right?.Major;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region (int, int), UnityVer
|
|
||||||
public static bool operator ==((int, int) left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return (left.Item1, left.Item2) == (right?.Major, right?.Minor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=((int, int) left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return (left.Item1, left.Item2) != (right?.Major, right?.Minor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >((int, int) left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return right?.CompareTo(left) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <((int, int) left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return right?.CompareTo(left) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >=((int, int) left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return left == right || left > right;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <=((int, int) left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return left == right || left < right;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region (int, int, int), UnityVer
|
|
||||||
public static bool operator ==((int, int, int) left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return (left.Item1, left.Item2, left.Item3) == (right?.Major, right?.Minor, right?.Patch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=((int, int, int) left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return (left.Item1, left.Item2, left.Item3) != (right?.Major, right?.Minor, right?.Patch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >((int, int, int) left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return right?.CompareTo(left) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <((int, int, int) left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return right?.CompareTo(left) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >=((int, int, int) left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return left == right || left > right;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <=((int, int, int) left, UnityVersion right)
|
|
||||||
{
|
|
||||||
return left == right || left < right;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private int CompareTo((int, int) other)
|
|
||||||
{
|
|
||||||
var result = Major.CompareTo(other.Item1);
|
|
||||||
if (result != 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = Minor.CompareTo(other.Item2);
|
|
||||||
if (result != 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int CompareTo((int, int, int) other)
|
|
||||||
{
|
|
||||||
var result = CompareTo((other.Item1, other.Item2));
|
|
||||||
if (result != 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = Patch.CompareTo(other.Item3);
|
|
||||||
if (result != 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int CompareTo(UnityVersion other)
|
|
||||||
{
|
|
||||||
return CompareTo((other.Major, other.Minor, other.Patch));
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool Equals(UnityVersion other)
|
|
||||||
{
|
|
||||||
return (Major, Minor, Patch) == (other.Major, other.Minor, other.Patch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object other)
|
|
||||||
{
|
|
||||||
return other is UnityVersion otherUnityVer && Equals(otherUnityVer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
var result = Major * 31;
|
|
||||||
result = result * 31 + Minor;
|
|
||||||
result = result * 31 + Patch;
|
|
||||||
result = result * 31 + Build;
|
|
||||||
|
|
||||||
return result.GetHashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int CompareTo(object obj)
|
|
||||||
{
|
|
||||||
return CompareTo((UnityVersion)obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed override string ToString()
|
|
||||||
{
|
|
||||||
return FullVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Tuple<int, int, int> ToTuple()
|
|
||||||
{
|
|
||||||
return new Tuple<int, int, int>(Major, Minor, Patch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] ToArray()
|
|
||||||
{
|
|
||||||
return new[] {Major, Minor, Patch};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class UnityVersionExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if the Unity version is within the range limits specified by the "lowerLimit" and "upperLimit" attributes.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="ver"></param>
|
|
||||||
/// <param name="lowerLimit">Minimal version. Included in the range.</param>
|
|
||||||
/// <param name="upperLimit">Maximal version. Not included in the range.</param>
|
|
||||||
/// <returns><see langword="true"/> if the Unity version is within the specified range; otherwise <see langword="false"/>.</returns>
|
|
||||||
/// <remarks>[lowerLimit, upperLimit)</remarks>
|
|
||||||
public static bool IsInRange(this UnityVersion ver, UnityVersion lowerLimit, UnityVersion upperLimit)
|
|
||||||
{
|
|
||||||
return ver >= lowerLimit && ver < upperLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsInRange(this UnityVersion ver, int lowerLimit, UnityVersion upperLimit)
|
|
||||||
{
|
|
||||||
return ver.Major >= lowerLimit && ver < upperLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsInRange(this UnityVersion ver, (int, int) lowerLimit, UnityVersion upperLimit)
|
|
||||||
{
|
|
||||||
return ver >= lowerLimit && ver < upperLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsInRange(this UnityVersion ver, (int, int, int) lowerLimit, UnityVersion upperLimit)
|
|
||||||
{
|
|
||||||
return ver >= lowerLimit && ver < upperLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsInRange(this UnityVersion ver, UnityVersion lowerLimit, int upperLimit)
|
|
||||||
{
|
|
||||||
return ver >= lowerLimit && ver.Major < upperLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsInRange(this UnityVersion ver, UnityVersion lowerLimit, (int, int) upperLimit)
|
|
||||||
{
|
|
||||||
return ver >= lowerLimit && ver < upperLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsInRange(this UnityVersion ver, UnityVersion lowerLimit, (int, int, int) upperLimit)
|
|
||||||
{
|
|
||||||
return ver >= lowerLimit && ver < upperLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsInRange(this UnityVersion ver, int lowerLimit, int upperLimit)
|
|
||||||
{
|
|
||||||
return ver.Major >= lowerLimit && ver.Major < upperLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsInRange(this UnityVersion ver, int lowerLimit, (int, int) upperLimit)
|
|
||||||
{
|
|
||||||
return ver.Major >= lowerLimit && ver < upperLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsInRange(this UnityVersion ver, int lowerLimit, (int, int, int) upperLimit)
|
|
||||||
{
|
|
||||||
return ver.Major >= lowerLimit && ver < upperLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsInRange(this UnityVersion ver, (int, int) lowerLimit, int upperLimit)
|
|
||||||
{
|
|
||||||
return ver >= lowerLimit && ver.Major < upperLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsInRange(this UnityVersion ver, (int, int, int) lowerLimit, int upperLimit)
|
|
||||||
{
|
|
||||||
return ver >= lowerLimit && ver.Major < upperLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsInRange(this UnityVersion ver, (int, int) lowerLimit, (int, int) upperLimit)
|
|
||||||
{
|
|
||||||
return ver >= lowerLimit && ver < upperLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsInRange(this UnityVersion ver, (int, int) lowerLimit, (int, int, int) upperLimit)
|
|
||||||
{
|
|
||||||
return ver >= lowerLimit && ver < upperLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsInRange(this UnityVersion ver, (int, int, int) lowerLimit, (int, int) upperLimit)
|
|
||||||
{
|
|
||||||
return ver >= lowerLimit && ver < upperLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsInRange(this UnityVersion ver, (int, int, int) lowerLimit, (int, int, int) upperLimit)
|
|
||||||
{
|
|
||||||
return ver >= lowerLimit && ver < upperLimit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,10 +3,10 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFrameworks>net472;net6.0;net7.0;net8.0</TargetFrameworks>
|
<TargetFrameworks>net472;net6.0;net7.0;net8.0</TargetFrameworks>
|
||||||
<AssemblyTitle>AssetStudioMod by aelurum</AssemblyTitle>
|
<AssemblyTitle>ArknightsStudio by aelurum</AssemblyTitle>
|
||||||
<AssemblyName>AssetStudioModCLI</AssemblyName>
|
<AssemblyName>ArknightsStudioCLI</AssemblyName>
|
||||||
<Version>0.18.0.0</Version>
|
<Version>1.2.0</Version>
|
||||||
<Copyright>Copyright © Perfare; Copyright © aelurum 2023-2024</Copyright>
|
<Copyright>Copyright © Perfare; Copyright © aelurum 2025</Copyright>
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
<DebugType>embedded</DebugType>
|
<DebugType>embedded</DebugType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
using AssetStudio;
|
using AssetStudio;
|
||||||
using AssetStudioCLI.Options;
|
using AssetStudioCLI.Options;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AssetStudioCLI
|
namespace AssetStudioCLI
|
||||||
{
|
{
|
||||||
@@ -17,29 +16,21 @@ namespace AssetStudioCLI
|
|||||||
|
|
||||||
internal class CLILogger : ILogger
|
internal class CLILogger : ILogger
|
||||||
{
|
{
|
||||||
public string LogName;
|
|
||||||
public string LogPath;
|
|
||||||
|
|
||||||
private static BlockingCollection<string> logMessageCollection = new BlockingCollection<string>();
|
|
||||||
private readonly LogOutputMode logOutput;
|
private readonly LogOutputMode logOutput;
|
||||||
private readonly LoggerEvent logMinLevel;
|
private readonly LoggerEvent logMinLevel;
|
||||||
|
public string LogName;
|
||||||
|
public string LogPath;
|
||||||
|
|
||||||
public CLILogger()
|
public CLILogger()
|
||||||
{
|
{
|
||||||
logOutput = CLIOptions.o_logOutput.Value;
|
logOutput = CLIOptions.o_logOutput.Value;
|
||||||
logMinLevel = CLIOptions.o_logLevel.Value;
|
logMinLevel = CLIOptions.o_logLevel.Value;
|
||||||
|
|
||||||
var appAssembly = typeof(Program).Assembly.GetName();
|
var appAssembly = typeof(Program).Assembly.GetName();
|
||||||
var arch = Environment.Is64BitProcess ? "x64" : "x32";
|
|
||||||
LogName = $"{appAssembly.Name}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log";
|
LogName = $"{appAssembly.Name}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log";
|
||||||
LogPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, LogName);
|
LogPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, LogName);
|
||||||
|
var arch = Environment.Is64BitProcess ? "x64" : "x32";
|
||||||
Console.OutputEncoding = System.Text.Encoding.UTF8;
|
Console.OutputEncoding = System.Text.Encoding.UTF8;
|
||||||
|
|
||||||
if (logOutput != LogOutputMode.Console)
|
|
||||||
{
|
|
||||||
ConcurrentFileWriter();
|
|
||||||
}
|
|
||||||
|
|
||||||
LogToFile(LoggerEvent.Verbose, $"---{appAssembly.Name} v{appAssembly.Version} [{arch}] | Logger launched---\n" +
|
LogToFile(LoggerEvent.Verbose, $"---{appAssembly.Name} v{appAssembly.Version} [{arch}] | Logger launched---\n" +
|
||||||
$"CMD Args: {string.Join(" ", CLIOptions.cliArgs)}");
|
$"CMD Args: {string.Join(" ", CLIOptions.cliArgs)}");
|
||||||
}
|
}
|
||||||
@@ -64,7 +55,7 @@ namespace AssetStudioCLI
|
|||||||
{
|
{
|
||||||
var curTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
var curTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||||
message = message.TrimEnd();
|
message = message.TrimEnd();
|
||||||
var multiLine = message.Contains("\n");
|
var multiLine = message.Contains('\n');
|
||||||
|
|
||||||
string formattedMessage;
|
string formattedMessage;
|
||||||
if (consoleMode)
|
if (consoleMode)
|
||||||
@@ -73,7 +64,7 @@ namespace AssetStudioCLI
|
|||||||
formattedMessage = $"{colorLogLevel} {message}";
|
formattedMessage = $"{colorLogLevel} {message}";
|
||||||
if (multiLine)
|
if (multiLine)
|
||||||
{
|
{
|
||||||
formattedMessage = formattedMessage.Replace("\n", $"\n{colorLogLevel} ") + $"\n{colorLogLevel}";
|
formattedMessage = formattedMessage.Replace("\n", $"\n{colorLogLevel} ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -83,7 +74,7 @@ namespace AssetStudioCLI
|
|||||||
formattedMessage = $"{curTime} | {logLevel} | {message}";
|
formattedMessage = $"{curTime} | {logLevel} | {message}";
|
||||||
if (multiLine)
|
if (multiLine)
|
||||||
{
|
{
|
||||||
formattedMessage = formattedMessage.Replace("\n", $"\n{curTime} | {logLevel} | ") + $"\n{curTime} | {logLevel} |";
|
formattedMessage = formattedMessage.Replace("\n", $"\n{curTime} | {logLevel} | ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return formattedMessage;
|
return formattedMessage;
|
||||||
@@ -97,27 +88,15 @@ namespace AssetStudioCLI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LogToFile(LoggerEvent logMsgLevel, string message)
|
public async void LogToFile(LoggerEvent logMsgLevel, string message)
|
||||||
{
|
{
|
||||||
if (logOutput != LogOutputMode.Console)
|
if (logOutput != LogOutputMode.Console)
|
||||||
{
|
|
||||||
logMessageCollection.Add(FormatMessage(logMsgLevel, message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ConcurrentFileWriter()
|
|
||||||
{
|
|
||||||
Task.Run(() =>
|
|
||||||
{
|
{
|
||||||
using (var sw = new StreamWriter(LogPath, append: true, System.Text.Encoding.UTF8))
|
using (var sw = new StreamWriter(LogPath, append: true, System.Text.Encoding.UTF8))
|
||||||
{
|
{
|
||||||
sw.AutoFlush = true;
|
await sw.WriteLineAsync(FormatMessage(logMsgLevel, message));
|
||||||
foreach (var msg in logMessageCollection.GetConsumingEnumerable())
|
|
||||||
{
|
|
||||||
sw.WriteLine(msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Log(LoggerEvent logMsgLevel, string message, bool ignoreLevel)
|
public void Log(LoggerEvent logMsgLevel, string message, bool ignoreLevel)
|
||||||
|
|||||||
228
AssetStudioCLI/Components/Arknights/AkSpriteHelper.cs
Normal file
228
AssetStudioCLI/Components/Arknights/AkSpriteHelper.cs
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
using Arknights.PortraitSpriteMono;
|
||||||
|
using AssetStudio;
|
||||||
|
using AssetStudioCLI;
|
||||||
|
using AssetStudioCLI.Options;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
|
using SixLabors.ImageSharp.Processing;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Arknights
|
||||||
|
{
|
||||||
|
internal static class AkSpriteHelper
|
||||||
|
{
|
||||||
|
public static Texture2D TryFindAlphaTex(AssetItem assetItem, AvgSprite avgSprite, bool isAvgSprite)
|
||||||
|
{
|
||||||
|
Sprite m_Sprite = (Sprite)assetItem.Asset;
|
||||||
|
var imgType = "arts/characters";
|
||||||
|
if (m_Sprite.m_RD.alphaTexture.m_PathID == 0)
|
||||||
|
{
|
||||||
|
if (isAvgSprite)
|
||||||
|
{
|
||||||
|
if (avgSprite?.FullAlphaTexture != null)
|
||||||
|
return avgSprite.FullAlphaTexture;
|
||||||
|
|
||||||
|
imgType = "avg/characters"; //since the avg hub was not found for some reason, let's try to find alpha tex by name
|
||||||
|
}
|
||||||
|
var spriteFullName = Path.GetFileNameWithoutExtension(assetItem.Container);
|
||||||
|
foreach (var item in Studio.loadedAssetsList)
|
||||||
|
{
|
||||||
|
if (item.Type == ClassIDType.Texture2D)
|
||||||
|
{
|
||||||
|
if (item.Container.Contains(imgType) && item.Container.Contains($"illust_{m_Sprite.m_Name}_material") && item.Text.Contains("[alpha]"))
|
||||||
|
return (Texture2D)item.Asset;
|
||||||
|
if (item.Container.Contains(imgType) && item.Container.Contains(spriteFullName) && item.Text == $"{m_Sprite.m_Name}[alpha]")
|
||||||
|
return (Texture2D)item.Asset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Image<Bgra32> AkGetImage(this Sprite m_Sprite, AvgSprite avgSprite = null, SpriteMaskMode spriteMaskMode = SpriteMaskMode.On)
|
||||||
|
{
|
||||||
|
if (m_Sprite.m_RD.texture.TryGet(out var m_Texture2D) && m_Sprite.m_RD.alphaTexture.TryGet(out var m_AlphaTexture2D) && spriteMaskMode != SpriteMaskMode.Off)
|
||||||
|
{
|
||||||
|
Image<Bgra32> tex;
|
||||||
|
Image<Bgra32> alphaTex;
|
||||||
|
|
||||||
|
if (avgSprite != null && avgSprite.IsHubParsed)
|
||||||
|
{
|
||||||
|
alphaTex = m_AlphaTexture2D.ConvertToImage(true);
|
||||||
|
if (avgSprite.IsFaceSprite)
|
||||||
|
{
|
||||||
|
var faceImage = m_Texture2D.ConvertToImage(true);
|
||||||
|
var faceAlpha = avgSprite.FaceSpriteAlphaTexture.ConvertToImage(true);
|
||||||
|
if (new Size(faceImage.Width, faceImage.Height) != avgSprite.FaceSize)
|
||||||
|
{
|
||||||
|
faceImage.Mutate(x => x.Resize(new ResizeOptions { Size = avgSprite.FaceSize, Sampler = KnownResamplers.Lanczos3, Mode = ResizeMode.Stretch }));
|
||||||
|
faceAlpha.Mutate(x => x.Resize(new ResizeOptions { Size = avgSprite.FaceSize, Sampler = KnownResamplers.Lanczos3, Mode = ResizeMode.Stretch }));
|
||||||
|
}
|
||||||
|
tex = avgSprite.FullTexture.ConvertToImage(true);
|
||||||
|
tex.Mutate(x => x.DrawImage(faceImage, avgSprite.FacePos, opacity: 1f));
|
||||||
|
alphaTex.Mutate(x => x.DrawImage(faceAlpha, avgSprite.FacePos, opacity: 1f));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tex = m_Texture2D.ConvertToImage(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tex = CutImage(m_Texture2D.ConvertToImage(false), m_Sprite.m_RD.textureRect, m_Sprite.m_RD.downscaleMultiplier);
|
||||||
|
alphaTex = CutImage(m_AlphaTexture2D.ConvertToImage(false), m_Sprite.m_RD.textureRect, m_Sprite.m_RD.downscaleMultiplier);
|
||||||
|
}
|
||||||
|
tex.ApplyRGBMask(alphaTex);
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
else if (m_Sprite.m_RD.texture.TryGet(out m_Texture2D) && avgSprite != null && avgSprite.IsHubParsed)
|
||||||
|
{
|
||||||
|
if (!avgSprite.IsFaceSprite)
|
||||||
|
{
|
||||||
|
return m_Texture2D.ConvertToImage(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
var faceImage = m_Texture2D.ConvertToImage(true);
|
||||||
|
var tex = avgSprite.FullTexture.ConvertToImage(true);
|
||||||
|
if (new Size(faceImage.Width, faceImage.Height) != avgSprite.FaceSize)
|
||||||
|
{
|
||||||
|
faceImage.Mutate(x => x.Resize(new ResizeOptions { Size = avgSprite.FaceSize, Sampler = KnownResamplers.Lanczos3, Mode = ResizeMode.Stretch }));
|
||||||
|
}
|
||||||
|
tex.Mutate(x => x.DrawImage(faceImage, avgSprite.FacePos, opacity: 1f));
|
||||||
|
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
else if (m_Sprite.m_RD.texture.TryGet(out m_Texture2D))
|
||||||
|
{
|
||||||
|
return CutImage(m_Texture2D.ConvertToImage(false), m_Sprite.m_RD.textureRect, m_Sprite.m_RD.downscaleMultiplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Image<Bgra32> AkGetImage(this PortraitSprite portraitSprite, SpriteMaskMode spriteMaskMode = SpriteMaskMode.On)
|
||||||
|
{
|
||||||
|
if (portraitSprite.Texture != null && portraitSprite.AlphaTexture != null)
|
||||||
|
{
|
||||||
|
var tex = CutImage(portraitSprite.Texture.ConvertToImage(false), portraitSprite.TextureRect, portraitSprite.DownscaleMultiplier, portraitSprite.Rotate);
|
||||||
|
|
||||||
|
if (spriteMaskMode == SpriteMaskMode.Off)
|
||||||
|
{
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var alphaTex = CutImage(portraitSprite.AlphaTexture.ConvertToImage(false), portraitSprite.TextureRect, portraitSprite.DownscaleMultiplier, portraitSprite.Rotate);
|
||||||
|
tex.ApplyRGBMask(alphaTex);
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<PortraitSprite> GeneratePortraits(AssetItem asset)
|
||||||
|
{
|
||||||
|
var portraits = new List<PortraitSprite>();
|
||||||
|
|
||||||
|
var portraitsDict = ((MonoBehaviour)asset.Asset).ToType();
|
||||||
|
if (portraitsDict == null)
|
||||||
|
{
|
||||||
|
Logger.Warning("Portraits MonoBehaviour is not readable.");
|
||||||
|
return portraits;
|
||||||
|
}
|
||||||
|
var portraitsJson = JsonConvert.SerializeObject(portraitsDict);
|
||||||
|
var portraitsData = JsonConvert.DeserializeObject<PortraitSpriteConfig>(portraitsJson);
|
||||||
|
|
||||||
|
var atlasTex = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == portraitsData._atlas.Texture.m_PathID).Asset;
|
||||||
|
var atlasAlpha = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == portraitsData._atlas.Alpha.m_PathID).Asset;
|
||||||
|
|
||||||
|
foreach (var portraitData in portraitsData._sprites)
|
||||||
|
{
|
||||||
|
var portraitSprite = new PortraitSprite()
|
||||||
|
{
|
||||||
|
Name = portraitData.Name,
|
||||||
|
AssetsFile = atlasTex.assetsFile,
|
||||||
|
Container = asset.Container,
|
||||||
|
Texture = atlasTex,
|
||||||
|
AlphaTexture = atlasAlpha,
|
||||||
|
TextureRect = new Rectf(portraitData.Rect.X, portraitData.Rect.Y, portraitData.Rect.W, portraitData.Rect.H),
|
||||||
|
Rotate = portraitData.Rotate,
|
||||||
|
};
|
||||||
|
portraits.Add(portraitSprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
return portraits;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ApplyRGBMask(this Image<Bgra32> tex, Image<Bgra32> texMask)
|
||||||
|
{
|
||||||
|
using (texMask)
|
||||||
|
{
|
||||||
|
bool resized = false;
|
||||||
|
if (tex.Width != texMask.Width || tex.Height != texMask.Height)
|
||||||
|
{
|
||||||
|
texMask.Mutate(x => x.Resize(tex.Width, tex.Height, CLIOptions.o_akAlphaTexResampler.Value));
|
||||||
|
resized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var invGamma = 1.0 / (1.0 + CLIOptions.o_akShadowGamma.Value / 10.0);
|
||||||
|
if (CLIOptions.akResizedOnly && !resized)
|
||||||
|
{
|
||||||
|
invGamma = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tex.ProcessPixelRows(texMask, (sourceTex, targetTexMask) =>
|
||||||
|
{
|
||||||
|
for (int y = 0; y < texMask.Height; y++)
|
||||||
|
{
|
||||||
|
var texRow = sourceTex.GetRowSpan(y);
|
||||||
|
var maskRow = targetTexMask.GetRowSpan(y);
|
||||||
|
for (int x = 0; x < maskRow.Length; x++)
|
||||||
|
{
|
||||||
|
var grayscale = (maskRow[x].R + maskRow[x].G + maskRow[x].B) / 3.0;
|
||||||
|
if (invGamma != 1.0)
|
||||||
|
{
|
||||||
|
grayscale = 255 - Math.Pow((255 - grayscale) / 255, invGamma) * 255;
|
||||||
|
}
|
||||||
|
texRow[x].A = (byte)grayscale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Image<Bgra32> CutImage(Image<Bgra32> originalImage, Rectf textureRect, float downscaleMultiplier, bool rotate = false)
|
||||||
|
{
|
||||||
|
if (originalImage != null)
|
||||||
|
{
|
||||||
|
if (downscaleMultiplier > 0f && downscaleMultiplier != 1f)
|
||||||
|
{
|
||||||
|
var newSize = (Size)(new Size(originalImage.Width, originalImage.Height) / downscaleMultiplier);
|
||||||
|
originalImage.Mutate(x => x.Resize(newSize, KnownResamplers.Lanczos3, compand: true));
|
||||||
|
}
|
||||||
|
var rectX = (int)Math.Floor(textureRect.x);
|
||||||
|
var rectY = (int)Math.Floor(textureRect.y);
|
||||||
|
var rectRight = (int)Math.Ceiling(textureRect.x + textureRect.width);
|
||||||
|
var rectBottom = (int)Math.Ceiling(textureRect.y + textureRect.height);
|
||||||
|
rectRight = Math.Min(rectRight, originalImage.Width);
|
||||||
|
rectBottom = Math.Min(rectBottom, originalImage.Height);
|
||||||
|
var rect = new Rectangle(rectX, rectY, rectRight - rectX, rectBottom - rectY);
|
||||||
|
var spriteImage = originalImage.Clone(x => x.Crop(rect));
|
||||||
|
originalImage.Dispose();
|
||||||
|
if (rotate)
|
||||||
|
{
|
||||||
|
spriteImage.Mutate(x => x.Rotate(RotateMode.Rotate270));
|
||||||
|
}
|
||||||
|
spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
|
||||||
|
|
||||||
|
return spriteImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
149
AssetStudioCLI/Components/Arknights/AvgSprite.cs
Normal file
149
AssetStudioCLI/Components/Arknights/AvgSprite.cs
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
using Arknights.AvgCharHubMono;
|
||||||
|
using AssetStudio;
|
||||||
|
using AssetStudioCLI;
|
||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using System.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Arknights
|
||||||
|
{
|
||||||
|
internal class AvgSprite
|
||||||
|
{
|
||||||
|
public Texture2D FaceSpriteAlphaTexture { get; }
|
||||||
|
public Texture2D FullTexture { get; }
|
||||||
|
public Texture2D FullAlphaTexture { get; }
|
||||||
|
public Point FacePos { get; }
|
||||||
|
public Size FaceSize { get; }
|
||||||
|
public string Alias { get; }
|
||||||
|
public bool IsWholeBodySprite { get; }
|
||||||
|
public bool IsFaceSprite { get; }
|
||||||
|
public bool IsHubParsed { get; }
|
||||||
|
|
||||||
|
private AvgSpriteConfig GetCurSpriteGroup(AvgSpriteConfigGroup spriteHubDataGrouped, long spriteItemID, string spriteName)
|
||||||
|
{
|
||||||
|
if (spriteHubDataGrouped.SpriteGroups.Length > 1)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(spriteName))
|
||||||
|
{
|
||||||
|
var groupFromName = int.TryParse(spriteName?.Substring(spriteName.IndexOf('$') + 1, 1), out int groupIndex);
|
||||||
|
if (groupFromName)
|
||||||
|
{
|
||||||
|
return spriteHubDataGrouped.SpriteGroups[groupIndex - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return spriteHubDataGrouped.SpriteGroups.FirstOrDefault(x => x.Sprites.Any(y => y.Sprite.m_PathID == spriteItemID));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return spriteHubDataGrouped.SpriteGroups[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryGetSpriteHub(AssetItem assetItem, out AvgSpriteConfig spriteHubData)
|
||||||
|
{
|
||||||
|
spriteHubData = null;
|
||||||
|
var scriptAssets = Studio.loadedAssetsList.FindAll(x =>
|
||||||
|
x.Type == ClassIDType.MonoBehaviour
|
||||||
|
&& x.Container == assetItem.Container);
|
||||||
|
if (scriptAssets.Count == 0)
|
||||||
|
{
|
||||||
|
Logger.Warning("No MonoBehaviours were found.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
OrderedDictionary spriteHubDict = null;
|
||||||
|
var isGrouped = false;
|
||||||
|
foreach (var scriptAsset in scriptAssets)
|
||||||
|
{
|
||||||
|
var scriptAssetDict = ((MonoBehaviour)scriptAsset.Asset).ToType();
|
||||||
|
if (scriptAssetDict == null)
|
||||||
|
{
|
||||||
|
Logger.Warning("MonoBehaviour is not readable.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scriptAssetDict.Contains("spriteGroups"))
|
||||||
|
{
|
||||||
|
spriteHubDict = scriptAssetDict;
|
||||||
|
isGrouped = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (scriptAssetDict.Contains("sprites"))
|
||||||
|
{
|
||||||
|
spriteHubDict = scriptAssetDict;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spriteHubDict == null)
|
||||||
|
{
|
||||||
|
Logger.Warning("AVGCharacterSpriteHub is not readable.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var spriteHubJson = JsonConvert.SerializeObject(spriteHubDict);
|
||||||
|
if (isGrouped)
|
||||||
|
{
|
||||||
|
var groupedSpriteHub = JsonConvert.DeserializeObject<AvgSpriteConfigGroup>(spriteHubJson);
|
||||||
|
spriteHubData = GetCurSpriteGroup(groupedSpriteHub, assetItem.m_PathID, assetItem.Text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spriteHubData = JsonConvert.DeserializeObject<AvgSpriteConfig>(spriteHubJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AvgSprite(AssetItem assetItem)
|
||||||
|
{
|
||||||
|
if (TryGetSpriteHub(assetItem, out var spriteHubData))
|
||||||
|
{
|
||||||
|
IsHubParsed = spriteHubData?.Sprites.Length > 0;
|
||||||
|
}
|
||||||
|
if (IsHubParsed)
|
||||||
|
{
|
||||||
|
var curSpriteData = spriteHubData.Sprites.FirstOrDefault(x => x.Sprite.m_PathID == assetItem.m_PathID);
|
||||||
|
|
||||||
|
if (curSpriteData == null)
|
||||||
|
{
|
||||||
|
Logger.Warning($"Sprite \"{assetItem.Text}\" was not found in the avg sprite hub");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Alias = curSpriteData.Alias;
|
||||||
|
IsWholeBodySprite = curSpriteData.IsWholeBody;
|
||||||
|
|
||||||
|
if (spriteHubData.FaceSize.X > 0 && spriteHubData.FaceSize.Y > 0) //If face data exist
|
||||||
|
{
|
||||||
|
var fullTexSpriteData = spriteHubData.Sprites.Last(); //Last sprite item in the list usually contains PathID of Sprite with full texture
|
||||||
|
|
||||||
|
var curSprite = (Sprite)assetItem.Asset;
|
||||||
|
IsFaceSprite = curSprite.m_Rect.width <= 256 && curSprite.m_Rect.height <= 256 && curSprite.m_PathID != fullTexSpriteData.Sprite.m_PathID;
|
||||||
|
|
||||||
|
var curSpriteAlphaID = curSpriteData.AlphaTex.m_PathID;
|
||||||
|
var curSpriteAlphaTex = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == curSpriteAlphaID)?.Asset;
|
||||||
|
if (curSpriteAlphaTex != null)
|
||||||
|
{
|
||||||
|
FaceSpriteAlphaTexture = IsFaceSprite ? curSpriteAlphaTex : null;
|
||||||
|
fullTexSpriteData = IsFaceSprite ? fullTexSpriteData : curSpriteData;
|
||||||
|
}
|
||||||
|
var fullTexSpriteID = fullTexSpriteData.Sprite.m_PathID;
|
||||||
|
var fullTexAlphaID = fullTexSpriteData.AlphaTex.m_PathID;
|
||||||
|
var fullTexSprite = (Sprite)Studio.loadedAssetsList.Find(x => x.m_PathID == fullTexSpriteID).Asset;
|
||||||
|
|
||||||
|
FullTexture = fullTexSprite.m_RD.texture.TryGet(out var fullTex) ? fullTex : null;
|
||||||
|
FullAlphaTexture = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == fullTexAlphaID)?.Asset;
|
||||||
|
FacePos = new Point((int)Math.Round(spriteHubData.FacePos.X), (int)Math.Round(spriteHubData.FacePos.Y));
|
||||||
|
FaceSize = new Size((int)Math.Round(spriteHubData.FaceSize.X), (int)Math.Round(spriteHubData.FaceSize.Y));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FullAlphaTexture = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == curSpriteData.AlphaTex.m_PathID).Asset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
AssetStudioCLI/Components/Arknights/AvgSpriteConfig.cs
Normal file
30
AssetStudioCLI/Components/Arknights/AvgSpriteConfig.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using AssetStudio;
|
||||||
|
|
||||||
|
namespace Arknights.AvgCharHubMono
|
||||||
|
{
|
||||||
|
internal class AvgAssetIDs
|
||||||
|
{
|
||||||
|
public int m_FileID { get; set; }
|
||||||
|
public long m_PathID { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class AvgSpriteData
|
||||||
|
{
|
||||||
|
public AvgAssetIDs Sprite { get; set; }
|
||||||
|
public AvgAssetIDs AlphaTex { get; set; }
|
||||||
|
public string Alias { get; set; }
|
||||||
|
public bool IsWholeBody { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class AvgSpriteConfig
|
||||||
|
{
|
||||||
|
public AvgSpriteData[] Sprites { get; set; }
|
||||||
|
public Vector2 FaceSize { get; set; }
|
||||||
|
public Vector3 FacePos { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class AvgSpriteConfigGroup
|
||||||
|
{
|
||||||
|
public AvgSpriteConfig[] SpriteGroups { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
24
AssetStudioCLI/Components/Arknights/PortraitSprite.cs
Normal file
24
AssetStudioCLI/Components/Arknights/PortraitSprite.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using AssetStudio;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Arknights
|
||||||
|
{
|
||||||
|
internal class PortraitSprite
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public ClassIDType Type { get; }
|
||||||
|
public SerializedFile AssetsFile { get; set; }
|
||||||
|
public string Container { get; set; }
|
||||||
|
public Texture2D Texture { get; set; }
|
||||||
|
public Texture2D AlphaTexture { get; set; }
|
||||||
|
public Rectf TextureRect { get; set; }
|
||||||
|
public bool Rotate { get; set; }
|
||||||
|
public float DownscaleMultiplier { get; }
|
||||||
|
|
||||||
|
public PortraitSprite()
|
||||||
|
{
|
||||||
|
Type = ClassIDType.AkPortraitSprite;
|
||||||
|
DownscaleMultiplier = 1f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
AssetStudioCLI/Components/Arknights/PortraitSpriteConfig.cs
Normal file
41
AssetStudioCLI/Components/Arknights/PortraitSpriteConfig.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
namespace Arknights.PortraitSpriteMono
|
||||||
|
{
|
||||||
|
internal class PortraitRect
|
||||||
|
{
|
||||||
|
public float X { get; set; }
|
||||||
|
public float Y { get; set; }
|
||||||
|
public float W { get; set; }
|
||||||
|
public float H { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class AtlasSprite
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Guid { get; set; }
|
||||||
|
public int Atlas { get; set; }
|
||||||
|
public PortraitRect Rect { get; set; }
|
||||||
|
public bool Rotate { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class TextureIDs
|
||||||
|
{
|
||||||
|
public int m_FileID { get; set; }
|
||||||
|
public long m_PathID { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class AtlasInfo
|
||||||
|
{
|
||||||
|
public int Index { get; set; }
|
||||||
|
public TextureIDs Texture { get; set; }
|
||||||
|
public TextureIDs Alpha { get; set; }
|
||||||
|
public int Size { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class PortraitSpriteConfig
|
||||||
|
{
|
||||||
|
public string m_Name { get; set; }
|
||||||
|
public AtlasSprite[] _sprites { get; set; }
|
||||||
|
public AtlasInfo _atlas { get; set; }
|
||||||
|
public int _index { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using AssetStudio;
|
using Arknights;
|
||||||
|
using AssetStudio;
|
||||||
|
|
||||||
namespace AssetStudioCLI
|
namespace AssetStudioCLI
|
||||||
{
|
{
|
||||||
@@ -14,6 +15,7 @@ namespace AssetStudioCLI
|
|||||||
public string Text;
|
public string Text;
|
||||||
public string UniqueID;
|
public string UniqueID;
|
||||||
public GameObjectNode Node;
|
public GameObjectNode Node;
|
||||||
|
public PortraitSprite AkPortraitSprite;
|
||||||
|
|
||||||
public AssetItem(Object asset)
|
public AssetItem(Object asset)
|
||||||
{
|
{
|
||||||
@@ -24,5 +26,17 @@ namespace AssetStudioCLI
|
|||||||
m_PathID = asset.m_PathID;
|
m_PathID = asset.m_PathID;
|
||||||
FullSize = asset.byteSize;
|
FullSize = asset.byteSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AssetItem(PortraitSprite akPortraitSprite)
|
||||||
|
{
|
||||||
|
Asset = null;
|
||||||
|
SourceFile = akPortraitSprite.AssetsFile;
|
||||||
|
Container = akPortraitSprite.Container;
|
||||||
|
Type = akPortraitSprite.Type;
|
||||||
|
TypeString = Type.ToString();
|
||||||
|
Text = akPortraitSprite.Name;
|
||||||
|
m_PathID = -1;
|
||||||
|
AkPortraitSprite = akPortraitSprite;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using AssetStudio;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace AssetStudioCLI
|
namespace AssetStudioCLI
|
||||||
@@ -5,12 +6,11 @@ namespace AssetStudioCLI
|
|||||||
internal class BaseNode
|
internal class BaseNode
|
||||||
{
|
{
|
||||||
public List<BaseNode> nodes = new List<BaseNode>();
|
public List<BaseNode> nodes = new List<BaseNode>();
|
||||||
public string FullPath = "";
|
|
||||||
public readonly string Text;
|
|
||||||
|
|
||||||
public BaseNode(string name)
|
public BaseNode()
|
||||||
{
|
{
|
||||||
Text = name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using AssetStudio;
|
using AssetStudio;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace AssetStudioCLI
|
namespace AssetStudioCLI
|
||||||
{
|
{
|
||||||
@@ -6,9 +7,10 @@ namespace AssetStudioCLI
|
|||||||
{
|
{
|
||||||
public GameObject gameObject;
|
public GameObject gameObject;
|
||||||
|
|
||||||
public GameObjectNode(GameObject gameObject) : base(gameObject.m_Name)
|
public GameObjectNode(GameObject gameObject)
|
||||||
{
|
{
|
||||||
this.gameObject = gameObject;
|
this.gameObject = gameObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,123 @@
|
|||||||
using AssetStudio;
|
using Arknights;
|
||||||
|
using AssetStudio;
|
||||||
using AssetStudioCLI.Options;
|
using AssetStudioCLI.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
|
using SixLabors.ImageSharp;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace AssetStudioCLI
|
namespace AssetStudioCLI
|
||||||
{
|
{
|
||||||
internal static class Exporter
|
internal static class Exporter
|
||||||
{
|
{
|
||||||
|
public static bool ExportTexture2D(AssetItem item, string exportPath)
|
||||||
|
{
|
||||||
|
var m_Texture2D = (Texture2D)item.Asset;
|
||||||
|
if (CLIOptions.convertTexture)
|
||||||
|
{
|
||||||
|
var type = CLIOptions.o_imageFormat.Value;
|
||||||
|
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (CLIOptions.o_logLevel.Value <= LoggerEvent.Debug)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine($"Converting \"{m_Texture2D.m_Name}\" to {type}..");
|
||||||
|
sb.AppendLine($"Width: {m_Texture2D.m_Width}");
|
||||||
|
sb.AppendLine($"Height: {m_Texture2D.m_Height}");
|
||||||
|
sb.AppendLine($"Format: {m_Texture2D.m_TextureFormat}");
|
||||||
|
switch (m_Texture2D.m_TextureSettings.m_FilterMode)
|
||||||
|
{
|
||||||
|
case 0: sb.AppendLine("Filter Mode: Point "); break;
|
||||||
|
case 1: sb.AppendLine("Filter Mode: Bilinear "); break;
|
||||||
|
case 2: sb.AppendLine("Filter Mode: Trilinear "); break;
|
||||||
|
}
|
||||||
|
sb.AppendLine($"Anisotropic level: {m_Texture2D.m_TextureSettings.m_Aniso}");
|
||||||
|
sb.AppendLine($"Mip map bias: {m_Texture2D.m_TextureSettings.m_MipBias}");
|
||||||
|
switch (m_Texture2D.m_TextureSettings.m_WrapMode)
|
||||||
|
{
|
||||||
|
case 0: sb.AppendLine($"Wrap mode: Repeat"); break;
|
||||||
|
case 1: sb.AppendLine($"Wrap mode: Clamp"); break;
|
||||||
|
}
|
||||||
|
Logger.Debug(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
var image = m_Texture2D.ConvertToImage(flip: true);
|
||||||
|
if (image == null)
|
||||||
|
{
|
||||||
|
Logger.Error($"Export error. Failed to convert texture \"{m_Texture2D.m_Name}\" into image");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
using (image)
|
||||||
|
{
|
||||||
|
using (var file = File.OpenWrite(exportFullPath))
|
||||||
|
{
|
||||||
|
image.WriteToStream(file, type);
|
||||||
|
}
|
||||||
|
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!TryExportFile(exportPath, item, ".tex", out var exportFullPath))
|
||||||
|
return false;
|
||||||
|
File.WriteAllBytes(exportFullPath, m_Texture2D.image_data.GetData());
|
||||||
|
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ExportAudioClip(AssetItem item, string exportPath)
|
||||||
|
{
|
||||||
|
string exportFullPath;
|
||||||
|
var m_AudioClip = (AudioClip)item.Asset;
|
||||||
|
var m_AudioData = m_AudioClip.m_AudioData.GetData();
|
||||||
|
if (m_AudioData == null || m_AudioData.Length == 0)
|
||||||
|
{
|
||||||
|
Logger.Error($"Export error. \"{item.Text}\": AudioData was not found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var converter = new AudioClipConverter(m_AudioClip);
|
||||||
|
if (CLIOptions.o_audioFormat.Value != AudioFormat.None && converter.IsSupport)
|
||||||
|
{
|
||||||
|
if (!TryExportFile(exportPath, item, ".wav", out exportFullPath))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (CLIOptions.o_logLevel.Value <= LoggerEvent.Debug)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine($"Converting \"{m_AudioClip.m_Name}\" to wav..");
|
||||||
|
sb.AppendLine(m_AudioClip.version[0] < 5 ? $"AudioClip type: {m_AudioClip.m_Type}" : $"AudioClip compression format: {m_AudioClip.m_CompressionFormat}");
|
||||||
|
sb.AppendLine($"AudioClip channel count: {m_AudioClip.m_Channels}");
|
||||||
|
sb.AppendLine($"AudioClip sample rate: {m_AudioClip.m_Frequency}");
|
||||||
|
sb.AppendLine($"AudioClip bit depth: {m_AudioClip.m_BitsPerSample}");
|
||||||
|
Logger.Debug(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
var buffer = converter.ConvertToWav(m_AudioData);
|
||||||
|
if (buffer == null)
|
||||||
|
{
|
||||||
|
Logger.Error($"Export error. \"{item.Text}\": Failed to convert to Wav");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
File.WriteAllBytes(exportFullPath, buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!TryExportFile(exportPath, item, converter.GetExtensionName(), out exportFullPath))
|
||||||
|
return false;
|
||||||
|
File.WriteAllBytes(exportFullPath, m_AudioData);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static bool ExportVideoClip(AssetItem item, string exportPath)
|
public static bool ExportVideoClip(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
var m_VideoClip = (VideoClip)item.Asset;
|
var m_VideoClip = (VideoClip)item.Asset;
|
||||||
@@ -129,6 +237,112 @@ namespace AssetStudioCLI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool ExportSprite(AssetItem item, string exportPath)
|
||||||
|
{
|
||||||
|
Image<Bgra32> image;
|
||||||
|
AvgSprite avgSprite = null;
|
||||||
|
var alias = "";
|
||||||
|
var m_Sprite = (Sprite)item.Asset;
|
||||||
|
var type = CLIOptions.o_imageFormat.Value;
|
||||||
|
var spriteMaskMode = CLIOptions.o_akSpriteAlphaMode.Value != AkSpriteAlphaMode.None ? SpriteMaskMode.Export : SpriteMaskMode.Off;
|
||||||
|
var isCharAvgSprite = item.Container.Contains("avg/characters");
|
||||||
|
var isCharArt = item.Container.Contains("arts/characters");
|
||||||
|
|
||||||
|
if (isCharAvgSprite)
|
||||||
|
{
|
||||||
|
avgSprite = new AvgSprite(item);
|
||||||
|
|
||||||
|
if (CLIOptions.f_akAddAliases.Value && !string.IsNullOrEmpty(avgSprite.Alias))
|
||||||
|
{
|
||||||
|
alias = $"_{avgSprite.Alias}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CLIOptions.f_akOriginalAvgNames.Value)
|
||||||
|
{
|
||||||
|
var groupedPattern = new Regex(@"^\d{1,2}\$\d{1,2}$"); // "spriteIndex$groupIndex"
|
||||||
|
var notGroupedPattern = new Regex(@"^\d{1,2}$"); // "spriteIndex"
|
||||||
|
if (groupedPattern.IsMatch(m_Sprite.m_Name) || notGroupedPattern.IsMatch(m_Sprite.m_Name))
|
||||||
|
{
|
||||||
|
var fullName = Path.GetFileNameWithoutExtension(item.Container);
|
||||||
|
item.Text = $"{fullName}#{m_Sprite.m_Name}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath, alias))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (CLIOptions.o_akSpriteAlphaMode.Value == AkSpriteAlphaMode.SearchExternal && (isCharAvgSprite || isCharArt))
|
||||||
|
{
|
||||||
|
if (m_Sprite.m_RD.alphaTexture.IsNull)
|
||||||
|
{
|
||||||
|
var charAlphaAtlas = AkSpriteHelper.TryFindAlphaTex(item, avgSprite, isCharAvgSprite);
|
||||||
|
if (charAlphaAtlas != null)
|
||||||
|
{
|
||||||
|
m_Sprite.m_RD.alphaTexture.Set(charAlphaAtlas);
|
||||||
|
m_Sprite.akSplitAlpha = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
image = m_Sprite.AkGetImage(avgSprite, spriteMaskMode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
image = m_Sprite.GetImage(spriteMaskMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
using (image)
|
||||||
|
{
|
||||||
|
using (var file = File.OpenWrite(exportFullPath))
|
||||||
|
{
|
||||||
|
image.WriteToStream(file, type);
|
||||||
|
}
|
||||||
|
Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ExportPortraitSprite(AssetItem item, string exportPath)
|
||||||
|
{
|
||||||
|
var type = CLIOptions.o_imageFormat.Value;
|
||||||
|
var spriteMaskMode = CLIOptions.o_akSpriteAlphaMode.Value != AkSpriteAlphaMode.None ? SpriteMaskMode.Export : SpriteMaskMode.Off;
|
||||||
|
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var image = item.AkPortraitSprite.AkGetImage(spriteMaskMode: spriteMaskMode);
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
using (image)
|
||||||
|
{
|
||||||
|
using (var file = File.OpenWrite(exportFullPath))
|
||||||
|
{
|
||||||
|
image.WriteToStream(file, type);
|
||||||
|
}
|
||||||
|
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ExportRawFile(AssetItem item, string exportPath)
|
||||||
|
{
|
||||||
|
if (item.Asset == null)
|
||||||
|
{
|
||||||
|
Logger.Warning($"Raw export is not supported for \"{item.Text}\" ({item.TypeString}) file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!TryExportFile(exportPath, item, ".dat", out var exportFullPath))
|
||||||
|
return false;
|
||||||
|
File.WriteAllBytes(exportFullPath, item.Asset.GetRawData());
|
||||||
|
|
||||||
|
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static void ExportGameObject(GameObject gameObject, string exportPath, List<AssetItem> animationList = null)
|
public static void ExportGameObject(GameObject gameObject, string exportPath, List<AssetItem> animationList = null)
|
||||||
{
|
{
|
||||||
var convert = animationList != null
|
var convert = animationList != null
|
||||||
@@ -141,7 +355,7 @@ namespace AssetStudioCLI
|
|||||||
private static void ExportFbx(IImported convert, string exportPath)
|
private static void ExportFbx(IImported convert, string exportPath)
|
||||||
{
|
{
|
||||||
var eulerFilter = true;
|
var eulerFilter = true;
|
||||||
var filterPrecision = 0.25f;
|
var filterPrecision = (float)0.25f;
|
||||||
var exportAllNodes = true;
|
var exportAllNodes = true;
|
||||||
var exportSkins = true;
|
var exportSkins = true;
|
||||||
var exportAnimations = true;
|
var exportAnimations = true;
|
||||||
@@ -156,19 +370,14 @@ namespace AssetStudioCLI
|
|||||||
exportAllNodes, exportSkins, exportAnimations, exportBlendShape, castToBone, boneSize, exportAllUvsAsDiffuseMaps, scaleFactor, fbxVersion, fbxFormat == 1);
|
exportAllNodes, exportSkins, exportAnimations, exportBlendShape, castToBone, boneSize, exportAllUvsAsDiffuseMaps, scaleFactor, fbxVersion, fbxFormat == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ExportRawFile(AssetItem item, string exportPath)
|
|
||||||
{
|
|
||||||
if (!TryExportFile(exportPath, item, ".dat", out var exportFullPath, mode: "ExportRaw"))
|
|
||||||
return false;
|
|
||||||
File.WriteAllBytes(exportFullPath, item.Asset.GetRawData());
|
|
||||||
|
|
||||||
Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ExportDumpFile(AssetItem item, string exportPath)
|
public static bool ExportDumpFile(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
if (!TryExportFile(exportPath, item, ".txt", out var exportFullPath, mode: "Dump"))
|
if (item.Asset == null)
|
||||||
|
{
|
||||||
|
Logger.Warning($"Dump is not supported for \"{item.Text}\" ({item.TypeString}) file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!TryExportFile(exportPath, item, ".txt", out var exportFullPath))
|
||||||
return false;
|
return false;
|
||||||
var str = item.Asset.Dump();
|
var str = item.Asset.Dump();
|
||||||
if (str == null && item.Asset is MonoBehaviour m_MonoBehaviour)
|
if (str == null && item.Asset is MonoBehaviour m_MonoBehaviour)
|
||||||
@@ -176,10 +385,6 @@ namespace AssetStudioCLI
|
|||||||
var m_Type = m_MonoBehaviour.ConvertToTypeTree(Studio.assemblyLoader);
|
var m_Type = m_MonoBehaviour.ConvertToTypeTree(Studio.assemblyLoader);
|
||||||
str = m_MonoBehaviour.Dump(m_Type);
|
str = m_MonoBehaviour.Dump(m_Type);
|
||||||
}
|
}
|
||||||
if (string.IsNullOrEmpty(str))
|
|
||||||
{
|
|
||||||
str = item.Asset.DumpObject();
|
|
||||||
}
|
|
||||||
if (str != null)
|
if (str != null)
|
||||||
{
|
{
|
||||||
File.WriteAllText(exportFullPath, str);
|
File.WriteAllText(exportFullPath, str);
|
||||||
@@ -189,35 +394,22 @@ namespace AssetStudioCLI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool TryExportFile(string dir, AssetItem item, string extension, out string fullPath, string mode = "Export")
|
private static bool TryExportFile(string dir, AssetItem item, string extension, out string fullPath, string alias = "")
|
||||||
{
|
{
|
||||||
var fileName = FixFileName(item.Text);
|
var fileName = FixFileName(item.Text) + alias;
|
||||||
var filenameFormat = CLIOptions.o_filenameFormat.Value;
|
|
||||||
switch (filenameFormat)
|
|
||||||
{
|
|
||||||
case FilenameFormat.AssetName_PathID:
|
|
||||||
fileName = $"{fileName} @{item.m_PathID}";
|
|
||||||
break;
|
|
||||||
case FilenameFormat.PathID:
|
|
||||||
fileName = item.m_PathID.ToString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fullPath = Path.Combine(dir, fileName + extension);
|
fullPath = Path.Combine(dir, fileName + extension);
|
||||||
if (!File.Exists(fullPath))
|
if (!File.Exists(fullPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(dir);
|
Directory.CreateDirectory(dir);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (filenameFormat == FilenameFormat.AssetName)
|
fullPath = Path.Combine(dir, fileName + item.UniqueID + extension);
|
||||||
|
if (!File.Exists(fullPath))
|
||||||
{
|
{
|
||||||
fullPath = Path.Combine(dir, fileName + item.UniqueID + extension);
|
Directory.CreateDirectory(dir);
|
||||||
if (!File.Exists(fullPath))
|
return true;
|
||||||
{
|
|
||||||
Directory.CreateDirectory(dir);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Logger.Error($"{mode} error. File \"{fullPath.Color(ColorConsole.BrightRed)}\" already exist");
|
Logger.Error($"Export error. File \"{fullPath.Color(ColorConsole.BrightRed)}\" already exist");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,10 +515,9 @@ namespace AssetStudioCLI
|
|||||||
switch (item.Type)
|
switch (item.Type)
|
||||||
{
|
{
|
||||||
case ClassIDType.Texture2D:
|
case ClassIDType.Texture2D:
|
||||||
case ClassIDType.Texture2DArray:
|
return ExportTexture2D(item, exportPath);
|
||||||
case ClassIDType.Sprite:
|
|
||||||
case ClassIDType.AudioClip:
|
case ClassIDType.AudioClip:
|
||||||
throw new System.NotImplementedException();
|
return ExportAudioClip(item, exportPath);
|
||||||
case ClassIDType.VideoClip:
|
case ClassIDType.VideoClip:
|
||||||
return ExportVideoClip(item, exportPath);
|
return ExportVideoClip(item, exportPath);
|
||||||
case ClassIDType.MovieTexture:
|
case ClassIDType.MovieTexture:
|
||||||
@@ -339,6 +530,10 @@ namespace AssetStudioCLI
|
|||||||
return ExportMonoBehaviour(item, exportPath);
|
return ExportMonoBehaviour(item, exportPath);
|
||||||
case ClassIDType.Font:
|
case ClassIDType.Font:
|
||||||
return ExportFont(item, exportPath);
|
return ExportFont(item, exportPath);
|
||||||
|
case ClassIDType.Sprite:
|
||||||
|
return ExportSprite(item, exportPath);
|
||||||
|
case ClassIDType.AkPortraitSprite:
|
||||||
|
return ExportPortraitSprite(item, exportPath);
|
||||||
case ClassIDType.Mesh:
|
case ClassIDType.Mesh:
|
||||||
return ExportMesh(item, exportPath);
|
return ExportMesh(item, exportPath);
|
||||||
default:
|
default:
|
||||||
@@ -348,9 +543,8 @@ namespace AssetStudioCLI
|
|||||||
|
|
||||||
public static string FixFileName(string str)
|
public static string FixFileName(string str)
|
||||||
{
|
{
|
||||||
return str.Length >= 260
|
if (str.Length >= 260) return Path.GetRandomFileName();
|
||||||
? Path.GetRandomFileName()
|
return Path.GetInvalidFileNameChars().Aggregate(str, (current, c) => current.Replace(c, '_'));
|
||||||
: Path.GetInvalidFileNameChars().Aggregate(str, (current, c) => current.Replace(c, '_'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,17 +4,15 @@
|
|||||||
{
|
{
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
public string Description { get; }
|
public string Description { get; }
|
||||||
public string Example { get; }
|
|
||||||
public T Value { get; set; }
|
public T Value { get; set; }
|
||||||
public T DefaultValue { get; }
|
public T DefaultValue { get; }
|
||||||
public HelpGroups HelpGroup { get; }
|
public HelpGroups HelpGroup { get; }
|
||||||
public bool IsFlag { get; }
|
public bool IsFlag { get; }
|
||||||
|
|
||||||
public Option(T optionDefaultValue, string optionName, string optionDescription, string optionExample, HelpGroups optionHelpGroup, bool isFlag)
|
public Option(T optionDefaultValue, string optionName, string optionDescription, HelpGroups optionHelpGroup, bool isFlag)
|
||||||
{
|
{
|
||||||
Name = optionName;
|
Name = optionName;
|
||||||
Description = optionDescription;
|
Description = optionDescription;
|
||||||
Example = optionExample;
|
|
||||||
DefaultValue = optionDefaultValue;
|
DefaultValue = optionDefaultValue;
|
||||||
Value = DefaultValue;
|
Value = DefaultValue;
|
||||||
HelpGroup = optionHelpGroup;
|
HelpGroup = optionHelpGroup;
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ namespace AssetStudioCLI.Options
|
|||||||
{
|
{
|
||||||
internal static class OptionExtensions
|
internal static class OptionExtensions
|
||||||
{
|
{
|
||||||
public static Action<string, string, string, HelpGroups, bool> OptionGrouping = (name, desc, example, group, isFlag) => { };
|
public static Action<string, string, HelpGroups, bool> OptionGrouping = (name, desc, group, isFlag) => { };
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class GroupedOption<T> : Option<T>
|
internal class GroupedOption<T> : Option<T>
|
||||||
{
|
{
|
||||||
public GroupedOption(T optionDefaultValue, string optionName, string optionDescription, string optionExample, HelpGroups optionHelpGroup, bool isFlag = false) : base(optionDefaultValue, optionName, optionDescription, optionExample, optionHelpGroup, isFlag)
|
public GroupedOption(T optionDefaultValue, string optionName, string optionDescription, HelpGroups optionHelpGroup, bool isFlag = false) : base(optionDefaultValue, optionName, optionDescription, optionHelpGroup, isFlag)
|
||||||
{
|
{
|
||||||
OptionExtensions.OptionGrouping(optionName, optionDescription, optionExample, optionHelpGroup, isFlag);
|
OptionExtensions.OptionGrouping(optionName, optionDescription, optionHelpGroup, isFlag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,223 +0,0 @@
|
|||||||
using AssetStudio;
|
|
||||||
using AssetStudioCLI.Options;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudioCLI
|
|
||||||
{
|
|
||||||
internal static class ParallelExporter
|
|
||||||
{
|
|
||||||
private static ConcurrentDictionary<string, bool> savePathHash = new ConcurrentDictionary<string, bool>();
|
|
||||||
|
|
||||||
public static bool ExportTexture2D(AssetItem item, string exportPath, out string debugLog)
|
|
||||||
{
|
|
||||||
debugLog = "";
|
|
||||||
var m_Texture2D = (Texture2D)item.Asset;
|
|
||||||
if (CLIOptions.convertTexture)
|
|
||||||
{
|
|
||||||
var type = CLIOptions.o_imageFormat.Value;
|
|
||||||
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (CLIOptions.o_logLevel.Value <= LoggerEvent.Debug)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine($"Converting {item.TypeString} \"{m_Texture2D.m_Name}\" to {type}..");
|
|
||||||
sb.AppendLine($"Width: {m_Texture2D.m_Width}");
|
|
||||||
sb.AppendLine($"Height: {m_Texture2D.m_Height}");
|
|
||||||
sb.AppendLine($"Format: {m_Texture2D.m_TextureFormat}");
|
|
||||||
switch (m_Texture2D.m_TextureSettings.m_FilterMode)
|
|
||||||
{
|
|
||||||
case 0: sb.AppendLine("Filter Mode: Point "); break;
|
|
||||||
case 1: sb.AppendLine("Filter Mode: Bilinear "); break;
|
|
||||||
case 2: sb.AppendLine("Filter Mode: Trilinear "); break;
|
|
||||||
}
|
|
||||||
sb.AppendLine($"Anisotropic level: {m_Texture2D.m_TextureSettings.m_Aniso}");
|
|
||||||
sb.AppendLine($"Mip map bias: {m_Texture2D.m_TextureSettings.m_MipBias}");
|
|
||||||
switch (m_Texture2D.m_TextureSettings.m_WrapMode)
|
|
||||||
{
|
|
||||||
case 0: sb.AppendLine($"Wrap mode: Repeat"); break;
|
|
||||||
case 1: sb.AppendLine($"Wrap mode: Clamp"); break;
|
|
||||||
}
|
|
||||||
debugLog += sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
var image = m_Texture2D.ConvertToImage(flip: true);
|
|
||||||
if (image == null)
|
|
||||||
{
|
|
||||||
Logger.Error($"{debugLog}Export error. Failed to convert texture \"{m_Texture2D.m_Name}\" into image");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
using (image)
|
|
||||||
{
|
|
||||||
using (var file = File.OpenWrite(exportFullPath))
|
|
||||||
{
|
|
||||||
image.WriteToStream(file, type);
|
|
||||||
}
|
|
||||||
debugLog += $"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!TryExportFile(exportPath, item, ".tex", out var exportFullPath))
|
|
||||||
return false;
|
|
||||||
File.WriteAllBytes(exportFullPath, m_Texture2D.image_data.GetData());
|
|
||||||
debugLog += $"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ExportSprite(AssetItem item, string exportPath, out string debugLog)
|
|
||||||
{
|
|
||||||
debugLog = "";
|
|
||||||
var type = CLIOptions.o_imageFormat.Value;
|
|
||||||
var alphaMask = SpriteMaskMode.On;
|
|
||||||
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
|
|
||||||
return false;
|
|
||||||
var image = ((Sprite)item.Asset).GetImage(alphaMask);
|
|
||||||
if (image != null)
|
|
||||||
{
|
|
||||||
using (image)
|
|
||||||
{
|
|
||||||
using (var file = File.OpenWrite(exportFullPath))
|
|
||||||
{
|
|
||||||
image.WriteToStream(file, type);
|
|
||||||
}
|
|
||||||
debugLog += $"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ExportAudioClip(AssetItem item, string exportPath, out string debugLog)
|
|
||||||
{
|
|
||||||
debugLog = "";
|
|
||||||
string exportFullPath;
|
|
||||||
var m_AudioClip = (AudioClip)item.Asset;
|
|
||||||
var m_AudioData = BigArrayPool<byte>.Shared.Rent(m_AudioClip.m_AudioData.Size);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m_AudioClip.m_AudioData.GetData(m_AudioData);
|
|
||||||
if (m_AudioData == null || m_AudioData.Length == 0)
|
|
||||||
{
|
|
||||||
Logger.Error($"Export error. \"{item.Text}\": AudioData was not found");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var converter = new AudioClipConverter(m_AudioClip);
|
|
||||||
if (CLIOptions.o_audioFormat.Value != AudioFormat.None && converter.IsSupport)
|
|
||||||
{
|
|
||||||
if (!TryExportFile(exportPath, item, ".wav", out exportFullPath))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (CLIOptions.o_logLevel.Value <= LoggerEvent.Debug)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine($"Converting {item.TypeString} \"{m_AudioClip.m_Name}\" to wav..");
|
|
||||||
sb.AppendLine(m_AudioClip.version < 5 ? $"AudioClip type: {m_AudioClip.m_Type}" : $"AudioClip compression format: {m_AudioClip.m_CompressionFormat}");
|
|
||||||
sb.AppendLine($"AudioClip channel count: {m_AudioClip.m_Channels}");
|
|
||||||
sb.AppendLine($"AudioClip sample rate: {m_AudioClip.m_Frequency}");
|
|
||||||
sb.AppendLine($"AudioClip bit depth: {m_AudioClip.m_BitsPerSample}");
|
|
||||||
debugLog += sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
var buffer = converter.ConvertToWav(m_AudioData, out var debugLogConverter);
|
|
||||||
debugLog += debugLogConverter;
|
|
||||||
if (buffer == null)
|
|
||||||
{
|
|
||||||
Logger.Error($"{debugLog}Export error. \"{item.Text}\": Failed to convert fmod audio to Wav");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
File.WriteAllBytes(exportFullPath, buffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!TryExportFile(exportPath, item, converter.GetExtensionName(), out exportFullPath))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (CLIOptions.o_logLevel.Value <= LoggerEvent.Debug)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine($"Exporting non-fmod {item.TypeString} \"{m_AudioClip.m_Name}\"..");
|
|
||||||
sb.AppendLine(m_AudioClip.version < 5 ? $"AudioClip type: {m_AudioClip.m_Type}" : $"AudioClip compression format: {m_AudioClip.m_CompressionFormat}");
|
|
||||||
sb.AppendLine($"AudioClip channel count: {m_AudioClip.m_Channels}");
|
|
||||||
sb.AppendLine($"AudioClip sample rate: {m_AudioClip.m_Frequency}");
|
|
||||||
sb.AppendLine($"AudioClip bit depth: {m_AudioClip.m_BitsPerSample}");
|
|
||||||
debugLog += sb.ToString();
|
|
||||||
}
|
|
||||||
File.WriteAllBytes(exportFullPath, m_AudioData);
|
|
||||||
}
|
|
||||||
debugLog += $"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
BigArrayPool<byte>.Shared.Return(m_AudioData, clearArray: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool TryExportFile(string dir, AssetItem item, string extension, out string fullPath)
|
|
||||||
{
|
|
||||||
var fileName = FixFileName(item.Text);
|
|
||||||
var filenameFormat = CLIOptions.o_filenameFormat.Value;
|
|
||||||
switch (filenameFormat)
|
|
||||||
{
|
|
||||||
case FilenameFormat.AssetName_PathID:
|
|
||||||
fileName = $"{fileName} @{item.m_PathID}";
|
|
||||||
break;
|
|
||||||
case FilenameFormat.PathID:
|
|
||||||
fileName = item.m_PathID.ToString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fullPath = Path.Combine(dir, fileName + extension);
|
|
||||||
if (savePathHash.TryAdd(fullPath.ToLower(), true) && !File.Exists(fullPath))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(dir);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (filenameFormat == FilenameFormat.AssetName)
|
|
||||||
{
|
|
||||||
fullPath = Path.Combine(dir, fileName + item.UniqueID + extension);
|
|
||||||
if (!File.Exists(fullPath))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(dir);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Logger.Error($"Export error. File \"{fullPath.Color(ColorConsole.BrightRed)}\" already exist");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ParallelExportConvertFile(AssetItem item, string exportPath, out string debugLog)
|
|
||||||
{
|
|
||||||
switch (item.Type)
|
|
||||||
{
|
|
||||||
case ClassIDType.Texture2D:
|
|
||||||
case ClassIDType.Texture2DArrayImage:
|
|
||||||
return ExportTexture2D(item, exportPath, out debugLog);
|
|
||||||
case ClassIDType.Sprite:
|
|
||||||
return ExportSprite(item, exportPath, out debugLog);
|
|
||||||
case ClassIDType.AudioClip:
|
|
||||||
return ExportAudioClip(item, exportPath, out debugLog);
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FixFileName(string str)
|
|
||||||
{
|
|
||||||
return str.Length >= 260
|
|
||||||
? Path.GetRandomFileName()
|
|
||||||
: Path.GetInvalidFileNameChars().Aggregate(str, (current, c) => current.Replace(c, '_'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ClearHash()
|
|
||||||
{
|
|
||||||
savePathHash.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -48,7 +48,7 @@ namespace AssetStudioCLI
|
|||||||
case WorkMode.Info:
|
case WorkMode.Info:
|
||||||
Studio.ShowExportableAssetsInfo();
|
Studio.ShowExportableAssetsInfo();
|
||||||
break;
|
break;
|
||||||
case WorkMode.Live2D:
|
case WorkMode.ExportLive2D:
|
||||||
Studio.ExportLive2D();
|
Studio.ExportLive2D();
|
||||||
break;
|
break;
|
||||||
case WorkMode.SplitObjects:
|
case WorkMode.SplitObjects:
|
||||||
|
|||||||
@@ -1,24 +1,25 @@
|
|||||||
## AssetStudioModCLI
|
## ArknightsStudioCLI
|
||||||
CLI version of AssetStudioMod.
|
CLI version of ArknightsStudio.
|
||||||
- Supported asset types for export: `Texture2D`, `Sprite`, `TextAsset`, `MonoBehaviour`, `Font`, `Shader`, `MovieTexture`, `AudioClip`, `VideoClip`, `Mesh`.
|
- Supported asset types for export: `Texture2D`, `Sprite`, `AkPortraitSprite`, `TextAsset`, `MonoBehaviour`, `Font`, `Shader`, `MovieTexture`, `AudioClip`, `VideoClip`, `Mesh`.
|
||||||
- *There are no plans to add support for `AnimationClip`, `Animator` for now.*
|
- *There are no plans to add support for `AnimationClip`, `Animator` for now.*
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
```
|
```
|
||||||
AssetStudioModCLI <input path to asset file/folder> [-m, --mode <value>]
|
ArknightsStudioCLI <input path to asset file/folder> [-m, --mode <value>]
|
||||||
[-t, --asset-type <value(s)>] [-g, --group-option <value>]
|
[-t, --asset-type <value(s)>] [-g, --group-option <value>]
|
||||||
[-f, --filename-format <value>] [-o, --output <path>]
|
[-o, --output <path>] [-h, --help]
|
||||||
[-h, --help] [--log-level <value>]
|
[--log-level <value>] [--log-output <value>]
|
||||||
[--log-output <value>] [--image-format <value>]
|
[--image-format <value>] [--audio-format <value>]
|
||||||
[--audio-format <value>] [--l2d-motion-mode <value>]
|
[--l2d-motion-mode <value>] [--l2d-force-bezier]
|
||||||
[--l2d-force-bezier] [--fbx-scale-factor <value>]
|
[--fbx-scale-factor <value>] [--fbx-bone-size <value>]
|
||||||
[--fbx-bone-size <value>] [--filter-by-name <text>]
|
[--filter-by-name <text>] [--filter-by-container <text>]
|
||||||
[--filter-by-container <text>] [--filter-by-pathid <text>]
|
[--filter-by-pathid <text>] [--filter-by-text <text>]
|
||||||
[--filter-by-text <text>] [--custom-compression <value>]
|
[--spritealpha-mode <value>] [--alphatex-resampler <value>]
|
||||||
[--max-export-tasks <value>] [--export-asset-list <value>]
|
[--shadow-gamma <value>] [--original-avg-names]
|
||||||
|
[--add-aliases] [--export-asset-list <value>]
|
||||||
[--assembly-folder <path>] [--unity-version <text>]
|
[--assembly-folder <path>] [--unity-version <text>]
|
||||||
[--not-restore-extension] [--avoid-typetree-loading]
|
[--not-restore-extension] [--load-all]
|
||||||
[--load-all]
|
|
||||||
|
|
||||||
General Options:
|
General Options:
|
||||||
-m, --mode <value> Specify working mode
|
-m, --mode <value> Specify working mode
|
||||||
@@ -27,33 +28,25 @@ General Options:
|
|||||||
ExportRaw - Exports raw data
|
ExportRaw - Exports raw data
|
||||||
Dump - Makes asset dumps
|
Dump - Makes asset dumps
|
||||||
Info - Loads file(s), shows the number of available for export assets and exits
|
Info - Loads file(s), shows the number of available for export assets and exits
|
||||||
Live2D - Exports Live2D Cubism models
|
Live2D - Exports Live2D Cubism 3 models
|
||||||
SplitObjects - Exports split objects (fbx)
|
SplitObjects - Exports split objects (fbx)
|
||||||
Example: "-m info"
|
Example: "-m info"
|
||||||
|
|
||||||
-t, --asset-type <value(s)> Specify asset type(s) to export
|
-t, --asset-type <value(s)> Specify asset type(s) to export
|
||||||
<Value(s): tex2d, tex2dArray, sprite, textAsset, monoBehaviour, font, shader
|
<Value(s): tex2d, sprite, akPortrait, textAsset, monoBehaviour, font, shader,
|
||||||
movieTexture, audio, video, mesh | all(default)>
|
movieTexture, audio, video, mesh | all(default)>
|
||||||
All - export all asset types, which are listed in the values
|
All - export all asset types, which are listed in the values
|
||||||
*To specify multiple asset types, write them separated by ',' or ';' without spaces
|
*To specify multiple asset types, write them separated by ',' or ';' without spaces
|
||||||
Examples: "-t sprite" or "-t tex2d,sprite,audio" or "-t tex2d;sprite;font"
|
Examples: "-t sprite" or "-t tex2d,sprite,audio" or "-t tex2d;sprite;font"
|
||||||
|
|
||||||
-g, --group-option <value> Specify the way in which exported assets should be grouped
|
-g, --group-option <value> Specify the way in which exported assets should be grouped
|
||||||
<Value: none | type | container(default) | containerFull | filename | sceneHierarchy>
|
<Value: none | type | container(default) | containerFull | filename>
|
||||||
None - Do not group exported assets
|
None - Do not group exported assets
|
||||||
Type - Group exported assets by type name
|
Type - Group exported assets by type name
|
||||||
Container - Group exported assets by container path
|
Container - Group exported assets by container path
|
||||||
ContainerFull - Group exported assets by full container path (e.g. with prefab name)
|
ContainerFull - Group exported assets by full container path (e.g. with prefab name)
|
||||||
SceneHierarchy - Group exported assets by their node path in scene hierarchy
|
|
||||||
Filename - Group exported assets by source file name
|
Filename - Group exported assets by source file name
|
||||||
Example: "-g containerFull"
|
Example: "-g container"
|
||||||
|
|
||||||
-f, --filename-format <value> Specify the file name format for exported assets
|
|
||||||
<Value: assetName(default) | assetName_pathID | pathID>
|
|
||||||
AssetName - Asset file names will look like "assetName.extension"
|
|
||||||
AssetName_pathID - Asset file names will look like "assetName @pathID.extension"
|
|
||||||
PathID - Asset file names will look like "pathID.extension"
|
|
||||||
Example: "-f assetName_pathID"
|
|
||||||
|
|
||||||
-o, --output <path> Specify path to the output folder
|
-o, --output <path> Specify path to the output folder
|
||||||
If path isn't specified, 'ASExport' folder will be created in the program's work folder
|
If path isn't specified, 'ASExport' folder will be created in the program's work folder
|
||||||
@@ -75,9 +68,9 @@ Convert Options:
|
|||||||
None - Do not convert images and export them as texture data (.tex)
|
None - Do not convert images and export them as texture data (.tex)
|
||||||
Example: "--image-format jpg"
|
Example: "--image-format jpg"
|
||||||
|
|
||||||
--audio-format <value> Specify the format for converting FMOD audio assets
|
--audio-format <value> Specify the format for converting audio assets
|
||||||
<Value: none | wav(default)>
|
<Value: none | wav(default)>
|
||||||
None - Do not convert fmod audios and export them in their own format
|
None - Do not convert audios and export them in their own format
|
||||||
Example: "--audio-format wav"
|
Example: "--audio-format wav"
|
||||||
|
|
||||||
Live2D Options:
|
Live2D Options:
|
||||||
@@ -93,11 +86,11 @@ Live2D Options:
|
|||||||
|
|
||||||
FBX Options:
|
FBX Options:
|
||||||
--fbx-scale-factor <value> Specify the FBX Scale Factor
|
--fbx-scale-factor <value> Specify the FBX Scale Factor
|
||||||
<Value: float number from 0 to 100 (default=1)>
|
<Value: float number from 0 to 100 (default=1)
|
||||||
Example: "--fbx-scale-factor 50"
|
Example: "--fbx-scale-factor 50"
|
||||||
|
|
||||||
--fbx-bone-size <value> Specify the FBX Bone Size
|
--fbx-bone-size <value> Specify the FBX Bone Size
|
||||||
<Value: integer number from 0 to 100 (default=10)>
|
<Value: integer number from 0 to 100 (default=10)
|
||||||
Example: "--fbx-bone-size 10"
|
Example: "--fbx-bone-size 10"
|
||||||
|
|
||||||
Filter Options:
|
Filter Options:
|
||||||
@@ -119,18 +112,35 @@ Filter Options:
|
|||||||
Example: "--filter-by-text portrait" or "--filter-by-text portrait,art"
|
Example: "--filter-by-text portrait" or "--filter-by-text portrait,art"
|
||||||
|
|
||||||
|
|
||||||
|
Arknights Options:
|
||||||
|
--spritealpha-mode <value> Specify the mode in which you want to export sprites with alpha texture
|
||||||
|
<Value: none | internalOnly | searchExternal(default)>
|
||||||
|
None - Export sprites without alpha texture applied
|
||||||
|
InternalOnly - Export sprites with internal alpha texture applied (if exist)
|
||||||
|
SearchExternal - Export sprites with internal alpha texture applied,
|
||||||
|
and in case it doesn't exist, Studio will try to find an external alpha texture
|
||||||
|
Example: "--spritealpha-mode internalOnly"
|
||||||
|
|
||||||
|
--alphatex-resampler <value> Specify the alpha texture upscale algorithm for 2048x2048 sprites
|
||||||
|
<Value: nearest | bilinear | bicubic | mitchell(default) | spline | welch>
|
||||||
|
Mitchell - Mitchell Netravali algorithm. Yields good equilibrium between
|
||||||
|
sharpness and smoothness (produces less artifacts than bicubic in the current use case)
|
||||||
|
Spline - Similar to Mitchell Netravali but yielding smoother results
|
||||||
|
Welch - A high speed algorithm that delivers very sharpened results
|
||||||
|
Example: "--alphatex-resampler bicubic"
|
||||||
|
|
||||||
|
--shadow-gamma <value> Specify the gamma correction of semi-transparent shadow for 2048x2048 sprites
|
||||||
|
<Value: integer number from -5 to 5 (default=2)>
|
||||||
|
<0 - Make the shadow darker
|
||||||
|
0 - Do not change the brightness of the shadow
|
||||||
|
>0 - Make the shadow lighter
|
||||||
|
Example: "--shadow-gamma 0"
|
||||||
|
|
||||||
|
--original-avg-names (Flag) If specified, names of avg character sprites will not be restored
|
||||||
|
|
||||||
|
--add-aliases (Flag) If specified, aliases will be added to avg character sprite names (if exist)
|
||||||
|
|
||||||
Advanced Options:
|
Advanced Options:
|
||||||
--custom-compression <value> Specify the compression type for assets that use custom compression
|
|
||||||
<Value: zstd(default) | lz4>
|
|
||||||
Zstd - Try to decompress as zstd archive
|
|
||||||
Lz4 - Try to decompress as lz4 archive
|
|
||||||
Example: "--custom-compression lz4"
|
|
||||||
|
|
||||||
--max-export-tasks <value> Specify the number of parallel tasks for asset export
|
|
||||||
<Value: integer number from 1 to max number of cores (default=max)>
|
|
||||||
Max - Number of cores in your CPU
|
|
||||||
Example: "--max-export-tasks 8"
|
|
||||||
|
|
||||||
--export-asset-list <value> Specify the format in which you want to export asset list
|
--export-asset-list <value> Specify the format in which you want to export asset list
|
||||||
<Value: none(default) | xml>
|
<Value: none(default) | xml>
|
||||||
None - Do not export asset list
|
None - Do not export asset list
|
||||||
@@ -141,12 +151,9 @@ Advanced Options:
|
|||||||
--unity-version <text> Specify Unity version
|
--unity-version <text> Specify Unity version
|
||||||
Example: "--unity-version 2017.4.39f1"
|
Example: "--unity-version 2017.4.39f1"
|
||||||
|
|
||||||
--not-restore-extension (Flag) If specified, AssetStudio will not try to use/restore original TextAsset
|
--not-restore-extension (Flag) If specified, Studio will not try to use/restore original TextAsset
|
||||||
extension name, and will just export all TextAssets with the ".txt" extension
|
extension name, and will just export all TextAssets with the ".txt" extension
|
||||||
|
|
||||||
--avoid-typetree-loading (Flag) If specified, AssetStudio will not try to parse assets at load time
|
--load-all (Flag) If specified, Studio will load assets of all types
|
||||||
using their type tree
|
|
||||||
|
|
||||||
--load-all (Flag) If specified, AssetStudio will load assets of all types
|
|
||||||
(Only for Dump, Info and ExportRaw modes)
|
(Only for Dump, Info and ExportRaw modes)
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
using AssetStudio;
|
using AssetStudio;
|
||||||
using AssetStudioCLI.Options;
|
using AssetStudioCLI.Options;
|
||||||
using CubismLive2DExtractor;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using static AssetStudioCLI.Exporter;
|
using static AssetStudioCLI.Exporter;
|
||||||
|
using static CubismLive2DExtractor.Live2DExtractor;
|
||||||
using Ansi = AssetStudio.ColorConsole;
|
using Ansi = AssetStudio.ColorConsole;
|
||||||
|
|
||||||
namespace AssetStudioCLI
|
namespace AssetStudioCLI
|
||||||
@@ -17,10 +14,10 @@ namespace AssetStudioCLI
|
|||||||
internal static class Studio
|
internal static class Studio
|
||||||
{
|
{
|
||||||
public static AssetsManager assetsManager = new AssetsManager();
|
public static AssetsManager assetsManager = new AssetsManager();
|
||||||
public static List<AssetItem> parsedAssetsList = new List<AssetItem>();
|
public static List<AssetItem> exportableAssetsList = new List<AssetItem>();
|
||||||
|
public static List<AssetItem> loadedAssetsList = new List<AssetItem>();
|
||||||
public static List<BaseNode> gameObjectTree = new List<BaseNode>();
|
public static List<BaseNode> gameObjectTree = new List<BaseNode>();
|
||||||
public static AssemblyLoader assemblyLoader = new AssemblyLoader();
|
public static AssemblyLoader assemblyLoader = new AssemblyLoader();
|
||||||
public static List<MonoBehaviour> cubismMocList = new List<MonoBehaviour>();
|
|
||||||
private static Dictionary<AssetStudio.Object, string> containers = new Dictionary<AssetStudio.Object, string>();
|
private static Dictionary<AssetStudio.Object, string> containers = new Dictionary<AssetStudio.Object, string>();
|
||||||
|
|
||||||
static Studio()
|
static Studio()
|
||||||
@@ -37,8 +34,6 @@ namespace AssetStudioCLI
|
|||||||
{
|
{
|
||||||
var isLoaded = false;
|
var isLoaded = false;
|
||||||
assetsManager.SpecifyUnityVersion = CLIOptions.o_unityVersion.Value;
|
assetsManager.SpecifyUnityVersion = CLIOptions.o_unityVersion.Value;
|
||||||
assetsManager.ZstdEnabled = CLIOptions.o_customCompressionType.Value == CustomCompressionType.Zstd;
|
|
||||||
assetsManager.LoadingViaTypeTreeEnabled = !CLIOptions.f_avoidLoadingViaTypetree.Value;
|
|
||||||
if (!CLIOptions.f_loadAllAssets.Value)
|
if (!CLIOptions.f_loadAllAssets.Value)
|
||||||
{
|
{
|
||||||
assetsManager.SetAssetFilter(CLIOptions.o_exportAssetTypes.Value);
|
assetsManager.SetAssetFilter(CLIOptions.o_exportAssetTypes.Value);
|
||||||
@@ -60,8 +55,6 @@ namespace AssetStudioCLI
|
|||||||
{
|
{
|
||||||
Logger.Info("Parse assets...");
|
Logger.Info("Parse assets...");
|
||||||
|
|
||||||
var fileAssetsList = new List<AssetItem>();
|
|
||||||
var tex2dArrayAssetList = new List<AssetItem>();
|
|
||||||
var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
|
var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
|
||||||
var objectAssetItemDic = new Dictionary<AssetStudio.Object, AssetItem>(objectCount);
|
var objectAssetItemDic = new Dictionary<AssetStudio.Object, AssetItem>(objectCount);
|
||||||
|
|
||||||
@@ -118,12 +111,6 @@ namespace AssetStudioCLI
|
|||||||
assetItem.FullSize = asset.byteSize + m_Texture2D.m_StreamData.size;
|
assetItem.FullSize = asset.byteSize + m_Texture2D.m_StreamData.size;
|
||||||
assetItem.Text = m_Texture2D.m_Name;
|
assetItem.Text = m_Texture2D.m_Name;
|
||||||
break;
|
break;
|
||||||
case Texture2DArray m_Texture2DArray:
|
|
||||||
if (!string.IsNullOrEmpty(m_Texture2DArray.m_StreamData?.path))
|
|
||||||
assetItem.FullSize = asset.byteSize + m_Texture2DArray.m_StreamData.size;
|
|
||||||
assetItem.Text = m_Texture2DArray.m_Name;
|
|
||||||
tex2dArrayAssetList.Add(assetItem);
|
|
||||||
break;
|
|
||||||
case AudioClip m_AudioClip:
|
case AudioClip m_AudioClip:
|
||||||
if (!string.IsNullOrEmpty(m_AudioClip.m_Source))
|
if (!string.IsNullOrEmpty(m_AudioClip.m_Source))
|
||||||
assetItem.FullSize = asset.byteSize + m_AudioClip.m_Size;
|
assetItem.FullSize = asset.byteSize + m_AudioClip.m_Size;
|
||||||
@@ -138,16 +125,14 @@ namespace AssetStudioCLI
|
|||||||
assetItem.Text = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name;
|
assetItem.Text = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name;
|
||||||
break;
|
break;
|
||||||
case MonoBehaviour m_MonoBehaviour:
|
case MonoBehaviour m_MonoBehaviour:
|
||||||
var assetName = m_MonoBehaviour.m_Name;
|
if (m_MonoBehaviour.m_Name == "" && m_MonoBehaviour.m_Script.TryGet(out var m_Script))
|
||||||
if (m_MonoBehaviour.m_Script.TryGet(out var m_Script))
|
|
||||||
{
|
{
|
||||||
assetName = assetName == "" ? m_Script.m_ClassName : assetName;
|
assetItem.Text = m_Script.m_ClassName;
|
||||||
if (m_Script.m_ClassName == "CubismMoc")
|
}
|
||||||
{
|
else
|
||||||
cubismMocList.Add(m_MonoBehaviour);
|
{
|
||||||
}
|
assetItem.Text = m_MonoBehaviour.m_Name;
|
||||||
}
|
}
|
||||||
assetItem.Text = assetName;
|
|
||||||
break;
|
break;
|
||||||
case GameObject m_GameObject:
|
case GameObject m_GameObject:
|
||||||
assetItem.Text = m_GameObject.m_Name;
|
assetItem.Text = m_GameObject.m_Name;
|
||||||
@@ -167,48 +152,45 @@ namespace AssetStudioCLI
|
|||||||
assetItem.Text = assetItem.TypeString + assetItem.UniqueID;
|
assetItem.Text = assetItem.TypeString + assetItem.UniqueID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadedAssetsList.Add(assetItem);
|
||||||
isExportable = CLIOptions.o_exportAssetTypes.Value.Contains(asset.type);
|
isExportable = CLIOptions.o_exportAssetTypes.Value.Contains(asset.type);
|
||||||
if (isExportable || (CLIOptions.f_loadAllAssets.Value && CLIOptions.o_exportAssetTypes.Value == CLIOptions.o_exportAssetTypes.DefaultValue))
|
if (isExportable || (CLIOptions.f_loadAllAssets.Value && CLIOptions.o_exportAssetTypes.Value == CLIOptions.o_exportAssetTypes.DefaultValue))
|
||||||
{
|
{
|
||||||
fileAssetsList.Add(assetItem);
|
exportableAssetsList.Add(assetItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
Progress.Report(++i, objectCount);
|
Progress.Report(++i, objectCount);
|
||||||
}
|
}
|
||||||
foreach (var asset in fileAssetsList)
|
foreach (var asset in loadedAssetsList)
|
||||||
{
|
{
|
||||||
if (containers.TryGetValue(asset.Asset, out var container))
|
if (containers.TryGetValue(asset.Asset, out var container))
|
||||||
{
|
{
|
||||||
asset.Container = container;
|
asset.Container = container;
|
||||||
|
|
||||||
|
if (asset.Type == ClassIDType.MonoBehaviour && container.Contains("/arts/charportraits/portraits"))
|
||||||
|
{
|
||||||
|
var portraitsList = Arknights.AkSpriteHelper.GeneratePortraits(asset);
|
||||||
|
foreach (var portrait in portraitsList)
|
||||||
|
{
|
||||||
|
exportableAssetsList.Add(new AssetItem(portrait));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var tex2dAssetItem in tex2dArrayAssetList)
|
if (CLIOptions.o_workMode.Value != WorkMode.ExportLive2D)
|
||||||
{
|
|
||||||
var m_Texture2DArray = (Texture2DArray)tex2dAssetItem.Asset;
|
|
||||||
for (var layer = 0; layer < m_Texture2DArray.m_Depth; layer++)
|
|
||||||
{
|
|
||||||
var fakeObj = new Texture2D(m_Texture2DArray, layer);
|
|
||||||
m_Texture2DArray.TextureList.Add(fakeObj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parsedAssetsList.AddRange(fileAssetsList);
|
|
||||||
fileAssetsList.Clear();
|
|
||||||
tex2dArrayAssetList.Clear();
|
|
||||||
if (CLIOptions.o_workMode.Value != WorkMode.Live2D)
|
|
||||||
{
|
{
|
||||||
containers.Clear();
|
containers.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CLIOptions.o_workMode.Value == WorkMode.SplitObjects || CLIOptions.o_groupAssetsBy.Value == AssetGroupOption.SceneHierarchy)
|
if (CLIOptions.o_workMode.Value == WorkMode.SplitObjects)
|
||||||
{
|
{
|
||||||
BuildTreeStructure(objectAssetItemDic);
|
BuildTreeStructure(objectAssetItemDic);
|
||||||
}
|
}
|
||||||
|
var log = $"Finished loading {assetsManager.assetsFileList.Count} files with {exportableAssetsList.Count} exportable assets";
|
||||||
var log = $"Finished loading {assetsManager.assetsFileList.Count} files with {parsedAssetsList.Count} exportable assets";
|
|
||||||
var unityVer = assetsManager.assetsFileList[0].version;
|
var unityVer = assetsManager.assetsFileList[0].version;
|
||||||
long m_ObjectsCount;
|
long m_ObjectsCount;
|
||||||
if (unityVer > 2020)
|
if (unityVer[0] > 2020)
|
||||||
{
|
{
|
||||||
m_ObjectsCount = assetsManager.assetsFileList.Sum(x => x.m_Objects.LongCount(y =>
|
m_ObjectsCount = assetsManager.assetsFileList.Sum(x => x.m_Objects.LongCount(y =>
|
||||||
y.classID != (int)ClassIDType.Shader
|
y.classID != (int)ClassIDType.Shader
|
||||||
@@ -237,7 +219,7 @@ namespace AssetStudioCLI
|
|||||||
Progress.Reset();
|
Progress.Reset();
|
||||||
foreach (var assetsFile in assetsManager.assetsFileList)
|
foreach (var assetsFile in assetsManager.assetsFileList)
|
||||||
{
|
{
|
||||||
var fileNode = new BaseNode(assetsFile.fileName); //RootNode
|
var fileNode = new BaseNode(); //RootNode
|
||||||
|
|
||||||
foreach (var obj in assetsFile.Objects)
|
foreach (var obj in assetsFile.Objects)
|
||||||
{
|
{
|
||||||
@@ -272,6 +254,7 @@ namespace AssetStudioCLI
|
|||||||
}
|
}
|
||||||
|
|
||||||
var parentNode = fileNode;
|
var parentNode = fileNode;
|
||||||
|
|
||||||
if (m_GameObject.m_Transform != null)
|
if (m_GameObject.m_Transform != null)
|
||||||
{
|
{
|
||||||
if (m_GameObject.m_Transform.m_Father.TryGet(out var m_Father))
|
if (m_GameObject.m_Transform.m_Father.TryGet(out var m_Father))
|
||||||
@@ -287,13 +270,14 @@ namespace AssetStudioCLI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parentNode.nodes.Add(currentNode);
|
parentNode.nodes.Add(currentNode);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileNode.nodes.Count > 0)
|
if (fileNode.nodes.Count > 0)
|
||||||
{
|
{
|
||||||
GenerateFullPath(fileNode, fileNode.Text);
|
|
||||||
gameObjectTree.Add(fileNode);
|
gameObjectTree.Add(fileNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,29 +288,13 @@ namespace AssetStudioCLI
|
|||||||
objectAssetItemDic.Clear();
|
objectAssetItemDic.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GenerateFullPath(BaseNode treeNode, string path)
|
|
||||||
{
|
|
||||||
treeNode.FullPath = path;
|
|
||||||
foreach (var node in treeNode.nodes)
|
|
||||||
{
|
|
||||||
if (node.nodes.Count > 0)
|
|
||||||
{
|
|
||||||
GenerateFullPath(node, Path.Combine(path, node.Text));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
node.FullPath = Path.Combine(path, node.Text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ShowExportableAssetsInfo()
|
public static void ShowExportableAssetsInfo()
|
||||||
{
|
{
|
||||||
var exportableAssetsCountDict = new Dictionary<ClassIDType, int>();
|
var exportableAssetsCountDict = new Dictionary<ClassIDType, int>();
|
||||||
string info = "";
|
string info = "";
|
||||||
if (parsedAssetsList.Count > 0)
|
if (exportableAssetsList.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var asset in parsedAssetsList)
|
foreach (var asset in exportableAssetsList)
|
||||||
{
|
{
|
||||||
if (exportableAssetsCountDict.ContainsKey(asset.Type))
|
if (exportableAssetsCountDict.ContainsKey(asset.Type))
|
||||||
{
|
{
|
||||||
@@ -345,7 +313,7 @@ namespace AssetStudioCLI
|
|||||||
}
|
}
|
||||||
if (exportableAssetsCountDict.Count > 1)
|
if (exportableAssetsCountDict.Count > 1)
|
||||||
{
|
{
|
||||||
info += $"#\n# Total: {parsedAssetsList.Count} assets";
|
info += $"#\n# Total: {exportableAssetsList.Count} assets";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -367,7 +335,7 @@ namespace AssetStudioCLI
|
|||||||
{
|
{
|
||||||
switch (CLIOptions.o_workMode.Value)
|
switch (CLIOptions.o_workMode.Value)
|
||||||
{
|
{
|
||||||
case WorkMode.Live2D:
|
case WorkMode.ExportLive2D:
|
||||||
case WorkMode.SplitObjects:
|
case WorkMode.SplitObjects:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -378,34 +346,34 @@ namespace AssetStudioCLI
|
|||||||
|
|
||||||
private static void FilterAssets()
|
private static void FilterAssets()
|
||||||
{
|
{
|
||||||
var assetsCount = parsedAssetsList.Count;
|
var assetsCount = exportableAssetsList.Count;
|
||||||
var filteredAssets = new List<AssetItem>();
|
var filteredAssets = new List<AssetItem>();
|
||||||
|
|
||||||
switch(CLIOptions.filterBy)
|
switch(CLIOptions.filterBy)
|
||||||
{
|
{
|
||||||
case FilterBy.Name:
|
case FilterBy.Name:
|
||||||
filteredAssets = parsedAssetsList.FindAll(x => CLIOptions.o_filterByName.Value.Any(y => x.Text.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0));
|
filteredAssets = exportableAssetsList.FindAll(x => CLIOptions.o_filterByName.Value.Any(y => x.Text.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0));
|
||||||
Logger.Info(
|
Logger.Info(
|
||||||
$"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " +
|
$"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " +
|
||||||
$"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByName.Value)}\"".Color(Ansi.BrightYellow)} in their Names."
|
$"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByName.Value)}\"".Color(Ansi.BrightYellow)} in their Names."
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case FilterBy.Container:
|
case FilterBy.Container:
|
||||||
filteredAssets = parsedAssetsList.FindAll(x => CLIOptions.o_filterByContainer.Value.Any(y => x.Container.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0));
|
filteredAssets = exportableAssetsList.FindAll(x => CLIOptions.o_filterByContainer.Value.Any(y => x.Container.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0));
|
||||||
Logger.Info(
|
Logger.Info(
|
||||||
$"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " +
|
$"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " +
|
||||||
$"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByContainer.Value)}\"".Color(Ansi.BrightYellow)} in their Containers."
|
$"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByContainer.Value)}\"".Color(Ansi.BrightYellow)} in their Containers."
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case FilterBy.PathID:
|
case FilterBy.PathID:
|
||||||
filteredAssets = parsedAssetsList.FindAll(x => CLIOptions.o_filterByPathID.Value.Any(y => x.m_PathID.ToString().IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0));
|
filteredAssets = exportableAssetsList.FindAll(x => CLIOptions.o_filterByPathID.Value.Any(y => x.m_PathID.ToString().IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0));
|
||||||
Logger.Info(
|
Logger.Info(
|
||||||
$"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " +
|
$"Found [{filteredAssets.Count}/{assetsCount}] asset(s) " +
|
||||||
$"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByPathID.Value)}\"".Color(Ansi.BrightYellow)} in their PathIDs."
|
$"that contain {$"\"{string.Join("\", \"", CLIOptions.o_filterByPathID.Value)}\"".Color(Ansi.BrightYellow)} in their PathIDs."
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case FilterBy.NameOrContainer:
|
case FilterBy.NameOrContainer:
|
||||||
filteredAssets = parsedAssetsList.FindAll(x =>
|
filteredAssets = exportableAssetsList.FindAll(x =>
|
||||||
CLIOptions.o_filterByText.Value.Any(y => x.Text.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0) ||
|
CLIOptions.o_filterByText.Value.Any(y => x.Text.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||||
CLIOptions.o_filterByText.Value.Any(y => x.Container.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0)
|
CLIOptions.o_filterByText.Value.Any(y => x.Container.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0)
|
||||||
);
|
);
|
||||||
@@ -415,7 +383,7 @@ namespace AssetStudioCLI
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case FilterBy.NameAndContainer:
|
case FilterBy.NameAndContainer:
|
||||||
filteredAssets = parsedAssetsList.FindAll(x =>
|
filteredAssets = exportableAssetsList.FindAll(x =>
|
||||||
CLIOptions.o_filterByName.Value.Any(y => x.Text.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0) &&
|
CLIOptions.o_filterByName.Value.Any(y => x.Text.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0) &&
|
||||||
CLIOptions.o_filterByContainer.Value.Any(y => x.Container.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0)
|
CLIOptions.o_filterByContainer.Value.Any(y => x.Container.IndexOf(y, StringComparison.OrdinalIgnoreCase) >= 0)
|
||||||
);
|
);
|
||||||
@@ -426,21 +394,18 @@ namespace AssetStudioCLI
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
parsedAssetsList.Clear();
|
exportableAssetsList.Clear();
|
||||||
parsedAssetsList = filteredAssets;
|
exportableAssetsList = filteredAssets;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ExportAssets()
|
public static void ExportAssets()
|
||||||
{
|
{
|
||||||
var savePath = CLIOptions.o_outputFolder.Value;
|
var savePath = CLIOptions.o_outputFolder.Value;
|
||||||
var toExportCount = parsedAssetsList.Count;
|
var toExportCount = exportableAssetsList.Count;
|
||||||
var exportedCount = 0;
|
var exportedCount = 0;
|
||||||
|
|
||||||
var groupOption = CLIOptions.o_groupAssetsBy.Value;
|
var groupOption = CLIOptions.o_groupAssetsBy.Value;
|
||||||
var parallelExportCount = CLIOptions.o_maxParallelExportTasks.Value;
|
foreach (var asset in exportableAssetsList)
|
||||||
var toExportAssetDict = new ConcurrentDictionary<AssetItem, string>();
|
|
||||||
var toParallelExportAssetDict = new ConcurrentDictionary<AssetItem, string>();
|
|
||||||
Parallel.ForEach(parsedAssetsList, asset =>
|
|
||||||
{
|
{
|
||||||
string exportPath;
|
string exportPath;
|
||||||
switch (groupOption)
|
switch (groupOption)
|
||||||
@@ -473,75 +438,36 @@ namespace AssetStudioCLI
|
|||||||
exportPath = Path.Combine(savePath, Path.GetFileName(asset.SourceFile.originalPath) + "_export", asset.SourceFile.fileName);
|
exportPath = Path.Combine(savePath, Path.GetFileName(asset.SourceFile.originalPath) + "_export", asset.SourceFile.fileName);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AssetGroupOption.SceneHierarchy:
|
|
||||||
if (asset.Node != null)
|
|
||||||
{
|
|
||||||
exportPath = Path.Combine(savePath, asset.Node.FullPath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
exportPath = Path.Combine(savePath, "_sceneRoot", asset.TypeString);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
exportPath = savePath;
|
exportPath = savePath;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
exportPath += Path.DirectorySeparatorChar;
|
exportPath += Path.DirectorySeparatorChar;
|
||||||
|
|
||||||
if (CLIOptions.o_workMode.Value == WorkMode.Export)
|
|
||||||
{
|
|
||||||
switch (asset.Type)
|
|
||||||
{
|
|
||||||
case ClassIDType.Texture2D:
|
|
||||||
case ClassIDType.Sprite:
|
|
||||||
case ClassIDType.AudioClip:
|
|
||||||
toParallelExportAssetDict.TryAdd(asset, exportPath);
|
|
||||||
break;
|
|
||||||
case ClassIDType.Texture2DArray:
|
|
||||||
var m_Texture2DArray = (Texture2DArray)asset.Asset;
|
|
||||||
toExportCount += m_Texture2DArray.TextureList.Count - 1;
|
|
||||||
foreach (var texture in m_Texture2DArray.TextureList)
|
|
||||||
{
|
|
||||||
var fakeItem = new AssetItem(texture)
|
|
||||||
{
|
|
||||||
Text = texture.m_Name,
|
|
||||||
Container = asset.Container,
|
|
||||||
};
|
|
||||||
toParallelExportAssetDict.TryAdd(fakeItem, exportPath);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
toExportAssetDict.TryAdd(asset, exportPath);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
toExportAssetDict.TryAdd(asset, exportPath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
foreach (var toExportAsset in toExportAssetDict)
|
|
||||||
{
|
|
||||||
var asset = toExportAsset.Key;
|
|
||||||
var exportPath = toExportAsset.Value;
|
|
||||||
var isExported = false;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch (CLIOptions.o_workMode.Value)
|
switch (CLIOptions.o_workMode.Value)
|
||||||
{
|
{
|
||||||
case WorkMode.ExportRaw:
|
case WorkMode.ExportRaw:
|
||||||
Logger.Debug($"{CLIOptions.o_workMode}: {asset.Type} : {asset.Container} : {asset.Text}");
|
Logger.Debug($"{CLIOptions.o_workMode}: {asset.Type} : {asset.Container} : {asset.Text}");
|
||||||
isExported = ExportRawFile(asset, exportPath);
|
if (ExportRawFile(asset, exportPath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WorkMode.Dump:
|
case WorkMode.Dump:
|
||||||
Logger.Debug($"{CLIOptions.o_workMode}: {asset.Type} : {asset.Container} : {asset.Text}");
|
Logger.Debug($"{CLIOptions.o_workMode}: {asset.Type} : {asset.Container} : {asset.Text}");
|
||||||
isExported = ExportDumpFile(asset, exportPath);
|
if (ExportDumpFile(asset, exportPath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WorkMode.Export:
|
case WorkMode.Export:
|
||||||
Logger.Debug($"{CLIOptions.o_workMode}: {asset.Type} : {asset.Container} : {asset.Text}");
|
Logger.Debug($"{CLIOptions.o_workMode}: {asset.Type} : {asset.Container} : {asset.Text}");
|
||||||
isExported = ExportConvertFile(asset, exportPath);
|
if (ExportConvertFile(asset, exportPath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -549,33 +475,8 @@ namespace AssetStudioCLI
|
|||||||
{
|
{
|
||||||
Logger.Error($"{asset.SourceFile.originalPath}: [{$"{asset.Type}: {asset.Text}".Color(Ansi.BrightRed)}] : Export error\n{ex}");
|
Logger.Error($"{asset.SourceFile.originalPath}: [{$"{asset.Type}: {asset.Text}".Color(Ansi.BrightRed)}] : Export error\n{ex}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isExported)
|
|
||||||
{
|
|
||||||
exportedCount++;
|
|
||||||
}
|
|
||||||
Console.Write($"Exported [{exportedCount}/{toExportCount}]\r");
|
Console.Write($"Exported [{exportedCount}/{toExportCount}]\r");
|
||||||
}
|
}
|
||||||
|
|
||||||
Parallel.ForEach(toParallelExportAssetDict, new ParallelOptions { MaxDegreeOfParallelism = parallelExportCount }, toExportAsset =>
|
|
||||||
{
|
|
||||||
var asset = toExportAsset.Key;
|
|
||||||
var exportPath = toExportAsset.Value;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (ParallelExporter.ParallelExportConvertFile(asset, exportPath, out var debugLog))
|
|
||||||
{
|
|
||||||
Interlocked.Increment(ref exportedCount);
|
|
||||||
Logger.Debug(debugLog);
|
|
||||||
Console.Write($"Exported [{exportedCount}/{toExportCount}]\r");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logger.Error($"{asset.SourceFile.originalPath}: [{$"{asset.Type}: {asset.Text}".Color(Ansi.BrightRed)}] : Export error\n{ex}");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
ParallelExporter.ClearHash();
|
|
||||||
Console.WriteLine("");
|
Console.WriteLine("");
|
||||||
|
|
||||||
if (exportedCount == 0)
|
if (exportedCount == 0)
|
||||||
@@ -609,14 +510,13 @@ namespace AssetStudioCLI
|
|||||||
new XElement("Assets",
|
new XElement("Assets",
|
||||||
new XAttribute("filename", filename),
|
new XAttribute("filename", filename),
|
||||||
new XAttribute("createdAt", DateTime.UtcNow.ToString("s")),
|
new XAttribute("createdAt", DateTime.UtcNow.ToString("s")),
|
||||||
parsedAssetsList.Select(
|
exportableAssetsList.Select(
|
||||||
asset => new XElement("Asset",
|
asset => new XElement("Asset",
|
||||||
new XElement("Name", asset.Text),
|
new XElement("Name", asset.Text),
|
||||||
new XElement("Container", asset.Container),
|
new XElement("Container", asset.Container),
|
||||||
new XElement("Type", new XAttribute("id", (int)asset.Type), asset.TypeString),
|
new XElement("Type", new XAttribute("id", (int)asset.Type), asset.TypeString),
|
||||||
new XElement("PathID", asset.m_PathID),
|
new XElement("PathID", asset.m_PathID),
|
||||||
new XElement("Source", asset.SourceFile.fullName),
|
new XElement("Source", asset.SourceFile.fullName),
|
||||||
new XElement("TreeNode", asset.Node != null ? asset.Node.FullPath : ""),
|
|
||||||
new XElement("Size", asset.FullSize)
|
new XElement("Size", asset.FullSize)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -626,7 +526,7 @@ namespace AssetStudioCLI
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Logger.Info($"Finished exporting asset list with {parsedAssetsList.Count} items.");
|
Logger.Info($"Finished exporting asset list with {exportableAssetsList.Count} items.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ExportSplitObjects()
|
public static void ExportSplitObjects()
|
||||||
@@ -648,7 +548,7 @@ namespace AssetStudioCLI
|
|||||||
{
|
{
|
||||||
if (isFiltered)
|
if (isFiltered)
|
||||||
{
|
{
|
||||||
if (!searchList.Any(searchText => j.Text.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0))
|
if (!searchList.Any(searchText => j.gameObject.m_Name.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var gameObjects = new List<GameObject>();
|
var gameObjects = new List<GameObject>();
|
||||||
@@ -727,60 +627,66 @@ namespace AssetStudioCLI
|
|||||||
public static void ExportLive2D()
|
public static void ExportLive2D()
|
||||||
{
|
{
|
||||||
var baseDestPath = Path.Combine(CLIOptions.o_outputFolder.Value, "Live2DOutput");
|
var baseDestPath = Path.Combine(CLIOptions.o_outputFolder.Value, "Live2DOutput");
|
||||||
var useFullContainerPath = true;
|
var useFullContainerPath = false;
|
||||||
var mocPathList = new List<string>();
|
|
||||||
var basePathSet = new HashSet<string>();
|
|
||||||
var motionMode = CLIOptions.o_l2dMotionMode.Value;
|
var motionMode = CLIOptions.o_l2dMotionMode.Value;
|
||||||
var forceBezier = CLIOptions.f_l2dForceBezier.Value;
|
var forceBezier = CLIOptions.f_l2dForceBezier.Value;
|
||||||
|
|
||||||
if (cubismMocList.Count == 0)
|
|
||||||
{
|
|
||||||
Logger.Default.Log(LoggerEvent.Info, "Live2D Cubism models were not found.", ignoreLevel: true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Progress.Reset();
|
Progress.Reset();
|
||||||
Logger.Info($"Searching for Live2D files...");
|
Logger.Info($"Searching for Live2D files...");
|
||||||
|
|
||||||
foreach (var mocMonoBehaviour in cubismMocList)
|
var cubismMocs = exportableAssetsList.Where(x =>
|
||||||
{
|
{
|
||||||
if (!containers.TryGetValue(mocMonoBehaviour, out var fullContainerPath))
|
if (x.Type == ClassIDType.MonoBehaviour)
|
||||||
continue;
|
{
|
||||||
|
((MonoBehaviour)x.Asset).m_Script.TryGet(out var m_Script);
|
||||||
|
return m_Script?.m_ClassName == "CubismMoc";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}).Select(x => x.Asset).ToArray();
|
||||||
|
|
||||||
var pathSepIndex = fullContainerPath.LastIndexOf('/');
|
if (cubismMocs.Length == 0)
|
||||||
var basePath = pathSepIndex > 0
|
|
||||||
? fullContainerPath.Substring(0, pathSepIndex)
|
|
||||||
: fullContainerPath;
|
|
||||||
basePathSet.Add(basePath);
|
|
||||||
mocPathList.Add(fullContainerPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mocPathList.Count == 0)
|
|
||||||
{
|
{
|
||||||
Logger.Error("Live2D Cubism export error: Cannot find any model related files.");
|
Logger.Default.Log(LoggerEvent.Info, "Live2D Cubism models were not found.", ignoreLevel: true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (basePathSet.Count == mocPathList.Count)
|
if (cubismMocs.Length > 1)
|
||||||
{
|
{
|
||||||
mocPathList = basePathSet.ToList();
|
var basePathSet = cubismMocs.Select(x =>
|
||||||
useFullContainerPath = false;
|
{
|
||||||
Logger.Debug($"useFullContainerPath: {useFullContainerPath}");
|
var pathLen = containers.TryGetValue(x, out var itemContainer) ? itemContainer.LastIndexOf("/") : 0;
|
||||||
}
|
pathLen = pathLen < 0 ? containers[x].Length : pathLen;
|
||||||
basePathSet.Clear();
|
return itemContainer?.Substring(0, pathLen);
|
||||||
|
}).ToHashSet();
|
||||||
|
|
||||||
var lookup = containers.AsParallel().ToLookup(
|
if (basePathSet.All(x => x == null))
|
||||||
x => mocPathList.Find(b => x.Value.Contains(b) && x.Value.Split('/').Any(y => y == b.Substring(b.LastIndexOf("/") + 1))),
|
{
|
||||||
|
Logger.Error($"Live2D Cubism export error: Cannot find any model related files.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basePathSet.Count != cubismMocs.Length)
|
||||||
|
{
|
||||||
|
useFullContainerPath = true;
|
||||||
|
Logger.Debug($"useFullContainerPath: {useFullContainerPath}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var basePathList = cubismMocs.Select(x =>
|
||||||
|
{
|
||||||
|
containers.TryGetValue(x, out var container);
|
||||||
|
container = useFullContainerPath
|
||||||
|
? container
|
||||||
|
: container?.Substring(0, container.LastIndexOf("/"));
|
||||||
|
return container;
|
||||||
|
}).Where(x => x != null).ToList();
|
||||||
|
|
||||||
|
var lookup = containers.ToLookup(
|
||||||
|
x => basePathList.Find(b => x.Value.Contains(b) && x.Value.Split('/').Any(y => y == b.Substring(b.LastIndexOf("/") + 1))),
|
||||||
x => x.Key
|
x => x.Key
|
||||||
);
|
);
|
||||||
|
|
||||||
if (cubismMocList[0].serializedType?.m_Type == null && CLIOptions.o_assemblyPath.Value == "")
|
|
||||||
{
|
|
||||||
Logger.Warning("Specifying the assembly folder may be needed for proper extraction");
|
|
||||||
}
|
|
||||||
|
|
||||||
var totalModelCount = lookup.LongCount(x => x.Key != null);
|
var totalModelCount = lookup.LongCount(x => x.Key != null);
|
||||||
Logger.Info($"Found {totalModelCount} model(s).");
|
Logger.Info($"Found {totalModelCount} model(s).");
|
||||||
var parallelTaskCount = CLIOptions.o_maxParallelExportTasks.Value;
|
|
||||||
var modelCounter = 0;
|
var modelCounter = 0;
|
||||||
foreach (var assets in lookup)
|
foreach (var assets in lookup)
|
||||||
{
|
{
|
||||||
@@ -792,16 +698,11 @@ namespace AssetStudioCLI
|
|||||||
Logger.Info($"[{modelCounter + 1}/{totalModelCount}] Exporting Live2D: \"{srcContainer.Color(Ansi.BrightCyan)}\"");
|
Logger.Info($"[{modelCounter + 1}/{totalModelCount}] Exporting Live2D: \"{srcContainer.Color(Ansi.BrightCyan)}\"");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var modelName = useFullContainerPath
|
var modelName = useFullContainerPath ? Path.GetFileNameWithoutExtension(container) : container.Substring(container.LastIndexOf('/') + 1);
|
||||||
? Path.GetFileNameWithoutExtension(container)
|
container = Path.HasExtension(container) ? container.Replace(Path.GetExtension(container), "") : container;
|
||||||
: container.Substring(container.LastIndexOf('/') + 1);
|
|
||||||
container = Path.HasExtension(container)
|
|
||||||
? container.Replace(Path.GetExtension(container), "")
|
|
||||||
: container;
|
|
||||||
var destPath = Path.Combine(baseDestPath, container) + Path.DirectorySeparatorChar;
|
var destPath = Path.Combine(baseDestPath, container) + Path.DirectorySeparatorChar;
|
||||||
|
|
||||||
var modelExtractor = new Live2DExtractor(assets);
|
ExtractLive2D(assets, destPath, modelName, assemblyLoader, motionMode, forceBezier);
|
||||||
modelExtractor.ExtractCubismModel(destPath, modelName, motionMode, assemblyLoader, forceBezier, parallelTaskCount);
|
|
||||||
modelCounter++;
|
modelCounter++;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows;net8.0;net8.0-windows</TargetFrameworks>
|
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows;net8.0;net8.0-windows</TargetFrameworks>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<Version>0.18.0.0</Version>
|
<Version>1.2.0</Version>
|
||||||
<Copyright>Copyright © Perfare 2018-2022; Copyright © hozuki 2020</Copyright>
|
<Copyright>Copyright © Perfare 2018-2022; Copyright © hozuki 2020</Copyright>
|
||||||
<DebugType>embedded</DebugType>
|
<DebugType>embedded</DebugType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
53
AssetStudioGUI/AboutForm.Designer.cs
generated
53
AssetStudioGUI/AboutForm.Designer.cs
generated
@@ -49,7 +49,7 @@
|
|||||||
this.label7 = new System.Windows.Forms.Label();
|
this.label7 = new System.Windows.Forms.Label();
|
||||||
this.modVersionLabel = new System.Windows.Forms.Label();
|
this.modVersionLabel = new System.Windows.Forms.Label();
|
||||||
this.label4 = new System.Windows.Forms.Label();
|
this.label4 = new System.Windows.Forms.Label();
|
||||||
this.label8 = new System.Windows.Forms.Label();
|
this.basedOnLabel = new System.Windows.Forms.Label();
|
||||||
this.checkUpdatesLinkLabel = new System.Windows.Forms.LinkLabel();
|
this.checkUpdatesLinkLabel = new System.Windows.Forms.LinkLabel();
|
||||||
this.tabPage2 = new System.Windows.Forms.TabPage();
|
this.tabPage2 = new System.Windows.Forms.TabPage();
|
||||||
this.licenseRichTextBox = new System.Windows.Forms.RichTextBox();
|
this.licenseRichTextBox = new System.Windows.Forms.RichTextBox();
|
||||||
@@ -116,8 +116,7 @@
|
|||||||
this.label2.Name = "label2";
|
this.label2.Name = "label2";
|
||||||
this.label2.Size = new System.Drawing.Size(347, 46);
|
this.label2.Size = new System.Drawing.Size(347, 46);
|
||||||
this.label2.TabIndex = 0;
|
this.label2.TabIndex = 0;
|
||||||
this.label2.Text = "AssetStudio is a tool for exploring, extracting, and exporting assets and asset b" +
|
this.label2.Text = "ArknightsStudio is a modified version of AssetStudio designed for Arknights.";
|
||||||
"undles.";
|
|
||||||
this.label2.UseCompatibleTextRendering = true;
|
this.label2.UseCompatibleTextRendering = true;
|
||||||
//
|
//
|
||||||
// textBox2
|
// textBox2
|
||||||
@@ -164,7 +163,7 @@
|
|||||||
this.tableLayoutPanel2.ColumnCount = 3;
|
this.tableLayoutPanel2.ColumnCount = 3;
|
||||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 41.37931F));
|
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 41.37931F));
|
||||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 58.62069F));
|
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 58.62069F));
|
||||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 112F));
|
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 113F));
|
||||||
this.tableLayoutPanel2.Controls.Add(this.label16, 0, 0);
|
this.tableLayoutPanel2.Controls.Add(this.label16, 0, 0);
|
||||||
this.tableLayoutPanel2.Controls.Add(this.label17, 1, 0);
|
this.tableLayoutPanel2.Controls.Add(this.label17, 1, 0);
|
||||||
this.tableLayoutPanel2.Controls.Add(this.gitPerfareLinkLabel, 2, 0);
|
this.tableLayoutPanel2.Controls.Add(this.gitPerfareLinkLabel, 2, 0);
|
||||||
@@ -204,7 +203,7 @@
|
|||||||
//
|
//
|
||||||
this.gitPerfareLinkLabel.AutoSize = true;
|
this.gitPerfareLinkLabel.AutoSize = true;
|
||||||
this.gitPerfareLinkLabel.BackColor = System.Drawing.Color.Transparent;
|
this.gitPerfareLinkLabel.BackColor = System.Drawing.Color.Transparent;
|
||||||
this.gitPerfareLinkLabel.Location = new System.Drawing.Point(238, 2);
|
this.gitPerfareLinkLabel.Location = new System.Drawing.Point(237, 2);
|
||||||
this.gitPerfareLinkLabel.Name = "gitPerfareLinkLabel";
|
this.gitPerfareLinkLabel.Name = "gitPerfareLinkLabel";
|
||||||
this.gitPerfareLinkLabel.Size = new System.Drawing.Size(67, 13);
|
this.gitPerfareLinkLabel.Size = new System.Drawing.Size(67, 13);
|
||||||
this.gitPerfareLinkLabel.TabIndex = 11;
|
this.gitPerfareLinkLabel.TabIndex = 11;
|
||||||
@@ -230,13 +229,13 @@
|
|||||||
this.label19.Name = "label19";
|
this.label19.Name = "label19";
|
||||||
this.label19.Size = new System.Drawing.Size(113, 13);
|
this.label19.Size = new System.Drawing.Size(113, 13);
|
||||||
this.label19.TabIndex = 13;
|
this.label19.TabIndex = 13;
|
||||||
this.label19.Text = "aelurum (c) 2021-2024";
|
this.label19.Text = "aelurum (c) 2021-2023";
|
||||||
//
|
//
|
||||||
// gitAelurumLinkLabel
|
// gitAelurumLinkLabel
|
||||||
//
|
//
|
||||||
this.gitAelurumLinkLabel.AutoSize = true;
|
this.gitAelurumLinkLabel.AutoSize = true;
|
||||||
this.gitAelurumLinkLabel.BackColor = System.Drawing.Color.Transparent;
|
this.gitAelurumLinkLabel.BackColor = System.Drawing.Color.Transparent;
|
||||||
this.gitAelurumLinkLabel.Location = new System.Drawing.Point(238, 20);
|
this.gitAelurumLinkLabel.Location = new System.Drawing.Point(237, 20);
|
||||||
this.gitAelurumLinkLabel.Name = "gitAelurumLinkLabel";
|
this.gitAelurumLinkLabel.Name = "gitAelurumLinkLabel";
|
||||||
this.gitAelurumLinkLabel.Size = new System.Drawing.Size(67, 13);
|
this.gitAelurumLinkLabel.Size = new System.Drawing.Size(67, 13);
|
||||||
this.gitAelurumLinkLabel.TabIndex = 14;
|
this.gitAelurumLinkLabel.TabIndex = 14;
|
||||||
@@ -250,13 +249,13 @@
|
|||||||
this.tableLayoutPanel1.ColumnCount = 3;
|
this.tableLayoutPanel1.ColumnCount = 3;
|
||||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 41.37931F));
|
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 41.37931F));
|
||||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 58.62069F));
|
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 58.62069F));
|
||||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 112F));
|
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 113F));
|
||||||
this.tableLayoutPanel1.Controls.Add(this.label5, 0, 0);
|
this.tableLayoutPanel1.Controls.Add(this.label5, 0, 0);
|
||||||
this.tableLayoutPanel1.Controls.Add(this.productNamelabel, 1, 0);
|
this.tableLayoutPanel1.Controls.Add(this.productNamelabel, 1, 0);
|
||||||
this.tableLayoutPanel1.Controls.Add(this.label7, 0, 1);
|
this.tableLayoutPanel1.Controls.Add(this.label7, 0, 1);
|
||||||
this.tableLayoutPanel1.Controls.Add(this.modVersionLabel, 1, 1);
|
this.tableLayoutPanel1.Controls.Add(this.modVersionLabel, 1, 1);
|
||||||
this.tableLayoutPanel1.Controls.Add(this.label4, 0, 2);
|
this.tableLayoutPanel1.Controls.Add(this.label4, 0, 2);
|
||||||
this.tableLayoutPanel1.Controls.Add(this.label8, 1, 2);
|
this.tableLayoutPanel1.Controls.Add(this.basedOnLabel, 1, 2);
|
||||||
this.tableLayoutPanel1.Controls.Add(this.checkUpdatesLinkLabel, 2, 1);
|
this.tableLayoutPanel1.Controls.Add(this.checkUpdatesLinkLabel, 2, 1);
|
||||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(6, 80);
|
this.tableLayoutPanel1.Location = new System.Drawing.Point(6, 80);
|
||||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||||
@@ -287,9 +286,9 @@
|
|||||||
this.productNamelabel.BackColor = System.Drawing.Color.Transparent;
|
this.productNamelabel.BackColor = System.Drawing.Color.Transparent;
|
||||||
this.productNamelabel.Location = new System.Drawing.Point(101, 2);
|
this.productNamelabel.Location = new System.Drawing.Point(101, 2);
|
||||||
this.productNamelabel.Name = "productNamelabel";
|
this.productNamelabel.Name = "productNamelabel";
|
||||||
this.productNamelabel.Size = new System.Drawing.Size(103, 13);
|
this.productNamelabel.Size = new System.Drawing.Size(100, 13);
|
||||||
this.productNamelabel.TabIndex = 1;
|
this.productNamelabel.TabIndex = 1;
|
||||||
this.productNamelabel.Text = "AssetStudioModGUI";
|
this.productNamelabel.Text = "ArknightsStudioGUI";
|
||||||
//
|
//
|
||||||
// label7
|
// label7
|
||||||
//
|
//
|
||||||
@@ -297,9 +296,9 @@
|
|||||||
this.label7.BackColor = System.Drawing.Color.Transparent;
|
this.label7.BackColor = System.Drawing.Color.Transparent;
|
||||||
this.label7.Location = new System.Drawing.Point(5, 20);
|
this.label7.Location = new System.Drawing.Point(5, 20);
|
||||||
this.label7.Name = "label7";
|
this.label7.Name = "label7";
|
||||||
this.label7.Size = new System.Drawing.Size(68, 13);
|
this.label7.Size = new System.Drawing.Size(45, 13);
|
||||||
this.label7.TabIndex = 2;
|
this.label7.TabIndex = 2;
|
||||||
this.label7.Text = "Mod version:";
|
this.label7.Text = "Version:";
|
||||||
//
|
//
|
||||||
// modVersionLabel
|
// modVersionLabel
|
||||||
//
|
//
|
||||||
@@ -308,9 +307,9 @@
|
|||||||
this.modVersionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
this.modVersionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||||
this.modVersionLabel.Location = new System.Drawing.Point(101, 20);
|
this.modVersionLabel.Location = new System.Drawing.Point(101, 20);
|
||||||
this.modVersionLabel.Name = "modVersionLabel";
|
this.modVersionLabel.Name = "modVersionLabel";
|
||||||
this.modVersionLabel.Size = new System.Drawing.Size(46, 13);
|
this.modVersionLabel.Size = new System.Drawing.Size(52, 13);
|
||||||
this.modVersionLabel.TabIndex = 3;
|
this.modVersionLabel.TabIndex = 3;
|
||||||
this.modVersionLabel.Text = "0.18.0.0";
|
this.modVersionLabel.Text = "0.16.48.1";
|
||||||
//
|
//
|
||||||
// label4
|
// label4
|
||||||
//
|
//
|
||||||
@@ -323,21 +322,21 @@
|
|||||||
this.label4.TabIndex = 4;
|
this.label4.TabIndex = 4;
|
||||||
this.label4.Text = "Based on:";
|
this.label4.Text = "Based on:";
|
||||||
//
|
//
|
||||||
// label8
|
// basedOnLabel
|
||||||
//
|
//
|
||||||
this.label8.AutoSize = true;
|
this.basedOnLabel.AutoSize = true;
|
||||||
this.label8.BackColor = System.Drawing.Color.Transparent;
|
this.basedOnLabel.BackColor = System.Drawing.Color.Transparent;
|
||||||
this.label8.Location = new System.Drawing.Point(101, 38);
|
this.basedOnLabel.Location = new System.Drawing.Point(101, 38);
|
||||||
this.label8.Name = "label8";
|
this.basedOnLabel.Name = "basedOnLabel";
|
||||||
this.label8.Size = new System.Drawing.Size(108, 13);
|
this.basedOnLabel.Size = new System.Drawing.Size(123, 13);
|
||||||
this.label8.TabIndex = 5;
|
this.basedOnLabel.TabIndex = 5;
|
||||||
this.label8.Text = "AssetStudio v0.16.47";
|
this.basedOnLabel.Text = "AssetStudioMod v0.17.0";
|
||||||
//
|
//
|
||||||
// checkUpdatesLinkLabel
|
// checkUpdatesLinkLabel
|
||||||
//
|
//
|
||||||
this.checkUpdatesLinkLabel.AutoSize = true;
|
this.checkUpdatesLinkLabel.AutoSize = true;
|
||||||
this.checkUpdatesLinkLabel.BackColor = System.Drawing.Color.Transparent;
|
this.checkUpdatesLinkLabel.BackColor = System.Drawing.Color.Transparent;
|
||||||
this.checkUpdatesLinkLabel.Location = new System.Drawing.Point(238, 20);
|
this.checkUpdatesLinkLabel.Location = new System.Drawing.Point(237, 20);
|
||||||
this.checkUpdatesLinkLabel.Name = "checkUpdatesLinkLabel";
|
this.checkUpdatesLinkLabel.Name = "checkUpdatesLinkLabel";
|
||||||
this.checkUpdatesLinkLabel.Size = new System.Drawing.Size(96, 13);
|
this.checkUpdatesLinkLabel.Size = new System.Drawing.Size(96, 13);
|
||||||
this.checkUpdatesLinkLabel.TabIndex = 6;
|
this.checkUpdatesLinkLabel.TabIndex = 6;
|
||||||
@@ -391,7 +390,7 @@
|
|||||||
this.productTitleLabel.Name = "productTitleLabel";
|
this.productTitleLabel.Name = "productTitleLabel";
|
||||||
this.productTitleLabel.Size = new System.Drawing.Size(384, 30);
|
this.productTitleLabel.Size = new System.Drawing.Size(384, 30);
|
||||||
this.productTitleLabel.TabIndex = 1;
|
this.productTitleLabel.TabIndex = 1;
|
||||||
this.productTitleLabel.Text = "AssetStudioModGUI";
|
this.productTitleLabel.Text = "ArknightsStudioGUI";
|
||||||
this.productTitleLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
this.productTitleLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||||
//
|
//
|
||||||
// CloseButton
|
// CloseButton
|
||||||
@@ -414,7 +413,7 @@
|
|||||||
this.productVersionLabel.Padding = new System.Windows.Forms.Padding(0, 0, 5, 0);
|
this.productVersionLabel.Padding = new System.Windows.Forms.Padding(0, 0, 5, 0);
|
||||||
this.productVersionLabel.Size = new System.Drawing.Size(384, 13);
|
this.productVersionLabel.Size = new System.Drawing.Size(384, 13);
|
||||||
this.productVersionLabel.TabIndex = 2;
|
this.productVersionLabel.TabIndex = 2;
|
||||||
this.productVersionLabel.Text = "v0.18.0.0 [x64]";
|
this.productVersionLabel.Text = "v0.16.48.1 [x64]";
|
||||||
this.productVersionLabel.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
|
this.productVersionLabel.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
|
||||||
//
|
//
|
||||||
// panel2
|
// panel2
|
||||||
@@ -492,7 +491,7 @@
|
|||||||
private System.Windows.Forms.Label label7;
|
private System.Windows.Forms.Label label7;
|
||||||
private System.Windows.Forms.Label modVersionLabel;
|
private System.Windows.Forms.Label modVersionLabel;
|
||||||
private System.Windows.Forms.Label label4;
|
private System.Windows.Forms.Label label4;
|
||||||
private System.Windows.Forms.Label label8;
|
private System.Windows.Forms.Label basedOnLabel;
|
||||||
private System.Windows.Forms.LinkLabel checkUpdatesLinkLabel;
|
private System.Windows.Forms.LinkLabel checkUpdatesLinkLabel;
|
||||||
private System.Windows.Forms.RichTextBox licenseRichTextBox;
|
private System.Windows.Forms.RichTextBox licenseRichTextBox;
|
||||||
private System.Windows.Forms.TextBox textBox2;
|
private System.Windows.Forms.TextBox textBox2;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ namespace AssetStudioGUI
|
|||||||
productVersionLabel.Text = $"v{productVer} [{arch}]";
|
productVersionLabel.Text = $"v{productVer} [{arch}]";
|
||||||
productNamelabel.Text = productName;
|
productNamelabel.Text = productName;
|
||||||
modVersionLabel.Text = productVer;
|
modVersionLabel.Text = productVer;
|
||||||
|
basedOnLabel.Text = "AssetStudioMod v0.17.4";
|
||||||
|
|
||||||
licenseRichTextBox.Text = GetLicenseText();
|
licenseRichTextBox.Text = GetLicenseText();
|
||||||
}
|
}
|
||||||
@@ -43,7 +44,7 @@ namespace AssetStudioGUI
|
|||||||
|
|
||||||
private void checkUpdatesLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
private void checkUpdatesLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||||
{
|
{
|
||||||
var ps = new ProcessStartInfo("https://github.com/aelurum/AssetStudio/releases")
|
var ps = new ProcessStartInfo("https://github.com/aelurum/AssetStudio/tags")
|
||||||
{
|
{
|
||||||
UseShellExecute = true
|
UseShellExecute = true
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
<TargetFrameworks>net472;net6.0-windows;net7.0-windows;net8.0-windows</TargetFrameworks>
|
<TargetFrameworks>net472;net6.0-windows;net7.0-windows;net8.0-windows</TargetFrameworks>
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<ApplicationIcon>Resources\as.ico</ApplicationIcon>
|
<ApplicationIcon>Resources\as.ico</ApplicationIcon>
|
||||||
<AssemblyTitle>AssetStudioMod by aelurum</AssemblyTitle>
|
<AssemblyTitle>ArknightsStudio by aelurum</AssemblyTitle>
|
||||||
<AssemblyName>AssetStudioModGUI</AssemblyName>
|
<AssemblyName>ArknightsStudioGUI</AssemblyName>
|
||||||
<Version>0.18.0.0</Version>
|
<Version>1.2.0</Version>
|
||||||
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2021-2024</Copyright>
|
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2021-2025</Copyright>
|
||||||
<DebugType>embedded</DebugType>
|
<DebugType>embedded</DebugType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
332
AssetStudioGUI/AssetStudioGUIForm.Designer.cs
generated
332
AssetStudioGUI/AssetStudioGUIForm.Designer.cs
generated
@@ -39,14 +39,14 @@
|
|||||||
this.extractFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.extractFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.displayAll = new System.Windows.Forms.ToolStripMenuItem();
|
this.displayAll = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.useAssetLoadingViaTypetreeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.assetLoadingToolStripSeparator = new System.Windows.Forms.ToolStripSeparator();
|
|
||||||
this.enablePreview = new System.Windows.Forms.ToolStripMenuItem();
|
this.enablePreview = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.displayInfo = new System.Windows.Forms.ToolStripMenuItem();
|
this.displayInfo = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.akSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
|
this.akTitleMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.akFixFaceSpriteNamesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.akUseExternalAlphaToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.akSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
this.buildTreeStructureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.buildTreeStructureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.customCompressionTypeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.customCompressionZstdToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.customCompressionLZ4ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.toolStripMenuItem14 = new System.Windows.Forms.ToolStripMenuItem();
|
this.toolStripMenuItem14 = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.specifyUnityVersion = new System.Windows.Forms.ToolStripTextBox();
|
this.specifyUnityVersion = new System.Windows.Forms.ToolStripTextBox();
|
||||||
this.showExpOpt = new System.Windows.Forms.ToolStripMenuItem();
|
this.showExpOpt = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
@@ -73,12 +73,7 @@
|
|||||||
this.toolStripMenuItem8 = new System.Windows.Forms.ToolStripMenuItem();
|
this.toolStripMenuItem8 = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.toolStripMenuItem9 = new System.Windows.Forms.ToolStripMenuItem();
|
this.toolStripMenuItem9 = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
|
this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
this.live2DCubismModelsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.allLive2DModelsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.allL2DModelsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.selectedL2DModelsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.l2DModelWithFadeListToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.l2DModelWithFadeMotionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.l2DModelWithClipsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
this.toolStripMenuItem10 = new System.Windows.Forms.ToolStripMenuItem();
|
this.toolStripMenuItem10 = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.toolStripMenuItem11 = new System.Windows.Forms.ToolStripMenuItem();
|
this.toolStripMenuItem11 = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
@@ -87,8 +82,8 @@
|
|||||||
this.filterTypeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.filterTypeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.allToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.allToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.debugMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.debugMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.showConsoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.toolStripMenuItem15 = new System.Windows.Forms.ToolStripMenuItem();
|
this.toolStripMenuItem15 = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.showConsoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.writeLogToFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.writeLogToFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.exportClassStructuresMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.exportClassStructuresMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
@@ -116,7 +111,7 @@
|
|||||||
this.progressBar1 = new System.Windows.Forms.ProgressBar();
|
this.progressBar1 = new System.Windows.Forms.ProgressBar();
|
||||||
this.tabControl2 = new System.Windows.Forms.TabControl();
|
this.tabControl2 = new System.Windows.Forms.TabControl();
|
||||||
this.tabPage4 = new System.Windows.Forms.TabPage();
|
this.tabPage4 = new System.Windows.Forms.TabPage();
|
||||||
this.previewPanel = new System.Windows.Forms.PictureBox();
|
this.previewPanel = new System.Windows.Forms.Panel();
|
||||||
this.assetInfoLabel = new System.Windows.Forms.Label();
|
this.assetInfoLabel = new System.Windows.Forms.Label();
|
||||||
this.FMODpanel = new System.Windows.Forms.Panel();
|
this.FMODpanel = new System.Windows.Forms.Panel();
|
||||||
this.FMODcopyright = new System.Windows.Forms.Label();
|
this.FMODcopyright = new System.Windows.Forms.Label();
|
||||||
@@ -150,12 +145,8 @@
|
|||||||
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
|
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||||
this.copyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.copyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.exportSelectedAssetsToolStripMenuItem = 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.dumpSelectedAssetsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.exportAnimatorWithSelectedAnimationClipMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.exportAsLive2DModelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.exportL2DWithFadeLstToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.exportL2DWithFadeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.exportL2DWithClipsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.goToSceneHierarchyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.goToSceneHierarchyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.showOriginalFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.showOriginalFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.menuStrip1.SuspendLayout();
|
this.menuStrip1.SuspendLayout();
|
||||||
@@ -171,7 +162,6 @@
|
|||||||
this.progressbarPanel.SuspendLayout();
|
this.progressbarPanel.SuspendLayout();
|
||||||
this.tabControl2.SuspendLayout();
|
this.tabControl2.SuspendLayout();
|
||||||
this.tabPage4.SuspendLayout();
|
this.tabPage4.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.previewPanel)).BeginInit();
|
|
||||||
this.previewPanel.SuspendLayout();
|
this.previewPanel.SuspendLayout();
|
||||||
this.FMODpanel.SuspendLayout();
|
this.FMODpanel.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.FMODprogressBar)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.FMODprogressBar)).BeginInit();
|
||||||
@@ -247,12 +237,14 @@
|
|||||||
//
|
//
|
||||||
this.optionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
this.optionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
this.displayAll,
|
this.displayAll,
|
||||||
this.useAssetLoadingViaTypetreeToolStripMenuItem,
|
|
||||||
this.assetLoadingToolStripSeparator,
|
|
||||||
this.enablePreview,
|
this.enablePreview,
|
||||||
this.displayInfo,
|
this.displayInfo,
|
||||||
|
this.akSeparator1,
|
||||||
|
this.akTitleMenuItem,
|
||||||
|
this.akFixFaceSpriteNamesToolStripMenuItem,
|
||||||
|
this.akUseExternalAlphaToolStripMenuItem,
|
||||||
|
this.akSeparator2,
|
||||||
this.buildTreeStructureToolStripMenuItem,
|
this.buildTreeStructureToolStripMenuItem,
|
||||||
this.customCompressionTypeToolStripMenuItem,
|
|
||||||
this.toolStripMenuItem14,
|
this.toolStripMenuItem14,
|
||||||
this.showExpOpt});
|
this.showExpOpt});
|
||||||
this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
|
this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
|
||||||
@@ -263,36 +255,19 @@
|
|||||||
//
|
//
|
||||||
this.displayAll.CheckOnClick = true;
|
this.displayAll.CheckOnClick = true;
|
||||||
this.displayAll.Name = "displayAll";
|
this.displayAll.Name = "displayAll";
|
||||||
this.displayAll.Size = new System.Drawing.Size(241, 22);
|
this.displayAll.Size = new System.Drawing.Size(276, 22);
|
||||||
this.displayAll.Text = "Display all assets";
|
this.displayAll.Text = "Display all assets";
|
||||||
this.displayAll.ToolTipText = "Check this option will display all types assets. Not extractable assets can expor" +
|
this.displayAll.ToolTipText = "Check this option will display all types assets. Not extractable assets can expor" +
|
||||||
"t the RAW file.";
|
"t the RAW file.";
|
||||||
this.displayAll.CheckedChanged += new System.EventHandler(this.displayAll_CheckedChanged);
|
this.displayAll.CheckedChanged += new System.EventHandler(this.displayAll_CheckedChanged);
|
||||||
//
|
//
|
||||||
// useAssetLoadingViaTypetreeToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.useAssetLoadingViaTypetreeToolStripMenuItem.Checked = true;
|
|
||||||
this.useAssetLoadingViaTypetreeToolStripMenuItem.CheckOnClick = true;
|
|
||||||
this.useAssetLoadingViaTypetreeToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
|
|
||||||
this.useAssetLoadingViaTypetreeToolStripMenuItem.Name = "useAssetLoadingViaTypetreeToolStripMenuItem";
|
|
||||||
this.useAssetLoadingViaTypetreeToolStripMenuItem.Size = new System.Drawing.Size(241, 22);
|
|
||||||
this.useAssetLoadingViaTypetreeToolStripMenuItem.Text = "Parse assets using their typetree";
|
|
||||||
this.useAssetLoadingViaTypetreeToolStripMenuItem.ToolTipText = "(Applies to assets with typetree included). Slower but more correct parsing. Only" +
|
|
||||||
" for Texture2D and AnimationClip assets for now.";
|
|
||||||
this.useAssetLoadingViaTypetreeToolStripMenuItem.CheckedChanged += new System.EventHandler(this.useAssetLoadingViaTypetreeToolStripMenuItem_CheckedChanged);
|
|
||||||
//
|
|
||||||
// assetLoadingToolStripSeparator
|
|
||||||
//
|
|
||||||
this.assetLoadingToolStripSeparator.Name = "assetLoadingToolStripSeparator";
|
|
||||||
this.assetLoadingToolStripSeparator.Size = new System.Drawing.Size(238, 6);
|
|
||||||
//
|
|
||||||
// enablePreview
|
// enablePreview
|
||||||
//
|
//
|
||||||
this.enablePreview.Checked = true;
|
this.enablePreview.Checked = true;
|
||||||
this.enablePreview.CheckOnClick = true;
|
this.enablePreview.CheckOnClick = true;
|
||||||
this.enablePreview.CheckState = System.Windows.Forms.CheckState.Checked;
|
this.enablePreview.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||||
this.enablePreview.Name = "enablePreview";
|
this.enablePreview.Name = "enablePreview";
|
||||||
this.enablePreview.Size = new System.Drawing.Size(241, 22);
|
this.enablePreview.Size = new System.Drawing.Size(276, 22);
|
||||||
this.enablePreview.Text = "Enable preview";
|
this.enablePreview.Text = "Enable preview";
|
||||||
this.enablePreview.ToolTipText = "Toggle the loading and preview of readable assets, such as images, sounds, text, " +
|
this.enablePreview.ToolTipText = "Toggle the loading and preview of readable assets, such as images, sounds, text, " +
|
||||||
"etc.\r\nDisable preview if you have performance or compatibility issues.";
|
"etc.\r\nDisable preview if you have performance or compatibility issues.";
|
||||||
@@ -304,62 +279,72 @@
|
|||||||
this.displayInfo.CheckOnClick = true;
|
this.displayInfo.CheckOnClick = true;
|
||||||
this.displayInfo.CheckState = System.Windows.Forms.CheckState.Checked;
|
this.displayInfo.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||||
this.displayInfo.Name = "displayInfo";
|
this.displayInfo.Name = "displayInfo";
|
||||||
this.displayInfo.Size = new System.Drawing.Size(241, 22);
|
this.displayInfo.Size = new System.Drawing.Size(276, 22);
|
||||||
this.displayInfo.Text = "Display asset information";
|
this.displayInfo.Text = "Display asset information";
|
||||||
this.displayInfo.ToolTipText = "Toggle the overlay that shows information about each asset, eg. image size, forma" +
|
this.displayInfo.ToolTipText = "Toggle the overlay that shows information about each asset, eg. image size, forma" +
|
||||||
"t, audio bitrate, etc.";
|
"t, audio bitrate, etc.";
|
||||||
this.displayInfo.CheckedChanged += new System.EventHandler(this.displayAssetInfo_Check);
|
this.displayInfo.CheckedChanged += new System.EventHandler(this.displayAssetInfo_Check);
|
||||||
//
|
//
|
||||||
|
// akSeparator1
|
||||||
|
//
|
||||||
|
this.akSeparator1.Name = "akSeparator1";
|
||||||
|
this.akSeparator1.Size = new System.Drawing.Size(273, 6);
|
||||||
|
//
|
||||||
|
// akTitleMenuItem
|
||||||
|
//
|
||||||
|
this.akTitleMenuItem.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||||
|
this.akTitleMenuItem.Enabled = false;
|
||||||
|
this.akTitleMenuItem.Name = "akTitleMenuItem";
|
||||||
|
this.akTitleMenuItem.ShowShortcutKeys = false;
|
||||||
|
this.akTitleMenuItem.Size = new System.Drawing.Size(276, 22);
|
||||||
|
this.akTitleMenuItem.Text = "Arknights";
|
||||||
|
//
|
||||||
|
// akFixFaceSpriteNamesToolStripMenuItem
|
||||||
|
//
|
||||||
|
this.akFixFaceSpriteNamesToolStripMenuItem.Checked = true;
|
||||||
|
this.akFixFaceSpriteNamesToolStripMenuItem.CheckOnClick = true;
|
||||||
|
this.akFixFaceSpriteNamesToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||||
|
this.akFixFaceSpriteNamesToolStripMenuItem.Name = "akFixFaceSpriteNamesToolStripMenuItem";
|
||||||
|
this.akFixFaceSpriteNamesToolStripMenuItem.Size = new System.Drawing.Size(276, 22);
|
||||||
|
this.akFixFaceSpriteNamesToolStripMenuItem.Text = "Restore names of avg character sprites";
|
||||||
|
this.akFixFaceSpriteNamesToolStripMenuItem.ToolTipText = "Rename face sprites with numeric names to correct ones";
|
||||||
|
this.akFixFaceSpriteNamesToolStripMenuItem.CheckedChanged += new System.EventHandler(this.akFixFaceSpriteNamesToolStripMenuItem_Check);
|
||||||
|
//
|
||||||
|
// akUseExternalAlphaToolStripMenuItem
|
||||||
|
//
|
||||||
|
this.akUseExternalAlphaToolStripMenuItem.Checked = true;
|
||||||
|
this.akUseExternalAlphaToolStripMenuItem.CheckOnClick = true;
|
||||||
|
this.akUseExternalAlphaToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||||
|
this.akUseExternalAlphaToolStripMenuItem.Name = "akUseExternalAlphaToolStripMenuItem";
|
||||||
|
this.akUseExternalAlphaToolStripMenuItem.Size = new System.Drawing.Size(276, 22);
|
||||||
|
this.akUseExternalAlphaToolStripMenuItem.Text = "Use external alpha texture for sprites";
|
||||||
|
this.akUseExternalAlphaToolStripMenuItem.ToolTipText = "Trying to find an external alpha texture for preview/export sprite assets (Skins," +
|
||||||
|
" Char arts, Avg char arts, etc.)";
|
||||||
|
this.akUseExternalAlphaToolStripMenuItem.CheckedChanged += new System.EventHandler(this.akUseExternalAlphaToolStripMenuItem_Check);
|
||||||
|
//
|
||||||
|
// akSeparator2
|
||||||
|
//
|
||||||
|
this.akSeparator2.Name = "akSeparator2";
|
||||||
|
this.akSeparator2.Size = new System.Drawing.Size(273, 6);
|
||||||
|
//
|
||||||
// buildTreeStructureToolStripMenuItem
|
// buildTreeStructureToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.buildTreeStructureToolStripMenuItem.Checked = true;
|
this.buildTreeStructureToolStripMenuItem.Checked = true;
|
||||||
this.buildTreeStructureToolStripMenuItem.CheckOnClick = true;
|
this.buildTreeStructureToolStripMenuItem.CheckOnClick = true;
|
||||||
this.buildTreeStructureToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
|
this.buildTreeStructureToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||||
this.buildTreeStructureToolStripMenuItem.Name = "buildTreeStructureToolStripMenuItem";
|
this.buildTreeStructureToolStripMenuItem.Name = "buildTreeStructureToolStripMenuItem";
|
||||||
this.buildTreeStructureToolStripMenuItem.Size = new System.Drawing.Size(241, 22);
|
this.buildTreeStructureToolStripMenuItem.Size = new System.Drawing.Size(276, 22);
|
||||||
this.buildTreeStructureToolStripMenuItem.Text = "Build tree structure";
|
this.buildTreeStructureToolStripMenuItem.Text = "Build tree structure";
|
||||||
this.buildTreeStructureToolStripMenuItem.ToolTipText = "You can disable tree structure building if you don\'t use the Scene Hierarchy tab";
|
this.buildTreeStructureToolStripMenuItem.ToolTipText = "You can disable tree structure building if you don\'t use the Scene Hierarchy tab";
|
||||||
this.buildTreeStructureToolStripMenuItem.CheckedChanged += new System.EventHandler(this.buildTreeStructureToolStripMenuItem_CheckedChanged);
|
this.buildTreeStructureToolStripMenuItem.CheckedChanged += new System.EventHandler(this.buildTreeStructureToolStripMenuItem_CheckedChanged);
|
||||||
//
|
//
|
||||||
// customCompressionTypeToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.customCompressionTypeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
|
||||||
this.customCompressionZstdToolStripMenuItem,
|
|
||||||
this.customCompressionLZ4ToolStripMenuItem});
|
|
||||||
this.customCompressionTypeToolStripMenuItem.Name = "customCompressionTypeToolStripMenuItem";
|
|
||||||
this.customCompressionTypeToolStripMenuItem.Size = new System.Drawing.Size(241, 22);
|
|
||||||
this.customCompressionTypeToolStripMenuItem.Text = "Custom compression type";
|
|
||||||
//
|
|
||||||
// customCompressionZstdToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.customCompressionZstdToolStripMenuItem.Checked = true;
|
|
||||||
this.customCompressionZstdToolStripMenuItem.CheckOnClick = true;
|
|
||||||
this.customCompressionZstdToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
|
|
||||||
this.customCompressionZstdToolStripMenuItem.Name = "customCompressionZstdToolStripMenuItem";
|
|
||||||
this.customCompressionZstdToolStripMenuItem.Size = new System.Drawing.Size(130, 22);
|
|
||||||
this.customCompressionZstdToolStripMenuItem.Text = "Zstd";
|
|
||||||
this.customCompressionZstdToolStripMenuItem.ToolTipText = "If selected, Zstd-decompression will be used for assets with custom compression t" +
|
|
||||||
"ype";
|
|
||||||
this.customCompressionZstdToolStripMenuItem.CheckedChanged += new System.EventHandler(this.customCompressionZstd_CheckedChanged);
|
|
||||||
//
|
|
||||||
// customCompressionLZ4ToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.customCompressionLZ4ToolStripMenuItem.CheckOnClick = true;
|
|
||||||
this.customCompressionLZ4ToolStripMenuItem.Name = "customCompressionLZ4ToolStripMenuItem";
|
|
||||||
this.customCompressionLZ4ToolStripMenuItem.Size = new System.Drawing.Size(130, 22);
|
|
||||||
this.customCompressionLZ4ToolStripMenuItem.Text = "Lz4/Lz4HC";
|
|
||||||
this.customCompressionLZ4ToolStripMenuItem.ToolTipText = "If selected, Lz4-decompression will be used for assets with custom compression ty" +
|
|
||||||
"pe";
|
|
||||||
this.customCompressionLZ4ToolStripMenuItem.CheckedChanged += new System.EventHandler(this.customCompressionLZ4_CheckedChanged);
|
|
||||||
//
|
|
||||||
// toolStripMenuItem14
|
// toolStripMenuItem14
|
||||||
//
|
//
|
||||||
this.toolStripMenuItem14.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
this.toolStripMenuItem14.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
this.specifyUnityVersion});
|
this.specifyUnityVersion});
|
||||||
this.toolStripMenuItem14.Name = "toolStripMenuItem14";
|
this.toolStripMenuItem14.Name = "toolStripMenuItem14";
|
||||||
this.toolStripMenuItem14.Size = new System.Drawing.Size(241, 22);
|
this.toolStripMenuItem14.Size = new System.Drawing.Size(276, 22);
|
||||||
this.toolStripMenuItem14.Text = "Specify Unity version";
|
this.toolStripMenuItem14.Text = "Specify Unity version";
|
||||||
this.toolStripMenuItem14.DropDownClosed += new System.EventHandler(this.specifyUnityVersion_Close);
|
|
||||||
//
|
//
|
||||||
// specifyUnityVersion
|
// specifyUnityVersion
|
||||||
//
|
//
|
||||||
@@ -372,7 +357,7 @@
|
|||||||
// showExpOpt
|
// showExpOpt
|
||||||
//
|
//
|
||||||
this.showExpOpt.Name = "showExpOpt";
|
this.showExpOpt.Name = "showExpOpt";
|
||||||
this.showExpOpt.Size = new System.Drawing.Size(241, 22);
|
this.showExpOpt.Size = new System.Drawing.Size(276, 22);
|
||||||
this.showExpOpt.Text = "Export options";
|
this.showExpOpt.Text = "Export options";
|
||||||
this.showExpOpt.Click += new System.EventHandler(this.showExpOpt_Click);
|
this.showExpOpt.Click += new System.EventHandler(this.showExpOpt_Click);
|
||||||
//
|
//
|
||||||
@@ -394,7 +379,7 @@
|
|||||||
this.exportAllObjectssplitToolStripMenuItem1.Name = "exportAllObjectssplitToolStripMenuItem1";
|
this.exportAllObjectssplitToolStripMenuItem1.Name = "exportAllObjectssplitToolStripMenuItem1";
|
||||||
this.exportAllObjectssplitToolStripMenuItem1.Size = new System.Drawing.Size(382, 22);
|
this.exportAllObjectssplitToolStripMenuItem1.Size = new System.Drawing.Size(382, 22);
|
||||||
this.exportAllObjectssplitToolStripMenuItem1.Text = "Export all objects (split)";
|
this.exportAllObjectssplitToolStripMenuItem1.Text = "Export all objects (split)";
|
||||||
this.exportAllObjectssplitToolStripMenuItem1.Click += new System.EventHandler(this.exportAllObjectsSplitToolStripMenuItem1_Click);
|
this.exportAllObjectssplitToolStripMenuItem1.Click += new System.EventHandler(this.exportAllObjectssplitToolStripMenuItem1_Click);
|
||||||
//
|
//
|
||||||
// exportSelectedObjectsToolStripMenuItem
|
// exportSelectedObjectsToolStripMenuItem
|
||||||
//
|
//
|
||||||
@@ -408,7 +393,7 @@
|
|||||||
this.exportSelectedObjectsWithAnimationClipToolStripMenuItem.Name = "exportSelectedObjectsWithAnimationClipToolStripMenuItem";
|
this.exportSelectedObjectsWithAnimationClipToolStripMenuItem.Name = "exportSelectedObjectsWithAnimationClipToolStripMenuItem";
|
||||||
this.exportSelectedObjectsWithAnimationClipToolStripMenuItem.Size = new System.Drawing.Size(382, 22);
|
this.exportSelectedObjectsWithAnimationClipToolStripMenuItem.Size = new System.Drawing.Size(382, 22);
|
||||||
this.exportSelectedObjectsWithAnimationClipToolStripMenuItem.Text = "Export selected objects (split) + selected AnimationClips";
|
this.exportSelectedObjectsWithAnimationClipToolStripMenuItem.Text = "Export selected objects (split) + selected AnimationClips";
|
||||||
this.exportSelectedObjectsWithAnimationClipToolStripMenuItem.Click += new System.EventHandler(this.exportObjectsWithAnimationClipMenuItem_Click);
|
this.exportSelectedObjectsWithAnimationClipToolStripMenuItem.Click += new System.EventHandler(this.exportObjectswithAnimationClipMenuItem_Click);
|
||||||
//
|
//
|
||||||
// toolStripSeparator1
|
// toolStripSeparator1
|
||||||
//
|
//
|
||||||
@@ -420,14 +405,14 @@
|
|||||||
this.exportSelectedObjectsmergeToolStripMenuItem.Name = "exportSelectedObjectsmergeToolStripMenuItem";
|
this.exportSelectedObjectsmergeToolStripMenuItem.Name = "exportSelectedObjectsmergeToolStripMenuItem";
|
||||||
this.exportSelectedObjectsmergeToolStripMenuItem.Size = new System.Drawing.Size(382, 22);
|
this.exportSelectedObjectsmergeToolStripMenuItem.Size = new System.Drawing.Size(382, 22);
|
||||||
this.exportSelectedObjectsmergeToolStripMenuItem.Text = "Export selected objects (merge)";
|
this.exportSelectedObjectsmergeToolStripMenuItem.Text = "Export selected objects (merge)";
|
||||||
this.exportSelectedObjectsmergeToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedObjectsMergeToolStripMenuItem_Click);
|
this.exportSelectedObjectsmergeToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedObjectsmergeToolStripMenuItem_Click);
|
||||||
//
|
//
|
||||||
// exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem
|
// exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Name = "exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem";
|
this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Name = "exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem";
|
||||||
this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Size = new System.Drawing.Size(382, 22);
|
this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Size = new System.Drawing.Size(382, 22);
|
||||||
this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Text = "Export selected objects (merge) + selected AnimationClips";
|
this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Text = "Export selected objects (merge) + selected AnimationClips";
|
||||||
this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedObjectsMergeWithAnimationClipToolStripMenuItem_Click);
|
this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem_Click);
|
||||||
//
|
//
|
||||||
// exportToolStripMenuItem
|
// exportToolStripMenuItem
|
||||||
//
|
//
|
||||||
@@ -441,7 +426,7 @@
|
|||||||
this.toolStripMenuItem2,
|
this.toolStripMenuItem2,
|
||||||
this.toolStripMenuItem3,
|
this.toolStripMenuItem3,
|
||||||
this.toolStripSeparator6,
|
this.toolStripSeparator6,
|
||||||
this.live2DCubismModelsToolStripMenuItem,
|
this.allLive2DModelsToolStripMenuItem,
|
||||||
this.toolStripSeparator2,
|
this.toolStripSeparator2,
|
||||||
this.toolStripMenuItem10});
|
this.toolStripMenuItem10});
|
||||||
this.exportToolStripMenuItem.Name = "exportToolStripMenuItem";
|
this.exportToolStripMenuItem.Name = "exportToolStripMenuItem";
|
||||||
@@ -479,7 +464,7 @@
|
|||||||
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Name = "exportAnimatorWithSelectedAnimationClipToolStripMenuItem";
|
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Name = "exportAnimatorWithSelectedAnimationClipToolStripMenuItem";
|
||||||
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Size = new System.Drawing.Size(266, 22);
|
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Size = new System.Drawing.Size(266, 22);
|
||||||
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Text = "Animator + selected AnimationClips";
|
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Text = "Animator + selected AnimationClips";
|
||||||
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Click += new System.EventHandler(this.exportAnimatorWithAnimationClipMenuItem_Click);
|
this.exportAnimatorWithSelectedAnimationClipToolStripMenuItem.Click += new System.EventHandler(this.exportAnimatorwithAnimationClipMenuItem_Click);
|
||||||
//
|
//
|
||||||
// toolStripSeparator4
|
// toolStripSeparator4
|
||||||
//
|
//
|
||||||
@@ -553,52 +538,12 @@
|
|||||||
this.toolStripSeparator6.Name = "toolStripSeparator6";
|
this.toolStripSeparator6.Name = "toolStripSeparator6";
|
||||||
this.toolStripSeparator6.Size = new System.Drawing.Size(263, 6);
|
this.toolStripSeparator6.Size = new System.Drawing.Size(263, 6);
|
||||||
//
|
//
|
||||||
// live2DCubismModelsToolStripMenuItem
|
// allLive2DModelsToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.live2DCubismModelsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
this.allLive2DModelsToolStripMenuItem.Name = "allLive2DModelsToolStripMenuItem";
|
||||||
this.allL2DModelsToolStripMenuItem,
|
this.allLive2DModelsToolStripMenuItem.Size = new System.Drawing.Size(266, 22);
|
||||||
this.selectedL2DModelsToolStripMenuItem,
|
this.allLive2DModelsToolStripMenuItem.Text = "Live2D Cubism models";
|
||||||
this.l2DModelWithFadeListToolStripMenuItem,
|
this.allLive2DModelsToolStripMenuItem.Click += new System.EventHandler(this.allLive2DModelsToolStripMenuItem_Click);
|
||||||
this.l2DModelWithFadeMotionsToolStripMenuItem,
|
|
||||||
this.l2DModelWithClipsToolStripMenuItem});
|
|
||||||
this.live2DCubismModelsToolStripMenuItem.Name = "live2DCubismModelsToolStripMenuItem";
|
|
||||||
this.live2DCubismModelsToolStripMenuItem.Size = new System.Drawing.Size(266, 22);
|
|
||||||
this.live2DCubismModelsToolStripMenuItem.Text = "Live2D Cubism models";
|
|
||||||
//
|
|
||||||
// allL2DModelsToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.allL2DModelsToolStripMenuItem.Name = "allL2DModelsToolStripMenuItem";
|
|
||||||
this.allL2DModelsToolStripMenuItem.Size = new System.Drawing.Size(292, 22);
|
|
||||||
this.allL2DModelsToolStripMenuItem.Text = "All models";
|
|
||||||
this.allL2DModelsToolStripMenuItem.Click += new System.EventHandler(this.exportAllL2D_Click);
|
|
||||||
//
|
|
||||||
// selectedL2DModelsToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.selectedL2DModelsToolStripMenuItem.Name = "selectedL2DModelsToolStripMenuItem";
|
|
||||||
this.selectedL2DModelsToolStripMenuItem.Size = new System.Drawing.Size(292, 22);
|
|
||||||
this.selectedL2DModelsToolStripMenuItem.Text = "Selected models";
|
|
||||||
this.selectedL2DModelsToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedL2D_Click);
|
|
||||||
//
|
|
||||||
// l2DModelWithFadeListToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.l2DModelWithFadeListToolStripMenuItem.Name = "l2DModelWithFadeListToolStripMenuItem";
|
|
||||||
this.l2DModelWithFadeListToolStripMenuItem.Size = new System.Drawing.Size(292, 22);
|
|
||||||
this.l2DModelWithFadeListToolStripMenuItem.Text = "Model + selected Fade Motion List";
|
|
||||||
this.l2DModelWithFadeListToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedL2DWithFadeList_Click);
|
|
||||||
//
|
|
||||||
// l2DModelWithFadeMotionsToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.l2DModelWithFadeMotionsToolStripMenuItem.Name = "l2DModelWithFadeMotionsToolStripMenuItem";
|
|
||||||
this.l2DModelWithFadeMotionsToolStripMenuItem.Size = new System.Drawing.Size(292, 22);
|
|
||||||
this.l2DModelWithFadeMotionsToolStripMenuItem.Text = "Model + selected Fade motions";
|
|
||||||
this.l2DModelWithFadeMotionsToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedL2DWithFadeMotions_Click);
|
|
||||||
//
|
|
||||||
// l2DModelWithClipsToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.l2DModelWithClipsToolStripMenuItem.Name = "l2DModelWithClipsToolStripMenuItem";
|
|
||||||
this.l2DModelWithClipsToolStripMenuItem.Size = new System.Drawing.Size(292, 22);
|
|
||||||
this.l2DModelWithClipsToolStripMenuItem.Text = "Model + selected AnimationClip motions";
|
|
||||||
this.l2DModelWithClipsToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedL2DWithClips_Click);
|
|
||||||
//
|
//
|
||||||
// toolStripSeparator2
|
// toolStripSeparator2
|
||||||
//
|
//
|
||||||
@@ -657,44 +602,44 @@
|
|||||||
// debugMenuItem
|
// debugMenuItem
|
||||||
//
|
//
|
||||||
this.debugMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
this.debugMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
this.showConsoleToolStripMenuItem,
|
|
||||||
this.toolStripMenuItem15,
|
this.toolStripMenuItem15,
|
||||||
|
this.showConsoleToolStripMenuItem,
|
||||||
this.writeLogToFileToolStripMenuItem,
|
this.writeLogToFileToolStripMenuItem,
|
||||||
this.exportClassStructuresMenuItem});
|
this.exportClassStructuresMenuItem});
|
||||||
this.debugMenuItem.Name = "debugMenuItem";
|
this.debugMenuItem.Name = "debugMenuItem";
|
||||||
this.debugMenuItem.Size = new System.Drawing.Size(54, 20);
|
this.debugMenuItem.Size = new System.Drawing.Size(54, 20);
|
||||||
this.debugMenuItem.Text = "Debug";
|
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);
|
||||||
|
//
|
||||||
// showConsoleToolStripMenuItem
|
// showConsoleToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.showConsoleToolStripMenuItem.Checked = true;
|
this.showConsoleToolStripMenuItem.Checked = true;
|
||||||
this.showConsoleToolStripMenuItem.CheckOnClick = true;
|
this.showConsoleToolStripMenuItem.CheckOnClick = true;
|
||||||
this.showConsoleToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
|
this.showConsoleToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||||
this.showConsoleToolStripMenuItem.Name = "showConsoleToolStripMenuItem";
|
this.showConsoleToolStripMenuItem.Name = "showConsoleToolStripMenuItem";
|
||||||
this.showConsoleToolStripMenuItem.Size = new System.Drawing.Size(288, 22);
|
this.showConsoleToolStripMenuItem.Size = new System.Drawing.Size(200, 22);
|
||||||
this.showConsoleToolStripMenuItem.Text = "Show console logger";
|
this.showConsoleToolStripMenuItem.Text = "Show console logger";
|
||||||
this.showConsoleToolStripMenuItem.Click += new System.EventHandler(this.showConsoleToolStripMenuItem_Click);
|
this.showConsoleToolStripMenuItem.Click += new System.EventHandler(this.showConsoleToolStripMenuItem_Click);
|
||||||
//
|
//
|
||||||
// toolStripMenuItem15
|
|
||||||
//
|
|
||||||
this.toolStripMenuItem15.CheckOnClick = true;
|
|
||||||
this.toolStripMenuItem15.Name = "toolStripMenuItem15";
|
|
||||||
this.toolStripMenuItem15.Size = new System.Drawing.Size(288, 22);
|
|
||||||
this.toolStripMenuItem15.Text = "Show debug messages in console logger";
|
|
||||||
this.toolStripMenuItem15.Click += new System.EventHandler(this.toolStripMenuItem15_Click);
|
|
||||||
//
|
|
||||||
// writeLogToFileToolStripMenuItem
|
// writeLogToFileToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.writeLogToFileToolStripMenuItem.CheckOnClick = true;
|
this.writeLogToFileToolStripMenuItem.CheckOnClick = true;
|
||||||
this.writeLogToFileToolStripMenuItem.Name = "writeLogToFileToolStripMenuItem";
|
this.writeLogToFileToolStripMenuItem.Name = "writeLogToFileToolStripMenuItem";
|
||||||
this.writeLogToFileToolStripMenuItem.Size = new System.Drawing.Size(288, 22);
|
this.writeLogToFileToolStripMenuItem.Size = new System.Drawing.Size(200, 22);
|
||||||
this.writeLogToFileToolStripMenuItem.Text = "Write log to file";
|
this.writeLogToFileToolStripMenuItem.Text = "Write log to file";
|
||||||
this.writeLogToFileToolStripMenuItem.CheckedChanged += new System.EventHandler(this.writeLogToFileToolStripMenuItem_CheckedChanged);
|
this.writeLogToFileToolStripMenuItem.CheckedChanged += new System.EventHandler(this.writeLogToFileToolStripMenuItem_CheckedChanged);
|
||||||
//
|
//
|
||||||
// exportClassStructuresMenuItem
|
// exportClassStructuresMenuItem
|
||||||
//
|
//
|
||||||
this.exportClassStructuresMenuItem.Name = "exportClassStructuresMenuItem";
|
this.exportClassStructuresMenuItem.Name = "exportClassStructuresMenuItem";
|
||||||
this.exportClassStructuresMenuItem.Size = new System.Drawing.Size(288, 22);
|
this.exportClassStructuresMenuItem.Size = new System.Drawing.Size(200, 22);
|
||||||
this.exportClassStructuresMenuItem.Text = "Export class structures";
|
this.exportClassStructuresMenuItem.Text = "Export class structures";
|
||||||
this.exportClassStructuresMenuItem.Click += new System.EventHandler(this.exportClassStructuresMenuItem_Click);
|
this.exportClassStructuresMenuItem.Click += new System.EventHandler(this.exportClassStructuresMenuItem_Click);
|
||||||
//
|
//
|
||||||
@@ -857,7 +802,7 @@
|
|||||||
this.listSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
this.listSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||||
| System.Windows.Forms.AnchorStyles.Left)
|
| System.Windows.Forms.AnchorStyles.Left)
|
||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.listSearch.BackColor = System.Drawing.SystemColors.Window;
|
this.listSearch.BackColor = System.Drawing.Color.White;
|
||||||
this.listSearch.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
this.listSearch.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||||
this.listSearch.DetectUrls = false;
|
this.listSearch.DetectUrls = false;
|
||||||
this.listSearch.ForeColor = System.Drawing.SystemColors.GrayText;
|
this.listSearch.ForeColor = System.Drawing.SystemColors.GrayText;
|
||||||
@@ -987,6 +932,8 @@
|
|||||||
// previewPanel
|
// previewPanel
|
||||||
//
|
//
|
||||||
this.previewPanel.BackColor = System.Drawing.SystemColors.ControlDark;
|
this.previewPanel.BackColor = System.Drawing.SystemColors.ControlDark;
|
||||||
|
this.previewPanel.BackgroundImage = global::AssetStudioGUI.Properties.Resources.preview;
|
||||||
|
this.previewPanel.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
|
||||||
this.previewPanel.Controls.Add(this.assetInfoLabel);
|
this.previewPanel.Controls.Add(this.assetInfoLabel);
|
||||||
this.previewPanel.Controls.Add(this.FMODpanel);
|
this.previewPanel.Controls.Add(this.FMODpanel);
|
||||||
this.previewPanel.Controls.Add(this.fontPreviewBox);
|
this.previewPanel.Controls.Add(this.fontPreviewBox);
|
||||||
@@ -994,20 +941,17 @@
|
|||||||
this.previewPanel.Controls.Add(this.textPreviewBox);
|
this.previewPanel.Controls.Add(this.textPreviewBox);
|
||||||
this.previewPanel.Controls.Add(this.classTextBox);
|
this.previewPanel.Controls.Add(this.classTextBox);
|
||||||
this.previewPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
this.previewPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
this.previewPanel.Image = global::AssetStudioGUI.Properties.Resources.preview;
|
|
||||||
this.previewPanel.Location = new System.Drawing.Point(0, 0);
|
this.previewPanel.Location = new System.Drawing.Point(0, 0);
|
||||||
this.previewPanel.Name = "previewPanel";
|
this.previewPanel.Name = "previewPanel";
|
||||||
this.previewPanel.Size = new System.Drawing.Size(768, 607);
|
this.previewPanel.Size = new System.Drawing.Size(768, 607);
|
||||||
this.previewPanel.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
|
|
||||||
this.previewPanel.TabIndex = 1;
|
this.previewPanel.TabIndex = 1;
|
||||||
this.previewPanel.TabStop = false;
|
|
||||||
this.previewPanel.Resize += new System.EventHandler(this.preview_Resize);
|
this.previewPanel.Resize += new System.EventHandler(this.preview_Resize);
|
||||||
//
|
//
|
||||||
// assetInfoLabel
|
// assetInfoLabel
|
||||||
//
|
//
|
||||||
this.assetInfoLabel.AutoSize = true;
|
this.assetInfoLabel.AutoSize = true;
|
||||||
this.assetInfoLabel.BackColor = System.Drawing.Color.Transparent;
|
this.assetInfoLabel.BackColor = System.Drawing.Color.Transparent;
|
||||||
this.assetInfoLabel.ForeColor = System.Drawing.Color.White;
|
this.assetInfoLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight;
|
||||||
this.assetInfoLabel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
this.assetInfoLabel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||||
this.assetInfoLabel.Location = new System.Drawing.Point(4, 8);
|
this.assetInfoLabel.Location = new System.Drawing.Point(4, 8);
|
||||||
this.assetInfoLabel.Name = "assetInfoLabel";
|
this.assetInfoLabel.Name = "assetInfoLabel";
|
||||||
@@ -1050,7 +994,7 @@
|
|||||||
//
|
//
|
||||||
this.FMODinfoLabel.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
this.FMODinfoLabel.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||||
this.FMODinfoLabel.AutoSize = true;
|
this.FMODinfoLabel.AutoSize = true;
|
||||||
this.FMODinfoLabel.ForeColor = System.Drawing.SystemColors.HighlightText;
|
this.FMODinfoLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight;
|
||||||
this.FMODinfoLabel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
this.FMODinfoLabel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||||
this.FMODinfoLabel.Location = new System.Drawing.Point(275, 255);
|
this.FMODinfoLabel.Location = new System.Drawing.Point(275, 255);
|
||||||
this.FMODinfoLabel.Name = "FMODinfoLabel";
|
this.FMODinfoLabel.Name = "FMODinfoLabel";
|
||||||
@@ -1061,7 +1005,7 @@
|
|||||||
//
|
//
|
||||||
this.FMODtimerLabel.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
this.FMODtimerLabel.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||||
this.FMODtimerLabel.AutoSize = true;
|
this.FMODtimerLabel.AutoSize = true;
|
||||||
this.FMODtimerLabel.ForeColor = System.Drawing.SystemColors.HighlightText;
|
this.FMODtimerLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight;
|
||||||
this.FMODtimerLabel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
this.FMODtimerLabel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||||
this.FMODtimerLabel.Location = new System.Drawing.Point(457, 253);
|
this.FMODtimerLabel.Location = new System.Drawing.Point(457, 253);
|
||||||
this.FMODtimerLabel.Name = "FMODtimerLabel";
|
this.FMODtimerLabel.Name = "FMODtimerLabel";
|
||||||
@@ -1073,7 +1017,7 @@
|
|||||||
//
|
//
|
||||||
this.FMODstatusLabel.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
this.FMODstatusLabel.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||||
this.FMODstatusLabel.AutoSize = true;
|
this.FMODstatusLabel.AutoSize = true;
|
||||||
this.FMODstatusLabel.ForeColor = System.Drawing.SystemColors.HighlightText;
|
this.FMODstatusLabel.ForeColor = System.Drawing.SystemColors.ControlLightLight;
|
||||||
this.FMODstatusLabel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
this.FMODstatusLabel.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||||
this.FMODstatusLabel.Location = new System.Drawing.Point(214, 255);
|
this.FMODstatusLabel.Location = new System.Drawing.Point(214, 255);
|
||||||
this.FMODstatusLabel.Name = "FMODstatusLabel";
|
this.FMODstatusLabel.Name = "FMODstatusLabel";
|
||||||
@@ -1334,82 +1278,46 @@
|
|||||||
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
this.copyToolStripMenuItem,
|
this.copyToolStripMenuItem,
|
||||||
this.exportSelectedAssetsToolStripMenuItem,
|
this.exportSelectedAssetsToolStripMenuItem,
|
||||||
|
this.exportAnimatorwithselectedAnimationClipMenuItem,
|
||||||
this.dumpSelectedAssetsToolStripMenuItem,
|
this.dumpSelectedAssetsToolStripMenuItem,
|
||||||
this.exportAnimatorWithSelectedAnimationClipMenuItem,
|
|
||||||
this.exportAsLive2DModelToolStripMenuItem,
|
|
||||||
this.exportL2DWithFadeLstToolStripMenuItem,
|
|
||||||
this.exportL2DWithFadeToolStripMenuItem,
|
|
||||||
this.exportL2DWithClipsToolStripMenuItem,
|
|
||||||
this.goToSceneHierarchyToolStripMenuItem,
|
this.goToSceneHierarchyToolStripMenuItem,
|
||||||
this.showOriginalFileToolStripMenuItem});
|
this.showOriginalFileToolStripMenuItem});
|
||||||
this.contextMenuStrip1.Name = "contextMenuStrip1";
|
this.contextMenuStrip1.Name = "contextMenuStrip1";
|
||||||
this.contextMenuStrip1.Size = new System.Drawing.Size(332, 224);
|
this.contextMenuStrip1.Size = new System.Drawing.Size(304, 136);
|
||||||
//
|
//
|
||||||
// copyToolStripMenuItem
|
// copyToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.copyToolStripMenuItem.Name = "copyToolStripMenuItem";
|
this.copyToolStripMenuItem.Name = "copyToolStripMenuItem";
|
||||||
this.copyToolStripMenuItem.Size = new System.Drawing.Size(331, 22);
|
this.copyToolStripMenuItem.Size = new System.Drawing.Size(303, 22);
|
||||||
this.copyToolStripMenuItem.Text = "Copy text";
|
this.copyToolStripMenuItem.Text = "Copy text";
|
||||||
this.copyToolStripMenuItem.Click += new System.EventHandler(this.copyToolStripMenuItem_Click);
|
this.copyToolStripMenuItem.Click += new System.EventHandler(this.copyToolStripMenuItem_Click);
|
||||||
//
|
//
|
||||||
// exportSelectedAssetsToolStripMenuItem
|
// exportSelectedAssetsToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.exportSelectedAssetsToolStripMenuItem.Name = "exportSelectedAssetsToolStripMenuItem";
|
this.exportSelectedAssetsToolStripMenuItem.Name = "exportSelectedAssetsToolStripMenuItem";
|
||||||
this.exportSelectedAssetsToolStripMenuItem.Size = new System.Drawing.Size(331, 22);
|
this.exportSelectedAssetsToolStripMenuItem.Size = new System.Drawing.Size(303, 22);
|
||||||
this.exportSelectedAssetsToolStripMenuItem.Text = "Export selected assets";
|
this.exportSelectedAssetsToolStripMenuItem.Text = "Export selected assets";
|
||||||
this.exportSelectedAssetsToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedAssetsToolStripMenuItem_Click);
|
this.exportSelectedAssetsToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedAssetsToolStripMenuItem_Click);
|
||||||
//
|
//
|
||||||
|
// exportAnimatorwithselectedAnimationClipMenuItem
|
||||||
|
//
|
||||||
|
this.exportAnimatorwithselectedAnimationClipMenuItem.Name = "exportAnimatorwithselectedAnimationClipMenuItem";
|
||||||
|
this.exportAnimatorwithselectedAnimationClipMenuItem.Size = new System.Drawing.Size(303, 22);
|
||||||
|
this.exportAnimatorwithselectedAnimationClipMenuItem.Text = "Export Animator + selected AnimationClips";
|
||||||
|
this.exportAnimatorwithselectedAnimationClipMenuItem.Visible = false;
|
||||||
|
this.exportAnimatorwithselectedAnimationClipMenuItem.Click += new System.EventHandler(this.exportAnimatorwithAnimationClipMenuItem_Click);
|
||||||
|
//
|
||||||
// dumpSelectedAssetsToolStripMenuItem
|
// dumpSelectedAssetsToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.dumpSelectedAssetsToolStripMenuItem.Name = "dumpSelectedAssetsToolStripMenuItem";
|
this.dumpSelectedAssetsToolStripMenuItem.Name = "dumpSelectedAssetsToolStripMenuItem";
|
||||||
this.dumpSelectedAssetsToolStripMenuItem.Size = new System.Drawing.Size(331, 22);
|
this.dumpSelectedAssetsToolStripMenuItem.Size = new System.Drawing.Size(303, 22);
|
||||||
this.dumpSelectedAssetsToolStripMenuItem.Text = "Dump selected assets";
|
this.dumpSelectedAssetsToolStripMenuItem.Text = "Dump selected assets";
|
||||||
this.dumpSelectedAssetsToolStripMenuItem.Click += new System.EventHandler(this.dumpSelectedAssetsToolStripMenuItem_Click);
|
this.dumpSelectedAssetsToolStripMenuItem.Click += new System.EventHandler(this.dumpSelectedAssetsToolStripMenuItem_Click);
|
||||||
//
|
//
|
||||||
// exportAnimatorWithSelectedAnimationClipMenuItem
|
|
||||||
//
|
|
||||||
this.exportAnimatorWithSelectedAnimationClipMenuItem.Name = "exportAnimatorWithSelectedAnimationClipMenuItem";
|
|
||||||
this.exportAnimatorWithSelectedAnimationClipMenuItem.Size = new System.Drawing.Size(331, 22);
|
|
||||||
this.exportAnimatorWithSelectedAnimationClipMenuItem.Text = "Export Animator + selected AnimationClips";
|
|
||||||
this.exportAnimatorWithSelectedAnimationClipMenuItem.Visible = false;
|
|
||||||
this.exportAnimatorWithSelectedAnimationClipMenuItem.Click += new System.EventHandler(this.exportAnimatorWithAnimationClipMenuItem_Click);
|
|
||||||
//
|
|
||||||
// exportAsLive2DModelToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.exportAsLive2DModelToolStripMenuItem.Name = "exportAsLive2DModelToolStripMenuItem";
|
|
||||||
this.exportAsLive2DModelToolStripMenuItem.Size = new System.Drawing.Size(331, 22);
|
|
||||||
this.exportAsLive2DModelToolStripMenuItem.Text = "Export as Live2D model(s)";
|
|
||||||
this.exportAsLive2DModelToolStripMenuItem.Visible = false;
|
|
||||||
this.exportAsLive2DModelToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedL2D_Click);
|
|
||||||
//
|
|
||||||
// exportL2DWithFadeLstToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.exportL2DWithFadeLstToolStripMenuItem.Name = "exportL2DWithFadeLstToolStripMenuItem";
|
|
||||||
this.exportL2DWithFadeLstToolStripMenuItem.Size = new System.Drawing.Size(331, 22);
|
|
||||||
this.exportL2DWithFadeLstToolStripMenuItem.Text = "Export Live2D model + selected Fade Motion List";
|
|
||||||
this.exportL2DWithFadeLstToolStripMenuItem.Visible = false;
|
|
||||||
this.exportL2DWithFadeLstToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedL2DWithFadeList_Click);
|
|
||||||
//
|
|
||||||
// exportL2DWithFadeToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.exportL2DWithFadeToolStripMenuItem.Name = "exportL2DWithFadeToolStripMenuItem";
|
|
||||||
this.exportL2DWithFadeToolStripMenuItem.Size = new System.Drawing.Size(331, 22);
|
|
||||||
this.exportL2DWithFadeToolStripMenuItem.Text = "Export Live2D model + selected Fade motions";
|
|
||||||
this.exportL2DWithFadeToolStripMenuItem.Visible = false;
|
|
||||||
this.exportL2DWithFadeToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedL2DWithFadeMotions_Click);
|
|
||||||
//
|
|
||||||
// exportL2DWithClipsToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.exportL2DWithClipsToolStripMenuItem.Name = "exportL2DWithClipsToolStripMenuItem";
|
|
||||||
this.exportL2DWithClipsToolStripMenuItem.Size = new System.Drawing.Size(331, 22);
|
|
||||||
this.exportL2DWithClipsToolStripMenuItem.Text = "Export Live2D model + selected AnimationClips";
|
|
||||||
this.exportL2DWithClipsToolStripMenuItem.Visible = false;
|
|
||||||
this.exportL2DWithClipsToolStripMenuItem.Click += new System.EventHandler(this.exportSelectedL2DWithClips_Click);
|
|
||||||
//
|
|
||||||
// goToSceneHierarchyToolStripMenuItem
|
// goToSceneHierarchyToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.goToSceneHierarchyToolStripMenuItem.Name = "goToSceneHierarchyToolStripMenuItem";
|
this.goToSceneHierarchyToolStripMenuItem.Name = "goToSceneHierarchyToolStripMenuItem";
|
||||||
this.goToSceneHierarchyToolStripMenuItem.Size = new System.Drawing.Size(331, 22);
|
this.goToSceneHierarchyToolStripMenuItem.Size = new System.Drawing.Size(303, 22);
|
||||||
this.goToSceneHierarchyToolStripMenuItem.Text = "Go to scene hierarchy";
|
this.goToSceneHierarchyToolStripMenuItem.Text = "Go to scene hierarchy";
|
||||||
this.goToSceneHierarchyToolStripMenuItem.Visible = false;
|
this.goToSceneHierarchyToolStripMenuItem.Visible = false;
|
||||||
this.goToSceneHierarchyToolStripMenuItem.Click += new System.EventHandler(this.goToSceneHierarchyToolStripMenuItem_Click);
|
this.goToSceneHierarchyToolStripMenuItem.Click += new System.EventHandler(this.goToSceneHierarchyToolStripMenuItem_Click);
|
||||||
@@ -1417,7 +1325,7 @@
|
|||||||
// showOriginalFileToolStripMenuItem
|
// showOriginalFileToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.showOriginalFileToolStripMenuItem.Name = "showOriginalFileToolStripMenuItem";
|
this.showOriginalFileToolStripMenuItem.Name = "showOriginalFileToolStripMenuItem";
|
||||||
this.showOriginalFileToolStripMenuItem.Size = new System.Drawing.Size(331, 22);
|
this.showOriginalFileToolStripMenuItem.Size = new System.Drawing.Size(303, 22);
|
||||||
this.showOriginalFileToolStripMenuItem.Text = "Show original file";
|
this.showOriginalFileToolStripMenuItem.Text = "Show original file";
|
||||||
this.showOriginalFileToolStripMenuItem.Visible = false;
|
this.showOriginalFileToolStripMenuItem.Visible = false;
|
||||||
this.showOriginalFileToolStripMenuItem.Click += new System.EventHandler(this.showOriginalFileToolStripMenuItem_Click);
|
this.showOriginalFileToolStripMenuItem.Click += new System.EventHandler(this.showOriginalFileToolStripMenuItem_Click);
|
||||||
@@ -1455,7 +1363,6 @@
|
|||||||
this.progressbarPanel.ResumeLayout(false);
|
this.progressbarPanel.ResumeLayout(false);
|
||||||
this.tabControl2.ResumeLayout(false);
|
this.tabControl2.ResumeLayout(false);
|
||||||
this.tabPage4.ResumeLayout(false);
|
this.tabPage4.ResumeLayout(false);
|
||||||
((System.ComponentModel.ISupportInitialize)(this.previewPanel)).EndInit();
|
|
||||||
this.previewPanel.ResumeLayout(false);
|
this.previewPanel.ResumeLayout(false);
|
||||||
this.previewPanel.PerformLayout();
|
this.previewPanel.PerformLayout();
|
||||||
this.FMODpanel.ResumeLayout(false);
|
this.FMODpanel.ResumeLayout(false);
|
||||||
@@ -1490,7 +1397,7 @@
|
|||||||
private System.Windows.Forms.ToolStripMenuItem exportToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem exportToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem exportAllAssetsMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem exportAllAssetsMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem exportSelectedAssetsMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem exportSelectedAssetsMenuItem;
|
||||||
private System.Windows.Forms.PictureBox previewPanel;
|
private System.Windows.Forms.Panel previewPanel;
|
||||||
private System.Windows.Forms.ProgressBar progressBar1;
|
private System.Windows.Forms.ProgressBar progressBar1;
|
||||||
private System.Windows.Forms.StatusStrip statusStrip1;
|
private System.Windows.Forms.StatusStrip statusStrip1;
|
||||||
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
|
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
|
||||||
@@ -1532,7 +1439,7 @@
|
|||||||
private OpenTK.GLControl glControl1;
|
private OpenTK.GLControl glControl1;
|
||||||
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
|
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
|
||||||
private System.Windows.Forms.ToolStripMenuItem showOriginalFileToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem showOriginalFileToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem exportAnimatorWithSelectedAnimationClipMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem exportAnimatorwithselectedAnimationClipMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem exportSelectedAssetsToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem exportSelectedAssetsToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem filterTypeToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem filterTypeToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem allToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem allToolStripMenuItem;
|
||||||
@@ -1582,27 +1489,18 @@
|
|||||||
private System.Windows.Forms.ComboBox listSearchHistory;
|
private System.Windows.Forms.ComboBox listSearchHistory;
|
||||||
private System.Windows.Forms.RichTextBox listSearch;
|
private System.Windows.Forms.RichTextBox listSearch;
|
||||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;
|
private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem allLive2DModelsToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem showRelatedAssetsToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem showRelatedAssetsToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator7;
|
private System.Windows.Forms.ToolStripSeparator toolStripSeparator7;
|
||||||
private System.Windows.Forms.ListView assetListView;
|
private System.Windows.Forms.ListView assetListView;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem akFixFaceSpriteNamesToolStripMenuItem;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem akUseExternalAlphaToolStripMenuItem;
|
||||||
|
private System.Windows.Forms.ToolStripSeparator akSeparator1;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem akTitleMenuItem;
|
||||||
|
private System.Windows.Forms.ToolStripSeparator akSeparator2;
|
||||||
private System.Windows.Forms.ToolStripMenuItem showConsoleToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem showConsoleToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem writeLogToFileToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem writeLogToFileToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem buildTreeStructureToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem buildTreeStructureToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem exportL2DWithClipsToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem exportAsLive2DModelToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem live2DCubismModelsToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem allL2DModelsToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem selectedL2DModelsToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem l2DModelWithClipsToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem l2DModelWithFadeMotionsToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem exportL2DWithFadeToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem l2DModelWithFadeListToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem exportL2DWithFadeLstToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem customCompressionTypeToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem customCompressionZstdToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem customCompressionLZ4ToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem useAssetLoadingViaTypetreeToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripSeparator assetLoadingToolStripSeparator;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using AssetStudio;
|
using Arknights;
|
||||||
|
using AssetStudio;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
using System;
|
using System;
|
||||||
@@ -18,6 +19,8 @@ using System.Timers;
|
|||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using static AssetStudioGUI.Studio;
|
using static AssetStudioGUI.Studio;
|
||||||
using Font = AssetStudio.Font;
|
using Font = AssetStudio.Font;
|
||||||
|
using SharpImage = SixLabors.ImageSharp;
|
||||||
|
using SharpImageFormat = SixLabors.ImageSharp.PixelFormats;
|
||||||
using Microsoft.WindowsAPICodePack.Taskbar;
|
using Microsoft.WindowsAPICodePack.Taskbar;
|
||||||
#if NET472
|
#if NET472
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
@@ -47,6 +50,7 @@ namespace AssetStudioGUI
|
|||||||
|
|
||||||
#region SpriteControl
|
#region SpriteControl
|
||||||
private SpriteMaskMode spriteMaskVisibleMode = SpriteMaskMode.On;
|
private SpriteMaskMode spriteMaskVisibleMode = SpriteMaskMode.On;
|
||||||
|
private bool showDebugInfo = false;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region TexControl
|
#region TexControl
|
||||||
@@ -89,10 +93,6 @@ namespace AssetStudioGUI
|
|||||||
private AlphanumComparatorFast alphanumComparator = new AlphanumComparatorFast();
|
private AlphanumComparatorFast alphanumComparator = new AlphanumComparatorFast();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//asset list selection
|
|
||||||
private List<int> selectedIndicesPrevList = new List<int>();
|
|
||||||
private List<AssetItem> selectedAnimationAssetsList = new List<AssetItem>();
|
|
||||||
|
|
||||||
//asset list filter
|
//asset list filter
|
||||||
private System.Timers.Timer delayTimer;
|
private System.Timers.Timer delayTimer;
|
||||||
private bool enableFiltering;
|
private bool enableFiltering;
|
||||||
@@ -133,9 +133,10 @@ namespace AssetStudioGUI
|
|||||||
displayAll.Checked = Properties.Settings.Default.displayAll;
|
displayAll.Checked = Properties.Settings.Default.displayAll;
|
||||||
displayInfo.Checked = Properties.Settings.Default.displayInfo;
|
displayInfo.Checked = Properties.Settings.Default.displayInfo;
|
||||||
enablePreview.Checked = Properties.Settings.Default.enablePreview;
|
enablePreview.Checked = Properties.Settings.Default.enablePreview;
|
||||||
|
akFixFaceSpriteNamesToolStripMenuItem.Checked = Properties.Settings.Default.fixFaceSpriteNames;
|
||||||
|
akUseExternalAlphaToolStripMenuItem.Checked = Properties.Settings.Default.useExternalAlpha;
|
||||||
showConsoleToolStripMenuItem.Checked = Properties.Settings.Default.showConsole;
|
showConsoleToolStripMenuItem.Checked = Properties.Settings.Default.showConsole;
|
||||||
buildTreeStructureToolStripMenuItem.Checked = Properties.Settings.Default.buildTreeStructure;
|
buildTreeStructureToolStripMenuItem.Checked = Properties.Settings.Default.buildTreeStructure;
|
||||||
useAssetLoadingViaTypetreeToolStripMenuItem.Checked = Properties.Settings.Default.useTypetreeLoading;
|
|
||||||
FMODinit();
|
FMODinit();
|
||||||
listSearchFilterMode.SelectedIndex = 0;
|
listSearchFilterMode.SelectedIndex = 0;
|
||||||
|
|
||||||
@@ -173,6 +174,7 @@ namespace AssetStudioGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
|
||||||
await Task.Run(() => assetsManager.LoadFilesAndFolders(out openDirectoryBackup, paths));
|
await Task.Run(() => assetsManager.LoadFilesAndFolders(out openDirectoryBackup, paths));
|
||||||
saveDirectoryBackup = openDirectoryBackup;
|
saveDirectoryBackup = openDirectoryBackup;
|
||||||
BuildAssetStructures();
|
BuildAssetStructures();
|
||||||
@@ -184,6 +186,7 @@ namespace AssetStudioGUI
|
|||||||
if (openFileDialog1.ShowDialog(this) == DialogResult.OK)
|
if (openFileDialog1.ShowDialog(this) == DialogResult.OK)
|
||||||
{
|
{
|
||||||
ResetForm();
|
ResetForm();
|
||||||
|
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
|
||||||
await Task.Run(() => assetsManager.LoadFilesAndFolders(out openDirectoryBackup, openFileDialog1.FileNames));
|
await Task.Run(() => assetsManager.LoadFilesAndFolders(out openDirectoryBackup, openFileDialog1.FileNames));
|
||||||
BuildAssetStructures();
|
BuildAssetStructures();
|
||||||
}
|
}
|
||||||
@@ -196,29 +199,12 @@ namespace AssetStudioGUI
|
|||||||
if (openFolderDialog.ShowDialog(this) == DialogResult.OK)
|
if (openFolderDialog.ShowDialog(this) == DialogResult.OK)
|
||||||
{
|
{
|
||||||
ResetForm();
|
ResetForm();
|
||||||
|
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
|
||||||
await Task.Run(() => assetsManager.LoadFilesAndFolders(out openDirectoryBackup, openFolderDialog.Folder));
|
await Task.Run(() => assetsManager.LoadFilesAndFolders(out openDirectoryBackup, openFolderDialog.Folder));
|
||||||
BuildAssetStructures();
|
BuildAssetStructures();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void specifyUnityVersion_Close(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(specifyUnityVersion.Text))
|
|
||||||
{
|
|
||||||
assetsManager.SpecifyUnityVersion = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
assetsManager.SpecifyUnityVersion = new UnityVersion(specifyUnityVersion.Text);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logger.Error(ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void extractFileToolStripMenuItem_Click(object sender, EventArgs e)
|
private async void extractFileToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (openFileDialog1.ShowDialog(this) == DialogResult.OK)
|
if (openFileDialog1.ShowDialog(this) == DialogResult.OK)
|
||||||
@@ -288,6 +274,9 @@ namespace AssetStudioGUI
|
|||||||
typeMap.Clear();
|
typeMap.Clear();
|
||||||
classesListView.EndUpdate();
|
classesListView.EndUpdate();
|
||||||
|
|
||||||
|
if (akFixFaceSpriteNamesToolStripMenuItem.Checked)
|
||||||
|
FixFaceSpriteNames();
|
||||||
|
|
||||||
var types = exportableAssets.Select(x => x.Type).Distinct().OrderBy(x => x.ToString()).ToArray();
|
var types = exportableAssets.Select(x => x.Type).Distinct().OrderBy(x => x.ToString()).ToArray();
|
||||||
foreach (var type in types)
|
foreach (var type in types)
|
||||||
{
|
{
|
||||||
@@ -302,9 +291,9 @@ namespace AssetStudioGUI
|
|||||||
filterTypeToolStripMenuItem.DropDownItems.Add(typeItem);
|
filterTypeToolStripMenuItem.DropDownItems.Add(typeItem);
|
||||||
}
|
}
|
||||||
allToolStripMenuItem.Checked = true;
|
allToolStripMenuItem.Checked = true;
|
||||||
var log = $"Finished loading {assetsManager.assetsFileList.Count} file(s) with {assetListView.Items.Count} exportable assets";
|
var log = $"Finished loading {assetsManager.assetsFileList.Count} files with {assetListView.Items.Count} exportable assets";
|
||||||
var unityVer = assetsManager.assetsFileList[0].version;
|
var unityVer = assetsManager.assetsFileList[0].version;
|
||||||
var m_ObjectsCount = unityVer > 2020 ?
|
var m_ObjectsCount = unityVer[0] > 2020 ?
|
||||||
assetsManager.assetsFileList.Sum(x => x.m_Objects.LongCount(y => y.classID != (int)ClassIDType.Shader)) :
|
assetsManager.assetsFileList.Sum(x => x.m_Objects.LongCount(y => y.classID != (int)ClassIDType.Shader)) :
|
||||||
assetsManager.assetsFileList.Sum(x => x.m_Objects.Count);
|
assetsManager.assetsFileList.Sum(x => x.m_Objects.Count);
|
||||||
var objectsCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
|
var objectsCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
|
||||||
@@ -365,7 +354,7 @@ namespace AssetStudioGUI
|
|||||||
if (e.Control)
|
if (e.Control)
|
||||||
{
|
{
|
||||||
var need = false;
|
var need = false;
|
||||||
if (lastSelectedItem?.Type == ClassIDType.Texture2D || lastSelectedItem?.Type == ClassIDType.Texture2DArrayImage)
|
if (lastSelectedItem?.Type == ClassIDType.Texture2D)
|
||||||
{
|
{
|
||||||
switch (e.KeyCode)
|
switch (e.KeyCode)
|
||||||
{
|
{
|
||||||
@@ -387,7 +376,7 @@ namespace AssetStudioGUI
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (lastSelectedItem?.Type == ClassIDType.Sprite && !((Sprite)lastSelectedItem.Asset).m_RD.alphaTexture.IsNull)
|
else if ((lastSelectedItem?.Type == ClassIDType.Sprite && !((Sprite)lastSelectedItem.Asset).m_RD.alphaTexture.IsNull) || lastSelectedItem?.Type == ClassIDType.AkPortraitSprite)
|
||||||
{
|
{
|
||||||
switch (e.KeyCode)
|
switch (e.KeyCode)
|
||||||
{
|
{
|
||||||
@@ -399,6 +388,10 @@ namespace AssetStudioGUI
|
|||||||
spriteMaskVisibleMode = spriteMaskVisibleMode == SpriteMaskMode.MaskOnly ? SpriteMaskMode.On : SpriteMaskMode.MaskOnly;
|
spriteMaskVisibleMode = spriteMaskVisibleMode == SpriteMaskMode.MaskOnly ? SpriteMaskMode.On : SpriteMaskMode.MaskOnly;
|
||||||
need = true;
|
need = true;
|
||||||
break;
|
break;
|
||||||
|
case Keys.D:
|
||||||
|
showDebugInfo = !showDebugInfo;
|
||||||
|
need = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (need)
|
if (need)
|
||||||
@@ -453,16 +446,17 @@ namespace AssetStudioGUI
|
|||||||
switch (lastSelectedItem.Type)
|
switch (lastSelectedItem.Type)
|
||||||
{
|
{
|
||||||
case ClassIDType.Texture2D:
|
case ClassIDType.Texture2D:
|
||||||
|
case ClassIDType.AkPortraitSprite:
|
||||||
case ClassIDType.Sprite:
|
case ClassIDType.Sprite:
|
||||||
{
|
{
|
||||||
if (enablePreview.Checked && imageTexture != null)
|
if (enablePreview.Checked && imageTexture != null)
|
||||||
{
|
{
|
||||||
previewPanel.Image = imageTexture.Bitmap;
|
previewPanel.BackgroundImage = imageTexture.Bitmap;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
previewPanel.Image = Properties.Resources.preview;
|
previewPanel.BackgroundImage = Properties.Resources.preview;
|
||||||
previewPanel.SizeMode = PictureBoxSizeMode.CenterImage;
|
previewPanel.BackgroundImageLayout = ImageLayout.Center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -660,7 +654,7 @@ namespace AssetStudioGUI
|
|||||||
enableFiltering = false;
|
enableFiltering = false;
|
||||||
listSearch.Text = " Filter ";
|
listSearch.Text = " Filter ";
|
||||||
listSearch.ForeColor = SystemColors.GrayText;
|
listSearch.ForeColor = SystemColors.GrayText;
|
||||||
listSearch.BackColor = SystemColors.Window;
|
listSearch.BackColor = System.Drawing.Color.White;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -715,8 +709,6 @@ namespace AssetStudioGUI
|
|||||||
sortColumn = e.Column;
|
sortColumn = e.Column;
|
||||||
assetListView.BeginUpdate();
|
assetListView.BeginUpdate();
|
||||||
assetListView.SelectedIndices.Clear();
|
assetListView.SelectedIndices.Clear();
|
||||||
selectedIndicesPrevList.Clear();
|
|
||||||
selectedAnimationAssetsList.Clear();
|
|
||||||
if (sortColumn == 4) //FullSize
|
if (sortColumn == 4) //FullSize
|
||||||
{
|
{
|
||||||
visibleAssets.Sort((a, b) =>
|
visibleAssets.Sort((a, b) =>
|
||||||
@@ -759,8 +751,8 @@ namespace AssetStudioGUI
|
|||||||
|
|
||||||
private void selectAsset(object sender, ListViewItemSelectionChangedEventArgs e)
|
private void selectAsset(object sender, ListViewItemSelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
previewPanel.Image = Properties.Resources.preview;
|
previewPanel.BackgroundImage = Properties.Resources.preview;
|
||||||
previewPanel.SizeMode = PictureBoxSizeMode.CenterImage;
|
previewPanel.BackgroundImageLayout = ImageLayout.Center;
|
||||||
classTextBox.Visible = false;
|
classTextBox.Visible = false;
|
||||||
assetInfoLabel.Visible = false;
|
assetInfoLabel.Visible = false;
|
||||||
assetInfoLabel.Text = null;
|
assetInfoLabel.Text = null;
|
||||||
@@ -826,12 +818,8 @@ namespace AssetStudioGUI
|
|||||||
switch (assetItem.Type)
|
switch (assetItem.Type)
|
||||||
{
|
{
|
||||||
case ClassIDType.Texture2D:
|
case ClassIDType.Texture2D:
|
||||||
case ClassIDType.Texture2DArrayImage:
|
|
||||||
PreviewTexture2D(assetItem, assetItem.Asset as Texture2D);
|
PreviewTexture2D(assetItem, assetItem.Asset as Texture2D);
|
||||||
break;
|
break;
|
||||||
case ClassIDType.Texture2DArray:
|
|
||||||
PreviewTexture2DArray(assetItem, assetItem.Asset as Texture2DArray);
|
|
||||||
break;
|
|
||||||
case ClassIDType.AudioClip:
|
case ClassIDType.AudioClip:
|
||||||
PreviewAudioClip(assetItem, assetItem.Asset as AudioClip);
|
PreviewAudioClip(assetItem, assetItem.Asset as AudioClip);
|
||||||
break;
|
break;
|
||||||
@@ -842,16 +830,7 @@ namespace AssetStudioGUI
|
|||||||
PreviewTextAsset(assetItem.Asset as TextAsset);
|
PreviewTextAsset(assetItem.Asset as TextAsset);
|
||||||
break;
|
break;
|
||||||
case ClassIDType.MonoBehaviour:
|
case ClassIDType.MonoBehaviour:
|
||||||
var m_MonoBehaviour = (MonoBehaviour)assetItem.Asset;
|
PreviewMonoBehaviour(assetItem.Asset as MonoBehaviour);
|
||||||
if (m_MonoBehaviour.m_Script.TryGet(out var m_Script))
|
|
||||||
{
|
|
||||||
if (m_Script.m_ClassName == "CubismMoc")
|
|
||||||
{
|
|
||||||
PreviewMoc(assetItem, m_MonoBehaviour);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PreviewMonoBehaviour(m_MonoBehaviour);
|
|
||||||
break;
|
break;
|
||||||
case ClassIDType.Font:
|
case ClassIDType.Font:
|
||||||
PreviewFont(assetItem.Asset as Font);
|
PreviewFont(assetItem.Asset as Font);
|
||||||
@@ -868,6 +847,9 @@ namespace AssetStudioGUI
|
|||||||
case ClassIDType.Sprite:
|
case ClassIDType.Sprite:
|
||||||
PreviewSprite(assetItem, assetItem.Asset as Sprite);
|
PreviewSprite(assetItem, assetItem.Asset as Sprite);
|
||||||
break;
|
break;
|
||||||
|
case ClassIDType.AkPortraitSprite:
|
||||||
|
PreviewAkPortraitSprite(assetItem);
|
||||||
|
break;
|
||||||
case ClassIDType.Animator:
|
case ClassIDType.Animator:
|
||||||
StatusStripUpdate("Can be exported to FBX file.");
|
StatusStripUpdate("Can be exported to FBX file.");
|
||||||
break;
|
break;
|
||||||
@@ -890,16 +872,6 @@ namespace AssetStudioGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PreviewTexture2DArray(AssetItem assetItem, Texture2DArray m_Texture2DArray)
|
|
||||||
{
|
|
||||||
assetItem.InfoText =
|
|
||||||
$"Width: {m_Texture2DArray.m_Width}\n" +
|
|
||||||
$"Height: {m_Texture2DArray.m_Height}\n" +
|
|
||||||
$"Graphics format: {m_Texture2DArray.m_Format}\n" +
|
|
||||||
$"Texture format: {m_Texture2DArray.m_Format.ToTextureFormat()}\n" +
|
|
||||||
$"Texture count: {m_Texture2DArray.m_Depth}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PreviewTexture2D(AssetItem assetItem, Texture2D m_Texture2D)
|
private void PreviewTexture2D(AssetItem assetItem, Texture2D m_Texture2D)
|
||||||
{
|
{
|
||||||
var image = m_Texture2D.ConvertToImage(true);
|
var image = m_Texture2D.ConvertToImage(true);
|
||||||
@@ -910,9 +882,9 @@ namespace AssetStudioGUI
|
|||||||
assetItem.InfoText = $"Width: {m_Texture2D.m_Width}\nHeight: {m_Texture2D.m_Height}\nFormat: {m_Texture2D.m_TextureFormat}";
|
assetItem.InfoText = $"Width: {m_Texture2D.m_Width}\nHeight: {m_Texture2D.m_Height}\nFormat: {m_Texture2D.m_TextureFormat}";
|
||||||
switch (m_Texture2D.m_TextureSettings.m_FilterMode)
|
switch (m_Texture2D.m_TextureSettings.m_FilterMode)
|
||||||
{
|
{
|
||||||
case 0: assetItem.InfoText += "\nFilter mode: Point "; break;
|
case 0: assetItem.InfoText += "\nFilter Mode: Point "; break;
|
||||||
case 1: assetItem.InfoText += "\nFilter mode: Bilinear "; break;
|
case 1: assetItem.InfoText += "\nFilter Mode: Bilinear "; break;
|
||||||
case 2: assetItem.InfoText += "\nFilter mode: Trilinear "; break;
|
case 2: assetItem.InfoText += "\nFilter Mode: Trilinear "; break;
|
||||||
}
|
}
|
||||||
assetItem.InfoText += $"\nAnisotropic level: {m_Texture2D.m_TextureSettings.m_Aniso}\nMip map bias: {m_Texture2D.m_TextureSettings.m_MipBias}";
|
assetItem.InfoText += $"\nAnisotropic level: {m_Texture2D.m_TextureSettings.m_Aniso}\nMip map bias: {m_Texture2D.m_TextureSettings.m_MipBias}";
|
||||||
switch (m_Texture2D.m_TextureSettings.m_WrapMode)
|
switch (m_Texture2D.m_TextureSettings.m_WrapMode)
|
||||||
@@ -948,8 +920,6 @@ namespace AssetStudioGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var switchSwizzled = m_Texture2D.m_PlatformBlob.Length != 0;
|
|
||||||
assetItem.InfoText += assetItem.Asset.platform == BuildTarget.Switch ? $"\nUses texture swizzling: {switchSwizzled}" : "";
|
|
||||||
PreviewTexture(bitmap);
|
PreviewTexture(bitmap);
|
||||||
|
|
||||||
StatusStripUpdate("'Ctrl'+'R'/'G'/'B'/'A' for Channel Toggle");
|
StatusStripUpdate("'Ctrl'+'R'/'G'/'B'/'A' for Channel Toggle");
|
||||||
@@ -964,12 +934,12 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
//Info
|
//Info
|
||||||
assetItem.InfoText = "Compression format: ";
|
assetItem.InfoText = "Compression format: ";
|
||||||
if (m_AudioClip.version < 5)
|
if (m_AudioClip.version[0] < 5)
|
||||||
{
|
{
|
||||||
switch (m_AudioClip.m_Type)
|
switch (m_AudioClip.m_Type)
|
||||||
{
|
{
|
||||||
case FMODSoundType.AAC:
|
case FMODSoundType.ACC:
|
||||||
assetItem.InfoText += "AAC";
|
assetItem.InfoText += "Acc";
|
||||||
break;
|
break;
|
||||||
case FMODSoundType.AIFF:
|
case FMODSoundType.AIFF:
|
||||||
assetItem.InfoText += "AIFF";
|
assetItem.InfoText += "AIFF";
|
||||||
@@ -1052,18 +1022,6 @@ namespace AssetStudioGUI
|
|||||||
var m_AudioData = m_AudioClip.m_AudioData.GetData();
|
var m_AudioData = m_AudioClip.m_AudioData.GetData();
|
||||||
if (m_AudioData == null || m_AudioData.Length == 0)
|
if (m_AudioData == null || m_AudioData.Length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!m_AudioClip.IsConvertSupport())
|
|
||||||
{
|
|
||||||
assetItem.InfoText +=
|
|
||||||
$"\nLength: {m_AudioClip.m_Length:.0##}\n" +
|
|
||||||
$"Channel count: {m_AudioClip.m_Channels}\n" +
|
|
||||||
$"Sample rate: {m_AudioClip.m_Frequency}\n" +
|
|
||||||
$"Bit depth: {m_AudioClip.m_BitsPerSample}";
|
|
||||||
StatusStripUpdate("Preview is not available for non-fmod sounds. Try to export instead.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var exinfo = new FMOD.CREATESOUNDEXINFO();
|
var exinfo = new FMOD.CREATESOUNDEXINFO();
|
||||||
|
|
||||||
exinfo.cbsize = Marshal.SizeOf(exinfo);
|
exinfo.cbsize = Marshal.SizeOf(exinfo);
|
||||||
@@ -1136,27 +1094,6 @@ namespace AssetStudioGUI
|
|||||||
PreviewText(str);
|
PreviewText(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PreviewMoc(AssetItem assetItem, MonoBehaviour m_MonoBehaviour)
|
|
||||||
{
|
|
||||||
using (var cubismModel = new CubismModel(m_MonoBehaviour))
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine($"SDK Version: {cubismModel.VersionDescription}");
|
|
||||||
if (cubismModel.Version > 0)
|
|
||||||
{
|
|
||||||
sb.AppendLine($"Canvas Width: {cubismModel.CanvasWidth}");
|
|
||||||
sb.AppendLine($"Canvas Height: {cubismModel.CanvasHeight}");
|
|
||||||
sb.AppendLine($"Center X: {cubismModel.CentralPosX}");
|
|
||||||
sb.AppendLine($"Center Y: {cubismModel.CentralPosY}");
|
|
||||||
sb.AppendLine($"Pixel Per Unit: {cubismModel.PixelPerUnit}");
|
|
||||||
sb.AppendLine($"Parameter Count: {cubismModel.ParamCount}");
|
|
||||||
sb.AppendLine($"Part Count: {cubismModel.PartCount}");
|
|
||||||
}
|
|
||||||
assetItem.InfoText = sb.ToString();
|
|
||||||
}
|
|
||||||
StatusStripUpdate("Can be exported as Live2D Cubism model.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PreviewFont(Font m_Font)
|
private void PreviewFont(Font m_Font)
|
||||||
{
|
{
|
||||||
if (m_Font.m_FontData != null)
|
if (m_Font.m_FontData != null)
|
||||||
@@ -1358,7 +1295,31 @@ namespace AssetStudioGUI
|
|||||||
|
|
||||||
private void PreviewSprite(AssetItem assetItem, Sprite m_Sprite)
|
private void PreviewSprite(AssetItem assetItem, Sprite m_Sprite)
|
||||||
{
|
{
|
||||||
var image = m_Sprite.GetImage(spriteMaskMode: spriteMaskVisibleMode);
|
SharpImage.Image<SharpImageFormat.Bgra32> image;
|
||||||
|
AvgSprite avgSprite = null;
|
||||||
|
|
||||||
|
bool isCharAvgSprite = assetItem.Container.Contains("avg/characters");
|
||||||
|
bool isCharArt = assetItem.Container.Contains("arts/characters");
|
||||||
|
if (akUseExternalAlphaToolStripMenuItem.Checked && (isCharAvgSprite || isCharArt))
|
||||||
|
{
|
||||||
|
avgSprite = isCharAvgSprite ? new AvgSprite(assetItem) : null;
|
||||||
|
|
||||||
|
if (m_Sprite.m_RD.alphaTexture.IsNull)
|
||||||
|
{
|
||||||
|
var charAlphaTex = AkSpriteHelper.TryFindAlphaTex(assetItem, avgSprite, isCharAvgSprite);
|
||||||
|
if (charAlphaTex != null)
|
||||||
|
{
|
||||||
|
m_Sprite.m_RD.alphaTexture.Set(charAlphaTex);
|
||||||
|
m_Sprite.akSplitAlpha = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
image = m_Sprite.AkGetImage(avgSprite, spriteMaskMode: spriteMaskVisibleMode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
image = m_Sprite.GetImage(spriteMaskMode: spriteMaskVisibleMode);
|
||||||
|
}
|
||||||
|
|
||||||
if (image != null)
|
if (image != null)
|
||||||
{
|
{
|
||||||
var bitmap = new DirectBitmap(image);
|
var bitmap = new DirectBitmap(image);
|
||||||
@@ -1366,10 +1327,33 @@ namespace AssetStudioGUI
|
|||||||
assetItem.InfoText = $"Width: {bitmap.Width}\nHeight: {bitmap.Height}\n";
|
assetItem.InfoText = $"Width: {bitmap.Width}\nHeight: {bitmap.Height}\n";
|
||||||
PreviewTexture(bitmap);
|
PreviewTexture(bitmap);
|
||||||
|
|
||||||
if (!m_Sprite.m_RD.alphaTexture.IsNull)
|
if (!m_Sprite.m_RD.alphaTexture.IsNull && (akUseExternalAlphaToolStripMenuItem.Checked || !m_Sprite.akSplitAlpha))
|
||||||
{
|
{
|
||||||
assetItem.InfoText += $"Alpha Mask: {spriteMaskVisibleMode}\n";
|
var sb = new StringBuilder();
|
||||||
StatusStripUpdate("'Ctrl'+'A' - Enable/Disable alpha mask usage. 'Ctrl'+'M' - Show alpha mask only.");
|
|
||||||
|
sb.AppendLine($"Alpha mask: {spriteMaskVisibleMode}");
|
||||||
|
sb.Append(spriteMaskVisibleMode != SpriteMaskMode.Off ? $"Is external mask: {m_Sprite.akSplitAlpha}\n" : "");
|
||||||
|
if (avgSprite != null)
|
||||||
|
{
|
||||||
|
sb.AppendLine($"Alias: \"{avgSprite.Alias}\"");
|
||||||
|
if (showDebugInfo)
|
||||||
|
{
|
||||||
|
sb.AppendLine($"[Debug]");
|
||||||
|
sb.AppendLine($"Is avg hub parsed: {avgSprite.IsHubParsed}");
|
||||||
|
if (avgSprite.IsHubParsed)
|
||||||
|
{
|
||||||
|
sb.AppendLine($"Is face data exist: {avgSprite.FaceSize.Width > 0}");
|
||||||
|
sb.AppendLine($"Is face sprite: {avgSprite.IsFaceSprite}");
|
||||||
|
sb.AppendLine($"Is whole body sprite: {avgSprite.IsWholeBodySprite}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatusStripUpdate("'Ctrl'+'A' - Enable/Disable alpha mask usage. 'Ctrl'+'M' - Show alpha mask only. 'Ctrl'+'D' - Show debug info.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StatusStripUpdate("'Ctrl'+'A' - Enable/Disable alpha mask usage. 'Ctrl'+'M' - Show alpha mask only.");
|
||||||
|
}
|
||||||
|
assetItem.InfoText += sb.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1378,15 +1362,34 @@ namespace AssetStudioGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PreviewAkPortraitSprite(AssetItem assetItem)
|
||||||
|
{
|
||||||
|
var image = assetItem.AkPortraitSprite.AkGetImage(spriteMaskMode: spriteMaskVisibleMode);
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
var bitmap = new DirectBitmap(image);
|
||||||
|
image.Dispose();
|
||||||
|
assetItem.InfoText = $"Width: {bitmap.Width}\nHeight: {bitmap.Height}\n";
|
||||||
|
assetItem.InfoText += $"Alpha mask: {spriteMaskVisibleMode}";
|
||||||
|
PreviewTexture(bitmap);
|
||||||
|
|
||||||
|
StatusStripUpdate("'Ctrl'+'A' - Enable/Disable alpha mask usage. 'Ctrl'+'M' - Show alpha mask only.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StatusStripUpdate("Unsupported sprite for preview.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void PreviewTexture(DirectBitmap bitmap)
|
private void PreviewTexture(DirectBitmap bitmap)
|
||||||
{
|
{
|
||||||
imageTexture?.Dispose();
|
imageTexture?.Dispose();
|
||||||
imageTexture = bitmap;
|
imageTexture = bitmap;
|
||||||
previewPanel.Image = imageTexture.Bitmap;
|
previewPanel.BackgroundImage = imageTexture.Bitmap;
|
||||||
if (imageTexture.Width > previewPanel.Width || imageTexture.Height > previewPanel.Height)
|
if (imageTexture.Width > previewPanel.Width || imageTexture.Height > previewPanel.Height)
|
||||||
previewPanel.SizeMode = PictureBoxSizeMode.Zoom;
|
previewPanel.BackgroundImageLayout = ImageLayout.Zoom;
|
||||||
else
|
else
|
||||||
previewPanel.SizeMode = PictureBoxSizeMode.CenterImage;
|
previewPanel.BackgroundImageLayout = ImageLayout.Center;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PreviewText(string text)
|
private void PreviewText(string text)
|
||||||
@@ -1446,13 +1449,10 @@ namespace AssetStudioGUI
|
|||||||
assetListView.Items.Clear();
|
assetListView.Items.Clear();
|
||||||
classesListView.Items.Clear();
|
classesListView.Items.Clear();
|
||||||
classesListView.Groups.Clear();
|
classesListView.Groups.Clear();
|
||||||
selectedAnimationAssetsList.Clear();
|
previewPanel.BackgroundImage = Properties.Resources.preview;
|
||||||
selectedIndicesPrevList.Clear();
|
|
||||||
cubismMocList.Clear();
|
|
||||||
previewPanel.Image = Properties.Resources.preview;
|
|
||||||
previewPanel.SizeMode = PictureBoxSizeMode.CenterImage;
|
|
||||||
imageTexture?.Dispose();
|
imageTexture?.Dispose();
|
||||||
imageTexture = null;
|
imageTexture = null;
|
||||||
|
previewPanel.BackgroundImageLayout = ImageLayout.Center;
|
||||||
assetInfoLabel.Visible = false;
|
assetInfoLabel.Visible = false;
|
||||||
assetInfoLabel.Text = null;
|
assetInfoLabel.Text = null;
|
||||||
textPreviewBox.Visible = false;
|
textPreviewBox.Visible = false;
|
||||||
@@ -1464,7 +1464,7 @@ namespace AssetStudioGUI
|
|||||||
enableFiltering = false;
|
enableFiltering = false;
|
||||||
listSearch.Text = " Filter ";
|
listSearch.Text = " Filter ";
|
||||||
listSearch.ForeColor = SystemColors.GrayText;
|
listSearch.ForeColor = SystemColors.GrayText;
|
||||||
listSearch.BackColor = SystemColors.Window;
|
listSearch.BackColor = System.Drawing.Color.White;
|
||||||
if (tabControl1.SelectedIndex == 1)
|
if (tabControl1.SelectedIndex == 1)
|
||||||
assetListView.Select();
|
assetListView.Select();
|
||||||
|
|
||||||
@@ -1478,6 +1478,34 @@ namespace AssetStudioGUI
|
|||||||
FMODreset();
|
FMODreset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void FixFaceSpriteNames()
|
||||||
|
{
|
||||||
|
assetListView.BeginUpdate();
|
||||||
|
for (int i = 0; i < assetListView.Items.Count; i++)
|
||||||
|
{
|
||||||
|
var assetItem = (AssetItem)assetListView.Items[i];
|
||||||
|
if (assetItem.Type == ClassIDType.Sprite)
|
||||||
|
{
|
||||||
|
var m_Sprite = (Sprite)assetItem.Asset;
|
||||||
|
if (akFixFaceSpriteNamesToolStripMenuItem.Checked)
|
||||||
|
{
|
||||||
|
var groupedPattern = new Regex(@"^\d{1,2}\$\d{1,2}$"); // "spriteIndex$groupIndex"
|
||||||
|
var notGroupedPattern = new Regex(@"^\d{1,2}$"); // "spriteIndex"
|
||||||
|
if (groupedPattern.IsMatch(m_Sprite.m_Name) || notGroupedPattern.IsMatch(m_Sprite.m_Name))
|
||||||
|
{
|
||||||
|
var fullName = Path.GetFileNameWithoutExtension(assetItem.Container);
|
||||||
|
assetItem.Text = $"{fullName}#{m_Sprite.m_Name}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (assetItem.Text != m_Sprite.m_Name)
|
||||||
|
{
|
||||||
|
assetItem.Text = m_Sprite.m_Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assetListView.EndUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
private void tabControl2_SelectedIndexChanged(object sender, EventArgs e)
|
private void tabControl2_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (tabControl2.SelectedIndex == 1 && lastSelectedItem != null)
|
if (tabControl2.SelectedIndex == 1 && lastSelectedItem != null)
|
||||||
@@ -1492,11 +1520,7 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
goToSceneHierarchyToolStripMenuItem.Visible = false;
|
goToSceneHierarchyToolStripMenuItem.Visible = false;
|
||||||
showOriginalFileToolStripMenuItem.Visible = false;
|
showOriginalFileToolStripMenuItem.Visible = false;
|
||||||
exportAnimatorWithSelectedAnimationClipMenuItem.Visible = false;
|
exportAnimatorwithselectedAnimationClipMenuItem.Visible = false;
|
||||||
exportAsLive2DModelToolStripMenuItem.Visible = false;
|
|
||||||
exportL2DWithFadeLstToolStripMenuItem.Visible = false;
|
|
||||||
exportL2DWithFadeToolStripMenuItem.Visible = false;
|
|
||||||
exportL2DWithClipsToolStripMenuItem.Visible = false;
|
|
||||||
|
|
||||||
if (assetListView.SelectedIndices.Count == 1)
|
if (assetListView.SelectedIndices.Count == 1)
|
||||||
{
|
{
|
||||||
@@ -1506,42 +1530,10 @@ namespace AssetStudioGUI
|
|||||||
if (assetListView.SelectedIndices.Count >= 1)
|
if (assetListView.SelectedIndices.Count >= 1)
|
||||||
{
|
{
|
||||||
var selectedAssets = GetSelectedAssets();
|
var selectedAssets = GetSelectedAssets();
|
||||||
|
if (selectedAssets.Any(x => x.Type == ClassIDType.Animator) && selectedAssets.Any(x => x.Type == ClassIDType.AnimationClip))
|
||||||
var selectedTypes = (SelectedAssetType)0;
|
|
||||||
foreach (var asset in selectedAssets)
|
|
||||||
{
|
{
|
||||||
switch (asset.Asset)
|
exportAnimatorwithselectedAnimationClipMenuItem.Visible = true;
|
||||||
{
|
|
||||||
case MonoBehaviour m_MonoBehaviour:
|
|
||||||
if (Studio.cubismMocList.Count > 0 && m_MonoBehaviour.m_Script.TryGet(out var m_Script))
|
|
||||||
{
|
|
||||||
if (m_Script.m_ClassName == "CubismMoc")
|
|
||||||
{
|
|
||||||
selectedTypes |= SelectedAssetType.MonoBehaviourMoc;
|
|
||||||
}
|
|
||||||
else if (m_Script.m_ClassName == "CubismFadeMotionData")
|
|
||||||
{
|
|
||||||
selectedTypes |= SelectedAssetType.MonoBehaviourFade;
|
|
||||||
}
|
|
||||||
else if (m_Script.m_ClassName == "CubismFadeMotionList")
|
|
||||||
{
|
|
||||||
selectedTypes |= SelectedAssetType.MonoBehaviourFadeLst;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AnimationClip _:
|
|
||||||
selectedTypes |= SelectedAssetType.AnimationClip;
|
|
||||||
break;
|
|
||||||
case Animator _:
|
|
||||||
selectedTypes |= SelectedAssetType.Animator;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
exportAnimatorWithSelectedAnimationClipMenuItem.Visible = (selectedTypes & SelectedAssetType.Animator) !=0 && (selectedTypes & SelectedAssetType.AnimationClip) != 0;
|
|
||||||
exportAsLive2DModelToolStripMenuItem.Visible = (selectedTypes & SelectedAssetType.MonoBehaviourMoc) != 0;
|
|
||||||
exportL2DWithFadeLstToolStripMenuItem.Visible = (selectedTypes & SelectedAssetType.MonoBehaviourMoc) !=0 && (selectedTypes & SelectedAssetType.MonoBehaviourFadeLst) != 0;
|
|
||||||
exportL2DWithFadeToolStripMenuItem.Visible = (selectedTypes & SelectedAssetType.MonoBehaviourMoc) != 0 && (selectedTypes & SelectedAssetType.MonoBehaviourFade) !=0;
|
|
||||||
exportL2DWithClipsToolStripMenuItem.Visible = (selectedTypes & SelectedAssetType.MonoBehaviourMoc) !=0 && (selectedTypes & SelectedAssetType.AnimationClip) != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectedElement = assetListView.HitTest(new Point(e.X, e.Y));
|
var selectedElement = assetListView.HitTest(new Point(e.X, e.Y));
|
||||||
@@ -1569,15 +1561,16 @@ namespace AssetStudioGUI
|
|||||||
|
|
||||||
private void showOriginalFileToolStripMenuItem_Click(object sender, EventArgs e)
|
private void showOriginalFileToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var selectAsset = (AssetItem)assetListView.Items[assetListView.SelectedIndices[0]];
|
var selectasset = (AssetItem)assetListView.Items[assetListView.SelectedIndices[0]];
|
||||||
var args = $"/select, \"{selectAsset.SourceFile.originalPath ?? selectAsset.SourceFile.fullName}\"";
|
var args = $"/select, \"{selectasset.SourceFile.originalPath ?? selectasset.SourceFile.fullName}\"";
|
||||||
var pfi = new ProcessStartInfo("explorer.exe", args);
|
var pfi = new ProcessStartInfo("explorer.exe", args);
|
||||||
Process.Start(pfi);
|
Process.Start(pfi);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void exportAnimatorWithAnimationClipMenuItem_Click(object sender, EventArgs e)
|
private void exportAnimatorwithAnimationClipMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
AssetItem animator = null;
|
AssetItem animator = null;
|
||||||
|
List<AssetItem> animationList = new List<AssetItem>();
|
||||||
var selectedAssets = GetSelectedAssets();
|
var selectedAssets = GetSelectedAssets();
|
||||||
foreach (var assetPreloadData in selectedAssets)
|
foreach (var assetPreloadData in selectedAssets)
|
||||||
{
|
{
|
||||||
@@ -1585,6 +1578,10 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
animator = assetPreloadData;
|
animator = assetPreloadData;
|
||||||
}
|
}
|
||||||
|
else if (assetPreloadData.Type == ClassIDType.AnimationClip)
|
||||||
|
{
|
||||||
|
animationList.Add(assetPreloadData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (animator != null)
|
if (animator != null)
|
||||||
@@ -1595,7 +1592,7 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
saveDirectoryBackup = saveFolderDialog.Folder;
|
saveDirectoryBackup = saveFolderDialog.Folder;
|
||||||
var exportPath = Path.Combine(saveFolderDialog.Folder, "Animator") + Path.DirectorySeparatorChar;
|
var exportPath = Path.Combine(saveFolderDialog.Folder, "Animator") + Path.DirectorySeparatorChar;
|
||||||
ExportAnimatorWithAnimationClip(animator, selectedAnimationAssetsList, exportPath);
|
ExportAnimatorWithAnimationClip(animator, animationList, exportPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1605,7 +1602,7 @@ namespace AssetStudioGUI
|
|||||||
ExportObjects(false);
|
ExportObjects(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void exportObjectsWithAnimationClipMenuItem_Click(object sender, EventArgs e)
|
private void exportObjectswithAnimationClipMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
ExportObjects(true);
|
ExportObjects(true);
|
||||||
}
|
}
|
||||||
@@ -1638,12 +1635,12 @@ namespace AssetStudioGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void exportSelectedObjectsMergeToolStripMenuItem_Click(object sender, EventArgs e)
|
private void exportSelectedObjectsmergeToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
ExportMergeObjects(false);
|
ExportMergeObjects(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void exportSelectedObjectsMergeWithAnimationClipToolStripMenuItem_Click(object sender, EventArgs e)
|
private void exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
ExportMergeObjects(true);
|
ExportMergeObjects(true);
|
||||||
}
|
}
|
||||||
@@ -1686,10 +1683,10 @@ namespace AssetStudioGUI
|
|||||||
|
|
||||||
private void goToSceneHierarchyToolStripMenuItem_Click(object sender, EventArgs e)
|
private void goToSceneHierarchyToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var selectAsset = (AssetItem)assetListView.Items[assetListView.SelectedIndices[0]];
|
var selectasset = (AssetItem)assetListView.Items[assetListView.SelectedIndices[0]];
|
||||||
if (selectAsset.TreeNode != null)
|
if (selectasset.TreeNode != null)
|
||||||
{
|
{
|
||||||
sceneTreeView.SelectedNode = selectAsset.TreeNode;
|
sceneTreeView.SelectedNode = selectasset.TreeNode;
|
||||||
tabControl1.SelectedTab = tabPage1;
|
tabControl1.SelectedTab = tabPage1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1754,7 +1751,7 @@ namespace AssetStudioGUI
|
|||||||
ExportAssetsList(ExportFilter.Filtered);
|
ExportAssetsList(ExportFilter.Filtered);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void exportAllObjectsSplitToolStripMenuItem1_Click(object sender, EventArgs e)
|
private void exportAllObjectssplitToolStripMenuItem1_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (sceneTreeView.Nodes.Count > 0)
|
if (sceneTreeView.Nodes.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -1775,44 +1772,14 @@ namespace AssetStudioGUI
|
|||||||
|
|
||||||
private void assetListView_SelectedIndexChanged(object sender, EventArgs e)
|
private void assetListView_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
ProcessSelectedItems();
|
if (assetListView.SelectedIndices.Count > 1)
|
||||||
|
StatusStripUpdate($"Selected {assetListView.SelectedIndices.Count} assets.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assetListView_VirtualItemsSelectionRangeChanged(object sender, ListViewVirtualItemsSelectionRangeChangedEventArgs e)
|
private void assetListView_VirtualItemsSelectionRangeChanged(object sender, ListViewVirtualItemsSelectionRangeChangedEventArgs e)
|
||||||
{
|
|
||||||
ProcessSelectedItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessSelectedItems()
|
|
||||||
{
|
{
|
||||||
if (assetListView.SelectedIndices.Count > 1)
|
if (assetListView.SelectedIndices.Count > 1)
|
||||||
{
|
|
||||||
StatusStripUpdate($"Selected {assetListView.SelectedIndices.Count} assets.");
|
StatusStripUpdate($"Selected {assetListView.SelectedIndices.Count} assets.");
|
||||||
}
|
|
||||||
|
|
||||||
var selectedIndicesList = assetListView.SelectedIndices.Cast<int>().ToList();
|
|
||||||
|
|
||||||
var addedIndices = selectedIndicesList.Except(selectedIndicesPrevList).ToArray();
|
|
||||||
foreach (var itemIndex in addedIndices)
|
|
||||||
{
|
|
||||||
selectedIndicesPrevList.Add(itemIndex);
|
|
||||||
var selectedItem = (AssetItem)assetListView.Items[itemIndex];
|
|
||||||
if (selectedItem.Type == ClassIDType.AnimationClip)
|
|
||||||
{
|
|
||||||
selectedAnimationAssetsList.Add(selectedItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var removedIndices = selectedIndicesPrevList.Except(selectedIndicesList).ToArray();
|
|
||||||
foreach (var itemIndex in removedIndices)
|
|
||||||
{
|
|
||||||
selectedIndicesPrevList.Remove(itemIndex);
|
|
||||||
var unselectedItem = (AssetItem)assetListView.Items[itemIndex];
|
|
||||||
if (unselectedItem.Type == ClassIDType.AnimationClip)
|
|
||||||
{
|
|
||||||
selectedAnimationAssetsList.Remove(unselectedItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<AssetItem> GetSelectedAssets()
|
private List<AssetItem> GetSelectedAssets()
|
||||||
@@ -1882,16 +1849,16 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
visibleAssets = visibleAssets.FindAll(x => Regex.IsMatch(x.SubItems[1].Text, pattern, regexOptions));
|
visibleAssets = visibleAssets.FindAll(x => Regex.IsMatch(x.SubItems[1].Text, pattern, regexOptions));
|
||||||
}
|
}
|
||||||
listSearch.BackColor = SystemInformation.HighContrast ? listSearch.BackColor : System.Drawing.Color.PaleGreen;
|
listSearch.BackColor = System.Drawing.Color.PaleGreen;
|
||||||
}
|
}
|
||||||
catch (ArgumentException e)
|
catch (ArgumentException e)
|
||||||
{
|
{
|
||||||
listSearch.BackColor = SystemInformation.HighContrast ? listSearch.BackColor : System.Drawing.Color.FromArgb(255, 160, 160);
|
listSearch.BackColor = System.Drawing.Color.FromArgb(255, 160, 160);
|
||||||
StatusStripUpdate($"Regex error: {e.Message}");
|
StatusStripUpdate($"Regex error: {e.Message}");
|
||||||
}
|
}
|
||||||
catch (RegexMatchTimeoutException)
|
catch (RegexMatchTimeoutException)
|
||||||
{
|
{
|
||||||
listSearch.BackColor = SystemInformation.HighContrast ? listSearch.BackColor : System.Drawing.Color.FromArgb(255, 160, 160);
|
listSearch.BackColor = System.Drawing.Color.FromArgb(255, 160, 160);
|
||||||
StatusStripUpdate($"Timeout error");
|
StatusStripUpdate($"Timeout error");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1924,19 +1891,6 @@ namespace AssetStudioGUI
|
|||||||
toExportAssets = visibleAssets;
|
toExportAssets = visibleAssets;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toExportAssets != null && filterTypeToolStripMenuItem.DropDownItems.ContainsKey("Texture2DArray"))
|
|
||||||
{
|
|
||||||
var tex2dArrayImgPathIdSet = toExportAssets.FindAll(x => x.Type == ClassIDType.Texture2DArrayImage).Select(x => x.m_PathID).ToHashSet();
|
|
||||||
foreach (var pathId in tex2dArrayImgPathIdSet)
|
|
||||||
{
|
|
||||||
toExportAssets = toExportAssets.Where(x =>
|
|
||||||
x.Type != ClassIDType.Texture2DArray
|
|
||||||
|| (x.Type == ClassIDType.Texture2DArray && x.m_PathID != pathId))
|
|
||||||
.ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Studio.ExportAssets(saveFolderDialog.Folder, toExportAssets, exportType);
|
Studio.ExportAssets(saveFolderDialog.Folder, toExportAssets, exportType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1982,7 +1936,7 @@ namespace AssetStudioGUI
|
|||||||
|
|
||||||
private void toolStripMenuItem15_Click(object sender, EventArgs e)
|
private void toolStripMenuItem15_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
GUILogger.ShowDebugMessage = toolStripMenuItem15.Checked;
|
logger.ShowErrorMessage = toolStripMenuItem15.Checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sceneTreeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
|
private void sceneTreeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
|
||||||
@@ -2005,7 +1959,7 @@ namespace AssetStudioGUI
|
|||||||
private void clearSelectionToolStripMenuItem_Click(object sender, EventArgs e)
|
private void clearSelectionToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
treeRecursionEnabled = false;
|
treeRecursionEnabled = false;
|
||||||
for (var i = 0; i < treeNodeSelectedList.Count; i++)
|
for(var i = 0; i < treeNodeSelectedList.Count; i++)
|
||||||
{
|
{
|
||||||
treeNodeSelectedList[i].Checked = false;
|
treeNodeSelectedList[i].Checked = false;
|
||||||
}
|
}
|
||||||
@@ -2040,6 +1994,26 @@ namespace AssetStudioGUI
|
|||||||
sceneTreeView.EndUpdate();
|
sceneTreeView.EndUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void akFixFaceSpriteNamesToolStripMenuItem_Check(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Properties.Settings.Default.fixFaceSpriteNames = akFixFaceSpriteNamesToolStripMenuItem.Checked;
|
||||||
|
Properties.Settings.Default.Save();
|
||||||
|
FixFaceSpriteNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void akUseExternalAlphaToolStripMenuItem_Check(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Properties.Settings.Default.useExternalAlpha = akUseExternalAlphaToolStripMenuItem.Checked;
|
||||||
|
Properties.Settings.Default.Save();
|
||||||
|
|
||||||
|
if (lastSelectedItem?.Type == ClassIDType.Sprite)
|
||||||
|
{
|
||||||
|
StatusStripUpdate("");
|
||||||
|
PreviewAsset(lastSelectedItem);
|
||||||
|
assetInfoLabel.Text = lastSelectedItem.InfoText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
|
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var aboutForm = new AboutForm();
|
var aboutForm = new AboutForm();
|
||||||
@@ -2048,7 +2022,7 @@ namespace AssetStudioGUI
|
|||||||
|
|
||||||
private void listSearchFilterMode_SelectedIndexChanged(object sender, EventArgs e)
|
private void listSearchFilterMode_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
listSearch.BackColor = SystemColors.Window;
|
listSearch.BackColor = System.Drawing.Color.White;
|
||||||
if (listSearch.Text != " Filter ")
|
if (listSearch.Text != " Filter ")
|
||||||
{
|
{
|
||||||
FilterAssetList();
|
FilterAssetList();
|
||||||
@@ -2062,6 +2036,42 @@ namespace AssetStudioGUI
|
|||||||
listSearch.SelectionStart = listSearch.Text.Length;
|
listSearch.SelectionStart = listSearch.Text.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void allLive2DModelsToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (exportableAssets.Count > 0)
|
||||||
|
{
|
||||||
|
var cubismMocs = exportableAssets.Where(x =>
|
||||||
|
{
|
||||||
|
if (x.Type == ClassIDType.MonoBehaviour)
|
||||||
|
{
|
||||||
|
((MonoBehaviour)x.Asset).m_Script.TryGet(out var m_Script);
|
||||||
|
return m_Script?.m_ClassName == "CubismMoc";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}).Select(x => x.Asset).ToArray();
|
||||||
|
if (cubismMocs.Length == 0)
|
||||||
|
{
|
||||||
|
Logger.Info("Live2D Cubism models were not found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var saveFolderDialog = new OpenFolderDialog();
|
||||||
|
saveFolderDialog.InitialFolder = saveDirectoryBackup;
|
||||||
|
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
|
||||||
|
{
|
||||||
|
timer.Stop();
|
||||||
|
saveDirectoryBackup = saveFolderDialog.Folder;
|
||||||
|
Progress.Reset();
|
||||||
|
BeginInvoke(new Action(() => { progressBar1.Style = ProgressBarStyle.Marquee; }));
|
||||||
|
Studio.ExportLive2D(cubismMocs, saveFolderDialog.Folder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.Info("No exportable assets loaded");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void selectRelatedAsset(object sender, EventArgs e)
|
private void selectRelatedAsset(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var selectedItem = (ToolStripMenuItem)sender;
|
var selectedItem = (ToolStripMenuItem)sender;
|
||||||
@@ -2165,158 +2175,6 @@ namespace AssetStudioGUI
|
|||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void exportAllL2D_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (exportableAssets.Count > 0)
|
|
||||||
{
|
|
||||||
if (Studio.cubismMocList.Count == 0)
|
|
||||||
{
|
|
||||||
Logger.Info("Live2D Cubism models were not found.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Live2DExporter();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger.Info("No exportable assets loaded");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void exportSelectedL2D_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
ExportSelectedL2DModels(ExportL2DFilter.Selected);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void exportSelectedL2DWithClips_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
ExportSelectedL2DModels(ExportL2DFilter.SelectedWithClips);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void exportSelectedL2DWithFadeMotions_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
ExportSelectedL2DModels(ExportL2DFilter.SelectedWithFade);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void exportSelectedL2DWithFadeList_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
ExportSelectedL2DModels(ExportL2DFilter.SelectedWithFadeList);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExportSelectedL2DModels(ExportL2DFilter l2dExportMode)
|
|
||||||
{
|
|
||||||
if (exportableAssets.Count == 0)
|
|
||||||
{
|
|
||||||
Logger.Info("No exportable assets loaded");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Studio.cubismMocList.Count == 0)
|
|
||||||
{
|
|
||||||
Logger.Info("Live2D Cubism models were not found.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var selectedAssets = GetSelectedAssets();
|
|
||||||
if (selectedAssets.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
MonoBehaviour selectedFadeLst = null;
|
|
||||||
var selectedMocs = new List<MonoBehaviour>();
|
|
||||||
var selectedFadeMotions = new List<MonoBehaviour>();
|
|
||||||
var selectedClips = new List<AnimationClip>();
|
|
||||||
foreach (var assetItem in selectedAssets)
|
|
||||||
{
|
|
||||||
if (assetItem.Asset is MonoBehaviour m_MonoBehaviour && m_MonoBehaviour.m_Script.TryGet(out var m_Script))
|
|
||||||
{
|
|
||||||
if (m_Script.m_ClassName == "CubismMoc")
|
|
||||||
{
|
|
||||||
selectedMocs.Add(m_MonoBehaviour);
|
|
||||||
}
|
|
||||||
else if (m_Script.m_ClassName == "CubismFadeMotionData")
|
|
||||||
{
|
|
||||||
selectedFadeMotions.Add(m_MonoBehaviour);
|
|
||||||
}
|
|
||||||
else if (m_Script.m_ClassName == "CubismFadeMotionList")
|
|
||||||
{
|
|
||||||
selectedFadeLst = m_MonoBehaviour;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (assetItem.Asset is AnimationClip m_AnimationClip)
|
|
||||||
{
|
|
||||||
selectedClips.Add(m_AnimationClip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (selectedMocs.Count == 0)
|
|
||||||
{
|
|
||||||
Logger.Info("Live2D Cubism models were not selected.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (l2dExportMode)
|
|
||||||
{
|
|
||||||
case ExportL2DFilter.Selected:
|
|
||||||
Live2DExporter(selectedMocs);
|
|
||||||
break;
|
|
||||||
case ExportL2DFilter.SelectedWithFadeList:
|
|
||||||
if (selectedFadeLst == null)
|
|
||||||
{
|
|
||||||
Logger.Info("Fade Motion List was not selected.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Live2DExporter(selectedMocs, selFadeLst: selectedFadeLst);
|
|
||||||
break;
|
|
||||||
case ExportL2DFilter.SelectedWithFade:
|
|
||||||
if (selectedFadeMotions.Count == 0)
|
|
||||||
{
|
|
||||||
Logger.Info("No Fade motions were selected.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Live2DExporter(selectedMocs, selFadeMotions: selectedFadeMotions);
|
|
||||||
break;
|
|
||||||
case ExportL2DFilter.SelectedWithClips:
|
|
||||||
if (selectedClips.Count == 0)
|
|
||||||
{
|
|
||||||
Logger.Info("No AnimationClips were selected.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Live2DExporter(selectedMocs, selectedClips);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Live2DExporter(List<MonoBehaviour> selMocs = null, List<AnimationClip> selClipMotions = null, List<MonoBehaviour> selFadeMotions = null, MonoBehaviour selFadeLst = null)
|
|
||||||
{
|
|
||||||
var saveFolderDialog = new OpenFolderDialog();
|
|
||||||
saveFolderDialog.InitialFolder = saveDirectoryBackup;
|
|
||||||
if (saveFolderDialog.ShowDialog(this) == DialogResult.OK)
|
|
||||||
{
|
|
||||||
timer.Stop();
|
|
||||||
saveDirectoryBackup = saveFolderDialog.Folder;
|
|
||||||
Progress.Reset();
|
|
||||||
BeginInvoke(new Action(() => { progressBar1.Style = ProgressBarStyle.Marquee; }));
|
|
||||||
|
|
||||||
Studio.ExportLive2D(saveFolderDialog.Folder, selMocs, selClipMotions, selFadeMotions, selFadeLst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void customCompressionZstd_CheckedChanged(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
customCompressionLZ4ToolStripMenuItem.Checked = !customCompressionZstdToolStripMenuItem.Checked;
|
|
||||||
assetsManager.ZstdEnabled = customCompressionZstdToolStripMenuItem.Checked;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void customCompressionLZ4_CheckedChanged(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
customCompressionZstdToolStripMenuItem.Checked = !customCompressionLZ4ToolStripMenuItem.Checked;
|
|
||||||
assetsManager.ZstdEnabled = customCompressionZstdToolStripMenuItem.Checked;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void useAssetLoadingViaTypetreeToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
var isEnabled = useAssetLoadingViaTypetreeToolStripMenuItem.Checked;
|
|
||||||
assetsManager.LoadingViaTypeTreeEnabled = isEnabled;
|
|
||||||
Properties.Settings.Default.useTypetreeLoading = isEnabled;
|
|
||||||
Properties.Settings.Default.Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
#region FMOD
|
#region FMOD
|
||||||
private void FMODinit()
|
private void FMODinit()
|
||||||
{
|
{
|
||||||
@@ -2329,7 +2187,7 @@ namespace AssetStudioGUI
|
|||||||
ERRCHECK(result);
|
ERRCHECK(result);
|
||||||
if (version < FMOD.VERSION.number)
|
if (version < FMOD.VERSION.number)
|
||||||
{
|
{
|
||||||
Logger.Error($"Error! You are using an old version of FMOD {version:X}. This program requires {FMOD.VERSION.number:X}.");
|
Logger.Error($"Error! You are using an old version of FMOD {version:X}. This program requires {FMOD.VERSION.number:X}.");
|
||||||
Application.Exit();
|
Application.Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
296
AssetStudioGUI/Components/Arknights/AkSpriteHelper.cs
Normal file
296
AssetStudioGUI/Components/Arknights/AkSpriteHelper.cs
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
using Arknights.PortraitSpriteMono;
|
||||||
|
using AssetStudio;
|
||||||
|
using AssetStudioGUI;
|
||||||
|
using AssetStudioGUI.Properties;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
|
using SixLabors.ImageSharp.Processing;
|
||||||
|
using SixLabors.ImageSharp.Processing.Processors.Transforms;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Arknights
|
||||||
|
{
|
||||||
|
internal static class AkSpriteHelper
|
||||||
|
{
|
||||||
|
public static Texture2D TryFindAlphaTex(AssetItem assetItem, AvgSprite avgSprite, bool isAvgSprite)
|
||||||
|
{
|
||||||
|
Sprite m_Sprite = (Sprite)assetItem.Asset;
|
||||||
|
var imgType = "arts/characters";
|
||||||
|
if (m_Sprite.m_RD.alphaTexture.m_PathID == 0)
|
||||||
|
{
|
||||||
|
if (isAvgSprite)
|
||||||
|
{
|
||||||
|
if (avgSprite?.FullAlphaTexture != null)
|
||||||
|
return avgSprite.FullAlphaTexture;
|
||||||
|
|
||||||
|
imgType = "avg/characters"; //since the avg hub was not found for some reason, let's try to find alpha tex by name
|
||||||
|
}
|
||||||
|
var spriteFullName = Path.GetFileNameWithoutExtension(assetItem.Container);
|
||||||
|
foreach (var item in Studio.exportableAssets)
|
||||||
|
{
|
||||||
|
if (item.Type == ClassIDType.Texture2D)
|
||||||
|
{
|
||||||
|
if (item.Container.Contains(imgType) && item.Container.Contains($"illust_{m_Sprite.m_Name}_material") && item.Text.Contains("[alpha]"))
|
||||||
|
return (Texture2D)item.Asset;
|
||||||
|
if (item.Container.Contains(imgType) && item.Container.Contains(spriteFullName) && item.Text == $"{m_Sprite.m_Name}[alpha]")
|
||||||
|
return (Texture2D)item.Asset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Image<Bgra32> AkGetImage(this Sprite m_Sprite, AvgSprite avgSprite = null, SpriteMaskMode spriteMaskMode = SpriteMaskMode.On)
|
||||||
|
{
|
||||||
|
if (m_Sprite.m_RD.texture.TryGet(out var m_Texture2D) && m_Sprite.m_RD.alphaTexture.TryGet(out var m_AlphaTexture2D) && spriteMaskMode != SpriteMaskMode.Off)
|
||||||
|
{
|
||||||
|
Image<Bgra32> tex = null;
|
||||||
|
Image<Bgra32> alphaTex = null;
|
||||||
|
|
||||||
|
if (avgSprite != null && avgSprite.IsHubParsed)
|
||||||
|
{
|
||||||
|
alphaTex = m_AlphaTexture2D.ConvertToImage(true);
|
||||||
|
if (avgSprite.IsFaceSprite)
|
||||||
|
{
|
||||||
|
var faceImage = m_Texture2D.ConvertToImage(true);
|
||||||
|
var faceAlpha = avgSprite.FaceSpriteAlphaTexture.ConvertToImage(true);
|
||||||
|
|
||||||
|
tex = avgSprite.FullTexture.ConvertToImage(true);
|
||||||
|
var facePos = tex.Width == 512 ? avgSprite.FacePos / 2 : avgSprite.FacePos; // ?
|
||||||
|
var faceSize = tex.Width == 512 ? avgSprite.FaceSize / 2 : avgSprite.FaceSize;
|
||||||
|
|
||||||
|
if (new Size(faceImage.Width, faceImage.Height) != avgSprite.FaceSize)
|
||||||
|
{
|
||||||
|
faceImage.Mutate(x => x.Resize(new ResizeOptions { Size = faceSize, Sampler = KnownResamplers.Lanczos3, Mode = ResizeMode.Stretch }));
|
||||||
|
faceAlpha.Mutate(x => x.Resize(new ResizeOptions { Size = faceSize, Sampler = KnownResamplers.Lanczos3, Mode = ResizeMode.Stretch }));
|
||||||
|
}
|
||||||
|
|
||||||
|
tex.Mutate(x => x.DrawImage(faceImage, facePos, opacity: 1f));
|
||||||
|
alphaTex.Mutate(x => x.DrawImage(faceAlpha, facePos, opacity: 1f));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tex = m_Texture2D.ConvertToImage(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (spriteMaskMode != SpriteMaskMode.MaskOnly)
|
||||||
|
{
|
||||||
|
tex = CutImage(m_Texture2D.ConvertToImage(false), m_Sprite.m_RD.textureRect, m_Sprite.m_RD.downscaleMultiplier);
|
||||||
|
}
|
||||||
|
alphaTex = CutImage(m_AlphaTexture2D.ConvertToImage(false), m_Sprite.m_RD.textureRect, m_Sprite.m_RD.downscaleMultiplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ImageRender(tex, alphaTex, spriteMaskMode);
|
||||||
|
}
|
||||||
|
else if (m_Sprite.m_RD.texture.TryGet(out m_Texture2D) && avgSprite != null && avgSprite.IsHubParsed)
|
||||||
|
{
|
||||||
|
if (!avgSprite.IsFaceSprite)
|
||||||
|
{
|
||||||
|
return m_Texture2D.ConvertToImage(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
var faceImage = m_Texture2D.ConvertToImage(true);
|
||||||
|
var tex = avgSprite.FullTexture.ConvertToImage(true);
|
||||||
|
if (new Size(faceImage.Width, faceImage.Height) != avgSprite.FaceSize)
|
||||||
|
{
|
||||||
|
faceImage.Mutate(x => x.Resize(new ResizeOptions {Size = avgSprite.FaceSize, Sampler = KnownResamplers.Lanczos3, Mode = ResizeMode.Stretch}));
|
||||||
|
}
|
||||||
|
tex.Mutate(x => x.DrawImage(faceImage, avgSprite.FacePos, opacity: 1f));
|
||||||
|
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
else if (m_Sprite.m_RD.texture.TryGet(out m_Texture2D))
|
||||||
|
{
|
||||||
|
return CutImage(m_Texture2D.ConvertToImage(false), m_Sprite.m_RD.textureRect, m_Sprite.m_RD.downscaleMultiplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Image<Bgra32> AkGetImage(this PortraitSprite portraitSprite, SpriteMaskMode spriteMaskMode = SpriteMaskMode.On)
|
||||||
|
{
|
||||||
|
if (portraitSprite.Texture != null && portraitSprite.AlphaTexture != null)
|
||||||
|
{
|
||||||
|
Image<Bgra32> tex = null;
|
||||||
|
Image<Bgra32> alphaTex = null;
|
||||||
|
|
||||||
|
if (spriteMaskMode != SpriteMaskMode.MaskOnly)
|
||||||
|
{
|
||||||
|
tex = CutImage(portraitSprite.Texture.ConvertToImage(false), portraitSprite.TextureRect, portraitSprite.DownscaleMultiplier, portraitSprite.Rotate);
|
||||||
|
}
|
||||||
|
if (spriteMaskMode != SpriteMaskMode.Off)
|
||||||
|
{
|
||||||
|
alphaTex = CutImage(portraitSprite.AlphaTexture.ConvertToImage(false), portraitSprite.TextureRect, portraitSprite.DownscaleMultiplier, portraitSprite.Rotate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ImageRender(tex, alphaTex, spriteMaskMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<PortraitSprite> GeneratePortraits(AssetItem asset)
|
||||||
|
{
|
||||||
|
var portraits = new List<PortraitSprite>();
|
||||||
|
|
||||||
|
var portraitsDict = ((MonoBehaviour)asset.Asset).ToType();
|
||||||
|
if (portraitsDict == null)
|
||||||
|
{
|
||||||
|
Logger.Warning("Portraits MonoBehaviour is not readable.");
|
||||||
|
return portraits;
|
||||||
|
}
|
||||||
|
var portraitsJson = JsonConvert.SerializeObject(portraitsDict);
|
||||||
|
var portraitsData = JsonConvert.DeserializeObject<PortraitSpriteConfig>(portraitsJson);
|
||||||
|
|
||||||
|
var atlasTex = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == portraitsData._atlas.Texture.m_PathID).Asset;
|
||||||
|
var atlasAlpha = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == portraitsData._atlas.Alpha.m_PathID).Asset;
|
||||||
|
|
||||||
|
foreach (var portraitData in portraitsData._sprites)
|
||||||
|
{
|
||||||
|
var portraitSprite = new PortraitSprite()
|
||||||
|
{
|
||||||
|
Name = portraitData.Name,
|
||||||
|
AssetsFile = atlasTex.assetsFile,
|
||||||
|
Container = asset.Container,
|
||||||
|
Texture = atlasTex,
|
||||||
|
AlphaTexture = atlasAlpha,
|
||||||
|
TextureRect = new Rectf(portraitData.Rect.X, portraitData.Rect.Y, portraitData.Rect.W, portraitData.Rect.H),
|
||||||
|
Rotate = portraitData.Rotate,
|
||||||
|
};
|
||||||
|
portraits.Add(portraitSprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
return portraits;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Image<Bgra32> ImageRender(Image<Bgra32> tex, Image<Bgra32> alpha, SpriteMaskMode maskMode)
|
||||||
|
{
|
||||||
|
switch (maskMode)
|
||||||
|
{
|
||||||
|
case SpriteMaskMode.On:
|
||||||
|
tex.ApplyRGBMask(alpha, isPreview: true);
|
||||||
|
return tex;
|
||||||
|
case SpriteMaskMode.Off:
|
||||||
|
alpha?.Dispose();
|
||||||
|
return tex;
|
||||||
|
case SpriteMaskMode.MaskOnly:
|
||||||
|
tex?.Dispose();
|
||||||
|
return alpha;
|
||||||
|
case SpriteMaskMode.Export:
|
||||||
|
tex.ApplyRGBMask(alpha);
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IResampler GetResampler(bool isPreview)
|
||||||
|
{
|
||||||
|
IResampler resampler;
|
||||||
|
if (isPreview)
|
||||||
|
{
|
||||||
|
resampler = KnownResamplers.NearestNeighbor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (Settings.Default.resamplerIndex)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
resampler = KnownResamplers.NearestNeighbor;
|
||||||
|
break;
|
||||||
|
case 1: //Bilinear
|
||||||
|
resampler = KnownResamplers.Triangle;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
resampler = KnownResamplers.Bicubic;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
resampler = KnownResamplers.MitchellNetravali;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
resampler = KnownResamplers.Spline;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
resampler = KnownResamplers.Welch;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
resampler = KnownResamplers.MitchellNetravali;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resampler;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ApplyRGBMask(this Image<Bgra32> tex, Image<Bgra32> texMask, bool isPreview = false)
|
||||||
|
{
|
||||||
|
using (texMask)
|
||||||
|
{
|
||||||
|
bool resized = false;
|
||||||
|
if (tex.Width != texMask.Width || tex.Height != texMask.Height)
|
||||||
|
{
|
||||||
|
texMask.Mutate(x => x.Resize(tex.Width, tex.Height, GetResampler(isPreview)));
|
||||||
|
resized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var invGamma = 1.0 / (1.0 + Settings.Default.alphaMaskGamma / 10.0);
|
||||||
|
if (Settings.Default.resizedOnly && !resized)
|
||||||
|
{
|
||||||
|
invGamma = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tex.ProcessPixelRows(texMask, (sourceTex, targetTexMask) =>
|
||||||
|
{
|
||||||
|
for (int y = 0; y < texMask.Height; y++)
|
||||||
|
{
|
||||||
|
var texRow = sourceTex.GetRowSpan(y);
|
||||||
|
var maskRow = targetTexMask.GetRowSpan(y);
|
||||||
|
for (int x = 0; x < maskRow.Length; x++)
|
||||||
|
{
|
||||||
|
var grayscale = (maskRow[x].R + maskRow[x].G + maskRow[x].B) / 3.0;
|
||||||
|
if (invGamma != 1)
|
||||||
|
{
|
||||||
|
grayscale = 255 - Math.Pow((255 - grayscale) / 255, invGamma) * 255;
|
||||||
|
}
|
||||||
|
texRow[x].A = (byte)grayscale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Image<Bgra32> CutImage(Image<Bgra32> originalImage, Rectf textureRect, float downscaleMultiplier, bool rotate = false)
|
||||||
|
{
|
||||||
|
if (originalImage != null)
|
||||||
|
{
|
||||||
|
if (downscaleMultiplier > 0f && downscaleMultiplier != 1f)
|
||||||
|
{
|
||||||
|
var newSize = (Size)(new Size(originalImage.Width, originalImage.Height) / downscaleMultiplier);
|
||||||
|
originalImage.Mutate(x => x.Resize(newSize, KnownResamplers.Lanczos3, compand: true));
|
||||||
|
}
|
||||||
|
var rectX = (int)Math.Floor(textureRect.x);
|
||||||
|
var rectY = (int)Math.Floor(textureRect.y);
|
||||||
|
var rectRight = (int)Math.Ceiling(textureRect.x + textureRect.width);
|
||||||
|
var rectBottom = (int)Math.Ceiling(textureRect.y + textureRect.height);
|
||||||
|
rectRight = Math.Min(rectRight, originalImage.Width);
|
||||||
|
rectBottom = Math.Min(rectBottom, originalImage.Height);
|
||||||
|
var rect = new Rectangle(rectX, rectY, rectRight - rectX, rectBottom - rectY);
|
||||||
|
var spriteImage = originalImage.Clone(x => x.Crop(rect));
|
||||||
|
originalImage.Dispose();
|
||||||
|
if (rotate)
|
||||||
|
{
|
||||||
|
spriteImage.Mutate(x => x.Rotate(RotateMode.Rotate270));
|
||||||
|
}
|
||||||
|
spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
|
||||||
|
|
||||||
|
return spriteImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
149
AssetStudioGUI/Components/Arknights/AvgSprite.cs
Normal file
149
AssetStudioGUI/Components/Arknights/AvgSprite.cs
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
using Arknights.AvgCharHubMono;
|
||||||
|
using AssetStudio;
|
||||||
|
using AssetStudioGUI;
|
||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using System.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Arknights
|
||||||
|
{
|
||||||
|
internal class AvgSprite
|
||||||
|
{
|
||||||
|
public Texture2D FaceSpriteAlphaTexture { get; }
|
||||||
|
public Texture2D FullTexture { get; }
|
||||||
|
public Texture2D FullAlphaTexture { get; }
|
||||||
|
public Point FacePos { get; }
|
||||||
|
public Size FaceSize { get; }
|
||||||
|
public string Alias { get; }
|
||||||
|
public bool IsWholeBodySprite { get; }
|
||||||
|
public bool IsFaceSprite { get; }
|
||||||
|
public bool IsHubParsed { get; }
|
||||||
|
|
||||||
|
private AvgSpriteConfig GetCurSpriteGroup(AvgSpriteConfigGroup spriteHubDataGrouped, long spriteItemID, string spriteName)
|
||||||
|
{
|
||||||
|
if (spriteHubDataGrouped.SpriteGroups.Length > 1)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(spriteName))
|
||||||
|
{
|
||||||
|
var groupFromName = int.TryParse(spriteName?.Substring(spriteName.IndexOf('$') + 1, 1), out int groupIndex);
|
||||||
|
if (groupFromName)
|
||||||
|
{
|
||||||
|
return spriteHubDataGrouped.SpriteGroups[groupIndex - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return spriteHubDataGrouped.SpriteGroups.FirstOrDefault(x => x.Sprites.Any(y => y.Sprite.m_PathID == spriteItemID));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return spriteHubDataGrouped.SpriteGroups[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryGetSpriteHub(AssetItem assetItem, out AvgSpriteConfig spriteHubData)
|
||||||
|
{
|
||||||
|
spriteHubData = null;
|
||||||
|
var scriptAssets = Studio.exportableAssets.FindAll(x =>
|
||||||
|
x.Type == ClassIDType.MonoBehaviour
|
||||||
|
&& x.Container == assetItem.Container);
|
||||||
|
if (scriptAssets.Count == 0)
|
||||||
|
{
|
||||||
|
Logger.Warning("No MonoBehaviours were found.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
OrderedDictionary spriteHubDict = null;
|
||||||
|
var isGrouped = false;
|
||||||
|
foreach (var scriptAsset in scriptAssets)
|
||||||
|
{
|
||||||
|
var scriptAssetDict = ((MonoBehaviour)scriptAsset.Asset).ToType();
|
||||||
|
if (scriptAssetDict == null)
|
||||||
|
{
|
||||||
|
Logger.Warning("MonoBehaviour is not readable.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scriptAssetDict.Contains("spriteGroups"))
|
||||||
|
{
|
||||||
|
spriteHubDict = scriptAssetDict;
|
||||||
|
isGrouped = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (scriptAssetDict.Contains("sprites"))
|
||||||
|
{
|
||||||
|
spriteHubDict = scriptAssetDict;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spriteHubDict == null)
|
||||||
|
{
|
||||||
|
Logger.Warning("AVGCharacterSpriteHub is not readable.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var spriteHubJson = JsonConvert.SerializeObject(spriteHubDict);
|
||||||
|
if (isGrouped)
|
||||||
|
{
|
||||||
|
var groupedSpriteHub = JsonConvert.DeserializeObject<AvgSpriteConfigGroup>(spriteHubJson);
|
||||||
|
spriteHubData = GetCurSpriteGroup(groupedSpriteHub, assetItem.m_PathID, assetItem.Text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spriteHubData = JsonConvert.DeserializeObject<AvgSpriteConfig>(spriteHubJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AvgSprite(AssetItem assetItem)
|
||||||
|
{
|
||||||
|
if (TryGetSpriteHub(assetItem, out var spriteHubData))
|
||||||
|
{
|
||||||
|
IsHubParsed = spriteHubData?.Sprites.Length > 0;
|
||||||
|
}
|
||||||
|
if (IsHubParsed)
|
||||||
|
{
|
||||||
|
var curSpriteData = spriteHubData.Sprites.FirstOrDefault(x => x.Sprite.m_PathID == assetItem.m_PathID);
|
||||||
|
|
||||||
|
if (curSpriteData == null)
|
||||||
|
{
|
||||||
|
Studio.StatusStripUpdate($"Sprite \"{assetItem.Text}\" was not found in the avg sprite hub.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Alias = curSpriteData.Alias;
|
||||||
|
IsWholeBodySprite = curSpriteData.IsWholeBody;
|
||||||
|
|
||||||
|
if (spriteHubData.FaceSize.X > 0 && spriteHubData.FaceSize.Y > 0) //If face data exist
|
||||||
|
{
|
||||||
|
var fullTexSpriteData = spriteHubData.Sprites.Last(); //Last sprite item in the list usually contains PathID of Sprite with full texture
|
||||||
|
|
||||||
|
var curSprite = (Sprite)assetItem.Asset;
|
||||||
|
IsFaceSprite = curSprite.m_Rect.width <= 256 && curSprite.m_Rect.height <= 256 && curSprite.m_PathID != fullTexSpriteData.Sprite.m_PathID;
|
||||||
|
|
||||||
|
var curSpriteAlphaID = curSpriteData.AlphaTex.m_PathID;
|
||||||
|
var curSpriteAlphaTex = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == curSpriteAlphaID)?.Asset;
|
||||||
|
if (curSpriteAlphaTex != null)
|
||||||
|
{
|
||||||
|
FaceSpriteAlphaTexture = IsFaceSprite ? curSpriteAlphaTex : null;
|
||||||
|
fullTexSpriteData = IsFaceSprite ? fullTexSpriteData : curSpriteData;
|
||||||
|
}
|
||||||
|
var fullTexSpriteID = fullTexSpriteData.Sprite.m_PathID;
|
||||||
|
var fullTexAlphaID = fullTexSpriteData.AlphaTex.m_PathID;
|
||||||
|
var fullTexSprite = (Sprite)Studio.exportableAssets.Find(x => x.m_PathID == fullTexSpriteID).Asset;
|
||||||
|
|
||||||
|
FullTexture = fullTexSprite.m_RD.texture.TryGet(out var fullTex) ? fullTex : null;
|
||||||
|
FullAlphaTexture = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == fullTexAlphaID)?.Asset;
|
||||||
|
FacePos = new Point((int)Math.Round(spriteHubData.FacePos.X), (int)Math.Round(spriteHubData.FacePos.Y));
|
||||||
|
FaceSize = new Size((int)Math.Round(spriteHubData.FaceSize.X), (int)Math.Round(spriteHubData.FaceSize.Y));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FullAlphaTexture = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == curSpriteData.AlphaTex.m_PathID)?.Asset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
AssetStudioGUI/Components/Arknights/AvgSpriteConfig.cs
Normal file
30
AssetStudioGUI/Components/Arknights/AvgSpriteConfig.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using AssetStudio;
|
||||||
|
|
||||||
|
namespace Arknights.AvgCharHubMono
|
||||||
|
{
|
||||||
|
internal class AvgAssetIDs
|
||||||
|
{
|
||||||
|
public int m_FileID { get; set; }
|
||||||
|
public long m_PathID { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class AvgSpriteData
|
||||||
|
{
|
||||||
|
public AvgAssetIDs Sprite { get; set; }
|
||||||
|
public AvgAssetIDs AlphaTex { get; set; }
|
||||||
|
public string Alias { get; set; }
|
||||||
|
public bool IsWholeBody { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class AvgSpriteConfig
|
||||||
|
{
|
||||||
|
public AvgSpriteData[] Sprites { get; set; }
|
||||||
|
public Vector2 FaceSize { get; set; }
|
||||||
|
public Vector3 FacePos { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class AvgSpriteConfigGroup
|
||||||
|
{
|
||||||
|
public AvgSpriteConfig[] SpriteGroups { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
24
AssetStudioGUI/Components/Arknights/PortraitSprite.cs
Normal file
24
AssetStudioGUI/Components/Arknights/PortraitSprite.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using AssetStudio;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Arknights
|
||||||
|
{
|
||||||
|
internal class PortraitSprite
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public ClassIDType Type { get; }
|
||||||
|
public SerializedFile AssetsFile { get; set; }
|
||||||
|
public string Container { get; set; }
|
||||||
|
public Texture2D Texture { get; set; }
|
||||||
|
public Texture2D AlphaTexture { get; set; }
|
||||||
|
public Rectf TextureRect { get; set; }
|
||||||
|
public bool Rotate { get; set; }
|
||||||
|
public float DownscaleMultiplier { get; }
|
||||||
|
|
||||||
|
public PortraitSprite()
|
||||||
|
{
|
||||||
|
Type = ClassIDType.AkPortraitSprite;
|
||||||
|
DownscaleMultiplier = 1f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
AssetStudioGUI/Components/Arknights/PortraitSpriteConfig.cs
Normal file
41
AssetStudioGUI/Components/Arknights/PortraitSpriteConfig.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
namespace Arknights.PortraitSpriteMono
|
||||||
|
{
|
||||||
|
internal class PortraitRect
|
||||||
|
{
|
||||||
|
public float X { get; set; }
|
||||||
|
public float Y { get; set; }
|
||||||
|
public float W { get; set; }
|
||||||
|
public float H { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class AtlasSprite
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Guid { get; set; }
|
||||||
|
public int Atlas { get; set; }
|
||||||
|
public PortraitRect Rect { get; set; }
|
||||||
|
public bool Rotate { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class TextureIDs
|
||||||
|
{
|
||||||
|
public int m_FileID { get; set; }
|
||||||
|
public long m_PathID { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class AtlasInfo
|
||||||
|
{
|
||||||
|
public int Index { get; set; }
|
||||||
|
public TextureIDs Texture { get; set; }
|
||||||
|
public TextureIDs Alpha { get; set; }
|
||||||
|
public int Size { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class PortraitSpriteConfig
|
||||||
|
{
|
||||||
|
public string m_Name { get; set; }
|
||||||
|
public AtlasSprite[] _sprites { get; set; }
|
||||||
|
public AtlasInfo _atlas { get; set; }
|
||||||
|
public int _index { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using AssetStudio;
|
using AssetStudio;
|
||||||
|
using Arknights;
|
||||||
|
|
||||||
namespace AssetStudioGUI
|
namespace AssetStudioGUI
|
||||||
{
|
{
|
||||||
@@ -15,6 +16,7 @@ namespace AssetStudioGUI
|
|||||||
public string InfoText;
|
public string InfoText;
|
||||||
public string UniqueID;
|
public string UniqueID;
|
||||||
public GameObjectTreeNode TreeNode;
|
public GameObjectTreeNode TreeNode;
|
||||||
|
public PortraitSprite AkPortraitSprite;
|
||||||
|
|
||||||
public AssetItem(Object asset)
|
public AssetItem(Object asset)
|
||||||
{
|
{
|
||||||
@@ -26,6 +28,19 @@ namespace AssetStudioGUI
|
|||||||
FullSize = asset.byteSize;
|
FullSize = asset.byteSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AssetItem(PortraitSprite akPortraitSprite)
|
||||||
|
{
|
||||||
|
Asset = null;
|
||||||
|
SourceFile = akPortraitSprite.AssetsFile;
|
||||||
|
Container = akPortraitSprite.Container;
|
||||||
|
Type = akPortraitSprite.Type;
|
||||||
|
TypeString = Type.ToString();
|
||||||
|
Text = akPortraitSprite.Name;
|
||||||
|
m_PathID = -1;
|
||||||
|
FullSize = (long)(akPortraitSprite.TextureRect.width * akPortraitSprite.TextureRect.height * 4);
|
||||||
|
AkPortraitSprite = akPortraitSprite;
|
||||||
|
}
|
||||||
|
|
||||||
public void SetSubItems()
|
public void SetSubItems()
|
||||||
{
|
{
|
||||||
SubItems.AddRange(new[]
|
SubItems.AddRange(new[]
|
||||||
|
|||||||
@@ -43,6 +43,6 @@ namespace AssetStudioGUI
|
|||||||
public Bitmap Bitmap => m_bitmap;
|
public Bitmap Bitmap => m_bitmap;
|
||||||
|
|
||||||
private Bitmap m_bitmap;
|
private Bitmap m_bitmap;
|
||||||
private GCHandle m_handle;
|
private readonly GCHandle m_handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
248
AssetStudioGUI/ExportOptions.Designer.cs
generated
248
AssetStudioGUI/ExportOptions.Designer.cs
generated
@@ -32,8 +32,6 @@
|
|||||||
this.OKbutton = new System.Windows.Forms.Button();
|
this.OKbutton = new System.Windows.Forms.Button();
|
||||||
this.Cancel = new System.Windows.Forms.Button();
|
this.Cancel = new System.Windows.Forms.Button();
|
||||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||||
this.filenameFormatLabel = new System.Windows.Forms.Label();
|
|
||||||
this.filenameFormatComboBox = new System.Windows.Forms.ComboBox();
|
|
||||||
this.exportSpriteWithAlphaMask = new System.Windows.Forms.CheckBox();
|
this.exportSpriteWithAlphaMask = new System.Windows.Forms.CheckBox();
|
||||||
this.openAfterExport = new System.Windows.Forms.CheckBox();
|
this.openAfterExport = new System.Windows.Forms.CheckBox();
|
||||||
this.restoreExtensionName = new System.Windows.Forms.CheckBox();
|
this.restoreExtensionName = new System.Windows.Forms.CheckBox();
|
||||||
@@ -71,10 +69,18 @@
|
|||||||
this.castToBone = new System.Windows.Forms.CheckBox();
|
this.castToBone = new System.Windows.Forms.CheckBox();
|
||||||
this.exportAllNodes = new System.Windows.Forms.CheckBox();
|
this.exportAllNodes = new System.Windows.Forms.CheckBox();
|
||||||
this.eulerFilter = new System.Windows.Forms.CheckBox();
|
this.eulerFilter = new System.Windows.Forms.CheckBox();
|
||||||
|
this.akResamplerLabel = new System.Windows.Forms.Label();
|
||||||
|
this.akResamplerComboBox = new System.Windows.Forms.ComboBox();
|
||||||
|
this.akSpritesAlphaGroupBox = new System.Windows.Forms.GroupBox();
|
||||||
|
this.akGammaNoteLabel = new System.Windows.Forms.Label();
|
||||||
|
this.akResamplerDescLabel = new System.Windows.Forms.Label();
|
||||||
|
this.akResizedOnlyCheckBox = new System.Windows.Forms.CheckBox();
|
||||||
|
this.akGammaValueLabel = new System.Windows.Forms.Label();
|
||||||
|
this.akGammaLabel = new System.Windows.Forms.Label();
|
||||||
|
this.akAlphaMaskGammaTrackBar = new System.Windows.Forms.TrackBar();
|
||||||
|
this.akSpritesExportGroupBox = new System.Windows.Forms.GroupBox();
|
||||||
|
this.akAddAliasesCheckBox = new System.Windows.Forms.CheckBox();
|
||||||
this.optionTooltip = new System.Windows.Forms.ToolTip(this.components);
|
this.optionTooltip = new System.Windows.Forms.ToolTip(this.components);
|
||||||
this.parallelExportUpDown = new System.Windows.Forms.NumericUpDown();
|
|
||||||
this.parallelExportCheckBox = new System.Windows.Forms.CheckBox();
|
|
||||||
this.parallelExportMaxLabel = new System.Windows.Forms.Label();
|
|
||||||
this.groupBox1.SuspendLayout();
|
this.groupBox1.SuspendLayout();
|
||||||
this.panel1.SuspendLayout();
|
this.panel1.SuspendLayout();
|
||||||
this.l2dGroupBox.SuspendLayout();
|
this.l2dGroupBox.SuspendLayout();
|
||||||
@@ -83,15 +89,17 @@
|
|||||||
((System.ComponentModel.ISupportInitialize)(this.scaleFactor)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.scaleFactor)).BeginInit();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.boneSize)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.boneSize)).BeginInit();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.filterPrecision)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.filterPrecision)).BeginInit();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.parallelExportUpDown)).BeginInit();
|
this.akSpritesAlphaGroupBox.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.akAlphaMaskGammaTrackBar)).BeginInit();
|
||||||
|
this.akSpritesExportGroupBox.SuspendLayout();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// OKbutton
|
// OKbutton
|
||||||
//
|
//
|
||||||
this.OKbutton.Location = new System.Drawing.Point(381, 380);
|
this.OKbutton.Location = new System.Drawing.Point(681, 381);
|
||||||
this.OKbutton.Name = "OKbutton";
|
this.OKbutton.Name = "OKbutton";
|
||||||
this.OKbutton.Size = new System.Drawing.Size(75, 23);
|
this.OKbutton.Size = new System.Drawing.Size(75, 23);
|
||||||
this.OKbutton.TabIndex = 4;
|
this.OKbutton.TabIndex = 6;
|
||||||
this.OKbutton.Text = "OK";
|
this.OKbutton.Text = "OK";
|
||||||
this.OKbutton.UseVisualStyleBackColor = true;
|
this.OKbutton.UseVisualStyleBackColor = true;
|
||||||
this.OKbutton.Click += new System.EventHandler(this.OKbutton_Click);
|
this.OKbutton.Click += new System.EventHandler(this.OKbutton_Click);
|
||||||
@@ -99,10 +107,10 @@
|
|||||||
// Cancel
|
// Cancel
|
||||||
//
|
//
|
||||||
this.Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
this.Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||||
this.Cancel.Location = new System.Drawing.Point(462, 380);
|
this.Cancel.Location = new System.Drawing.Point(762, 381);
|
||||||
this.Cancel.Name = "Cancel";
|
this.Cancel.Name = "Cancel";
|
||||||
this.Cancel.Size = new System.Drawing.Size(75, 23);
|
this.Cancel.Size = new System.Drawing.Size(75, 23);
|
||||||
this.Cancel.TabIndex = 5;
|
this.Cancel.TabIndex = 7;
|
||||||
this.Cancel.Text = "Cancel";
|
this.Cancel.Text = "Cancel";
|
||||||
this.Cancel.UseVisualStyleBackColor = true;
|
this.Cancel.UseVisualStyleBackColor = true;
|
||||||
this.Cancel.Click += new System.EventHandler(this.Cancel_Click);
|
this.Cancel.Click += new System.EventHandler(this.Cancel_Click);
|
||||||
@@ -110,11 +118,6 @@
|
|||||||
// groupBox1
|
// groupBox1
|
||||||
//
|
//
|
||||||
this.groupBox1.AutoSize = true;
|
this.groupBox1.AutoSize = true;
|
||||||
this.groupBox1.Controls.Add(this.parallelExportMaxLabel);
|
|
||||||
this.groupBox1.Controls.Add(this.parallelExportCheckBox);
|
|
||||||
this.groupBox1.Controls.Add(this.parallelExportUpDown);
|
|
||||||
this.groupBox1.Controls.Add(this.filenameFormatLabel);
|
|
||||||
this.groupBox1.Controls.Add(this.filenameFormatComboBox);
|
|
||||||
this.groupBox1.Controls.Add(this.exportSpriteWithAlphaMask);
|
this.groupBox1.Controls.Add(this.exportSpriteWithAlphaMask);
|
||||||
this.groupBox1.Controls.Add(this.openAfterExport);
|
this.groupBox1.Controls.Add(this.openAfterExport);
|
||||||
this.groupBox1.Controls.Add(this.restoreExtensionName);
|
this.groupBox1.Controls.Add(this.restoreExtensionName);
|
||||||
@@ -130,28 +133,6 @@
|
|||||||
this.groupBox1.TabStop = false;
|
this.groupBox1.TabStop = false;
|
||||||
this.groupBox1.Text = "Export";
|
this.groupBox1.Text = "Export";
|
||||||
//
|
//
|
||||||
// filenameFormatLabel
|
|
||||||
//
|
|
||||||
this.filenameFormatLabel.AutoSize = true;
|
|
||||||
this.filenameFormatLabel.Location = new System.Drawing.Point(177, 18);
|
|
||||||
this.filenameFormatLabel.Name = "filenameFormatLabel";
|
|
||||||
this.filenameFormatLabel.Size = new System.Drawing.Size(84, 13);
|
|
||||||
this.filenameFormatLabel.TabIndex = 10;
|
|
||||||
this.filenameFormatLabel.Text = "File name format";
|
|
||||||
//
|
|
||||||
// filenameFormatComboBox
|
|
||||||
//
|
|
||||||
this.filenameFormatComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
|
||||||
this.filenameFormatComboBox.FormattingEnabled = true;
|
|
||||||
this.filenameFormatComboBox.Items.AddRange(new object[] {
|
|
||||||
"assetName",
|
|
||||||
"assetName@pathID",
|
|
||||||
"pathID"});
|
|
||||||
this.filenameFormatComboBox.Location = new System.Drawing.Point(177, 35);
|
|
||||||
this.filenameFormatComboBox.Name = "filenameFormatComboBox";
|
|
||||||
this.filenameFormatComboBox.Size = new System.Drawing.Size(118, 21);
|
|
||||||
this.filenameFormatComboBox.TabIndex = 9;
|
|
||||||
//
|
|
||||||
// exportSpriteWithAlphaMask
|
// exportSpriteWithAlphaMask
|
||||||
//
|
//
|
||||||
this.exportSpriteWithAlphaMask.AutoSize = true;
|
this.exportSpriteWithAlphaMask.AutoSize = true;
|
||||||
@@ -198,7 +179,6 @@
|
|||||||
"container path",
|
"container path",
|
||||||
"container path full (with name)",
|
"container path full (with name)",
|
||||||
"source file name",
|
"source file name",
|
||||||
"scene hierarchy",
|
|
||||||
"do not group"});
|
"do not group"});
|
||||||
this.assetGroupOptions.Location = new System.Drawing.Point(6, 35);
|
this.assetGroupOptions.Location = new System.Drawing.Point(6, 35);
|
||||||
this.assetGroupOptions.Name = "assetGroupOptions";
|
this.assetGroupOptions.Name = "assetGroupOptions";
|
||||||
@@ -221,9 +201,9 @@
|
|||||||
this.convertAudio.CheckState = System.Windows.Forms.CheckState.Checked;
|
this.convertAudio.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||||
this.convertAudio.Location = new System.Drawing.Point(6, 173);
|
this.convertAudio.Location = new System.Drawing.Point(6, 173);
|
||||||
this.convertAudio.Name = "convertAudio";
|
this.convertAudio.Name = "convertAudio";
|
||||||
this.convertAudio.Size = new System.Drawing.Size(213, 17);
|
this.convertAudio.Size = new System.Drawing.Size(179, 17);
|
||||||
this.convertAudio.TabIndex = 7;
|
this.convertAudio.TabIndex = 7;
|
||||||
this.convertAudio.Text = "Convert FMOD AudioClip to WAV(PCM)";
|
this.convertAudio.Text = "Convert AudioClip to WAV(PCM)";
|
||||||
this.convertAudio.UseVisualStyleBackColor = true;
|
this.convertAudio.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// panel1
|
// panel1
|
||||||
@@ -339,7 +319,7 @@
|
|||||||
//
|
//
|
||||||
// l2dAnimationClipRadioButton
|
// l2dAnimationClipRadioButton
|
||||||
//
|
//
|
||||||
this.l2dAnimationClipRadioButton.AccessibleName = "AnimationClipV2";
|
this.l2dAnimationClipRadioButton.AccessibleName = "AnimationClip";
|
||||||
this.l2dAnimationClipRadioButton.AutoSize = true;
|
this.l2dAnimationClipRadioButton.AutoSize = true;
|
||||||
this.l2dAnimationClipRadioButton.Location = new System.Drawing.Point(172, 5);
|
this.l2dAnimationClipRadioButton.Location = new System.Drawing.Point(172, 5);
|
||||||
this.l2dAnimationClipRadioButton.Name = "l2dAnimationClipRadioButton";
|
this.l2dAnimationClipRadioButton.Name = "l2dAnimationClipRadioButton";
|
||||||
@@ -600,52 +580,130 @@
|
|||||||
this.eulerFilter.Text = "EulerFilter";
|
this.eulerFilter.Text = "EulerFilter";
|
||||||
this.eulerFilter.UseVisualStyleBackColor = true;
|
this.eulerFilter.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// parallelExportUpDown
|
// akResamplerLabel
|
||||||
//
|
//
|
||||||
this.parallelExportUpDown.Location = new System.Drawing.Point(209, 218);
|
this.akResamplerLabel.AutoSize = true;
|
||||||
this.parallelExportUpDown.Maximum = new decimal(new int[] {
|
this.akResamplerLabel.Location = new System.Drawing.Point(6, 21);
|
||||||
8,
|
this.akResamplerLabel.Name = "akResamplerLabel";
|
||||||
0,
|
this.akResamplerLabel.Size = new System.Drawing.Size(120, 13);
|
||||||
0,
|
this.akResamplerLabel.TabIndex = 1;
|
||||||
0});
|
this.akResamplerLabel.Text = "Alpha texture resampler:";
|
||||||
this.parallelExportUpDown.Minimum = new decimal(new int[] {
|
this.optionTooltip.SetToolTip(this.akResamplerLabel, "Only affects exported images");
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0});
|
|
||||||
this.parallelExportUpDown.Name = "parallelExportUpDown";
|
|
||||||
this.parallelExportUpDown.Size = new System.Drawing.Size(42, 20);
|
|
||||||
this.parallelExportUpDown.TabIndex = 13;
|
|
||||||
this.parallelExportUpDown.Value = new decimal(new int[] {
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0});
|
|
||||||
//
|
//
|
||||||
// parallelExportCheckBox
|
// akResamplerComboBox
|
||||||
//
|
//
|
||||||
this.parallelExportCheckBox.AutoSize = true;
|
this.akResamplerComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
this.parallelExportCheckBox.Checked = true;
|
this.akResamplerComboBox.FormattingEnabled = true;
|
||||||
this.parallelExportCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
|
this.akResamplerComboBox.Items.AddRange(new object[] {
|
||||||
this.parallelExportCheckBox.Location = new System.Drawing.Point(6, 219);
|
"Nearest Neighbor",
|
||||||
this.parallelExportCheckBox.Name = "parallelExportCheckBox";
|
"Bilinear",
|
||||||
this.parallelExportCheckBox.Size = new System.Drawing.Size(203, 17);
|
"Bicubic",
|
||||||
this.parallelExportCheckBox.TabIndex = 15;
|
"Mitchell-Netravali",
|
||||||
this.parallelExportCheckBox.Text = "Export in parallel with number of tasks";
|
"Spline",
|
||||||
this.optionTooltip.SetToolTip(this.parallelExportCheckBox, "*Requires slightly more RAM than in single-task mode");
|
"Welch"});
|
||||||
this.parallelExportCheckBox.UseVisualStyleBackColor = true;
|
this.akResamplerComboBox.Location = new System.Drawing.Point(132, 18);
|
||||||
this.parallelExportCheckBox.CheckedChanged += new System.EventHandler(this.parallelExportCheckBox_CheckedChanged);
|
this.akResamplerComboBox.Name = "akResamplerComboBox";
|
||||||
|
this.akResamplerComboBox.Size = new System.Drawing.Size(162, 21);
|
||||||
|
this.akResamplerComboBox.TabIndex = 2;
|
||||||
|
this.optionTooltip.SetToolTip(this.akResamplerComboBox, "Only affects exported images");
|
||||||
//
|
//
|
||||||
// parallelExportMaxLabel
|
// akSpritesAlphaGroupBox
|
||||||
//
|
//
|
||||||
this.parallelExportMaxLabel.AutoSize = true;
|
this.akSpritesAlphaGroupBox.Controls.Add(this.akGammaNoteLabel);
|
||||||
this.parallelExportMaxLabel.ForeColor = System.Drawing.SystemColors.ControlDark;
|
this.akSpritesAlphaGroupBox.Controls.Add(this.akResamplerDescLabel);
|
||||||
this.parallelExportMaxLabel.Location = new System.Drawing.Point(256, 221);
|
this.akSpritesAlphaGroupBox.Controls.Add(this.akResamplerLabel);
|
||||||
this.parallelExportMaxLabel.Name = "parallelExportMaxLabel";
|
this.akSpritesAlphaGroupBox.Controls.Add(this.akResamplerComboBox);
|
||||||
this.parallelExportMaxLabel.Size = new System.Drawing.Size(33, 13);
|
this.akSpritesAlphaGroupBox.Controls.Add(this.akResizedOnlyCheckBox);
|
||||||
this.parallelExportMaxLabel.TabIndex = 16;
|
this.akSpritesAlphaGroupBox.Controls.Add(this.akGammaValueLabel);
|
||||||
this.parallelExportMaxLabel.Text = "Max: ";
|
this.akSpritesAlphaGroupBox.Controls.Add(this.akGammaLabel);
|
||||||
this.optionTooltip.SetToolTip(this.parallelExportMaxLabel, "*The maximum number matches the number of CPU cores");
|
this.akSpritesAlphaGroupBox.Controls.Add(this.akAlphaMaskGammaTrackBar);
|
||||||
|
this.akSpritesAlphaGroupBox.Location = new System.Drawing.Point(537, 13);
|
||||||
|
this.akSpritesAlphaGroupBox.Name = "akSpritesAlphaGroupBox";
|
||||||
|
this.akSpritesAlphaGroupBox.Size = new System.Drawing.Size(300, 178);
|
||||||
|
this.akSpritesAlphaGroupBox.TabIndex = 4;
|
||||||
|
this.akSpritesAlphaGroupBox.TabStop = false;
|
||||||
|
this.akSpritesAlphaGroupBox.Text = "Sprites: Alpha Texture [Arknights]";
|
||||||
|
//
|
||||||
|
// akGammaNoteLabel
|
||||||
|
//
|
||||||
|
this.akGammaNoteLabel.AutoSize = true;
|
||||||
|
this.akGammaNoteLabel.ForeColor = System.Drawing.SystemColors.GrayText;
|
||||||
|
this.akGammaNoteLabel.Location = new System.Drawing.Point(6, 138);
|
||||||
|
this.akGammaNoteLabel.Name = "akGammaNoteLabel";
|
||||||
|
this.akGammaNoteLabel.Size = new System.Drawing.Size(230, 13);
|
||||||
|
this.akGammaNoteLabel.TabIndex = 8;
|
||||||
|
this.akGammaNoteLabel.Text = "* Gamma settings also affect the preview image";
|
||||||
|
//
|
||||||
|
// akResamplerDescLabel
|
||||||
|
//
|
||||||
|
this.akResamplerDescLabel.AutoSize = true;
|
||||||
|
this.akResamplerDescLabel.ForeColor = System.Drawing.SystemColors.GrayText;
|
||||||
|
this.akResamplerDescLabel.Location = new System.Drawing.Point(6, 43);
|
||||||
|
this.akResamplerDescLabel.Name = "akResamplerDescLabel";
|
||||||
|
this.akResamplerDescLabel.Size = new System.Drawing.Size(251, 13);
|
||||||
|
this.akResamplerDescLabel.TabIndex = 3;
|
||||||
|
this.akResamplerDescLabel.Text = "Alpha texture upscale method for 2048x2048 sprites";
|
||||||
|
//
|
||||||
|
// akResizedOnlyCheckBox
|
||||||
|
//
|
||||||
|
this.akResizedOnlyCheckBox.AutoSize = true;
|
||||||
|
this.akResizedOnlyCheckBox.Checked = true;
|
||||||
|
this.akResizedOnlyCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||||
|
this.akResizedOnlyCheckBox.Location = new System.Drawing.Point(172, 85);
|
||||||
|
this.akResizedOnlyCheckBox.Name = "akResizedOnlyCheckBox";
|
||||||
|
this.akResizedOnlyCheckBox.Size = new System.Drawing.Size(122, 17);
|
||||||
|
this.akResizedOnlyCheckBox.TabIndex = 6;
|
||||||
|
this.akResizedOnlyCheckBox.Text = "Apply to resized only";
|
||||||
|
this.akResizedOnlyCheckBox.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// akGammaValueLabel
|
||||||
|
//
|
||||||
|
this.akGammaValueLabel.AutoSize = true;
|
||||||
|
this.akGammaValueLabel.Location = new System.Drawing.Point(111, 86);
|
||||||
|
this.akGammaValueLabel.Name = "akGammaValueLabel";
|
||||||
|
this.akGammaValueLabel.Size = new System.Drawing.Size(41, 13);
|
||||||
|
this.akGammaValueLabel.TabIndex = 5;
|
||||||
|
this.akGammaValueLabel.Text = "Default";
|
||||||
|
//
|
||||||
|
// akGammaLabel
|
||||||
|
//
|
||||||
|
this.akGammaLabel.AutoSize = true;
|
||||||
|
this.akGammaLabel.Location = new System.Drawing.Point(6, 86);
|
||||||
|
this.akGammaLabel.Name = "akGammaLabel";
|
||||||
|
this.akGammaLabel.Size = new System.Drawing.Size(86, 13);
|
||||||
|
this.akGammaLabel.TabIndex = 4;
|
||||||
|
this.akGammaLabel.Text = "Shadow gamma:";
|
||||||
|
//
|
||||||
|
// akAlphaMaskGammaTrackBar
|
||||||
|
//
|
||||||
|
this.akAlphaMaskGammaTrackBar.LargeChange = 2;
|
||||||
|
this.akAlphaMaskGammaTrackBar.Location = new System.Drawing.Point(6, 102);
|
||||||
|
this.akAlphaMaskGammaTrackBar.Maximum = 5;
|
||||||
|
this.akAlphaMaskGammaTrackBar.Minimum = -5;
|
||||||
|
this.akAlphaMaskGammaTrackBar.Name = "akAlphaMaskGammaTrackBar";
|
||||||
|
this.akAlphaMaskGammaTrackBar.Size = new System.Drawing.Size(288, 45);
|
||||||
|
this.akAlphaMaskGammaTrackBar.TabIndex = 7;
|
||||||
|
this.akAlphaMaskGammaTrackBar.Scroll += new System.EventHandler(this.akAlphaMaskGammaTrackBar_Scroll);
|
||||||
|
//
|
||||||
|
// akSpritesExportGroupBox
|
||||||
|
//
|
||||||
|
this.akSpritesExportGroupBox.Controls.Add(this.akAddAliasesCheckBox);
|
||||||
|
this.akSpritesExportGroupBox.Location = new System.Drawing.Point(537, 197);
|
||||||
|
this.akSpritesExportGroupBox.Name = "akSpritesExportGroupBox";
|
||||||
|
this.akSpritesExportGroupBox.Size = new System.Drawing.Size(300, 178);
|
||||||
|
this.akSpritesExportGroupBox.TabIndex = 5;
|
||||||
|
this.akSpritesExportGroupBox.TabStop = false;
|
||||||
|
this.akSpritesExportGroupBox.Text = "Sprites: Export [Arknights]";
|
||||||
|
//
|
||||||
|
// akAddAliasesCheckBox
|
||||||
|
//
|
||||||
|
this.akAddAliasesCheckBox.AutoSize = true;
|
||||||
|
this.akAddAliasesCheckBox.Location = new System.Drawing.Point(6, 28);
|
||||||
|
this.akAddAliasesCheckBox.Name = "akAddAliasesCheckBox";
|
||||||
|
this.akAddAliasesCheckBox.Size = new System.Drawing.Size(261, 17);
|
||||||
|
this.akAddAliasesCheckBox.TabIndex = 1;
|
||||||
|
this.akAddAliasesCheckBox.Text = "Add aliases to avg character sprite names (if exist)";
|
||||||
|
this.akAddAliasesCheckBox.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// ExportOptions
|
// ExportOptions
|
||||||
//
|
//
|
||||||
@@ -653,8 +711,10 @@
|
|||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.CancelButton = this.Cancel;
|
this.CancelButton = this.Cancel;
|
||||||
this.ClientSize = new System.Drawing.Size(549, 416);
|
this.ClientSize = new System.Drawing.Size(849, 416);
|
||||||
this.Controls.Add(this.l2dGroupBox);
|
this.Controls.Add(this.l2dGroupBox);
|
||||||
|
this.Controls.Add(this.akSpritesExportGroupBox);
|
||||||
|
this.Controls.Add(this.akSpritesAlphaGroupBox);
|
||||||
this.Controls.Add(this.groupBox2);
|
this.Controls.Add(this.groupBox2);
|
||||||
this.Controls.Add(this.groupBox1);
|
this.Controls.Add(this.groupBox1);
|
||||||
this.Controls.Add(this.Cancel);
|
this.Controls.Add(this.Cancel);
|
||||||
@@ -680,7 +740,11 @@
|
|||||||
((System.ComponentModel.ISupportInitialize)(this.scaleFactor)).EndInit();
|
((System.ComponentModel.ISupportInitialize)(this.scaleFactor)).EndInit();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.boneSize)).EndInit();
|
((System.ComponentModel.ISupportInitialize)(this.boneSize)).EndInit();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.filterPrecision)).EndInit();
|
((System.ComponentModel.ISupportInitialize)(this.filterPrecision)).EndInit();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.parallelExportUpDown)).EndInit();
|
this.akSpritesAlphaGroupBox.ResumeLayout(false);
|
||||||
|
this.akSpritesAlphaGroupBox.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.akAlphaMaskGammaTrackBar)).EndInit();
|
||||||
|
this.akSpritesExportGroupBox.ResumeLayout(false);
|
||||||
|
this.akSpritesExportGroupBox.PerformLayout();
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
this.PerformLayout();
|
this.PerformLayout();
|
||||||
|
|
||||||
@@ -722,16 +786,22 @@
|
|||||||
private System.Windows.Forms.ToolTip optionTooltip;
|
private System.Windows.Forms.ToolTip optionTooltip;
|
||||||
private System.Windows.Forms.CheckBox exportSpriteWithAlphaMask;
|
private System.Windows.Forms.CheckBox exportSpriteWithAlphaMask;
|
||||||
private System.Windows.Forms.RadioButton towebp;
|
private System.Windows.Forms.RadioButton towebp;
|
||||||
|
private System.Windows.Forms.GroupBox akSpritesAlphaGroupBox;
|
||||||
|
private System.Windows.Forms.TrackBar akAlphaMaskGammaTrackBar;
|
||||||
|
private System.Windows.Forms.Label akResamplerDescLabel;
|
||||||
|
private System.Windows.Forms.Label akResamplerLabel;
|
||||||
|
private System.Windows.Forms.ComboBox akResamplerComboBox;
|
||||||
|
private System.Windows.Forms.CheckBox akResizedOnlyCheckBox;
|
||||||
|
private System.Windows.Forms.Label akGammaValueLabel;
|
||||||
|
private System.Windows.Forms.Label akGammaLabel;
|
||||||
|
private System.Windows.Forms.GroupBox akSpritesExportGroupBox;
|
||||||
|
private System.Windows.Forms.CheckBox akAddAliasesCheckBox;
|
||||||
|
private System.Windows.Forms.Label akGammaNoteLabel;
|
||||||
private System.Windows.Forms.GroupBox l2dGroupBox;
|
private System.Windows.Forms.GroupBox l2dGroupBox;
|
||||||
private System.Windows.Forms.CheckBox l2dForceBezierCheckBox;
|
private System.Windows.Forms.CheckBox l2dForceBezierCheckBox;
|
||||||
private System.Windows.Forms.Label l2dMotionExportMethodLabel;
|
private System.Windows.Forms.Label l2dMotionExportMethodLabel;
|
||||||
private System.Windows.Forms.RadioButton l2dAnimationClipRadioButton;
|
private System.Windows.Forms.RadioButton l2dAnimationClipRadioButton;
|
||||||
private System.Windows.Forms.RadioButton l2dMonoBehaviourRadioButton;
|
private System.Windows.Forms.RadioButton l2dMonoBehaviourRadioButton;
|
||||||
private System.Windows.Forms.Panel l2dMotionExportMethodPanel;
|
private System.Windows.Forms.Panel l2dMotionExportMethodPanel;
|
||||||
private System.Windows.Forms.ComboBox filenameFormatComboBox;
|
|
||||||
private System.Windows.Forms.Label filenameFormatLabel;
|
|
||||||
private System.Windows.Forms.NumericUpDown parallelExportUpDown;
|
|
||||||
private System.Windows.Forms.CheckBox parallelExportCheckBox;
|
|
||||||
private System.Windows.Forms.Label parallelExportMaxLabel;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,16 +30,17 @@ namespace AssetStudioGUI
|
|||||||
scaleFactor.Value = Properties.Settings.Default.scaleFactor;
|
scaleFactor.Value = Properties.Settings.Default.scaleFactor;
|
||||||
fbxVersion.SelectedIndex = Properties.Settings.Default.fbxVersion;
|
fbxVersion.SelectedIndex = Properties.Settings.Default.fbxVersion;
|
||||||
fbxFormat.SelectedIndex = Properties.Settings.Default.fbxFormat;
|
fbxFormat.SelectedIndex = Properties.Settings.Default.fbxFormat;
|
||||||
|
|
||||||
|
//Arknights
|
||||||
|
akResamplerComboBox.SelectedIndex = Properties.Settings.Default.resamplerIndex;
|
||||||
|
akAlphaMaskGammaTrackBar.Value = Properties.Settings.Default.alphaMaskGamma;
|
||||||
|
akGammaValueLabel.Text = akAlphaMaskGammaTrackBar.Value == 0 ? "Default" : $"{akAlphaMaskGammaTrackBar.Value * 10:+#;-#;0}%";
|
||||||
|
akResizedOnlyCheckBox.Checked = Properties.Settings.Default.resizedOnly;
|
||||||
|
akAddAliasesCheckBox.Checked = Properties.Settings.Default.addAliases;
|
||||||
|
|
||||||
var defaultMotionMode = Properties.Settings.Default.l2dMotionMode.ToString();
|
var defaultMotionMode = Properties.Settings.Default.l2dMotionMode.ToString();
|
||||||
((RadioButton)l2dMotionExportMethodPanel.Controls.Cast<Control>().First(x => x.AccessibleName == defaultMotionMode)).Checked = true;
|
((RadioButton)l2dMotionExportMethodPanel.Controls.Cast<Control>().First(x => x.AccessibleName == defaultMotionMode)).Checked = true;
|
||||||
l2dForceBezierCheckBox.Checked = Properties.Settings.Default.l2dForceBezier;
|
l2dForceBezierCheckBox.Checked = Properties.Settings.Default.l2dForceBezier;
|
||||||
filenameFormatComboBox.SelectedIndex = Properties.Settings.Default.filenameFormat;
|
|
||||||
var maxParallelTasks = Environment.ProcessorCount;
|
|
||||||
var taskCount = Properties.Settings.Default.parallelExportCount;
|
|
||||||
parallelExportUpDown.Maximum = maxParallelTasks;
|
|
||||||
parallelExportUpDown.Value = taskCount <= 0 ? maxParallelTasks : Math.Min(taskCount, maxParallelTasks);
|
|
||||||
parallelExportMaxLabel.Text += maxParallelTasks;
|
|
||||||
parallelExportCheckBox.Checked = Properties.Settings.Default.parallelExport;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OKbutton_Click(object sender, EventArgs e)
|
private void OKbutton_Click(object sender, EventArgs e)
|
||||||
@@ -64,26 +65,31 @@ namespace AssetStudioGUI
|
|||||||
Properties.Settings.Default.scaleFactor = scaleFactor.Value;
|
Properties.Settings.Default.scaleFactor = scaleFactor.Value;
|
||||||
Properties.Settings.Default.fbxVersion = fbxVersion.SelectedIndex;
|
Properties.Settings.Default.fbxVersion = fbxVersion.SelectedIndex;
|
||||||
Properties.Settings.Default.fbxFormat = fbxFormat.SelectedIndex;
|
Properties.Settings.Default.fbxFormat = fbxFormat.SelectedIndex;
|
||||||
|
|
||||||
|
//Arknights
|
||||||
|
Properties.Settings.Default.resamplerIndex = akResamplerComboBox.SelectedIndex;
|
||||||
|
Properties.Settings.Default.alphaMaskGamma = akAlphaMaskGammaTrackBar.Value;
|
||||||
|
Properties.Settings.Default.resizedOnly = akResizedOnlyCheckBox.Checked;
|
||||||
|
Properties.Settings.Default.addAliases = akAddAliasesCheckBox.Checked;
|
||||||
|
|
||||||
var checkedMotionMode = (RadioButton)l2dMotionExportMethodPanel.Controls.Cast<Control>().First(x => ((RadioButton)x).Checked);
|
var checkedMotionMode = (RadioButton)l2dMotionExportMethodPanel.Controls.Cast<Control>().First(x => ((RadioButton)x).Checked);
|
||||||
Properties.Settings.Default.l2dMotionMode = (CubismLive2DExtractor.Live2DMotionMode)Enum.Parse(typeof(CubismLive2DExtractor.Live2DMotionMode), checkedMotionMode.AccessibleName);
|
Properties.Settings.Default.l2dMotionMode = (CubismLive2DExtractor.Live2DMotionMode)Enum.Parse(typeof(CubismLive2DExtractor.Live2DMotionMode), checkedMotionMode.AccessibleName);
|
||||||
Properties.Settings.Default.l2dForceBezier = l2dForceBezierCheckBox.Checked;
|
Properties.Settings.Default.l2dForceBezier = l2dForceBezierCheckBox.Checked;
|
||||||
Properties.Settings.Default.filenameFormat = filenameFormatComboBox.SelectedIndex;
|
|
||||||
Properties.Settings.Default.parallelExport = parallelExportCheckBox.Checked;
|
|
||||||
Properties.Settings.Default.parallelExportCount = (int)parallelExportUpDown.Value;
|
|
||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
DialogResult = DialogResult.OK;
|
DialogResult = DialogResult.OK;
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Arknights
|
||||||
|
private void akAlphaMaskGammaTrackBar_Scroll(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
akGammaValueLabel.Text = akAlphaMaskGammaTrackBar.Value == 0 ? "Default" : $"{akAlphaMaskGammaTrackBar.Value * 10:+#;-#;0}%";
|
||||||
|
}
|
||||||
|
|
||||||
private void Cancel_Click(object sender, EventArgs e)
|
private void Cancel_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
DialogResult = DialogResult.Cancel;
|
DialogResult = DialogResult.Cancel;
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parallelExportCheckBox_CheckedChanged(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
parallelExportUpDown.Enabled = parallelExportCheckBox.Checked;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,10 +120,4 @@
|
|||||||
<metadata name="optionTooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="optionTooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>17, 17</value>
|
<value>17, 17</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
<metadata name="optionTooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
|
||||||
<value>17, 17</value>
|
|
||||||
</metadata>
|
|
||||||
<metadata name="optionTooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
|
||||||
<value>17, 17</value>
|
|
||||||
</metadata>
|
|
||||||
</root>
|
</root>
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
using AssetStudio;
|
using Arknights;
|
||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
|
using AssetStudio;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -9,6 +12,60 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
internal static class Exporter
|
internal static class Exporter
|
||||||
{
|
{
|
||||||
|
public static bool ExportTexture2D(AssetItem item, string exportPath)
|
||||||
|
{
|
||||||
|
var m_Texture2D = (Texture2D)item.Asset;
|
||||||
|
if (Properties.Settings.Default.convertTexture)
|
||||||
|
{
|
||||||
|
var type = Properties.Settings.Default.convertType;
|
||||||
|
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
|
||||||
|
return false;
|
||||||
|
var image = m_Texture2D.ConvertToImage(true);
|
||||||
|
if (image == null)
|
||||||
|
return false;
|
||||||
|
using (image)
|
||||||
|
{
|
||||||
|
using (var file = File.OpenWrite(exportFullPath))
|
||||||
|
{
|
||||||
|
image.WriteToStream(file, type);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!TryExportFile(exportPath, item, ".tex", out var exportFullPath))
|
||||||
|
return false;
|
||||||
|
File.WriteAllBytes(exportFullPath, m_Texture2D.image_data.GetData());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ExportAudioClip(AssetItem item, string exportPath)
|
||||||
|
{
|
||||||
|
var m_AudioClip = (AudioClip)item.Asset;
|
||||||
|
var m_AudioData = m_AudioClip.m_AudioData.GetData();
|
||||||
|
if (m_AudioData == null || m_AudioData.Length == 0)
|
||||||
|
return false;
|
||||||
|
var converter = new AudioClipConverter(m_AudioClip);
|
||||||
|
if (Properties.Settings.Default.convertAudio && converter.IsSupport)
|
||||||
|
{
|
||||||
|
if (!TryExportFile(exportPath, item, ".wav", out var exportFullPath))
|
||||||
|
return false;
|
||||||
|
var buffer = converter.ConvertToWav(m_AudioData);
|
||||||
|
if (buffer == null)
|
||||||
|
return false;
|
||||||
|
File.WriteAllBytes(exportFullPath, buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!TryExportFile(exportPath, item, converter.GetExtensionName(), out var exportFullPath))
|
||||||
|
return false;
|
||||||
|
File.WriteAllBytes(exportFullPath, m_AudioData);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static bool ExportShader(AssetItem item, string exportPath)
|
public static bool ExportShader(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
if (!TryExportFile(exportPath, item, ".shader", out var exportFullPath))
|
if (!TryExportFile(exportPath, item, ".shader", out var exportFullPath))
|
||||||
@@ -183,43 +240,109 @@ namespace AssetStudioGUI
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool ExportSprite(AssetItem item, string exportPath)
|
||||||
|
{
|
||||||
|
Image<Bgra32> image;
|
||||||
|
AvgSprite avgSprite = null;
|
||||||
|
var alias = "";
|
||||||
|
var m_Sprite = (Sprite)item.Asset;
|
||||||
|
var spriteMaskMode = Properties.Settings.Default.exportSpriteWithMask ? SpriteMaskMode.Export : SpriteMaskMode.Off;
|
||||||
|
var type = Properties.Settings.Default.convertType;
|
||||||
|
var isCharAvgSprite = item.Container.Contains("avg/characters");
|
||||||
|
var isCharArt = item.Container.Contains("arts/characters");
|
||||||
|
|
||||||
|
if (isCharAvgSprite)
|
||||||
|
{
|
||||||
|
avgSprite = new AvgSprite(item);
|
||||||
|
|
||||||
|
if (Properties.Settings.Default.addAliases && !string.IsNullOrEmpty(avgSprite.Alias))
|
||||||
|
{
|
||||||
|
alias = $"_{avgSprite.Alias}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath, alias))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (Properties.Settings.Default.useExternalAlpha && (isCharAvgSprite || isCharArt))
|
||||||
|
{
|
||||||
|
if (m_Sprite.m_RD.alphaTexture.IsNull)
|
||||||
|
{
|
||||||
|
var charAlphaAtlas = AkSpriteHelper.TryFindAlphaTex(item, avgSprite, isCharAvgSprite);
|
||||||
|
if (charAlphaAtlas != null)
|
||||||
|
{
|
||||||
|
m_Sprite.m_RD.alphaTexture.Set(charAlphaAtlas);
|
||||||
|
m_Sprite.akSplitAlpha = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
image = m_Sprite.AkGetImage(avgSprite, spriteMaskMode: spriteMaskMode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
image = m_Sprite.GetImage(spriteMaskMode: spriteMaskMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
using (image)
|
||||||
|
{
|
||||||
|
using (var file = File.OpenWrite(exportFullPath))
|
||||||
|
{
|
||||||
|
image.WriteToStream(file, type);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ExportPortraitSprite(AssetItem item, string exportPath)
|
||||||
|
{
|
||||||
|
var type = Properties.Settings.Default.convertType;
|
||||||
|
var spriteMaskMode = Properties.Settings.Default.exportSpriteWithMask ? SpriteMaskMode.Export : SpriteMaskMode.Off;
|
||||||
|
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var image = item.AkPortraitSprite.AkGetImage(spriteMaskMode: spriteMaskMode);
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
using (image)
|
||||||
|
{
|
||||||
|
using (var file = File.OpenWrite(exportFullPath))
|
||||||
|
{
|
||||||
|
image.WriteToStream(file, type);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static bool ExportRawFile(AssetItem item, string exportPath)
|
public static bool ExportRawFile(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
if (!TryExportFile(exportPath, item, ".dat", out var exportFullPath, mode: "ExportRaw"))
|
if (item.Asset == null)
|
||||||
|
return false;
|
||||||
|
if (!TryExportFile(exportPath, item, ".dat", out var exportFullPath))
|
||||||
return false;
|
return false;
|
||||||
File.WriteAllBytes(exportFullPath, item.Asset.GetRawData());
|
File.WriteAllBytes(exportFullPath, item.Asset.GetRawData());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool TryExportFile(string dir, AssetItem item, string extension, out string fullPath, string mode = "Export")
|
private static bool TryExportFile(string dir, AssetItem item, string extension, out string fullPath, string alias = "")
|
||||||
{
|
{
|
||||||
var fileName = FixFileName(item.Text);
|
var fileName = FixFileName(item.Text) + alias;
|
||||||
var filenameFormatIndex = Properties.Settings.Default.filenameFormat;
|
|
||||||
switch (filenameFormatIndex)
|
|
||||||
{
|
|
||||||
case 1: //assetName@pathID
|
|
||||||
fileName = $"{fileName} @{item.m_PathID}";
|
|
||||||
break;
|
|
||||||
case 2: //pathID
|
|
||||||
fileName = item.m_PathID.ToString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fullPath = Path.Combine(dir, fileName + extension);
|
fullPath = Path.Combine(dir, fileName + extension);
|
||||||
if (!File.Exists(fullPath))
|
if (!File.Exists(fullPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(dir);
|
Directory.CreateDirectory(dir);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (filenameFormatIndex == 0) //assetName
|
fullPath = Path.Combine(dir, fileName + item.UniqueID + extension);
|
||||||
|
if (!File.Exists(fullPath))
|
||||||
{
|
{
|
||||||
fullPath = Path.Combine(dir, fileName + item.UniqueID + extension);
|
Directory.CreateDirectory(dir);
|
||||||
if (!File.Exists(fullPath))
|
return true;
|
||||||
{
|
|
||||||
Directory.CreateDirectory(dir);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Logger.Warning($"{mode} failed. File \"{fullPath.Color(ColorConsole.BrightYellow)}\" already exist");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,7 +399,9 @@ namespace AssetStudioGUI
|
|||||||
|
|
||||||
public static bool ExportDumpFile(AssetItem item, string exportPath)
|
public static bool ExportDumpFile(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
if (!TryExportFile(exportPath, item, ".txt", out var exportFullPath, mode: "Dump"))
|
if (item.Asset == null)
|
||||||
|
return false;
|
||||||
|
if (!TryExportFile(exportPath, item, ".txt", out var exportFullPath))
|
||||||
return false;
|
return false;
|
||||||
var str = item.Asset.Dump();
|
var str = item.Asset.Dump();
|
||||||
if (str == null && item.Asset is MonoBehaviour m_MonoBehaviour)
|
if (str == null && item.Asset is MonoBehaviour m_MonoBehaviour)
|
||||||
@@ -284,10 +409,6 @@ namespace AssetStudioGUI
|
|||||||
var m_Type = Studio.MonoBehaviourToTypeTree(m_MonoBehaviour);
|
var m_Type = Studio.MonoBehaviourToTypeTree(m_MonoBehaviour);
|
||||||
str = m_MonoBehaviour.Dump(m_Type);
|
str = m_MonoBehaviour.Dump(m_Type);
|
||||||
}
|
}
|
||||||
if (string.IsNullOrEmpty(str))
|
|
||||||
{
|
|
||||||
str = item.Asset.DumpObject();
|
|
||||||
}
|
|
||||||
if (str != null)
|
if (str != null)
|
||||||
{
|
{
|
||||||
File.WriteAllText(exportFullPath, str);
|
File.WriteAllText(exportFullPath, str);
|
||||||
@@ -301,11 +422,9 @@ namespace AssetStudioGUI
|
|||||||
switch (item.Type)
|
switch (item.Type)
|
||||||
{
|
{
|
||||||
case ClassIDType.Texture2D:
|
case ClassIDType.Texture2D:
|
||||||
case ClassIDType.Texture2DArrayImage:
|
return ExportTexture2D(item, exportPath);
|
||||||
case ClassIDType.Texture2DArray:
|
|
||||||
case ClassIDType.AudioClip:
|
case ClassIDType.AudioClip:
|
||||||
case ClassIDType.Sprite:
|
return ExportAudioClip(item, exportPath);
|
||||||
throw new System.NotImplementedException();
|
|
||||||
case ClassIDType.Shader:
|
case ClassIDType.Shader:
|
||||||
return ExportShader(item, exportPath);
|
return ExportShader(item, exportPath);
|
||||||
case ClassIDType.TextAsset:
|
case ClassIDType.TextAsset:
|
||||||
@@ -320,6 +439,10 @@ namespace AssetStudioGUI
|
|||||||
return ExportVideoClip(item, exportPath);
|
return ExportVideoClip(item, exportPath);
|
||||||
case ClassIDType.MovieTexture:
|
case ClassIDType.MovieTexture:
|
||||||
return ExportMovieTexture(item, exportPath);
|
return ExportMovieTexture(item, exportPath);
|
||||||
|
case ClassIDType.Sprite:
|
||||||
|
return ExportSprite(item, exportPath);
|
||||||
|
case ClassIDType.AkPortraitSprite:
|
||||||
|
return ExportPortraitSprite(item, exportPath);
|
||||||
case ClassIDType.Animator:
|
case ClassIDType.Animator:
|
||||||
return ExportAnimator(item, exportPath);
|
return ExportAnimator(item, exportPath);
|
||||||
case ClassIDType.AnimationClip:
|
case ClassIDType.AnimationClip:
|
||||||
@@ -331,9 +454,8 @@ namespace AssetStudioGUI
|
|||||||
|
|
||||||
public static string FixFileName(string str)
|
public static string FixFileName(string str)
|
||||||
{
|
{
|
||||||
return str.Length >= 260
|
if (str.Length >= 260) return Path.GetRandomFileName();
|
||||||
? Path.GetRandomFileName()
|
return Path.GetInvalidFileNameChars().Aggregate(str, (current, c) => current.Replace(c, '_'));
|
||||||
: Path.GetInvalidFileNameChars().Aggregate(str, (current, c) => current.Replace(c, '_'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,20 @@
|
|||||||
using AssetStudio;
|
using AssetStudio;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace AssetStudioGUI
|
namespace AssetStudioGUI
|
||||||
{
|
{
|
||||||
class GUILogger : ILogger
|
class GUILogger : ILogger
|
||||||
{
|
{
|
||||||
public static bool ShowDebugMessage = false;
|
public bool ShowErrorMessage = false;
|
||||||
|
private bool IsFileLoggerRunning = false;
|
||||||
private bool isFileLoggerRunning = false;
|
private string LoggerInitString;
|
||||||
private string loggerInitString;
|
private string FileLogName;
|
||||||
private string fileLogName;
|
private string FileLogPath;
|
||||||
private string fileLogPath;
|
|
||||||
private Action<string> action;
|
private Action<string> action;
|
||||||
private CancellationTokenSource tokenSource;
|
|
||||||
private BlockingCollection<string> consoleLogMessageCollection = new BlockingCollection<string>();
|
|
||||||
private BlockingCollection<string> fileLogMessageCollection = new BlockingCollection<string>();
|
|
||||||
|
|
||||||
private bool _useFileLogger = false;
|
private bool _useFileLogger = false;
|
||||||
public bool UseFileLogger
|
public bool UseFileLogger
|
||||||
@@ -29,23 +23,19 @@ namespace AssetStudioGUI
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
_useFileLogger = value;
|
_useFileLogger = value;
|
||||||
if (_useFileLogger && !isFileLoggerRunning)
|
if (_useFileLogger && !IsFileLoggerRunning)
|
||||||
{
|
{
|
||||||
var appAssembly = typeof(Program).Assembly.GetName();
|
var appAssembly = typeof(Program).Assembly.GetName();
|
||||||
fileLogName = $"{appAssembly.Name}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log";
|
FileLogName = $"{appAssembly.Name}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log";
|
||||||
fileLogPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileLogName);
|
FileLogPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, FileLogName);
|
||||||
tokenSource = new CancellationTokenSource();
|
|
||||||
isFileLoggerRunning = true;
|
|
||||||
|
|
||||||
ConcurrentFileWriter(tokenSource.Token);
|
LogToFile(LoggerEvent.Verbose, $"# {LoggerInitString} - Logger launched #");
|
||||||
LogToFile(LoggerEvent.Verbose, $"# {loggerInitString} - Logger launched #");
|
IsFileLoggerRunning = true;
|
||||||
}
|
}
|
||||||
else if (!_useFileLogger && isFileLoggerRunning)
|
else if (!_useFileLogger && IsFileLoggerRunning)
|
||||||
{
|
{
|
||||||
LogToFile(LoggerEvent.Verbose, "# Logger closed #");
|
LogToFile(LoggerEvent.Verbose, "# Logger closed #");
|
||||||
isFileLoggerRunning = false;
|
IsFileLoggerRunning = false;
|
||||||
tokenSource.Cancel();
|
|
||||||
tokenSource.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,7 +47,7 @@ namespace AssetStudioGUI
|
|||||||
var appAssembly = typeof(Program).Assembly.GetName();
|
var appAssembly = typeof(Program).Assembly.GetName();
|
||||||
var arch = Environment.Is64BitProcess ? "x64" : "x32";
|
var arch = Environment.Is64BitProcess ? "x64" : "x32";
|
||||||
var frameworkName = AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName;
|
var frameworkName = AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName;
|
||||||
loggerInitString = $"{appAssembly.Name} v{appAssembly.Version} [{arch}] [{frameworkName}]";
|
LoggerInitString = $"{appAssembly.Name} v{appAssembly.Version} [{arch}] [{frameworkName}]";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Console.Title = $"Console Logger - {appAssembly.Name} v{appAssembly.Version}";
|
Console.Title = $"Console Logger - {appAssembly.Name} v{appAssembly.Version}";
|
||||||
@@ -67,9 +57,7 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
Console.WriteLine($"# {LoggerInitString}");
|
||||||
ConcurrentConsoleWriter();
|
|
||||||
Console.WriteLine($"# {loggerInitString}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ColorLogLevel(LoggerEvent logLevel)
|
private static string ColorLogLevel(LoggerEvent logLevel)
|
||||||
@@ -91,7 +79,7 @@ namespace AssetStudioGUI
|
|||||||
private static string FormatMessage(LoggerEvent logMsgLevel, string message, bool toConsole)
|
private static string FormatMessage(LoggerEvent logMsgLevel, string message, bool toConsole)
|
||||||
{
|
{
|
||||||
message = message.TrimEnd();
|
message = message.TrimEnd();
|
||||||
var multiLine = message.Contains("\n");
|
var multiLine = message.Contains('\n');
|
||||||
|
|
||||||
string formattedMessage;
|
string formattedMessage;
|
||||||
if (toConsole)
|
if (toConsole)
|
||||||
@@ -100,7 +88,7 @@ namespace AssetStudioGUI
|
|||||||
formattedMessage = $"{colorLogLevel} {message}";
|
formattedMessage = $"{colorLogLevel} {message}";
|
||||||
if (multiLine)
|
if (multiLine)
|
||||||
{
|
{
|
||||||
formattedMessage = formattedMessage.Replace("\n", $"\n{colorLogLevel} ") + $"\n{colorLogLevel}";
|
formattedMessage = formattedMessage.Replace("\n", $"\n{colorLogLevel} ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -111,48 +99,19 @@ namespace AssetStudioGUI
|
|||||||
formattedMessage = $"{curTime} | {logLevel} | {message}";
|
formattedMessage = $"{curTime} | {logLevel} | {message}";
|
||||||
if (multiLine)
|
if (multiLine)
|
||||||
{
|
{
|
||||||
formattedMessage = formattedMessage.Replace("\n", $"\n{curTime} | {logLevel} | ") + $"\n{curTime} | {logLevel} |";
|
formattedMessage = formattedMessage.Replace("\n", $"\n{curTime} | {logLevel} | ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return formattedMessage;
|
return formattedMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ConcurrentFileWriter(CancellationToken token)
|
private async void LogToFile(LoggerEvent logMsgLevel, string message)
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
using (var sw = new StreamWriter(FileLogPath, append: true, System.Text.Encoding.UTF8))
|
||||||
{
|
{
|
||||||
using (var sw = new StreamWriter(fileLogPath, append: true, System.Text.Encoding.UTF8))
|
await sw.WriteLineAsync(FormatMessage(logMsgLevel, message, toConsole: false));
|
||||||
{
|
}
|
||||||
sw.AutoFlush = true;
|
|
||||||
foreach (var msg in fileLogMessageCollection.GetConsumingEnumerable())
|
|
||||||
{
|
|
||||||
sw.WriteLine(msg);
|
|
||||||
if (token.IsCancellationRequested)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ConcurrentConsoleWriter()
|
|
||||||
{
|
|
||||||
Task.Run(() =>
|
|
||||||
{
|
|
||||||
foreach (var msg in consoleLogMessageCollection.GetConsumingEnumerable())
|
|
||||||
{
|
|
||||||
Console.WriteLine(msg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LogToFile(LoggerEvent logMsgLevel, string message)
|
|
||||||
{
|
|
||||||
fileLogMessageCollection.Add(FormatMessage(logMsgLevel, message, toConsole: false));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LogToConsole(LoggerEvent logMsgLevel, string message)
|
|
||||||
{
|
|
||||||
consoleLogMessageCollection.Add(FormatMessage(logMsgLevel, message, toConsole: true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Log(LoggerEvent loggerEvent, string message, bool ignoreLevel)
|
public void Log(LoggerEvent loggerEvent, string message, bool ignoreLevel)
|
||||||
@@ -164,9 +123,7 @@ namespace AssetStudioGUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Console logger
|
//Console logger
|
||||||
if (!ShowDebugMessage && loggerEvent == LoggerEvent.Debug)
|
Console.WriteLine(FormatMessage(loggerEvent, message, toConsole: true));
|
||||||
return;
|
|
||||||
LogToConsole(loggerEvent, message);
|
|
||||||
|
|
||||||
//GUI logger
|
//GUI logger
|
||||||
switch (loggerEvent)
|
switch (loggerEvent)
|
||||||
@@ -175,7 +132,14 @@ namespace AssetStudioGUI
|
|||||||
MessageBox.Show(message, "Error");
|
MessageBox.Show(message, "Error");
|
||||||
break;
|
break;
|
||||||
case LoggerEvent.Warning:
|
case LoggerEvent.Warning:
|
||||||
action("Some warnings occurred. See Console Logger for details.");
|
if (ShowErrorMessage)
|
||||||
|
{
|
||||||
|
MessageBox.Show(message, "Warning");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
action("An error has occurred. Turn on \"Show all error messages\" to see details next time.");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case LoggerEvent.Debug:
|
case LoggerEvent.Debug:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,226 +0,0 @@
|
|||||||
using AssetStudio;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudioGUI
|
|
||||||
{
|
|
||||||
internal static class ParallelExporter
|
|
||||||
{
|
|
||||||
private static ConcurrentDictionary<string, bool> savePathHash = new ConcurrentDictionary<string, bool>();
|
|
||||||
|
|
||||||
public static bool ExportTexture2D(AssetItem item, string exportPath, out string debugLog)
|
|
||||||
{
|
|
||||||
debugLog = "";
|
|
||||||
var m_Texture2D = (Texture2D)item.Asset;
|
|
||||||
if (Properties.Settings.Default.convertTexture)
|
|
||||||
{
|
|
||||||
var type = Properties.Settings.Default.convertType;
|
|
||||||
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (GUILogger.ShowDebugMessage)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine($"Converting {item.TypeString} \"{m_Texture2D.m_Name}\" to {type}..");
|
|
||||||
sb.AppendLine($"Width: {m_Texture2D.m_Width}");
|
|
||||||
sb.AppendLine($"Height: {m_Texture2D.m_Height}");
|
|
||||||
sb.AppendLine($"Format: {m_Texture2D.m_TextureFormat}");
|
|
||||||
switch (m_Texture2D.m_TextureSettings.m_FilterMode)
|
|
||||||
{
|
|
||||||
case 0: sb.AppendLine("Filter Mode: Point "); break;
|
|
||||||
case 1: sb.AppendLine("Filter Mode: Bilinear "); break;
|
|
||||||
case 2: sb.AppendLine("Filter Mode: Trilinear "); break;
|
|
||||||
}
|
|
||||||
sb.AppendLine($"Anisotropic level: {m_Texture2D.m_TextureSettings.m_Aniso}");
|
|
||||||
sb.AppendLine($"Mip map bias: {m_Texture2D.m_TextureSettings.m_MipBias}");
|
|
||||||
switch (m_Texture2D.m_TextureSettings.m_WrapMode)
|
|
||||||
{
|
|
||||||
case 0: sb.AppendLine($"Wrap mode: Repeat"); break;
|
|
||||||
case 1: sb.AppendLine($"Wrap mode: Clamp"); break;
|
|
||||||
}
|
|
||||||
debugLog += sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
var image = m_Texture2D.ConvertToImage(flip: true);
|
|
||||||
if (image == null)
|
|
||||||
{
|
|
||||||
Logger.Warning($"Failed to convert texture \"{m_Texture2D.m_Name}\" into image");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
using (image)
|
|
||||||
{
|
|
||||||
using (var file = File.OpenWrite(exportFullPath))
|
|
||||||
{
|
|
||||||
image.WriteToStream(file, type);
|
|
||||||
}
|
|
||||||
debugLog += $"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!TryExportFile(exportPath, item, ".tex", out var exportFullPath))
|
|
||||||
return false;
|
|
||||||
File.WriteAllBytes(exportFullPath, m_Texture2D.image_data.GetData());
|
|
||||||
debugLog += $"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ExportSprite(AssetItem item, string exportPath, out string debugLog)
|
|
||||||
{
|
|
||||||
debugLog = "";
|
|
||||||
var type = Properties.Settings.Default.convertType;
|
|
||||||
var spriteMaskMode = Properties.Settings.Default.exportSpriteWithMask ? SpriteMaskMode.Export : SpriteMaskMode.Off;
|
|
||||||
if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath))
|
|
||||||
return false;
|
|
||||||
var image = ((Sprite)item.Asset).GetImage(spriteMaskMode: spriteMaskMode);
|
|
||||||
if (image != null)
|
|
||||||
{
|
|
||||||
using (image)
|
|
||||||
{
|
|
||||||
using (var file = File.OpenWrite(exportFullPath))
|
|
||||||
{
|
|
||||||
image.WriteToStream(file, type);
|
|
||||||
}
|
|
||||||
debugLog += $"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ExportAudioClip(AssetItem item, string exportPath, out string debugLog)
|
|
||||||
{
|
|
||||||
debugLog = "";
|
|
||||||
string exportFullPath;
|
|
||||||
var m_AudioClip = (AudioClip)item.Asset;
|
|
||||||
var m_AudioData = BigArrayPool<byte>.Shared.Rent(m_AudioClip.m_AudioData.Size);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m_AudioClip.m_AudioData.GetData(m_AudioData);
|
|
||||||
if (m_AudioData == null || m_AudioData.Length == 0)
|
|
||||||
{
|
|
||||||
Logger.Warning($"Failed to export \"{item.Text}\": AudioData was not found");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var converter = new AudioClipConverter(m_AudioClip);
|
|
||||||
if (Properties.Settings.Default.convertAudio && converter.IsSupport)
|
|
||||||
{
|
|
||||||
if (!TryExportFile(exportPath, item, ".wav", out exportFullPath))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (GUILogger.ShowDebugMessage)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine($"Converting {item.TypeString} \"{m_AudioClip.m_Name}\" to wav..");
|
|
||||||
sb.AppendLine(m_AudioClip.version < 5
|
|
||||||
? $"AudioClip type: {m_AudioClip.m_Type}"
|
|
||||||
: $"AudioClip compression format: {m_AudioClip.m_CompressionFormat}");
|
|
||||||
sb.AppendLine($"AudioClip channel count: {m_AudioClip.m_Channels}");
|
|
||||||
sb.AppendLine($"AudioClip sample rate: {m_AudioClip.m_Frequency}");
|
|
||||||
sb.AppendLine($"AudioClip bit depth: {m_AudioClip.m_BitsPerSample}");
|
|
||||||
debugLog += sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
var buffer = converter.ConvertToWav(m_AudioData, out var debugLogConverter);
|
|
||||||
debugLog += debugLogConverter;
|
|
||||||
if (buffer == null)
|
|
||||||
{
|
|
||||||
Logger.Warning($"{debugLog}Failed to export \"{item.Text}\": Failed to convert fmod audio to Wav");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
File.WriteAllBytes(exportFullPath, buffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!TryExportFile(exportPath, item, converter.GetExtensionName(), out exportFullPath))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (GUILogger.ShowDebugMessage)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine($"Exporting non-fmod {item.TypeString} \"{m_AudioClip.m_Name}\"..");
|
|
||||||
sb.AppendLine(m_AudioClip.version < 5
|
|
||||||
? $"AudioClip type: {m_AudioClip.m_Type}"
|
|
||||||
: $"AudioClip compression format: {m_AudioClip.m_CompressionFormat}");
|
|
||||||
sb.AppendLine($"AudioClip channel count: {m_AudioClip.m_Channels}");
|
|
||||||
sb.AppendLine($"AudioClip sample rate: {m_AudioClip.m_Frequency}");
|
|
||||||
sb.AppendLine($"AudioClip bit depth: {m_AudioClip.m_BitsPerSample}");
|
|
||||||
debugLog += sb.ToString();
|
|
||||||
}
|
|
||||||
File.WriteAllBytes(exportFullPath, m_AudioData);
|
|
||||||
}
|
|
||||||
debugLog += $"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\"";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
BigArrayPool<byte>.Shared.Return(m_AudioData, clearArray: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool TryExportFile(string dir, AssetItem item, string extension, out string fullPath)
|
|
||||||
{
|
|
||||||
var fileName = FixFileName(item.Text);
|
|
||||||
var filenameFormatIndex = Properties.Settings.Default.filenameFormat;
|
|
||||||
switch (filenameFormatIndex)
|
|
||||||
{
|
|
||||||
case 1: //assetName@pathID
|
|
||||||
fileName = $"{fileName} @{item.m_PathID}";
|
|
||||||
break;
|
|
||||||
case 2: //pathID
|
|
||||||
fileName = item.m_PathID.ToString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fullPath = Path.Combine(dir, fileName + extension);
|
|
||||||
if (savePathHash.TryAdd(fullPath.ToLower(), true) && !File.Exists(fullPath))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(dir);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (filenameFormatIndex == 0) //assetName
|
|
||||||
{
|
|
||||||
fullPath = Path.Combine(dir, fileName + item.UniqueID + extension);
|
|
||||||
if (!File.Exists(fullPath))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(dir);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Logger.Warning($"Export failed. File \"{fullPath.Color(ColorConsole.BrightYellow)}\" already exist");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ParallelExportConvertFile(AssetItem item, string exportPath, out string debugLog)
|
|
||||||
{
|
|
||||||
switch (item.Type)
|
|
||||||
{
|
|
||||||
case ClassIDType.Texture2D:
|
|
||||||
case ClassIDType.Texture2DArrayImage:
|
|
||||||
return ExportTexture2D(item, exportPath, out debugLog);
|
|
||||||
case ClassIDType.Sprite:
|
|
||||||
return ExportSprite(item, exportPath, out debugLog);
|
|
||||||
case ClassIDType.AudioClip:
|
|
||||||
return ExportAudioClip(item, exportPath, out debugLog);
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FixFileName(string str)
|
|
||||||
{
|
|
||||||
return str.Length >= 260
|
|
||||||
? Path.GetRandomFileName()
|
|
||||||
: Path.GetInvalidFileNameChars().Aggregate(str, (current, c) => current.Replace(c, '_'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ClearHash()
|
|
||||||
{
|
|
||||||
savePathHash.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
122
AssetStudioGUI/Properties/Settings.Designer.cs
generated
122
AssetStudioGUI/Properties/Settings.Designer.cs
generated
@@ -12,7 +12,7 @@ namespace AssetStudioGUI.Properties {
|
|||||||
|
|
||||||
|
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.9.0.0")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.8.0.0")]
|
||||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
@@ -287,6 +287,78 @@ namespace AssetStudioGUI.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||||
|
public bool fixFaceSpriteNames {
|
||||||
|
get {
|
||||||
|
return ((bool)(this["fixFaceSpriteNames"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["fixFaceSpriteNames"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||||
|
public bool useExternalAlpha {
|
||||||
|
get {
|
||||||
|
return ((bool)(this["useExternalAlpha"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["useExternalAlpha"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||||
|
public bool addAliases {
|
||||||
|
get {
|
||||||
|
return ((bool)(this["addAliases"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["addAliases"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("3")]
|
||||||
|
public int resamplerIndex {
|
||||||
|
get {
|
||||||
|
return ((int)(this["resamplerIndex"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["resamplerIndex"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||||
|
public bool resizedOnly {
|
||||||
|
get {
|
||||||
|
return ((bool)(this["resizedOnly"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["resizedOnly"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("2")]
|
||||||
|
public int alphaMaskGamma {
|
||||||
|
get {
|
||||||
|
return ((int)(this["alphaMaskGamma"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["alphaMaskGamma"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
[global::System.Configuration.DefaultSettingValueAttribute("MonoBehaviour")]
|
[global::System.Configuration.DefaultSettingValueAttribute("MonoBehaviour")]
|
||||||
@@ -346,53 +418,5 @@ namespace AssetStudioGUI.Properties {
|
|||||||
this["buildTreeStructure"] = value;
|
this["buildTreeStructure"] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
|
||||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
|
||||||
public int filenameFormat {
|
|
||||||
get {
|
|
||||||
return ((int)(this["filenameFormat"]));
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
this["filenameFormat"] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
|
||||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
|
||||||
public bool parallelExport {
|
|
||||||
get {
|
|
||||||
return ((bool)(this["parallelExport"]));
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
this["parallelExport"] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
|
||||||
[global::System.Configuration.DefaultSettingValueAttribute("-1")]
|
|
||||||
public int parallelExportCount {
|
|
||||||
get {
|
|
||||||
return ((int)(this["parallelExportCount"]));
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
this["parallelExportCount"] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
|
||||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
|
||||||
public bool useTypetreeLoading {
|
|
||||||
get {
|
|
||||||
return ((bool)(this["useTypetreeLoading"]));
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
this["useTypetreeLoading"] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,24 @@
|
|||||||
<Setting Name="exportSpriteWithMask" Type="System.Boolean" Scope="User">
|
<Setting Name="exportSpriteWithMask" Type="System.Boolean" Scope="User">
|
||||||
<Value Profile="(Default)">True</Value>
|
<Value Profile="(Default)">True</Value>
|
||||||
</Setting>
|
</Setting>
|
||||||
|
<Setting Name="fixFaceSpriteNames" Type="System.Boolean" Scope="User">
|
||||||
|
<Value Profile="(Default)">True</Value>
|
||||||
|
</Setting>
|
||||||
|
<Setting Name="useExternalAlpha" Type="System.Boolean" Scope="User">
|
||||||
|
<Value Profile="(Default)">True</Value>
|
||||||
|
</Setting>
|
||||||
|
<Setting Name="addAliases" Type="System.Boolean" Scope="User">
|
||||||
|
<Value Profile="(Default)">False</Value>
|
||||||
|
</Setting>
|
||||||
|
<Setting Name="resamplerIndex" Type="System.Int32" Scope="User">
|
||||||
|
<Value Profile="(Default)">3</Value>
|
||||||
|
</Setting>
|
||||||
|
<Setting Name="resizedOnly" Type="System.Boolean" Scope="User">
|
||||||
|
<Value Profile="(Default)">True</Value>
|
||||||
|
</Setting>
|
||||||
|
<Setting Name="alphaMaskGamma" Type="System.Int32" Scope="User">
|
||||||
|
<Value Profile="(Default)">2</Value>
|
||||||
|
</Setting>
|
||||||
<Setting Name="l2dMotionMode" Type="CubismLive2DExtractor.Live2DMotionMode" Scope="User">
|
<Setting Name="l2dMotionMode" Type="CubismLive2DExtractor.Live2DMotionMode" Scope="User">
|
||||||
<Value Profile="(Default)">MonoBehaviour</Value>
|
<Value Profile="(Default)">MonoBehaviour</Value>
|
||||||
</Setting>
|
</Setting>
|
||||||
@@ -83,17 +101,5 @@
|
|||||||
<Setting Name="buildTreeStructure" Type="System.Boolean" Scope="User">
|
<Setting Name="buildTreeStructure" Type="System.Boolean" Scope="User">
|
||||||
<Value Profile="(Default)">True</Value>
|
<Value Profile="(Default)">True</Value>
|
||||||
</Setting>
|
</Setting>
|
||||||
<Setting Name="filenameFormat" Type="System.Int32" Scope="User">
|
|
||||||
<Value Profile="(Default)">0</Value>
|
|
||||||
</Setting>
|
|
||||||
<Setting Name="parallelExport" Type="System.Boolean" Scope="User">
|
|
||||||
<Value Profile="(Default)">True</Value>
|
|
||||||
</Setting>
|
|
||||||
<Setting Name="parallelExportCount" Type="System.Int32" Scope="User">
|
|
||||||
<Value Profile="(Default)">-1</Value>
|
|
||||||
</Setting>
|
|
||||||
<Setting Name="useTypetreeLoading" Type="System.Boolean" Scope="User">
|
|
||||||
<Value Profile="(Default)">True</Value>
|
|
||||||
</Setting>
|
|
||||||
</Settings>
|
</Settings>
|
||||||
</SettingsFile>
|
</SettingsFile>
|
||||||
@@ -1,17 +1,15 @@
|
|||||||
using AssetStudio;
|
using AssetStudio;
|
||||||
using CubismLive2DExtractor;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using static AssetStudioGUI.Exporter;
|
using static AssetStudioGUI.Exporter;
|
||||||
|
using static CubismLive2DExtractor.Live2DExtractor;
|
||||||
using Object = AssetStudio.Object;
|
using Object = AssetStudio.Object;
|
||||||
|
|
||||||
namespace AssetStudioGUI
|
namespace AssetStudioGUI
|
||||||
@@ -30,15 +28,6 @@ namespace AssetStudioGUI
|
|||||||
Filtered
|
Filtered
|
||||||
}
|
}
|
||||||
|
|
||||||
internal enum ExportL2DFilter
|
|
||||||
{
|
|
||||||
All,
|
|
||||||
Selected,
|
|
||||||
SelectedWithFadeList,
|
|
||||||
SelectedWithFade,
|
|
||||||
SelectedWithClips,
|
|
||||||
}
|
|
||||||
|
|
||||||
internal enum ExportListType
|
internal enum ExportListType
|
||||||
{
|
{
|
||||||
XML
|
XML
|
||||||
@@ -49,8 +38,7 @@ namespace AssetStudioGUI
|
|||||||
TypeName,
|
TypeName,
|
||||||
ContainerPath,
|
ContainerPath,
|
||||||
ContainerPathFull,
|
ContainerPathFull,
|
||||||
SourceFileName,
|
SourceFileName
|
||||||
SceneHierarchy,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal enum ListSearchFilterMode
|
internal enum ListSearchFilterMode
|
||||||
@@ -61,24 +49,13 @@ namespace AssetStudioGUI
|
|||||||
RegexContainer,
|
RegexContainer,
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
|
||||||
internal enum SelectedAssetType
|
|
||||||
{
|
|
||||||
Animator = 0x01,
|
|
||||||
AnimationClip = 0x02,
|
|
||||||
MonoBehaviourMoc = 0x04,
|
|
||||||
MonoBehaviourFade = 0x08,
|
|
||||||
MonoBehaviourFadeLst = 0x10
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static class Studio
|
internal static class Studio
|
||||||
{
|
{
|
||||||
public static AssetsManager assetsManager = new AssetsManager();
|
public static AssetsManager assetsManager = new AssetsManager();
|
||||||
public static AssemblyLoader assemblyLoader = new AssemblyLoader();
|
public static AssemblyLoader assemblyLoader = new AssemblyLoader();
|
||||||
public static List<AssetItem> exportableAssets = new List<AssetItem>();
|
public static List<AssetItem> exportableAssets = new List<AssetItem>();
|
||||||
public static List<AssetItem> visibleAssets = new List<AssetItem>();
|
public static List<AssetItem> visibleAssets = new List<AssetItem>();
|
||||||
public static List<MonoBehaviour> cubismMocList = new List<MonoBehaviour>();
|
private static Dictionary<Object, string> allContainers = new Dictionary<Object, string>();
|
||||||
private static Dictionary<Object, string> l2dResourceContainers = new Dictionary<Object, string>();
|
|
||||||
internal static Action<string> StatusStripUpdate = x => { };
|
internal static Action<string> StatusStripUpdate = x => { };
|
||||||
|
|
||||||
public static int ExtractFolder(string path, string savePath)
|
public static int ExtractFolder(string path, string savePath)
|
||||||
@@ -126,7 +103,7 @@ namespace AssetStudioGUI
|
|||||||
private static int ExtractBundleFile(FileReader reader, string savePath)
|
private static int ExtractBundleFile(FileReader reader, string savePath)
|
||||||
{
|
{
|
||||||
Logger.Info($"Decompressing {reader.FileName} ...");
|
Logger.Info($"Decompressing {reader.FileName} ...");
|
||||||
var bundleFile = new BundleFile(reader, assetsManager.ZstdEnabled, assetsManager.SpecifyUnityVersion);
|
var bundleFile = new BundleFile(reader, assetsManager.SpecifyUnityVersion);
|
||||||
reader.Dispose();
|
reader.Dispose();
|
||||||
if (bundleFile.fileList.Length > 0)
|
if (bundleFile.fileList.Length > 0)
|
||||||
{
|
{
|
||||||
@@ -181,8 +158,7 @@ namespace AssetStudioGUI
|
|||||||
var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
|
var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
|
||||||
var objectAssetItemDic = new Dictionary<Object, AssetItem>(objectCount);
|
var objectAssetItemDic = new Dictionary<Object, AssetItem>(objectCount);
|
||||||
var containers = new List<(PPtr<Object>, string)>();
|
var containers = new List<(PPtr<Object>, string)>();
|
||||||
var tex2dArrayAssetList = new List<AssetItem>();
|
allContainers.Clear();
|
||||||
l2dResourceContainers.Clear();
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
Progress.Reset();
|
Progress.Reset();
|
||||||
foreach (var assetsFile in assetsManager.assetsFileList)
|
foreach (var assetsFile in assetsManager.assetsFileList)
|
||||||
@@ -209,13 +185,6 @@ namespace AssetStudioGUI
|
|||||||
assetItem.Text = m_Texture2D.m_Name;
|
assetItem.Text = m_Texture2D.m_Name;
|
||||||
exportable = true;
|
exportable = true;
|
||||||
break;
|
break;
|
||||||
case Texture2DArray m_Texture2DArray:
|
|
||||||
if (!string.IsNullOrEmpty(m_Texture2DArray.m_StreamData?.path))
|
|
||||||
assetItem.FullSize = asset.byteSize + m_Texture2DArray.m_StreamData.size;
|
|
||||||
assetItem.Text = m_Texture2DArray.m_Name;
|
|
||||||
tex2dArrayAssetList.Add(assetItem);
|
|
||||||
exportable = true;
|
|
||||||
break;
|
|
||||||
case AudioClip m_AudioClip:
|
case AudioClip m_AudioClip:
|
||||||
if (!string.IsNullOrEmpty(m_AudioClip.m_Source))
|
if (!string.IsNullOrEmpty(m_AudioClip.m_Source))
|
||||||
assetItem.FullSize = asset.byteSize + m_AudioClip.m_Size;
|
assetItem.FullSize = asset.byteSize + m_AudioClip.m_Size;
|
||||||
@@ -249,16 +218,14 @@ namespace AssetStudioGUI
|
|||||||
exportable = true;
|
exportable = true;
|
||||||
break;
|
break;
|
||||||
case MonoBehaviour m_MonoBehaviour:
|
case MonoBehaviour m_MonoBehaviour:
|
||||||
var assetName = m_MonoBehaviour.m_Name;
|
if (m_MonoBehaviour.m_Name == "" && m_MonoBehaviour.m_Script.TryGet(out var m_Script))
|
||||||
if (m_MonoBehaviour.m_Script.TryGet(out var m_Script))
|
|
||||||
{
|
{
|
||||||
assetName = assetName == "" ? m_Script.m_ClassName : assetName;
|
assetItem.Text = m_Script.m_ClassName;
|
||||||
if (m_Script.m_ClassName == "CubismMoc")
|
}
|
||||||
{
|
else
|
||||||
cubismMocList.Add(m_MonoBehaviour);
|
{
|
||||||
}
|
assetItem.Text = m_MonoBehaviour.m_Name;
|
||||||
}
|
}
|
||||||
assetItem.Text = assetName;
|
|
||||||
exportable = true;
|
exportable = true;
|
||||||
break;
|
break;
|
||||||
case PlayerSettings m_PlayerSettings:
|
case PlayerSettings m_PlayerSettings:
|
||||||
@@ -308,32 +275,18 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
if (pptr.TryGet(out var obj))
|
if (pptr.TryGet(out var obj))
|
||||||
{
|
{
|
||||||
objectAssetItemDic[obj].Container = container;
|
var asset = objectAssetItemDic[obj];
|
||||||
switch (obj)
|
asset.Container = container;
|
||||||
{
|
allContainers[obj] = container;
|
||||||
case AnimationClip _:
|
|
||||||
case GameObject _:
|
|
||||||
case Texture2D _:
|
|
||||||
case MonoBehaviour _:
|
|
||||||
l2dResourceContainers[obj] = container;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach (var tex2dAssetItem in tex2dArrayAssetList)
|
|
||||||
{
|
|
||||||
var m_Texture2DArray = (Texture2DArray)tex2dAssetItem.Asset;
|
|
||||||
for (var layer = 0; layer < m_Texture2DArray.m_Depth; layer++)
|
|
||||||
{
|
|
||||||
var fakeObj = new Texture2D(m_Texture2DArray, layer);
|
|
||||||
m_Texture2DArray.TextureList.Add(fakeObj);
|
|
||||||
|
|
||||||
var fakeItem = new AssetItem(fakeObj)
|
if (asset.Type == ClassIDType.MonoBehaviour && container.Contains("/arts/charportraits/portraits"))
|
||||||
{
|
{
|
||||||
Text = fakeObj.m_Name,
|
var portraitsList = Arknights.AkSpriteHelper.GeneratePortraits(asset);
|
||||||
Container = tex2dAssetItem.Container
|
foreach (var portrait in portraitsList)
|
||||||
};
|
{
|
||||||
exportableAssets.Add(fakeItem);
|
exportableAssets.Add(new AssetItem(portrait));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var tmp in exportableAssets)
|
foreach (var tmp in exportableAssets)
|
||||||
@@ -341,7 +294,6 @@ namespace AssetStudioGUI
|
|||||||
tmp.SetSubItems();
|
tmp.SetSubItems();
|
||||||
}
|
}
|
||||||
containers.Clear();
|
containers.Clear();
|
||||||
tex2dArrayAssetList.Clear();
|
|
||||||
|
|
||||||
visibleAssets = exportableAssets;
|
visibleAssets = exportableAssets;
|
||||||
|
|
||||||
@@ -412,6 +364,7 @@ namespace AssetStudioGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parentNode.Nodes.Add(currentNode);
|
parentNode.Nodes.Add(currentNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -470,21 +423,12 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
|
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
|
||||||
|
|
||||||
var groupOption = (AssetGroupOption)Properties.Settings.Default.assetGroupOption;
|
int toExportCount = toExportAssets.Count;
|
||||||
var parallelExportCount = Properties.Settings.Default.parallelExportCount <= 0
|
int exportedCount = 0;
|
||||||
? Environment.ProcessorCount - 1
|
int i = 0;
|
||||||
: Math.Min(Properties.Settings.Default.parallelExportCount, Environment.ProcessorCount - 1);
|
|
||||||
parallelExportCount = Properties.Settings.Default.parallelExport ? parallelExportCount : 1;
|
|
||||||
var toExportAssetDict = new ConcurrentDictionary<AssetItem, string>();
|
|
||||||
var toParallelExportAssetDict = new ConcurrentDictionary<AssetItem, string>();
|
|
||||||
var exceptionMsgs = new ConcurrentDictionary<Exception, string>();
|
|
||||||
var mode = exportType == ExportType.Dump ? "Dump" : "Export";
|
|
||||||
var toExportCount = toExportAssets.Count;
|
|
||||||
var exportedCount = 0;
|
|
||||||
var i = 0;
|
|
||||||
Progress.Reset();
|
Progress.Reset();
|
||||||
|
var groupOption = (AssetGroupOption)Properties.Settings.Default.assetGroupOption;
|
||||||
Parallel.ForEach(toExportAssets, asset =>
|
foreach (var asset in toExportAssets)
|
||||||
{
|
{
|
||||||
string exportPath;
|
string exportPath;
|
||||||
switch (groupOption)
|
switch (groupOption)
|
||||||
@@ -517,146 +461,52 @@ namespace AssetStudioGUI
|
|||||||
exportPath = Path.Combine(savePath, Path.GetFileName(asset.SourceFile.originalPath) + "_export", asset.SourceFile.fileName);
|
exportPath = Path.Combine(savePath, Path.GetFileName(asset.SourceFile.originalPath) + "_export", asset.SourceFile.fileName);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AssetGroupOption.SceneHierarchy:
|
|
||||||
if (asset.TreeNode != null)
|
|
||||||
{
|
|
||||||
exportPath = Path.Combine(savePath, asset.TreeNode.FullPath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
exportPath = Path.Combine(savePath, "_sceneRoot", asset.TypeString);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
exportPath = savePath;
|
exportPath = savePath;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
exportPath += Path.DirectorySeparatorChar;
|
exportPath += Path.DirectorySeparatorChar;
|
||||||
|
Logger.Info($"[{exportedCount + 1}/{toExportCount}] Exporting {asset.TypeString}: {asset.Text}");
|
||||||
if (exportType == ExportType.Convert)
|
|
||||||
{
|
|
||||||
switch (asset.Type)
|
|
||||||
{
|
|
||||||
case ClassIDType.Texture2D:
|
|
||||||
case ClassIDType.Texture2DArrayImage:
|
|
||||||
case ClassIDType.Sprite:
|
|
||||||
case ClassIDType.AudioClip:
|
|
||||||
toParallelExportAssetDict.TryAdd(asset, exportPath);
|
|
||||||
break;
|
|
||||||
case ClassIDType.Texture2DArray:
|
|
||||||
var m_Texture2DArray = (Texture2DArray)asset.Asset;
|
|
||||||
toExportCount += m_Texture2DArray.TextureList.Count - 1;
|
|
||||||
foreach (var texture in m_Texture2DArray.TextureList)
|
|
||||||
{
|
|
||||||
var fakeItem = new AssetItem(texture)
|
|
||||||
{
|
|
||||||
Text = texture.m_Name,
|
|
||||||
Container = asset.Container,
|
|
||||||
};
|
|
||||||
toParallelExportAssetDict.TryAdd(fakeItem, exportPath);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
toExportAssetDict.TryAdd(asset, exportPath);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
toExportAssetDict.TryAdd(asset, exportPath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
foreach (var toExportAsset in toExportAssetDict)
|
|
||||||
{
|
|
||||||
var asset = toExportAsset.Key;
|
|
||||||
var exportPath = toExportAsset.Value;
|
|
||||||
var isExported = false;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.Info($"[{exportedCount + 1}/{toExportCount}] {mode}ing {asset.TypeString}: {asset.Text}");
|
|
||||||
switch (exportType)
|
switch (exportType)
|
||||||
{
|
{
|
||||||
case ExportType.Raw:
|
case ExportType.Raw:
|
||||||
isExported = ExportRawFile(asset, exportPath);
|
if (ExportRawFile(asset, exportPath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ExportType.Dump:
|
case ExportType.Dump:
|
||||||
isExported = ExportDumpFile(asset, exportPath);
|
if (ExportDumpFile(asset, exportPath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ExportType.Convert:
|
case ExportType.Convert:
|
||||||
isExported = ExportConvertFile(asset, exportPath);
|
if (ExportConvertFile(asset, exportPath))
|
||||||
|
{
|
||||||
|
exportedCount++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.Error($"{mode} {asset.TypeString}: {asset.Text} error", ex);
|
Logger.Error($"Export {asset.Type}:{asset.Text} error", ex);
|
||||||
}
|
|
||||||
|
|
||||||
if (isExported)
|
|
||||||
{
|
|
||||||
exportedCount++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger.Warning($"Unable to {mode.ToLower()} {asset.TypeString}: {asset.Text}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Progress.Report(++i, toExportCount);
|
Progress.Report(++i, toExportCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
Parallel.ForEach(toParallelExportAssetDict, new ParallelOptions { MaxDegreeOfParallelism = parallelExportCount }, (toExportAsset, loopState) =>
|
var statusText = exportedCount == 0 ? "Nothing exported." : $"Finished exporting {exportedCount} assets.";
|
||||||
{
|
|
||||||
var asset = toExportAsset.Key;
|
|
||||||
var exportPath = toExportAsset.Value;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (ParallelExporter.ParallelExportConvertFile(asset, exportPath, out var debugLog))
|
|
||||||
{
|
|
||||||
Interlocked.Increment(ref exportedCount);
|
|
||||||
if (GUILogger.ShowDebugMessage)
|
|
||||||
{
|
|
||||||
Logger.Debug(debugLog);
|
|
||||||
StatusStripUpdate($"[{exportedCount}/{toExportCount}] Exporting {asset.TypeString}: {asset.Text}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger.Info($"[{exportedCount}/{toExportCount}] Exporting {asset.TypeString}: {asset.Text}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Interlocked.Increment(ref i);
|
|
||||||
Progress.Report(i, toExportCount);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (parallelExportCount == 1)
|
|
||||||
{
|
|
||||||
Logger.Error($"{mode} {asset.TypeString}: {asset.Text} error", ex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
loopState.Break();
|
|
||||||
exceptionMsgs.TryAdd(ex, $"Exception occurred when exporting {asset.TypeString}: {asset.Text}\n{ex}\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
ParallelExporter.ClearHash();
|
|
||||||
|
|
||||||
foreach (var ex in exceptionMsgs)
|
|
||||||
{
|
|
||||||
Logger.Error(ex.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
var statusText = exportedCount == 0 ? "Nothing exported." : $"Finished {mode.ToLower()}ing [{exportedCount}/{toExportCount}] assets.";
|
|
||||||
if (toExportCount > exportedCount)
|
if (toExportCount > exportedCount)
|
||||||
{
|
{
|
||||||
statusText += exceptionMsgs.IsEmpty
|
statusText += $" {toExportCount - exportedCount} assets skipped (not extractable or files already exist)";
|
||||||
? $" {toExportCount - exportedCount} assets skipped (not extractable or files already exist)."
|
|
||||||
: " Export process was stopped because one or more exceptions occurred.";
|
|
||||||
Progress.Report(toExportCount, toExportCount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Info(statusText);
|
Logger.Info(statusText);
|
||||||
exceptionMsgs.Clear();
|
|
||||||
|
|
||||||
if (Properties.Settings.Default.openAfterExport && exportedCount > 0)
|
if (Properties.Settings.Default.openAfterExport && exportedCount > 0)
|
||||||
{
|
{
|
||||||
@@ -688,7 +538,6 @@ namespace AssetStudioGUI
|
|||||||
new XElement("Type", new XAttribute("id", (int)asset.Type), asset.TypeString),
|
new XElement("Type", new XAttribute("id", (int)asset.Type), asset.TypeString),
|
||||||
new XElement("PathID", asset.m_PathID),
|
new XElement("PathID", asset.m_PathID),
|
||||||
new XElement("Source", asset.SourceFile.fullName),
|
new XElement("Source", asset.SourceFile.fullName),
|
||||||
new XElement("TreeNode", asset.TreeNode != null ? asset.TreeNode.FullPath : ""),
|
|
||||||
new XElement("Size", asset.FullSize)
|
new XElement("Size", asset.FullSize)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -700,11 +549,11 @@ namespace AssetStudioGUI
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var statusText = $"Finished exporting asset list with {toExportAssets.Count} items.";
|
var statusText = $"Finished exporting asset list with {toExportAssets.Count()} items.";
|
||||||
|
|
||||||
Logger.Info(statusText);
|
Logger.Info(statusText);
|
||||||
|
|
||||||
if (Properties.Settings.Default.openAfterExport && toExportAssets.Count > 0)
|
if (Properties.Settings.Default.openAfterExport && toExportAssets.Count() > 0)
|
||||||
{
|
{
|
||||||
OpenFolderInExplorer(savePath);
|
OpenFolderInExplorer(savePath);
|
||||||
}
|
}
|
||||||
@@ -787,7 +636,6 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
Progress.Reset();
|
Progress.Reset();
|
||||||
Logger.Info($"Exporting {animator.Text}");
|
Logger.Info($"Exporting {animator.Text}");
|
||||||
Logger.Debug($"Selected AnimationClip(s):\n\"{string.Join("\"\n\"", animationList.Select(x => x.Text))}\"");
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ExportAnimator(animator, exportPath, animationList);
|
ExportAnimator(animator, exportPath, animationList);
|
||||||
@@ -886,12 +734,6 @@ namespace AssetStudioGUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static TypeTree MonoBehaviourToTypeTree(MonoBehaviour m_MonoBehaviour)
|
public static TypeTree MonoBehaviourToTypeTree(MonoBehaviour m_MonoBehaviour)
|
||||||
{
|
|
||||||
SelectAssemblyFolder();
|
|
||||||
return m_MonoBehaviour.ConvertToTypeTree(assemblyLoader);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SelectAssemblyFolder()
|
|
||||||
{
|
{
|
||||||
if (!assemblyLoader.Loaded)
|
if (!assemblyLoader.Loaded)
|
||||||
{
|
{
|
||||||
@@ -906,20 +748,17 @@ namespace AssetStudioGUI
|
|||||||
assemblyLoader.Loaded = true;
|
assemblyLoader.Loaded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return m_MonoBehaviour.ConvertToTypeTree(assemblyLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string DumpAsset(Object obj)
|
public static string DumpAsset(Object obj)
|
||||||
{
|
{
|
||||||
var str = obj.Dump();
|
var str = obj?.Dump();
|
||||||
if (str == null && obj is MonoBehaviour m_MonoBehaviour)
|
if (str == null && obj is MonoBehaviour m_MonoBehaviour)
|
||||||
{
|
{
|
||||||
var type = MonoBehaviourToTypeTree(m_MonoBehaviour);
|
var type = MonoBehaviourToTypeTree(m_MonoBehaviour);
|
||||||
str = m_MonoBehaviour.Dump(type);
|
str = m_MonoBehaviour.Dump(type);
|
||||||
}
|
}
|
||||||
if (string.IsNullOrEmpty(str))
|
|
||||||
{
|
|
||||||
str = obj.DumpObject();
|
|
||||||
}
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -930,70 +769,56 @@ namespace AssetStudioGUI
|
|||||||
Process.Start(info);
|
Process.Start(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ExportLive2D(string exportPath, List<MonoBehaviour> selMocs = null, List<AnimationClip> selClipMotions = null, List<MonoBehaviour> selFadeMotions = null, MonoBehaviour selFadeLst = null)
|
public static void ExportLive2D(Object[] cubismMocs, string exportPath)
|
||||||
{
|
{
|
||||||
var baseDestPath = Path.Combine(exportPath, "Live2DOutput");
|
var baseDestPath = Path.Combine(exportPath, "Live2DOutput");
|
||||||
var forceBezier = Properties.Settings.Default.l2dForceBezier;
|
|
||||||
var mocList = selMocs ?? cubismMocList;
|
|
||||||
var motionMode = Properties.Settings.Default.l2dMotionMode;
|
var motionMode = Properties.Settings.Default.l2dMotionMode;
|
||||||
if (selClipMotions != null)
|
var forceBezier = Properties.Settings.Default.l2dForceBezier;
|
||||||
motionMode = Live2DMotionMode.AnimationClipV2;
|
|
||||||
else if (selFadeMotions != null || selFadeLst != null)
|
|
||||||
motionMode = Live2DMotionMode.MonoBehaviour;
|
|
||||||
|
|
||||||
ThreadPool.QueueUserWorkItem(state =>
|
ThreadPool.QueueUserWorkItem(state =>
|
||||||
{
|
{
|
||||||
Logger.Info($"Searching for Live2D files...");
|
Logger.Info($"Searching for Live2D files...");
|
||||||
|
|
||||||
var mocPathDict = new Dictionary<MonoBehaviour, (string, string)>();
|
var useFullContainerPath = false;
|
||||||
var mocPathList = new List<string>();
|
if (cubismMocs.Length > 1)
|
||||||
foreach (var mocMonoBehaviour in cubismMocList)
|
|
||||||
{
|
{
|
||||||
if (!l2dResourceContainers.TryGetValue(mocMonoBehaviour, out var fullContainerPath))
|
var basePathSet = cubismMocs.Select(x =>
|
||||||
continue;
|
{
|
||||||
|
var pathLen = allContainers.TryGetValue(x, out var itemContainer) ? itemContainer.LastIndexOf("/") : 0;
|
||||||
|
pathLen = pathLen < 0 ? allContainers[x].Length : pathLen;
|
||||||
|
return itemContainer?.Substring(0, pathLen);
|
||||||
|
}).ToHashSet();
|
||||||
|
|
||||||
var pathSepIndex = fullContainerPath.LastIndexOf('/');
|
if (basePathSet.All(x => x == null))
|
||||||
var basePath = pathSepIndex > 0
|
{
|
||||||
? fullContainerPath.Substring(0, pathSepIndex)
|
Logger.Error($"Live2D Cubism export error\r\nCannot find any model related files");
|
||||||
: fullContainerPath;
|
StatusStripUpdate("Live2D export canceled");
|
||||||
mocPathDict.Add(mocMonoBehaviour, (fullContainerPath, basePath));
|
Progress.Reset();
|
||||||
}
|
return;
|
||||||
if (mocPathDict.Count == 0)
|
}
|
||||||
{
|
|
||||||
Logger.Error("Live2D Cubism export error\r\nCannot find any model related files");
|
if (basePathSet.Count != cubismMocs.Length)
|
||||||
StatusStripUpdate("Live2D export canceled");
|
{
|
||||||
Progress.Reset();
|
useFullContainerPath = true;
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var basePathSet = mocPathDict.Values.Select(x => x.Item2).ToHashSet();
|
var basePathList = cubismMocs.Select(x =>
|
||||||
var useFullContainerPath = mocPathDict.Count != basePathSet.Count;
|
|
||||||
foreach (var moc in mocList)
|
|
||||||
{
|
{
|
||||||
var mocPath = useFullContainerPath
|
allContainers.TryGetValue(x, out var container);
|
||||||
? mocPathDict[moc].Item1 //fullContainerPath
|
container = useFullContainerPath
|
||||||
: mocPathDict[moc].Item2; //basePath
|
? container
|
||||||
mocPathList.Add(mocPath);
|
: container?.Substring(0, container.LastIndexOf("/"));
|
||||||
}
|
return container;
|
||||||
mocPathDict.Clear();
|
}).Where(x => x != null).ToList();
|
||||||
|
|
||||||
var lookup = l2dResourceContainers.AsParallel().ToLookup(
|
var lookup = allContainers.ToLookup(
|
||||||
x => mocPathList.Find(b => x.Value.Contains(b) && x.Value.Split('/').Any(y => y == b.Substring(b.LastIndexOf("/") + 1))),
|
x => basePathList.Find(b => x.Value.Contains(b) && x.Value.Split('/').Any(y => y == b.Substring(b.LastIndexOf("/") + 1))),
|
||||||
x => x.Key
|
x => x.Key
|
||||||
);
|
);
|
||||||
|
|
||||||
if (mocList[0].serializedType?.m_Type == null && !assemblyLoader.Loaded)
|
|
||||||
{
|
|
||||||
Logger.Warning("Specifying the assembly folder may be needed for proper extraction");
|
|
||||||
SelectAssemblyFolder();
|
|
||||||
}
|
|
||||||
|
|
||||||
var totalModelCount = lookup.LongCount(x => x.Key != null);
|
var totalModelCount = lookup.LongCount(x => x.Key != null);
|
||||||
var modelCounter = 0;
|
var modelCounter = 0;
|
||||||
var parallelExportCount = Properties.Settings.Default.parallelExportCount <= 0
|
|
||||||
? Environment.ProcessorCount - 1
|
|
||||||
: Math.Min(Properties.Settings.Default.parallelExportCount, Environment.ProcessorCount - 1);
|
|
||||||
parallelExportCount = Properties.Settings.Default.parallelExport ? parallelExportCount : 1;
|
|
||||||
foreach (var assets in lookup)
|
foreach (var assets in lookup)
|
||||||
{
|
{
|
||||||
var srcContainer = assets.Key;
|
var srcContainer = assets.Key;
|
||||||
@@ -1004,16 +829,11 @@ namespace AssetStudioGUI
|
|||||||
Logger.Info($"[{modelCounter + 1}/{totalModelCount}] Exporting Live2D: \"{srcContainer}\"...");
|
Logger.Info($"[{modelCounter + 1}/{totalModelCount}] Exporting Live2D: \"{srcContainer}\"...");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var modelName = useFullContainerPath
|
var modelName = useFullContainerPath ? Path.GetFileNameWithoutExtension(container) : container.Substring(container.LastIndexOf('/') + 1);
|
||||||
? Path.GetFileNameWithoutExtension(container)
|
container = Path.HasExtension(container) ? container.Replace(Path.GetExtension(container), "") : container;
|
||||||
: container.Substring(container.LastIndexOf('/') + 1);
|
|
||||||
container = Path.HasExtension(container)
|
|
||||||
? container.Replace(Path.GetExtension(container), "")
|
|
||||||
: container;
|
|
||||||
var destPath = Path.Combine(baseDestPath, container) + Path.DirectorySeparatorChar;
|
var destPath = Path.Combine(baseDestPath, container) + Path.DirectorySeparatorChar;
|
||||||
|
|
||||||
var modelExtractor = new Live2DExtractor(assets, selClipMotions, selFadeMotions, selFadeLst);
|
ExtractLive2D(assets, destPath, modelName, assemblyLoader, motionMode, forceBezier);
|
||||||
modelExtractor.ExtractCubismModel(destPath, modelName, motionMode, assemblyLoader, forceBezier, parallelExportCount);
|
|
||||||
modelCounter++;
|
modelCounter++;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows;net8.0;net8.0-windows</TargetFrameworks>
|
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows;net8.0;net8.0-windows</TargetFrameworks>
|
||||||
<Version>0.18.0.0</Version>
|
<Version>1.2.0</Version>
|
||||||
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2023-2024</Copyright>
|
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2025</Copyright>
|
||||||
<DebugType>embedded</DebugType>
|
<DebugType>embedded</DebugType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<PackageReference Include="Kyaru.Texture2DDecoder">
|
<PackageReference Include="Kyaru.Texture2DDecoder">
|
||||||
<Version>0.17.0</Version>
|
<Version>0.17.0</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.2" />
|
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
|
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
|
||||||
|
|||||||
@@ -7,37 +7,25 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public class AudioClipConverter
|
public class AudioClipConverter
|
||||||
{
|
{
|
||||||
public bool IsSupport => m_AudioClip.IsConvertSupport();
|
|
||||||
|
|
||||||
private AudioClip m_AudioClip;
|
private AudioClip m_AudioClip;
|
||||||
private static FMOD.System system;
|
|
||||||
|
|
||||||
static AudioClipConverter()
|
|
||||||
{
|
|
||||||
var result = Factory.System_Create(out system);
|
|
||||||
if (result != RESULT.OK)
|
|
||||||
{
|
|
||||||
Logger.Error($"FMOD error! {result} - {Error.String(result)}");
|
|
||||||
}
|
|
||||||
result = system.init(1, INITFLAGS.NORMAL, IntPtr.Zero);
|
|
||||||
if (result != RESULT.OK)
|
|
||||||
{
|
|
||||||
Logger.Error($"FMOD error! {result} - {Error.String(result)}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AudioClipConverter(AudioClip audioClip)
|
public AudioClipConverter(AudioClip audioClip)
|
||||||
{
|
{
|
||||||
m_AudioClip = audioClip;
|
m_AudioClip = audioClip;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] ConvertToWav(byte[] m_AudioData, out string debugLog)
|
public byte[] ConvertToWav(byte[] m_AudioData)
|
||||||
{
|
{
|
||||||
debugLog = "";
|
|
||||||
var exinfo = new CREATESOUNDEXINFO();
|
var exinfo = new CREATESOUNDEXINFO();
|
||||||
|
var result = Factory.System_Create(out var system);
|
||||||
|
if (result != RESULT.OK)
|
||||||
|
return null;
|
||||||
|
result = system.init(1, INITFLAGS.NORMAL, IntPtr.Zero);
|
||||||
|
if (result != RESULT.OK)
|
||||||
|
return null;
|
||||||
exinfo.cbsize = Marshal.SizeOf(exinfo);
|
exinfo.cbsize = Marshal.SizeOf(exinfo);
|
||||||
exinfo.length = (uint)m_AudioClip.m_Size;
|
exinfo.length = (uint)m_AudioClip.m_Size;
|
||||||
var result = system.createSound(m_AudioData, MODE.OPENMEMORY, ref exinfo, out var sound);
|
result = system.createSound(m_AudioData, MODE.OPENMEMORY, ref exinfo, out var sound);
|
||||||
if (result != RESULT.OK)
|
if (result != RESULT.OK)
|
||||||
return null;
|
return null;
|
||||||
result = sound.getNumSubSounds(out var numsubsounds);
|
result = sound.getNumSubSounds(out var numsubsounds);
|
||||||
@@ -49,29 +37,28 @@ namespace AssetStudio
|
|||||||
result = sound.getSubSound(0, out var subsound);
|
result = sound.getSubSound(0, out var subsound);
|
||||||
if (result != RESULT.OK)
|
if (result != RESULT.OK)
|
||||||
return null;
|
return null;
|
||||||
buff = SoundToWav(subsound, out debugLog);
|
buff = SoundToWav(subsound);
|
||||||
subsound.release();
|
subsound.release();
|
||||||
subsound.clearHandle();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buff = SoundToWav(sound, out debugLog);
|
buff = SoundToWav(sound);
|
||||||
}
|
}
|
||||||
sound.release();
|
sound.release();
|
||||||
sound.clearHandle();
|
system.release();
|
||||||
return buff;
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] SoundToWav(Sound sound, out string debugLog)
|
public byte[] SoundToWav(Sound sound)
|
||||||
{
|
{
|
||||||
debugLog = "[Fmod] Detecting sound format..\n";
|
Logger.Debug($"[Fmod] Detecting sound format..\n");
|
||||||
var result = sound.getFormat(out SOUND_TYPE soundType, out SOUND_FORMAT soundFormat, out int channels, out int bits);
|
var result = sound.getFormat(out SOUND_TYPE soundType, out SOUND_FORMAT soundFormat, out int channels, out int bits);
|
||||||
if (result != RESULT.OK)
|
if (result != RESULT.OK)
|
||||||
return null;
|
return null;
|
||||||
debugLog += $"Detected sound type: {soundType}\n" +
|
Logger.Debug($"Detected sound type: {soundType}\n" +
|
||||||
$"Detected sound format: {soundFormat}\n" +
|
$"Detected sound format: {soundFormat}\n" +
|
||||||
$"Detected channels: {channels}\n" +
|
$"Detected channels: {channels}\n" +
|
||||||
$"Detected bit depth: {bits}\n";
|
$"Detected bit depth: {bits}");
|
||||||
result = sound.getDefaults(out var frequency, out _);
|
result = sound.getDefaults(out var frequency, out _);
|
||||||
if (result != RESULT.OK)
|
if (result != RESULT.OK)
|
||||||
return null;
|
return null;
|
||||||
@@ -82,11 +69,11 @@ namespace AssetStudio
|
|||||||
result = sound.@lock(0, length, out var ptr1, out var ptr2, out var len1, out var len2);
|
result = sound.@lock(0, length, out var ptr1, out var ptr2, out var len1, out var len2);
|
||||||
if (result != RESULT.OK)
|
if (result != RESULT.OK)
|
||||||
return null;
|
return null;
|
||||||
var buffer = new byte[len1 + 44];
|
byte[] buffer = new byte[len1 + 44];
|
||||||
//添加wav头
|
//添加wav头
|
||||||
Encoding.ASCII.GetBytes("RIFF").CopyTo(buffer, 0);
|
Encoding.UTF8.GetBytes("RIFF").CopyTo(buffer, 0);
|
||||||
BitConverter.GetBytes(len1 + 36).CopyTo(buffer, 4);
|
BitConverter.GetBytes(len1 + 36).CopyTo(buffer, 4);
|
||||||
Encoding.ASCII.GetBytes("WAVEfmt ").CopyTo(buffer, 8);
|
Encoding.UTF8.GetBytes("WAVEfmt ").CopyTo(buffer, 8);
|
||||||
BitConverter.GetBytes(16).CopyTo(buffer, 16);
|
BitConverter.GetBytes(16).CopyTo(buffer, 16);
|
||||||
BitConverter.GetBytes((short)1).CopyTo(buffer, 20);
|
BitConverter.GetBytes((short)1).CopyTo(buffer, 20);
|
||||||
BitConverter.GetBytes((short)channels).CopyTo(buffer, 22);
|
BitConverter.GetBytes((short)channels).CopyTo(buffer, 22);
|
||||||
@@ -94,7 +81,7 @@ namespace AssetStudio
|
|||||||
BitConverter.GetBytes(sampleRate * channels * bits / 8).CopyTo(buffer, 28);
|
BitConverter.GetBytes(sampleRate * channels * bits / 8).CopyTo(buffer, 28);
|
||||||
BitConverter.GetBytes((short)(channels * bits / 8)).CopyTo(buffer, 32);
|
BitConverter.GetBytes((short)(channels * bits / 8)).CopyTo(buffer, 32);
|
||||||
BitConverter.GetBytes((short)bits).CopyTo(buffer, 34);
|
BitConverter.GetBytes((short)bits).CopyTo(buffer, 34);
|
||||||
Encoding.ASCII.GetBytes("data").CopyTo(buffer, 36);
|
Encoding.UTF8.GetBytes("data").CopyTo(buffer, 36);
|
||||||
BitConverter.GetBytes(len1).CopyTo(buffer, 40);
|
BitConverter.GetBytes(len1).CopyTo(buffer, 40);
|
||||||
Marshal.Copy(ptr1, buffer, 44, (int)len1);
|
Marshal.Copy(ptr1, buffer, 44, (int)len1);
|
||||||
result = sound.unlock(ptr1, ptr2, len1, len2);
|
result = sound.unlock(ptr1, ptr2, len1, len2);
|
||||||
@@ -105,11 +92,11 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public string GetExtensionName()
|
public string GetExtensionName()
|
||||||
{
|
{
|
||||||
if (m_AudioClip.version < 5)
|
if (m_AudioClip.version[0] < 5)
|
||||||
{
|
{
|
||||||
switch (m_AudioClip.m_Type)
|
switch (m_AudioClip.m_Type)
|
||||||
{
|
{
|
||||||
case FMODSoundType.AAC:
|
case FMODSoundType.ACC:
|
||||||
return ".m4a";
|
return ".m4a";
|
||||||
case FMODSoundType.AIFF:
|
case FMODSoundType.AIFF:
|
||||||
return ".aif";
|
return ".aif";
|
||||||
@@ -162,42 +149,43 @@ namespace AssetStudio
|
|||||||
return ".fsb";
|
return ".fsb";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ".AudioClip";
|
return ".AudioClip";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static class AudioClipExtension
|
public bool IsSupport
|
||||||
{
|
|
||||||
public static bool IsConvertSupport(this AudioClip m_AudioClip)
|
|
||||||
{
|
{
|
||||||
if (m_AudioClip.version < 5)
|
get
|
||||||
{
|
{
|
||||||
switch (m_AudioClip.m_Type)
|
if (m_AudioClip.version[0] < 5)
|
||||||
{
|
{
|
||||||
case FMODSoundType.AIFF:
|
switch (m_AudioClip.m_Type)
|
||||||
case FMODSoundType.IT:
|
{
|
||||||
case FMODSoundType.MOD:
|
case FMODSoundType.AIFF:
|
||||||
case FMODSoundType.S3M:
|
case FMODSoundType.IT:
|
||||||
case FMODSoundType.XM:
|
case FMODSoundType.MOD:
|
||||||
case FMODSoundType.XMA:
|
case FMODSoundType.S3M:
|
||||||
case FMODSoundType.AUDIOQUEUE:
|
case FMODSoundType.XM:
|
||||||
return true;
|
case FMODSoundType.XMA:
|
||||||
default:
|
case FMODSoundType.AUDIOQUEUE:
|
||||||
return false;
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (m_AudioClip.m_CompressionFormat)
|
|
||||||
{
|
{
|
||||||
case AudioCompressionFormat.PCM:
|
switch (m_AudioClip.m_CompressionFormat)
|
||||||
case AudioCompressionFormat.Vorbis:
|
{
|
||||||
case AudioCompressionFormat.ADPCM:
|
case AudioCompressionFormat.PCM:
|
||||||
case AudioCompressionFormat.MP3:
|
case AudioCompressionFormat.Vorbis:
|
||||||
case AudioCompressionFormat.XMA:
|
case AudioCompressionFormat.ADPCM:
|
||||||
return true;
|
case AudioCompressionFormat.MP3:
|
||||||
default:
|
case AudioCompressionFormat.XMA:
|
||||||
return false;
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace CubismLive2DExtractor
|
|
||||||
{
|
|
||||||
public class CubismCdi3Json
|
|
||||||
{
|
|
||||||
public int Version { get; set; }
|
|
||||||
public ParamGroupArray[] Parameters { get; set; }
|
|
||||||
public ParamGroupArray[] ParameterGroups { get; set; }
|
|
||||||
public PartArray[] Parts { get; set; }
|
|
||||||
|
|
||||||
public class ParamGroupArray : IComparable
|
|
||||||
{
|
|
||||||
public string Id { get; set; }
|
|
||||||
public string GroupId { get; set; }
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
public int CompareTo(object obj)
|
|
||||||
{
|
|
||||||
return string.Compare(Id, ((ParamGroupArray)obj).Id, StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PartArray : IComparable
|
|
||||||
{
|
|
||||||
public string Id { get; set; }
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
public int CompareTo(object obj)
|
|
||||||
{
|
|
||||||
return string.Compare(Id, ((PartArray)obj).Id, StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,5 @@
|
|||||||
namespace CubismLive2DExtractor
|
namespace CubismLive2DExtractor
|
||||||
{
|
{
|
||||||
public enum BlendType
|
|
||||||
{
|
|
||||||
Add,
|
|
||||||
Multiply,
|
|
||||||
Overwrite,
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CubismExpression3Json
|
public class CubismExpression3Json
|
||||||
{
|
{
|
||||||
public string Type;
|
public string Type;
|
||||||
@@ -18,7 +11,7 @@
|
|||||||
{
|
{
|
||||||
public string Id;
|
public string Id;
|
||||||
public float Value;
|
public float Value;
|
||||||
public BlendType Blend;
|
public int Blend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace CubismLive2DExtractor
|
namespace CubismLive2DExtractor
|
||||||
{
|
{
|
||||||
public sealed class AnimationCurve
|
public class AnimationCurve
|
||||||
{
|
{
|
||||||
public CubismKeyframeData[] m_Curve { get; set; }
|
public CubismKeyframeData[] m_Curve { get; set; }
|
||||||
public int m_PreInfinity { get; set; }
|
public int m_PreInfinity { get; set; }
|
||||||
@@ -10,7 +10,7 @@ namespace CubismLive2DExtractor
|
|||||||
public int m_RotationOrder { get; set; }
|
public int m_RotationOrder { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class CubismFadeMotion
|
public class CubismFadeMotion
|
||||||
{
|
{
|
||||||
public string m_Name { get; set; }
|
public string m_Name { get; set; }
|
||||||
public string MotionName { get; set; }
|
public string MotionName { get; set; }
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ namespace CubismLive2DExtractor
|
|||||||
{
|
{
|
||||||
public string Moc;
|
public string Moc;
|
||||||
public string[] Textures;
|
public string[] Textures;
|
||||||
public string DisplayInfo;
|
|
||||||
public string Physics;
|
public string Physics;
|
||||||
public JObject Motions;
|
public JObject Motions;
|
||||||
public JArray Expressions;
|
public JArray Expressions;
|
||||||
|
|||||||
@@ -7,35 +7,26 @@ namespace CubismLive2DExtractor
|
|||||||
{
|
{
|
||||||
class CubismMotion3Converter
|
class CubismMotion3Converter
|
||||||
{
|
{
|
||||||
private SerializedFile assetsFile;
|
|
||||||
private Dictionary<uint, string> bonePathHash = new Dictionary<uint, string>();
|
private Dictionary<uint, string> bonePathHash = new Dictionary<uint, string>();
|
||||||
public List<ImportedKeyframedAnimation> AnimationList { get; protected set; } = new List<ImportedKeyframedAnimation>();
|
public List<ImportedKeyframedAnimation> AnimationList { get; protected set; } = new List<ImportedKeyframedAnimation>();
|
||||||
|
|
||||||
public CubismMotion3Converter(GameObject rootGameObject, List<AnimationClip> animationClips)
|
public CubismMotion3Converter(GameObject rootGameObject, AnimationClip[] animationClips)
|
||||||
{
|
{
|
||||||
var rootTransform = GetTransform(rootGameObject);
|
var rootTransform = GetTransform(rootGameObject);
|
||||||
CreateBonePathHash(rootTransform);
|
CreateBonePathHash(rootTransform);
|
||||||
ConvertAnimations(animationClips);
|
ConvertAnimations(animationClips);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CubismMotion3Converter(List<AnimationClip> animationClips, HashSet<string> partIds, HashSet<string> parameterIds)
|
private void ConvertAnimations(AnimationClip[] animationClips)
|
||||||
{
|
|
||||||
CreateBonePathHash(partIds, pathType: "Parts/");
|
|
||||||
CreateBonePathHash(parameterIds, pathType: "Parameters/");
|
|
||||||
ConvertAnimations(animationClips);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ConvertAnimations(List<AnimationClip> animationClips)
|
|
||||||
{
|
{
|
||||||
foreach (var animationClip in animationClips)
|
foreach (var animationClip in animationClips)
|
||||||
{
|
{
|
||||||
var iAnim = new ImportedKeyframedAnimation();
|
var iAnim = new ImportedKeyframedAnimation();
|
||||||
assetsFile = animationClip.assetsFile;
|
|
||||||
AnimationList.Add(iAnim);
|
AnimationList.Add(iAnim);
|
||||||
iAnim.Name = animationClip.m_Name;
|
iAnim.Name = animationClip.m_Name;
|
||||||
iAnim.SampleRate = animationClip.m_SampleRate;
|
iAnim.SampleRate = animationClip.m_SampleRate;
|
||||||
iAnim.Duration = animationClip.m_MuscleClip.m_StopTime;
|
iAnim.Duration = animationClip.m_MuscleClip.m_StopTime;
|
||||||
var m_Clip = animationClip.m_MuscleClip.m_Clip.data;
|
var m_Clip = animationClip.m_MuscleClip.m_Clip;
|
||||||
var streamedFrames = m_Clip.m_StreamedClip.ReadData();
|
var streamedFrames = m_Clip.m_StreamedClip.ReadData();
|
||||||
var m_ClipBindingConstant = animationClip.m_ClipBindingConstant;
|
var m_ClipBindingConstant = animationClip.m_ClipBindingConstant;
|
||||||
for (int frameIndex = 1; frameIndex < streamedFrames.Count - 1; frameIndex++)
|
for (int frameIndex = 1; frameIndex < streamedFrames.Count - 1; frameIndex++)
|
||||||
@@ -136,7 +127,7 @@ namespace CubismLive2DExtractor
|
|||||||
target = "PartOpacity";
|
target = "PartOpacity";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (binding.script.TryGet(out MonoScript script, assetsFile))
|
else if (binding.script.TryGet(out MonoScript script))
|
||||||
{
|
{
|
||||||
switch (script.m_ClassName)
|
switch (script.m_ClassName)
|
||||||
{
|
{
|
||||||
@@ -169,30 +160,21 @@ namespace CubismLive2DExtractor
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateBonePathHash(HashSet<string> ids, string pathType)
|
|
||||||
{
|
|
||||||
foreach (var id in ids)
|
|
||||||
{
|
|
||||||
var name = pathType + id;;
|
|
||||||
bonePathHash[GetCRC(name)] = name;
|
|
||||||
int index;
|
|
||||||
while ((index = name.IndexOf("/", StringComparison.Ordinal)) >= 0)
|
|
||||||
{
|
|
||||||
name = name.Substring(index + 1);
|
|
||||||
bonePathHash[GetCRC(name)] = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CreateBonePathHash(Transform m_Transform)
|
private void CreateBonePathHash(Transform m_Transform)
|
||||||
{
|
{
|
||||||
var name = GetTransformPath(m_Transform);
|
var name = GetTransformPath(m_Transform);
|
||||||
bonePathHash[GetCRC(name)] = name;
|
var crc = new SevenZip.CRC();
|
||||||
|
var bytes = Encoding.UTF8.GetBytes(name);
|
||||||
|
crc.Update(bytes, 0, (uint)bytes.Length);
|
||||||
|
bonePathHash[crc.GetDigest()] = name;
|
||||||
int index;
|
int index;
|
||||||
while ((index = name.IndexOf("/", StringComparison.Ordinal)) >= 0)
|
while ((index = name.IndexOf("/", StringComparison.Ordinal)) >= 0)
|
||||||
{
|
{
|
||||||
name = name.Substring(index + 1);
|
name = name.Substring(index + 1);
|
||||||
bonePathHash[GetCRC(name)] = name;
|
crc = new SevenZip.CRC();
|
||||||
|
bytes = Encoding.UTF8.GetBytes(name);
|
||||||
|
crc.Update(bytes, 0, (uint)bytes.Length);
|
||||||
|
bonePathHash[crc.GetDigest()] = name;
|
||||||
}
|
}
|
||||||
foreach (var pptr in m_Transform.m_Children)
|
foreach (var pptr in m_Transform.m_Children)
|
||||||
{
|
{
|
||||||
@@ -201,13 +183,7 @@ namespace CubismLive2DExtractor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static uint GetCRC(string name)
|
private string GetTransformPath(Transform transform)
|
||||||
{
|
|
||||||
var bytes = Encoding.UTF8.GetBytes(name);
|
|
||||||
return SevenZip.CRC.CalculateDigest(bytes, 0, (uint)bytes.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetTransformPath(Transform transform)
|
|
||||||
{
|
{
|
||||||
transform.m_GameObject.TryGet(out var m_GameObject);
|
transform.m_GameObject.TryGet(out var m_GameObject);
|
||||||
if (transform.m_Father.TryGet(out var father))
|
if (transform.m_Father.TryGet(out var father))
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using AssetStudio;
|
|
||||||
|
|
||||||
namespace CubismLive2DExtractor
|
|
||||||
{
|
|
||||||
public sealed class CubismObjectList
|
|
||||||
{
|
|
||||||
public static SerializedFile AssetsFile { get; set; }
|
|
||||||
public HashSet<ObjectData> CubismExpressionObjects { get; set; }
|
|
||||||
public HashSet<ObjectData> CubismFadeMotionObjects { get; set; }
|
|
||||||
|
|
||||||
public class ObjectData
|
|
||||||
{
|
|
||||||
private long _pathID;
|
|
||||||
public Object Asset { get; set; }
|
|
||||||
public int m_FileID { get; set; }
|
|
||||||
public long m_PathID
|
|
||||||
{
|
|
||||||
get => _pathID;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_pathID = value;
|
|
||||||
Asset = GetObjByPathID(_pathID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
return obj is ObjectData objectData && _pathID == objectData.m_PathID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return _pathID.GetHashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<MonoBehaviour> GetFadeMotionAssetList()
|
|
||||||
{
|
|
||||||
return CubismFadeMotionObjects?.Where(x => x.Asset != null).Select(x => (MonoBehaviour)x.Asset).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<MonoBehaviour> GetExpressionList()
|
|
||||||
{
|
|
||||||
return CubismExpressionObjects?.Where(x => x.Asset != null).Select(x => (MonoBehaviour)x.Asset).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object GetObjByPathID(long pathID)
|
|
||||||
{
|
|
||||||
var assetFileList = AssetsFile.assetsManager.assetsFileList;
|
|
||||||
foreach (var assetFile in assetFileList)
|
|
||||||
{
|
|
||||||
if (assetFile.ObjectsDic.TryGetValue(pathID, out var obj))
|
|
||||||
{
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,163 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Specialized;
|
|
||||||
using System.Linq;
|
|
||||||
using AssetStudio;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace CubismLive2DExtractor
|
|
||||||
{
|
|
||||||
public static class CubismParsers
|
|
||||||
{
|
|
||||||
public enum CubismMonoBehaviourType
|
|
||||||
{
|
|
||||||
FadeMotionList,
|
|
||||||
FadeMotion,
|
|
||||||
Expression,
|
|
||||||
Physics,
|
|
||||||
DisplayInfo,
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ParsePhysics(OrderedDictionary physicsDict)
|
|
||||||
{
|
|
||||||
var cubismPhysicsRig = JsonConvert.DeserializeObject<CubismPhysics>(JsonConvert.SerializeObject(physicsDict))._rig;
|
|
||||||
|
|
||||||
var physicsSettings = new CubismPhysics3Json.SerializablePhysicsSettings[cubismPhysicsRig.SubRigs.Length];
|
|
||||||
for (int i = 0; i < physicsSettings.Length; i++)
|
|
||||||
{
|
|
||||||
var subRigs = cubismPhysicsRig.SubRigs[i];
|
|
||||||
physicsSettings[i] = new CubismPhysics3Json.SerializablePhysicsSettings
|
|
||||||
{
|
|
||||||
Id = $"PhysicsSetting{i + 1}",
|
|
||||||
Input = new CubismPhysics3Json.SerializableInput[subRigs.Input.Length],
|
|
||||||
Output = new CubismPhysics3Json.SerializableOutput[subRigs.Output.Length],
|
|
||||||
Vertices = new CubismPhysics3Json.SerializableVertex[subRigs.Particles.Length],
|
|
||||||
Normalization = new CubismPhysics3Json.SerializableNormalization
|
|
||||||
{
|
|
||||||
Position = new CubismPhysics3Json.SerializableNormalizationValue
|
|
||||||
{
|
|
||||||
Minimum = subRigs.Normalization.Position.Minimum,
|
|
||||||
Default = subRigs.Normalization.Position.Default,
|
|
||||||
Maximum = subRigs.Normalization.Position.Maximum
|
|
||||||
},
|
|
||||||
Angle = new CubismPhysics3Json.SerializableNormalizationValue
|
|
||||||
{
|
|
||||||
Minimum = subRigs.Normalization.Angle.Minimum,
|
|
||||||
Default = subRigs.Normalization.Angle.Default,
|
|
||||||
Maximum = subRigs.Normalization.Angle.Maximum
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
for (int j = 0; j < subRigs.Input.Length; j++)
|
|
||||||
{
|
|
||||||
var input = subRigs.Input[j];
|
|
||||||
physicsSettings[i].Input[j] = new CubismPhysics3Json.SerializableInput
|
|
||||||
{
|
|
||||||
Source = new CubismPhysics3Json.SerializableParameter
|
|
||||||
{
|
|
||||||
Target = "Parameter", //同名GameObject父节点的名称
|
|
||||||
Id = input.SourceId
|
|
||||||
},
|
|
||||||
Weight = input.Weight,
|
|
||||||
Type = Enum.GetName(typeof(CubismPhysicsSourceComponent), input.SourceComponent),
|
|
||||||
Reflect = input.IsInverted
|
|
||||||
};
|
|
||||||
}
|
|
||||||
for (int j = 0; j < subRigs.Output.Length; j++)
|
|
||||||
{
|
|
||||||
var output = subRigs.Output[j];
|
|
||||||
physicsSettings[i].Output[j] = new CubismPhysics3Json.SerializableOutput
|
|
||||||
{
|
|
||||||
Destination = new CubismPhysics3Json.SerializableParameter
|
|
||||||
{
|
|
||||||
Target = "Parameter", //同名GameObject父节点的名称
|
|
||||||
Id = output.DestinationId
|
|
||||||
},
|
|
||||||
VertexIndex = output.ParticleIndex,
|
|
||||||
Scale = output.AngleScale,
|
|
||||||
Weight = output.Weight,
|
|
||||||
Type = Enum.GetName(typeof(CubismPhysicsSourceComponent), output.SourceComponent),
|
|
||||||
Reflect = output.IsInverted
|
|
||||||
};
|
|
||||||
}
|
|
||||||
for (int j = 0; j < subRigs.Particles.Length; j++)
|
|
||||||
{
|
|
||||||
var particles = subRigs.Particles[j];
|
|
||||||
physicsSettings[i].Vertices[j] = new CubismPhysics3Json.SerializableVertex
|
|
||||||
{
|
|
||||||
Position = particles.InitialPosition,
|
|
||||||
Mobility = particles.Mobility,
|
|
||||||
Delay = particles.Delay,
|
|
||||||
Acceleration = particles.Acceleration,
|
|
||||||
Radius = particles.Radius
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var physicsDictionary = new CubismPhysics3Json.SerializablePhysicsDictionary[physicsSettings.Length];
|
|
||||||
for (int i = 0; i < physicsSettings.Length; i++)
|
|
||||||
{
|
|
||||||
physicsDictionary[i] = new CubismPhysics3Json.SerializablePhysicsDictionary
|
|
||||||
{
|
|
||||||
Id = $"PhysicsSetting{i + 1}",
|
|
||||||
Name = $"Dummy{i + 1}"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
var physicsJson = new CubismPhysics3Json
|
|
||||||
{
|
|
||||||
Version = 3,
|
|
||||||
Meta = new CubismPhysics3Json.SerializableMeta
|
|
||||||
{
|
|
||||||
PhysicsSettingCount = cubismPhysicsRig.SubRigs.Length,
|
|
||||||
TotalInputCount = cubismPhysicsRig.SubRigs.Sum(x => x.Input.Length),
|
|
||||||
TotalOutputCount = cubismPhysicsRig.SubRigs.Sum(x => x.Output.Length),
|
|
||||||
VertexCount = cubismPhysicsRig.SubRigs.Sum(x => x.Particles.Length),
|
|
||||||
EffectiveForces = new CubismPhysics3Json.SerializableEffectiveForces
|
|
||||||
{
|
|
||||||
Gravity = cubismPhysicsRig.Gravity,
|
|
||||||
Wind = cubismPhysicsRig.Wind
|
|
||||||
},
|
|
||||||
PhysicsDictionary = physicsDictionary
|
|
||||||
},
|
|
||||||
PhysicsSettings = physicsSettings
|
|
||||||
};
|
|
||||||
return JsonConvert.SerializeObject(physicsJson, Formatting.Indented, new MyJsonConverter2());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static OrderedDictionary ParseMonoBehaviour(MonoBehaviour m_MonoBehaviour, CubismMonoBehaviourType cubismMonoBehaviourType, AssemblyLoader assemblyLoader)
|
|
||||||
{
|
|
||||||
var orderedDict = m_MonoBehaviour.ToType();
|
|
||||||
if (orderedDict != null)
|
|
||||||
return orderedDict;
|
|
||||||
|
|
||||||
var fieldName = "";
|
|
||||||
var m_Type = m_MonoBehaviour.ConvertToTypeTree(assemblyLoader);
|
|
||||||
switch (cubismMonoBehaviourType)
|
|
||||||
{
|
|
||||||
case CubismMonoBehaviourType.FadeMotionList:
|
|
||||||
fieldName = "cubismfademotionobjects";
|
|
||||||
break;
|
|
||||||
case CubismMonoBehaviourType.FadeMotion:
|
|
||||||
fieldName = "parameterids";
|
|
||||||
break;
|
|
||||||
case CubismMonoBehaviourType.Expression:
|
|
||||||
fieldName = "parameters";
|
|
||||||
break;
|
|
||||||
case CubismMonoBehaviourType.Physics:
|
|
||||||
fieldName = "_rig";
|
|
||||||
break;
|
|
||||||
case CubismMonoBehaviourType.DisplayInfo:
|
|
||||||
fieldName = "name";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (m_Type.m_Nodes.FindIndex(x => x.m_Name.ToLower() == fieldName) < 0)
|
|
||||||
{
|
|
||||||
m_MonoBehaviour.m_Script.TryGet(out var m_MonoScript);
|
|
||||||
var assetName = m_MonoBehaviour.m_Name != "" ? m_MonoBehaviour.m_Name : m_MonoScript.m_ClassName;
|
|
||||||
Logger.Warning($"{cubismMonoBehaviourType} asset \"{assetName}\" is not readable");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
orderedDict = m_MonoBehaviour.ToType(m_Type);
|
|
||||||
|
|
||||||
return orderedDict;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +1,43 @@
|
|||||||
////
|
////
|
||||||
// Based on UnityLive2DExtractor by Perfare
|
// Based on UnityLive2DExtractorMod by aelurum
|
||||||
|
// https://github.com/aelurum/UnityLive2DExtractor
|
||||||
|
//
|
||||||
|
// Original version - by Perfare
|
||||||
// https://github.com/Perfare/UnityLive2DExtractor
|
// https://github.com/Perfare/UnityLive2DExtractor
|
||||||
////
|
////
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AssetStudio;
|
using AssetStudio;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using static CubismLive2DExtractor.CubismParsers;
|
|
||||||
|
|
||||||
namespace CubismLive2DExtractor
|
namespace CubismLive2DExtractor
|
||||||
{
|
{
|
||||||
public sealed class Live2DExtractor
|
public static class Live2DExtractor
|
||||||
{
|
{
|
||||||
private List<MonoBehaviour> Expressions { get; set; }
|
public static void ExtractLive2D(IGrouping<string, AssetStudio.Object> assets, string destPath, string modelName, AssemblyLoader assemblyLoader, Live2DMotionMode motionMode, bool forceBezier = false)
|
||||||
private List<MonoBehaviour> FadeMotions { get; set; }
|
|
||||||
private List<GameObject> GameObjects { get; set; }
|
|
||||||
private List<AnimationClip> AnimationClips { get; set; }
|
|
||||||
private List<Texture2D> Texture2Ds { get; set; }
|
|
||||||
private HashSet<string> EyeBlinkParameters { get; set; }
|
|
||||||
private HashSet<string> LipSyncParameters { get; set; }
|
|
||||||
private HashSet<string> ParameterNames { get; set; }
|
|
||||||
private HashSet<string> PartNames { get; set; }
|
|
||||||
private MonoBehaviour MocMono { get; set; }
|
|
||||||
private MonoBehaviour PhysicsMono { get; set; }
|
|
||||||
private MonoBehaviour FadeMotionLst { get; set; }
|
|
||||||
private List<MonoBehaviour> ParametersCdi { get; set; }
|
|
||||||
private List<MonoBehaviour> PartsCdi { get; set; }
|
|
||||||
|
|
||||||
public Live2DExtractor(IGrouping<string, AssetStudio.Object> assets, List<AnimationClip> inClipMotions = null, List<MonoBehaviour> inFadeMotions = null, MonoBehaviour inFadeMotionLst = null)
|
|
||||||
{
|
{
|
||||||
Expressions = new List<MonoBehaviour>();
|
var destTexturePath = Path.Combine(destPath, "textures") + Path.DirectorySeparatorChar;
|
||||||
FadeMotions = inFadeMotions ?? new List<MonoBehaviour>();
|
var destMotionPath = Path.Combine(destPath, "motions") + Path.DirectorySeparatorChar;
|
||||||
AnimationClips = inClipMotions ?? new List<AnimationClip>();
|
var destExpressionPath = Path.Combine(destPath, "expressions") + Path.DirectorySeparatorChar;
|
||||||
GameObjects = new List<GameObject>();
|
Directory.CreateDirectory(destPath);
|
||||||
Texture2Ds = new List<Texture2D>();
|
Directory.CreateDirectory(destTexturePath);
|
||||||
EyeBlinkParameters = new HashSet<string>();
|
|
||||||
LipSyncParameters = new HashSet<string>();
|
var expressionList = new List<MonoBehaviour>();
|
||||||
ParameterNames = new HashSet<string>();
|
var fadeMotionList = new List<MonoBehaviour>();
|
||||||
PartNames = new HashSet<string>();
|
var gameObjects = new List<GameObject>();
|
||||||
FadeMotionLst = inFadeMotionLst;
|
var animationClips = new List<AnimationClip>();
|
||||||
ParametersCdi = new List<MonoBehaviour>();
|
|
||||||
PartsCdi = new List<MonoBehaviour>();
|
var textures = new SortedSet<string>();
|
||||||
|
var eyeBlinkParameters = new HashSet<string>();
|
||||||
|
var lipSyncParameters = new HashSet<string>();
|
||||||
|
var parameterNames = new HashSet<string>();
|
||||||
|
var partNames = new HashSet<string>();
|
||||||
|
MonoBehaviour physics = null;
|
||||||
|
|
||||||
Logger.Debug("Sorting model assets..");
|
|
||||||
foreach (var asset in assets)
|
foreach (var asset in assets)
|
||||||
{
|
{
|
||||||
switch (asset)
|
switch (asset)
|
||||||
@@ -60,346 +48,226 @@ namespace CubismLive2DExtractor
|
|||||||
switch (m_Script.m_ClassName)
|
switch (m_Script.m_ClassName)
|
||||||
{
|
{
|
||||||
case "CubismMoc":
|
case "CubismMoc":
|
||||||
MocMono = m_MonoBehaviour;
|
File.WriteAllBytes($"{destPath}{modelName}.moc3", ParseMoc(m_MonoBehaviour)); //moc
|
||||||
break;
|
break;
|
||||||
case "CubismPhysicsController":
|
case "CubismPhysicsController":
|
||||||
PhysicsMono = m_MonoBehaviour;
|
physics = physics ?? m_MonoBehaviour;
|
||||||
break;
|
break;
|
||||||
case "CubismExpressionData":
|
case "CubismExpressionData":
|
||||||
Expressions.Add(m_MonoBehaviour);
|
expressionList.Add(m_MonoBehaviour);
|
||||||
break;
|
break;
|
||||||
case "CubismFadeMotionData":
|
case "CubismFadeMotionData":
|
||||||
if (inFadeMotions == null && inFadeMotionLst == null)
|
fadeMotionList.Add(m_MonoBehaviour);
|
||||||
{
|
|
||||||
FadeMotions.Add(m_MonoBehaviour);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "CubismFadeMotionList":
|
|
||||||
if (inFadeMotions == null && inFadeMotionLst == null)
|
|
||||||
{
|
|
||||||
FadeMotionLst = m_MonoBehaviour;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case "CubismEyeBlinkParameter":
|
case "CubismEyeBlinkParameter":
|
||||||
if (m_MonoBehaviour.m_GameObject.TryGet(out var blinkGameObject))
|
if (m_MonoBehaviour.m_GameObject.TryGet(out var blinkGameObject))
|
||||||
{
|
{
|
||||||
EyeBlinkParameters.Add(blinkGameObject.m_Name);
|
eyeBlinkParameters.Add(blinkGameObject.m_Name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "CubismMouthParameter":
|
case "CubismMouthParameter":
|
||||||
if (m_MonoBehaviour.m_GameObject.TryGet(out var mouthGameObject))
|
if (m_MonoBehaviour.m_GameObject.TryGet(out var mouthGameObject))
|
||||||
{
|
{
|
||||||
LipSyncParameters.Add(mouthGameObject.m_Name);
|
lipSyncParameters.Add(mouthGameObject.m_Name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "CubismParameter":
|
case "CubismParameter":
|
||||||
if (m_MonoBehaviour.m_GameObject.TryGet(out var paramGameObject))
|
if (m_MonoBehaviour.m_GameObject.TryGet(out var paramGameObject))
|
||||||
{
|
{
|
||||||
ParameterNames.Add(paramGameObject.m_Name);
|
parameterNames.Add(paramGameObject.m_Name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "CubismPart":
|
case "CubismPart":
|
||||||
if (m_MonoBehaviour.m_GameObject.TryGet(out var partGameObject))
|
if (m_MonoBehaviour.m_GameObject.TryGet(out var partGameObject))
|
||||||
{
|
{
|
||||||
PartNames.Add(partGameObject.m_Name);
|
partNames.Add(partGameObject.m_Name);
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "CubismDisplayInfoParameterName":
|
|
||||||
if (m_MonoBehaviour.m_GameObject.TryGet(out _))
|
|
||||||
{
|
|
||||||
ParametersCdi.Add(m_MonoBehaviour);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "CubismDisplayInfoPartName":
|
|
||||||
if (m_MonoBehaviour.m_GameObject.TryGet(out _))
|
|
||||||
{
|
|
||||||
PartsCdi.Add(m_MonoBehaviour);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AnimationClip m_AnimationClip:
|
case Texture2D m_Texture2D:
|
||||||
if (inClipMotions == null)
|
using (var image = m_Texture2D.ConvertToImage(flip: true))
|
||||||
{
|
{
|
||||||
AnimationClips.Add(m_AnimationClip);
|
using (var file = File.OpenWrite($"{destTexturePath}{m_Texture2D.m_Name}.png"))
|
||||||
|
{
|
||||||
|
image.WriteToStream(file, ImageFormat.Png);
|
||||||
|
}
|
||||||
|
textures.Add($"textures/{m_Texture2D.m_Name}.png"); //texture
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GameObject m_GameObject:
|
case GameObject m_GameObject:
|
||||||
GameObjects.Add(m_GameObject);
|
gameObjects.Add(m_GameObject);
|
||||||
break;
|
break;
|
||||||
case Texture2D m_Texture2D:
|
case AnimationClip m_AnimationClip:
|
||||||
Texture2Ds.Add(m_Texture2D);
|
animationClips.Add(m_AnimationClip);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void ExtractCubismModel(string destPath, string modelName, Live2DMotionMode motionMode, AssemblyLoader assemblyLoader, bool forceBezier = false, int parallelTaskCount = 1)
|
if (textures.Count == 0)
|
||||||
{
|
|
||||||
Directory.CreateDirectory(destPath);
|
|
||||||
|
|
||||||
#region moc3
|
|
||||||
using (var cubismModel = new CubismModel(MocMono))
|
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder();
|
Logger.Warning($"No textures found for \"{modelName}\" model.");
|
||||||
sb.AppendLine("Model Stats:");
|
|
||||||
sb.AppendLine($"SDK Version: {cubismModel.VersionDescription}");
|
|
||||||
if (cubismModel.Version > 0)
|
|
||||||
{
|
|
||||||
sb.AppendLine($"Canvas Width: {cubismModel.CanvasWidth}");
|
|
||||||
sb.AppendLine($"Canvas Height: {cubismModel.CanvasHeight}");
|
|
||||||
sb.AppendLine($"Center X: {cubismModel.CentralPosX}");
|
|
||||||
sb.AppendLine($"Center Y: {cubismModel.CentralPosY}");
|
|
||||||
sb.AppendLine($"Pixel Per Unit: {cubismModel.PixelPerUnit}");
|
|
||||||
sb.AppendLine($"Part Count: {cubismModel.PartCount}");
|
|
||||||
sb.AppendLine($"Parameter Count: {cubismModel.ParamCount}");
|
|
||||||
Logger.Debug(sb.ToString());
|
|
||||||
|
|
||||||
ParameterNames = cubismModel.ParamNames;
|
|
||||||
PartNames = cubismModel.PartNames;
|
|
||||||
}
|
|
||||||
cubismModel.SaveMoc3($"{destPath}{modelName}.moc3");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region textures
|
|
||||||
var textures = new SortedSet<string>();
|
|
||||||
var destTexturePath = Path.Combine(destPath, "textures") + Path.DirectorySeparatorChar;
|
|
||||||
|
|
||||||
if (Texture2Ds.Count == 0)
|
|
||||||
{
|
|
||||||
Logger.Warning($"No textures found for \"{modelName}\" model");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(destTexturePath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var textureBag = new ConcurrentBag<string>();
|
//physics
|
||||||
var savePathHash = new ConcurrentDictionary<string, bool>();
|
if (physics != null)
|
||||||
Parallel.ForEach(Texture2Ds, new ParallelOptions { MaxDegreeOfParallelism = parallelTaskCount }, texture2D =>
|
|
||||||
{
|
{
|
||||||
var savePath = $"{destTexturePath}{texture2D.m_Name}.png";
|
try
|
||||||
if (!savePathHash.TryAdd(savePath, true))
|
|
||||||
return;
|
|
||||||
|
|
||||||
using (var image = texture2D.ConvertToImage(flip: true))
|
|
||||||
{
|
{
|
||||||
using (var file = File.OpenWrite(savePath))
|
var buff = ParsePhysics(physics, assemblyLoader);
|
||||||
{
|
File.WriteAllText($"{destPath}{modelName}.physics3.json", buff);
|
||||||
image.WriteToStream(file, ImageFormat.Png);
|
|
||||||
}
|
|
||||||
textureBag.Add($"textures/{texture2D.m_Name}.png");
|
|
||||||
}
|
}
|
||||||
});
|
catch (Exception e)
|
||||||
textures.UnionWith(textureBag);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region physics3.json
|
|
||||||
if (PhysicsMono != null)
|
|
||||||
{
|
|
||||||
var physicsDict = ParseMonoBehaviour(PhysicsMono, CubismMonoBehaviourType.Physics, assemblyLoader);
|
|
||||||
if (physicsDict != null)
|
|
||||||
{
|
{
|
||||||
try
|
Logger.Warning($"Error in parsing physics data: {e.Message}");
|
||||||
{
|
physics = null;
|
||||||
var buff = ParsePhysics(physicsDict);
|
|
||||||
File.WriteAllText($"{destPath}{modelName}.physics3.json", buff);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Logger.Warning($"Error in parsing physics data: {e.Message}");
|
|
||||||
PhysicsMono = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PhysicsMono = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region cdi3.json
|
//motion
|
||||||
var isCdiParsed = false;
|
|
||||||
if (ParametersCdi.Count > 0 || PartsCdi.Count > 0)
|
|
||||||
{
|
|
||||||
var cdiJson = new CubismCdi3Json
|
|
||||||
{
|
|
||||||
Version = 3,
|
|
||||||
ParameterGroups = Array.Empty<CubismCdi3Json.ParamGroupArray>()
|
|
||||||
};
|
|
||||||
|
|
||||||
var parameters = new SortedSet<CubismCdi3Json.ParamGroupArray>();
|
|
||||||
foreach (var paramMono in ParametersCdi)
|
|
||||||
{
|
|
||||||
var displayName = GetDisplayName(paramMono, assemblyLoader);
|
|
||||||
if (displayName == null)
|
|
||||||
break;
|
|
||||||
|
|
||||||
paramMono.m_GameObject.TryGet(out var paramGameObject);
|
|
||||||
var paramId = paramGameObject.m_Name;
|
|
||||||
parameters.Add(new CubismCdi3Json.ParamGroupArray
|
|
||||||
{
|
|
||||||
Id = paramId,
|
|
||||||
GroupId = "",
|
|
||||||
Name = displayName
|
|
||||||
});
|
|
||||||
}
|
|
||||||
cdiJson.Parameters = parameters.ToArray();
|
|
||||||
|
|
||||||
var parts = new SortedSet<CubismCdi3Json.PartArray>();
|
|
||||||
foreach (var partMono in PartsCdi)
|
|
||||||
{
|
|
||||||
var displayName = GetDisplayName(partMono, assemblyLoader);
|
|
||||||
if (displayName == null)
|
|
||||||
break;
|
|
||||||
|
|
||||||
partMono.m_GameObject.TryGet(out var partGameObject);
|
|
||||||
var paramId = partGameObject.m_Name;
|
|
||||||
parts.Add(new CubismCdi3Json.PartArray
|
|
||||||
{
|
|
||||||
Id = paramId,
|
|
||||||
Name = displayName
|
|
||||||
});
|
|
||||||
}
|
|
||||||
cdiJson.Parts = parts.ToArray();
|
|
||||||
|
|
||||||
if (parts.Count > 0 || parameters.Count > 0)
|
|
||||||
{
|
|
||||||
File.WriteAllText($"{destPath}{modelName}.cdi3.json", JsonConvert.SerializeObject(cdiJson, Formatting.Indented));
|
|
||||||
isCdiParsed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region motion3.json
|
|
||||||
var motions = new SortedDictionary<string, JArray>();
|
var motions = new SortedDictionary<string, JArray>();
|
||||||
var destMotionPath = Path.Combine(destPath, "motions") + Path.DirectorySeparatorChar;
|
|
||||||
|
|
||||||
if (motionMode == Live2DMotionMode.MonoBehaviour && FadeMotionLst != null) //Fade motions from Fade Motion List
|
if (motionMode == Live2DMotionMode.MonoBehaviour && fadeMotionList.Count > 0) //motion from MonoBehaviour
|
||||||
{
|
{
|
||||||
Logger.Debug("Motion export method: MonoBehaviour (Fade motion)");
|
Logger.Debug("Motion export method: MonoBehaviour (Fade motion)");
|
||||||
var fadeMotionLstDict = ParseMonoBehaviour(FadeMotionLst, CubismMonoBehaviourType.FadeMotionList, assemblyLoader);
|
Directory.CreateDirectory(destMotionPath);
|
||||||
if (fadeMotionLstDict != null)
|
foreach (var fadeMotionMono in fadeMotionList)
|
||||||
{
|
{
|
||||||
CubismObjectList.AssetsFile = FadeMotionLst.assetsFile;
|
var fadeMotionObj = fadeMotionMono.ToType();
|
||||||
var fadeMotionAssetList = JsonConvert.DeserializeObject<CubismObjectList>(JsonConvert.SerializeObject(fadeMotionLstDict)).GetFadeMotionAssetList();
|
if (fadeMotionObj == null)
|
||||||
if (fadeMotionAssetList?.Count > 0)
|
|
||||||
{
|
{
|
||||||
FadeMotions = fadeMotionAssetList;
|
var m_Type = fadeMotionMono.ConvertToTypeTree(assemblyLoader);
|
||||||
Logger.Debug($"\"{FadeMotionLst.m_Name}\": found {fadeMotionAssetList.Count} motion(s)");
|
fadeMotionObj = fadeMotionMono.ToType(m_Type);
|
||||||
|
if (fadeMotionObj == null)
|
||||||
|
{
|
||||||
|
Logger.Warning($"Fade motion \"{fadeMotionMono.m_Name}\" is not readable.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
var fadeMotion = JsonConvert.DeserializeObject<CubismFadeMotion>(JsonConvert.SerializeObject(fadeMotionObj));
|
||||||
|
if (fadeMotion.ParameterIds.Length == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var motionJson = new CubismMotion3Json(fadeMotion, parameterNames, partNames, forceBezier);
|
||||||
|
|
||||||
|
var animName = Path.GetFileNameWithoutExtension(fadeMotion.m_Name);
|
||||||
|
if (motions.ContainsKey(animName))
|
||||||
|
{
|
||||||
|
animName = $"{animName}_{fadeMotion.GetHashCode()}";
|
||||||
|
|
||||||
|
if (motions.ContainsKey(animName))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var motionPath = new JObject(new JProperty("File", $"motions/{animName}.motion3.json"));
|
||||||
|
motions.Add(animName, new JArray(motionPath));
|
||||||
|
File.WriteAllText($"{destMotionPath}{animName}.motion3.json", JsonConvert.SerializeObject(motionJson, Formatting.Indented, new MyJsonConverter()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (gameObjects.Count > 0) //motion from AnimationClip
|
||||||
if (motionMode == Live2DMotionMode.MonoBehaviour && FadeMotions.Count > 0) //motion from MonoBehaviour
|
|
||||||
{
|
{
|
||||||
ExportFadeMotions(destMotionPath, assemblyLoader, forceBezier, motions);
|
var exportMethod = motionMode == Live2DMotionMode.AnimationClip
|
||||||
}
|
? "AnimationClip"
|
||||||
|
: "AnimationClip (no Fade motions found)";
|
||||||
if (motions.Count == 0) //motion from AnimationClip
|
|
||||||
{
|
|
||||||
CubismMotion3Converter converter = null;
|
|
||||||
var exportMethod = "AnimationClip";
|
|
||||||
if (motionMode != Live2DMotionMode.AnimationClipV1) //AnimationClipV2
|
|
||||||
{
|
|
||||||
exportMethod += "V2";
|
|
||||||
converter = new CubismMotion3Converter(AnimationClips, PartNames, ParameterNames);
|
|
||||||
}
|
|
||||||
else if (GameObjects.Count > 0) //AnimationClipV1
|
|
||||||
{
|
|
||||||
exportMethod += "V1";
|
|
||||||
var rootTransform = GameObjects[0].m_Transform;
|
|
||||||
while (rootTransform.m_Father.TryGet(out var m_Father))
|
|
||||||
{
|
|
||||||
rootTransform = m_Father;
|
|
||||||
}
|
|
||||||
rootTransform.m_GameObject.TryGet(out var rootGameObject);
|
|
||||||
converter = new CubismMotion3Converter(rootGameObject, AnimationClips);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (motionMode == Live2DMotionMode.MonoBehaviour)
|
|
||||||
{
|
|
||||||
exportMethod = FadeMotions.Count > 0
|
|
||||||
? exportMethod + " (unable to export motions using Fade motion method)"
|
|
||||||
: exportMethod + " (no Fade motions found)";
|
|
||||||
}
|
|
||||||
Logger.Debug($"Motion export method: {exportMethod}");
|
Logger.Debug($"Motion export method: {exportMethod}");
|
||||||
|
var rootTransform = gameObjects[0].m_Transform;
|
||||||
|
while (rootTransform.m_Father.TryGet(out var m_Father))
|
||||||
|
{
|
||||||
|
rootTransform = m_Father;
|
||||||
|
}
|
||||||
|
rootTransform.m_GameObject.TryGet(out var rootGameObject);
|
||||||
|
var converter = new CubismMotion3Converter(rootGameObject, animationClips.ToArray());
|
||||||
|
if (converter.AnimationList.Count > 0)
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(destMotionPath);
|
||||||
|
}
|
||||||
|
foreach (var animation in converter.AnimationList)
|
||||||
|
{
|
||||||
|
var motionJson = new CubismMotion3Json(animation, forceBezier);
|
||||||
|
|
||||||
ExportClipMotions(destMotionPath, converter, forceBezier, motions);
|
var animName = animation.Name;
|
||||||
|
if (motions.ContainsKey(animName))
|
||||||
|
{
|
||||||
|
animName = $"{animName}_{animation.GetHashCode()}";
|
||||||
|
|
||||||
|
if (motions.ContainsKey(animName))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var motionPath = new JObject(new JProperty("File", $"motions/{animName}.motion3.json"));
|
||||||
|
motions.Add(animName, new JArray(motionPath));
|
||||||
|
File.WriteAllText($"{destMotionPath}{animName}.motion3.json", JsonConvert.SerializeObject(motionJson, Formatting.Indented, new MyJsonConverter()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (motions.Count == 0)
|
if (motions.Count == 0)
|
||||||
{
|
{
|
||||||
Logger.Warning($"No exportable motions found for \"{modelName}\" model");
|
Logger.Warning($"No motions found for \"{modelName}\" model.");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger.Info($"Exported {motions.Count} motion(s)");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region exp3.json
|
//expression
|
||||||
var expressions = new JArray();
|
var expressions = new JArray();
|
||||||
var destExpressionPath = Path.Combine(destPath, "expressions") + Path.DirectorySeparatorChar;
|
if (expressionList.Count > 0)
|
||||||
|
|
||||||
if (Expressions.Count > 0)
|
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(destExpressionPath);
|
Directory.CreateDirectory(destExpressionPath);
|
||||||
}
|
}
|
||||||
foreach (var monoBehaviour in Expressions)
|
foreach (var monoBehaviour in expressionList)
|
||||||
{
|
{
|
||||||
var expressionName = monoBehaviour.m_Name.Replace(".exp3", "");
|
var expressionName = monoBehaviour.m_Name.Replace(".exp3", "");
|
||||||
var expressionDict = ParseMonoBehaviour(monoBehaviour, CubismMonoBehaviourType.Expression, assemblyLoader);
|
var expressionObj = monoBehaviour.ToType();
|
||||||
if (expressionDict == null)
|
if (expressionObj == null)
|
||||||
continue;
|
{
|
||||||
|
var m_Type = monoBehaviour.ConvertToTypeTree(assemblyLoader);
|
||||||
var expression = JsonConvert.DeserializeObject<CubismExpression3Json>(JsonConvert.SerializeObject(expressionDict));
|
expressionObj = monoBehaviour.ToType(m_Type);
|
||||||
|
if (expressionObj == null)
|
||||||
|
{
|
||||||
|
Logger.Warning($"Expression \"{expressionName}\" is not readable.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var expression = JsonConvert.DeserializeObject<CubismExpression3Json>(JsonConvert.SerializeObject(expressionObj));
|
||||||
|
|
||||||
expressions.Add(new JObject
|
expressions.Add(new JObject
|
||||||
{
|
{
|
||||||
{ "Name", expressionName },
|
{ "Name", expressionName },
|
||||||
{ "File", $"expressions/{expressionName}.exp3.json" }
|
{ "File", $"expressions/{expressionName}.exp3.json" }
|
||||||
});
|
});
|
||||||
File.WriteAllText($"{destExpressionPath}{expressionName}.exp3.json", JsonConvert.SerializeObject(expression, Formatting.Indented));
|
File.WriteAllText($"{destExpressionPath}{expressionName}.exp3.json", JsonConvert.SerializeObject(expression, Formatting.Indented));
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region model3.json
|
//group
|
||||||
var groups = new List<CubismModel3Json.SerializableGroup>();
|
var groups = new List<CubismModel3Json.SerializableGroup>();
|
||||||
|
|
||||||
//Try looking for group IDs among the parameter names manually
|
//Try looking for group IDs among the gameObjects
|
||||||
if (EyeBlinkParameters.Count == 0)
|
if (eyeBlinkParameters.Count == 0)
|
||||||
{
|
{
|
||||||
EyeBlinkParameters = ParameterNames.Where(x =>
|
eyeBlinkParameters = gameObjects.Where(x =>
|
||||||
x.ToLower().Contains("eye")
|
x.m_Name.ToLower().Contains("eye")
|
||||||
&& x.ToLower().Contains("open")
|
&& x.m_Name.ToLower().Contains("open")
|
||||||
&& (x.ToLower().Contains('l') || x.ToLower().Contains('r'))
|
&& (x.m_Name.ToLower().Contains('l') || x.m_Name.ToLower().Contains('r'))
|
||||||
).ToHashSet();
|
).Select(x => x.m_Name).ToHashSet();
|
||||||
}
|
}
|
||||||
if (LipSyncParameters.Count == 0)
|
if (lipSyncParameters.Count == 0)
|
||||||
{
|
{
|
||||||
LipSyncParameters = ParameterNames.Where(x =>
|
lipSyncParameters = gameObjects.Where(x =>
|
||||||
x.ToLower().Contains("mouth")
|
x.m_Name.ToLower().Contains("mouth")
|
||||||
&& x.ToLower().Contains("open")
|
&& x.m_Name.ToLower().Contains("open")
|
||||||
&& x.ToLower().Contains('y')
|
&& x.m_Name.ToLower().Contains('y')
|
||||||
).ToHashSet();
|
).Select(x => x.m_Name).ToHashSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
groups.Add(new CubismModel3Json.SerializableGroup
|
groups.Add(new CubismModel3Json.SerializableGroup
|
||||||
{
|
{
|
||||||
Target = "Parameter",
|
Target = "Parameter",
|
||||||
Name = "EyeBlink",
|
Name = "EyeBlink",
|
||||||
Ids = EyeBlinkParameters.ToArray()
|
Ids = eyeBlinkParameters.ToArray()
|
||||||
});
|
});
|
||||||
groups.Add(new CubismModel3Json.SerializableGroup
|
groups.Add(new CubismModel3Json.SerializableGroup
|
||||||
{
|
{
|
||||||
Target = "Parameter",
|
Target = "Parameter",
|
||||||
Name = "LipSync",
|
Name = "LipSync",
|
||||||
Ids = LipSyncParameters.ToArray()
|
Ids = lipSyncParameters.ToArray()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//model
|
||||||
var model3 = new CubismModel3Json
|
var model3 = new CubismModel3Json
|
||||||
{
|
{
|
||||||
Version = 3,
|
Version = 3,
|
||||||
@@ -408,90 +276,140 @@ namespace CubismLive2DExtractor
|
|||||||
{
|
{
|
||||||
Moc = $"{modelName}.moc3",
|
Moc = $"{modelName}.moc3",
|
||||||
Textures = textures.ToArray(),
|
Textures = textures.ToArray(),
|
||||||
DisplayInfo = isCdiParsed ? $"{modelName}.cdi3.json" : null,
|
|
||||||
Physics = PhysicsMono != null ? $"{modelName}.physics3.json" : null,
|
|
||||||
Motions = JObject.FromObject(motions),
|
Motions = JObject.FromObject(motions),
|
||||||
Expressions = expressions,
|
Expressions = expressions,
|
||||||
},
|
},
|
||||||
Groups = groups.ToArray()
|
Groups = groups.ToArray()
|
||||||
};
|
};
|
||||||
|
if (physics != null)
|
||||||
|
{
|
||||||
|
model3.FileReferences.Physics = $"{modelName}.physics3.json";
|
||||||
|
}
|
||||||
File.WriteAllText($"{destPath}{modelName}.model3.json", JsonConvert.SerializeObject(model3, Formatting.Indented));
|
File.WriteAllText($"{destPath}{modelName}.model3.json", JsonConvert.SerializeObject(model3, Formatting.Indented));
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExportFadeMotions(string destMotionPath, AssemblyLoader assemblyLoader, bool forceBezier, SortedDictionary<string, JArray> motions)
|
private static string ParsePhysics(MonoBehaviour physics, AssemblyLoader assemblyLoader)
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(destMotionPath);
|
var physicsObj = physics.ToType();
|
||||||
foreach (var fadeMotionMono in FadeMotions)
|
if (physicsObj == null)
|
||||||
{
|
{
|
||||||
var fadeMotionDict = ParseMonoBehaviour(fadeMotionMono, CubismMonoBehaviourType.FadeMotion, assemblyLoader);
|
var m_Type = physics.ConvertToTypeTree(assemblyLoader);
|
||||||
if (fadeMotionDict == null)
|
physicsObj = physics.ToType(m_Type);
|
||||||
continue;
|
if (physicsObj == null)
|
||||||
|
|
||||||
var fadeMotion = JsonConvert.DeserializeObject<CubismFadeMotion>(JsonConvert.SerializeObject(fadeMotionDict));
|
|
||||||
if (fadeMotion.ParameterIds.Length == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var motionJson = new CubismMotion3Json(fadeMotion, ParameterNames, PartNames, forceBezier);
|
|
||||||
|
|
||||||
var animName = Path.GetFileNameWithoutExtension(fadeMotion.m_Name);
|
|
||||||
if (motions.ContainsKey(animName))
|
|
||||||
{
|
{
|
||||||
animName = $"{animName}_{fadeMotion.GetHashCode()}";
|
throw new Exception("MonoBehaviour is not readable.");
|
||||||
if (motions.ContainsKey(animName))
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
var motionPath = new JObject(new JProperty("File", $"motions/{animName}.motion3.json"));
|
|
||||||
motions.Add(animName, new JArray(motionPath));
|
|
||||||
File.WriteAllText($"{destMotionPath}{animName}.motion3.json", JsonConvert.SerializeObject(motionJson, Formatting.Indented, new MyJsonConverter()));
|
|
||||||
}
|
}
|
||||||
|
var cubismPhysicsRig = JsonConvert.DeserializeObject<CubismPhysics>(JsonConvert.SerializeObject(physicsObj))._rig;
|
||||||
|
|
||||||
|
var physicsSettings = new CubismPhysics3Json.SerializablePhysicsSettings[cubismPhysicsRig.SubRigs.Length];
|
||||||
|
for (int i = 0; i < physicsSettings.Length; i++)
|
||||||
|
{
|
||||||
|
var subRigs = cubismPhysicsRig.SubRigs[i];
|
||||||
|
physicsSettings[i] = new CubismPhysics3Json.SerializablePhysicsSettings
|
||||||
|
{
|
||||||
|
Id = $"PhysicsSetting{i + 1}",
|
||||||
|
Input = new CubismPhysics3Json.SerializableInput[subRigs.Input.Length],
|
||||||
|
Output = new CubismPhysics3Json.SerializableOutput[subRigs.Output.Length],
|
||||||
|
Vertices = new CubismPhysics3Json.SerializableVertex[subRigs.Particles.Length],
|
||||||
|
Normalization = new CubismPhysics3Json.SerializableNormalization
|
||||||
|
{
|
||||||
|
Position = new CubismPhysics3Json.SerializableNormalizationValue
|
||||||
|
{
|
||||||
|
Minimum = subRigs.Normalization.Position.Minimum,
|
||||||
|
Default = subRigs.Normalization.Position.Default,
|
||||||
|
Maximum = subRigs.Normalization.Position.Maximum
|
||||||
|
},
|
||||||
|
Angle = new CubismPhysics3Json.SerializableNormalizationValue
|
||||||
|
{
|
||||||
|
Minimum = subRigs.Normalization.Angle.Minimum,
|
||||||
|
Default = subRigs.Normalization.Angle.Default,
|
||||||
|
Maximum = subRigs.Normalization.Angle.Maximum
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (int j = 0; j < subRigs.Input.Length; j++)
|
||||||
|
{
|
||||||
|
var input = subRigs.Input[j];
|
||||||
|
physicsSettings[i].Input[j] = new CubismPhysics3Json.SerializableInput
|
||||||
|
{
|
||||||
|
Source = new CubismPhysics3Json.SerializableParameter
|
||||||
|
{
|
||||||
|
Target = "Parameter", //同名GameObject父节点的名称
|
||||||
|
Id = input.SourceId
|
||||||
|
},
|
||||||
|
Weight = input.Weight,
|
||||||
|
Type = Enum.GetName(typeof(CubismPhysicsSourceComponent), input.SourceComponent),
|
||||||
|
Reflect = input.IsInverted
|
||||||
|
};
|
||||||
|
}
|
||||||
|
for (int j = 0; j < subRigs.Output.Length; j++)
|
||||||
|
{
|
||||||
|
var output = subRigs.Output[j];
|
||||||
|
physicsSettings[i].Output[j] = new CubismPhysics3Json.SerializableOutput
|
||||||
|
{
|
||||||
|
Destination = new CubismPhysics3Json.SerializableParameter
|
||||||
|
{
|
||||||
|
Target = "Parameter", //同名GameObject父节点的名称
|
||||||
|
Id = output.DestinationId
|
||||||
|
},
|
||||||
|
VertexIndex = output.ParticleIndex,
|
||||||
|
Scale = output.AngleScale,
|
||||||
|
Weight = output.Weight,
|
||||||
|
Type = Enum.GetName(typeof(CubismPhysicsSourceComponent), output.SourceComponent),
|
||||||
|
Reflect = output.IsInverted
|
||||||
|
};
|
||||||
|
}
|
||||||
|
for (int j = 0; j < subRigs.Particles.Length; j++)
|
||||||
|
{
|
||||||
|
var particles = subRigs.Particles[j];
|
||||||
|
physicsSettings[i].Vertices[j] = new CubismPhysics3Json.SerializableVertex
|
||||||
|
{
|
||||||
|
Position = particles.InitialPosition,
|
||||||
|
Mobility = particles.Mobility,
|
||||||
|
Delay = particles.Delay,
|
||||||
|
Acceleration = particles.Acceleration,
|
||||||
|
Radius = particles.Radius
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var physicsDictionary = new CubismPhysics3Json.SerializablePhysicsDictionary[physicsSettings.Length];
|
||||||
|
for (int i = 0; i < physicsSettings.Length; i++)
|
||||||
|
{
|
||||||
|
physicsDictionary[i] = new CubismPhysics3Json.SerializablePhysicsDictionary
|
||||||
|
{
|
||||||
|
Id = $"PhysicsSetting{i + 1}",
|
||||||
|
Name = $"Dummy{i + 1}"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var physicsJson = new CubismPhysics3Json
|
||||||
|
{
|
||||||
|
Version = 3,
|
||||||
|
Meta = new CubismPhysics3Json.SerializableMeta
|
||||||
|
{
|
||||||
|
PhysicsSettingCount = cubismPhysicsRig.SubRigs.Length,
|
||||||
|
TotalInputCount = cubismPhysicsRig.SubRigs.Sum(x => x.Input.Length),
|
||||||
|
TotalOutputCount = cubismPhysicsRig.SubRigs.Sum(x => x.Output.Length),
|
||||||
|
VertexCount = cubismPhysicsRig.SubRigs.Sum(x => x.Particles.Length),
|
||||||
|
EffectiveForces = new CubismPhysics3Json.SerializableEffectiveForces
|
||||||
|
{
|
||||||
|
Gravity = cubismPhysicsRig.Gravity,
|
||||||
|
Wind = cubismPhysicsRig.Wind
|
||||||
|
},
|
||||||
|
PhysicsDictionary = physicsDictionary
|
||||||
|
},
|
||||||
|
PhysicsSettings = physicsSettings
|
||||||
|
};
|
||||||
|
return JsonConvert.SerializeObject(physicsJson, Formatting.Indented, new MyJsonConverter2());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ExportClipMotions(string destMotionPath, CubismMotion3Converter converter, bool forceBezier, SortedDictionary<string, JArray> motions)
|
private static byte[] ParseMoc(MonoBehaviour moc)
|
||||||
{
|
{
|
||||||
if (converter == null)
|
var reader = moc.reader;
|
||||||
return;
|
reader.Reset();
|
||||||
|
reader.Position += 28; //PPtr<GameObject> m_GameObject, m_Enabled, PPtr<MonoScript>
|
||||||
if (converter.AnimationList.Count > 0)
|
reader.ReadAlignedString(); //m_Name
|
||||||
{
|
return reader.ReadBytes(reader.ReadInt32());
|
||||||
Directory.CreateDirectory(destMotionPath);
|
|
||||||
}
|
|
||||||
foreach (var animation in converter.AnimationList)
|
|
||||||
{
|
|
||||||
var animName = animation.Name;
|
|
||||||
if (animation.TrackList.Count == 0)
|
|
||||||
{
|
|
||||||
Logger.Warning($"Motion \"{animName}\" is empty. Export skipped");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var motionJson = new CubismMotion3Json(animation, forceBezier);
|
|
||||||
|
|
||||||
if (motions.ContainsKey(animName))
|
|
||||||
{
|
|
||||||
animName = $"{animName}_{animation.GetHashCode()}";
|
|
||||||
|
|
||||||
if (motions.ContainsKey(animName))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var motionPath = new JObject(new JProperty("File", $"motions/{animName}.motion3.json"));
|
|
||||||
motions.Add(animName, new JArray(motionPath));
|
|
||||||
File.WriteAllText($"{destMotionPath}{animName}.motion3.json", JsonConvert.SerializeObject(motionJson, Formatting.Indented, new MyJsonConverter()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetDisplayName(MonoBehaviour cdiMono, AssemblyLoader assemblyLoader)
|
|
||||||
{
|
|
||||||
var dict = ParseMonoBehaviour(cdiMono, CubismMonoBehaviourType.DisplayInfo, assemblyLoader);
|
|
||||||
if (dict == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var name = (string)dict["Name"];
|
|
||||||
if (dict.Contains("DisplayName"))
|
|
||||||
{
|
|
||||||
var displayName = (string)dict["DisplayName"];
|
|
||||||
name = displayName != "" ? displayName : name;
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
public enum Live2DMotionMode
|
public enum Live2DMotionMode
|
||||||
{
|
{
|
||||||
MonoBehaviour,
|
MonoBehaviour,
|
||||||
AnimationClipV1,
|
AnimationClip
|
||||||
AnimationClipV2,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private ImageFormat imageFormat;
|
private ImageFormat imageFormat;
|
||||||
private Avatar avatar;
|
private Avatar avatar;
|
||||||
private AnimationClip[] animationClipUniqArray = Array.Empty<AnimationClip>(); //TODO: a proper AnimationClip equality comparer
|
private HashSet<AnimationClip> animationClipHashSet = new HashSet<AnimationClip>();
|
||||||
private Dictionary<AnimationClip, string> boundAnimationPathDic = new Dictionary<AnimationClip, string>();
|
private Dictionary<AnimationClip, string> boundAnimationPathDic = new Dictionary<AnimationClip, string>();
|
||||||
private Dictionary<uint, string> bonePathHash = new Dictionary<uint, string>();
|
private Dictionary<uint, string> bonePathHash = new Dictionary<uint, string>();
|
||||||
private Dictionary<Texture2D, string> textureNameDictionary = new Dictionary<Texture2D, string>();
|
private Dictionary<Texture2D, string> textureNameDictionary = new Dictionary<Texture2D, string>();
|
||||||
@@ -40,7 +40,10 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
if (animationList != null)
|
if (animationList != null)
|
||||||
{
|
{
|
||||||
animationClipUniqArray = animationList.Distinct().ToArray();
|
foreach (var animationClip in animationList)
|
||||||
|
{
|
||||||
|
animationClipHashSet.Add(animationClip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ConvertAnimations();
|
ConvertAnimations();
|
||||||
}
|
}
|
||||||
@@ -67,7 +70,10 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
if (animationList != null)
|
if (animationList != null)
|
||||||
{
|
{
|
||||||
animationClipUniqArray = animationList.Distinct().ToArray();
|
foreach (var animationClip in animationList)
|
||||||
|
{
|
||||||
|
animationClipHashSet.Add(animationClip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ConvertAnimations();
|
ConvertAnimations();
|
||||||
}
|
}
|
||||||
@@ -82,7 +88,10 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
animationClipUniqArray = animationList.Distinct().ToArray();
|
foreach (var animationClip in animationList)
|
||||||
|
{
|
||||||
|
animationClipHashSet.Add(animationClip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ConvertAnimations();
|
ConvertAnimations();
|
||||||
}
|
}
|
||||||
@@ -151,7 +160,6 @@ namespace AssetStudio
|
|||||||
|
|
||||||
if (m_GameObject.m_Animation != null)
|
if (m_GameObject.m_Animation != null)
|
||||||
{
|
{
|
||||||
var animationList = new List<AnimationClip>();
|
|
||||||
foreach (var animation in m_GameObject.m_Animation.m_Animations)
|
foreach (var animation in m_GameObject.m_Animation.m_Animations)
|
||||||
{
|
{
|
||||||
if (animation.TryGet(out var animationClip))
|
if (animation.TryGet(out var animationClip))
|
||||||
@@ -160,10 +168,9 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
boundAnimationPathDic.Add(animationClip, GetTransformPath(m_Transform));
|
boundAnimationPathDic.Add(animationClip, GetTransformPath(m_Transform));
|
||||||
}
|
}
|
||||||
animationList.Add(animationClip);
|
animationClipHashSet.Add(animationClip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
animationClipUniqArray = animationList.Distinct().ToArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var pptr in m_Transform.m_Children)
|
foreach (var pptr in m_Transform.m_Children)
|
||||||
@@ -177,7 +184,6 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
if (m_Animator.m_Controller.TryGet(out var m_Controller))
|
if (m_Animator.m_Controller.TryGet(out var m_Controller))
|
||||||
{
|
{
|
||||||
var animationList = new List<AnimationClip>();
|
|
||||||
switch (m_Controller)
|
switch (m_Controller)
|
||||||
{
|
{
|
||||||
case AnimatorOverrideController m_AnimatorOverrideController:
|
case AnimatorOverrideController m_AnimatorOverrideController:
|
||||||
@@ -188,7 +194,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
if (pptr.TryGet(out var m_AnimationClip))
|
if (pptr.TryGet(out var m_AnimationClip))
|
||||||
{
|
{
|
||||||
animationList.Add(m_AnimationClip);
|
animationClipHashSet.Add(m_AnimationClip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -201,13 +207,12 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
if (pptr.TryGet(out var m_AnimationClip))
|
if (pptr.TryGet(out var m_AnimationClip))
|
||||||
{
|
{
|
||||||
animationList.Add(m_AnimationClip);
|
animationClipHashSet.Add(m_AnimationClip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
animationClipUniqArray = animationList.Distinct().ToArray();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,7 +371,6 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
if (iMesh.hasUV[uv])
|
if (iMesh.hasUV[uv])
|
||||||
{
|
{
|
||||||
c = 4;
|
|
||||||
var m_UV = mesh.GetUV(uv);
|
var m_UV = mesh.GetUV(uv);
|
||||||
if (m_UV.Length == mesh.m_VertexCount * 2)
|
if (m_UV.Length == mesh.m_VertexCount * 2)
|
||||||
{
|
{
|
||||||
@@ -765,7 +769,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private void ConvertAnimations()
|
private void ConvertAnimations()
|
||||||
{
|
{
|
||||||
foreach (var animationClip in animationClipUniqArray)
|
foreach (var animationClip in animationClipHashSet)
|
||||||
{
|
{
|
||||||
var iAnim = new ImportedKeyframedAnimation();
|
var iAnim = new ImportedKeyframedAnimation();
|
||||||
var name = animationClip.m_Name;
|
var name = animationClip.m_Name;
|
||||||
@@ -873,7 +877,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var m_Clip = animationClip.m_MuscleClip.m_Clip.data;
|
var m_Clip = animationClip.m_MuscleClip.m_Clip;
|
||||||
var streamedFrames = m_Clip.m_StreamedClip.ReadData();
|
var streamedFrames = m_Clip.m_StreamedClip.ReadData();
|
||||||
var m_ClipBindingConstant = animationClip.m_ClipBindingConstant ?? m_Clip.ConvertValueArrayToGenericBinding();
|
var m_ClipBindingConstant = animationClip.m_ClipBindingConstant ?? m_Clip.ConvertValueArrayToGenericBinding();
|
||||||
for (int frameIndex = 1; frameIndex < streamedFrames.Count - 1; frameIndex++)
|
for (int frameIndex = 1; frameIndex < streamedFrames.Count - 1; frameIndex++)
|
||||||
@@ -1012,16 +1016,18 @@ namespace AssetStudio
|
|||||||
private void CreateBonePathHash(Transform m_Transform)
|
private void CreateBonePathHash(Transform m_Transform)
|
||||||
{
|
{
|
||||||
var name = GetTransformPathByFather(m_Transform);
|
var name = GetTransformPathByFather(m_Transform);
|
||||||
|
var crc = new SevenZip.CRC();
|
||||||
var bytes = Encoding.UTF8.GetBytes(name);
|
var bytes = Encoding.UTF8.GetBytes(name);
|
||||||
var crc = SevenZip.CRC.CalculateDigest(bytes, 0, (uint)bytes.Length);
|
crc.Update(bytes, 0, (uint)bytes.Length);
|
||||||
bonePathHash[crc] = name;
|
bonePathHash[crc.GetDigest()] = name;
|
||||||
int index;
|
int index;
|
||||||
while ((index = name.IndexOf("/", StringComparison.Ordinal)) >= 0)
|
while ((index = name.IndexOf("/", StringComparison.Ordinal)) >= 0)
|
||||||
{
|
{
|
||||||
name = name.Substring(index + 1);
|
name = name.Substring(index + 1);
|
||||||
|
crc = new SevenZip.CRC();
|
||||||
bytes = Encoding.UTF8.GetBytes(name);
|
bytes = Encoding.UTF8.GetBytes(name);
|
||||||
crc = SevenZip.CRC.CalculateDigest(bytes, 0, (uint)bytes.Length);
|
crc.Update(bytes, 0, (uint)bytes.Length);
|
||||||
bonePathHash[crc] = name;
|
bonePathHash[crc.GetDigest()] = name;
|
||||||
}
|
}
|
||||||
foreach (var pptr in m_Transform.m_Children)
|
foreach (var pptr in m_Transform.m_Children)
|
||||||
{
|
{
|
||||||
@@ -1096,7 +1102,10 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
return null;
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public class SerializedTypeHelper
|
public class SerializedTypeHelper
|
||||||
{
|
{
|
||||||
private readonly UnityVersion version;
|
private readonly int[] version;
|
||||||
|
|
||||||
public SerializedTypeHelper(UnityVersion version)
|
public SerializedTypeHelper(int[] version)
|
||||||
{
|
{
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
nodes.Add(new TypeTreeNode($"PPtr<{type}>", name, indent, false));
|
nodes.Add(new TypeTreeNode($"PPtr<{type}>", name, indent, false));
|
||||||
nodes.Add(new TypeTreeNode("int", "m_FileID", indent + 1, false));
|
nodes.Add(new TypeTreeNode("int", "m_FileID", indent + 1, false));
|
||||||
if (version >= 5) //5.0 and up
|
if (version[0] >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
nodes.Add(new TypeTreeNode("SInt64", "m_PathID", indent + 1, false));
|
nodes.Add(new TypeTreeNode("SInt64", "m_PathID", indent + 1, false));
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ namespace AssetStudio
|
|||||||
nodes.Add(new TypeTreeNode("float", "value", indent + 4, false));
|
nodes.Add(new TypeTreeNode("float", "value", indent + 4, false));
|
||||||
nodes.Add(new TypeTreeNode("float", "inSlope", indent + 4, false));
|
nodes.Add(new TypeTreeNode("float", "inSlope", indent + 4, false));
|
||||||
nodes.Add(new TypeTreeNode("float", "outSlope", indent + 4, false));
|
nodes.Add(new TypeTreeNode("float", "outSlope", indent + 4, false));
|
||||||
if (version >= 2018) //2018 and up
|
if (version[0] >= 2018) //2018 and up
|
||||||
{
|
{
|
||||||
nodes.Add(new TypeTreeNode("int", "weightedMode", indent + 4, false));
|
nodes.Add(new TypeTreeNode("int", "weightedMode", indent + 4, false));
|
||||||
nodes.Add(new TypeTreeNode("float", "inWeight", indent + 4, false));
|
nodes.Add(new TypeTreeNode("float", "inWeight", indent + 4, false));
|
||||||
@@ -66,7 +66,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
nodes.Add(new TypeTreeNode("int", "m_PreInfinity", indent + 1, false));
|
nodes.Add(new TypeTreeNode("int", "m_PreInfinity", indent + 1, false));
|
||||||
nodes.Add(new TypeTreeNode("int", "m_PostInfinity", indent + 1, false));
|
nodes.Add(new TypeTreeNode("int", "m_PostInfinity", indent + 1, false));
|
||||||
if (version >= (5, 3)) //5.3 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3)) //5.3 and up
|
||||||
{
|
{
|
||||||
nodes.Add(new TypeTreeNode("int", "m_RotationOrder", indent + 1, false));
|
nodes.Add(new TypeTreeNode("int", "m_RotationOrder", indent + 1, false));
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ namespace AssetStudio
|
|||||||
public void AddGradient(List<TypeTreeNode> nodes, string name, int indent)
|
public void AddGradient(List<TypeTreeNode> nodes, string name, int indent)
|
||||||
{
|
{
|
||||||
nodes.Add(new TypeTreeNode("Gradient", name, indent, false));
|
nodes.Add(new TypeTreeNode("Gradient", name, indent, false));
|
||||||
if (version >= (5, 6)) //5.6 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
|
||||||
{
|
{
|
||||||
AddColorRGBA(nodes, "key0", indent + 1);
|
AddColorRGBA(nodes, "key0", indent + 1);
|
||||||
AddColorRGBA(nodes, "key1", indent + 1);
|
AddColorRGBA(nodes, "key1", indent + 1);
|
||||||
@@ -113,7 +113,7 @@ namespace AssetStudio
|
|||||||
nodes.Add(new TypeTreeNode("UInt16", "atime5", indent + 1, false));
|
nodes.Add(new TypeTreeNode("UInt16", "atime5", indent + 1, false));
|
||||||
nodes.Add(new TypeTreeNode("UInt16", "atime6", indent + 1, false));
|
nodes.Add(new TypeTreeNode("UInt16", "atime6", indent + 1, false));
|
||||||
nodes.Add(new TypeTreeNode("UInt16", "atime7", indent + 1, false));
|
nodes.Add(new TypeTreeNode("UInt16", "atime7", indent + 1, false));
|
||||||
if (version >= (5, 5)) //5.5 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5)) //5.5 and up
|
||||||
{
|
{
|
||||||
nodes.Add(new TypeTreeNode("int", "m_Mode", indent + 1, false));
|
nodes.Add(new TypeTreeNode("int", "m_Mode", indent + 1, false));
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@ namespace AssetStudio
|
|||||||
AddGUIStyleState(nodes, "m_OnActive", indent + 1);
|
AddGUIStyleState(nodes, "m_OnActive", indent + 1);
|
||||||
AddGUIStyleState(nodes, "m_OnFocused", indent + 1);
|
AddGUIStyleState(nodes, "m_OnFocused", indent + 1);
|
||||||
AddRectOffset(nodes, "m_Border", indent + 1);
|
AddRectOffset(nodes, "m_Border", indent + 1);
|
||||||
if (version >= 4) //4 and up
|
if (version[0] >= 4) //4 and up
|
||||||
{
|
{
|
||||||
AddRectOffset(nodes, "m_Margin", indent + 1);
|
AddRectOffset(nodes, "m_Margin", indent + 1);
|
||||||
AddRectOffset(nodes, "m_Padding", indent + 1);
|
AddRectOffset(nodes, "m_Padding", indent + 1);
|
||||||
@@ -146,7 +146,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
AddRectOffset(nodes, "m_Overflow", indent + 1);
|
AddRectOffset(nodes, "m_Overflow", indent + 1);
|
||||||
AddPPtr(nodes, "Font", "m_Font", indent + 1);
|
AddPPtr(nodes, "Font", "m_Font", indent + 1);
|
||||||
if (version >= 4) //4 and up
|
if (version[0] >= 4) //4 and up
|
||||||
{
|
{
|
||||||
nodes.Add(new TypeTreeNode("int", "m_FontSize", indent + 1, false));
|
nodes.Add(new TypeTreeNode("int", "m_FontSize", indent + 1, false));
|
||||||
nodes.Add(new TypeTreeNode("int", "m_FontStyle", indent + 1, false));
|
nodes.Add(new TypeTreeNode("int", "m_FontStyle", indent + 1, false));
|
||||||
@@ -171,7 +171,7 @@ namespace AssetStudio
|
|||||||
AddVector2f(nodes, "m_ClipOffset", indent + 1);
|
AddVector2f(nodes, "m_ClipOffset", indent + 1);
|
||||||
nodes.Add(new TypeTreeNode("float", "m_FixedWidth", indent + 1, false));
|
nodes.Add(new TypeTreeNode("float", "m_FixedWidth", indent + 1, false));
|
||||||
nodes.Add(new TypeTreeNode("float", "m_FixedHeight", indent + 1, false));
|
nodes.Add(new TypeTreeNode("float", "m_FixedHeight", indent + 1, false));
|
||||||
if (version >= 3) //3 and up
|
if (version[0] >= 3) //3 and up
|
||||||
{
|
{
|
||||||
nodes.Add(new TypeTreeNode("int", "m_FontSize", indent + 1, false));
|
nodes.Add(new TypeTreeNode("int", "m_FontSize", indent + 1, false));
|
||||||
nodes.Add(new TypeTreeNode("int", "m_FontStyle", indent + 1, false));
|
nodes.Add(new TypeTreeNode("int", "m_FontStyle", indent + 1, false));
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user