66 Commits

Author SHA1 Message Date
Perfare
50c17c2ec4 improved model export 2019-07-16 04:33:37 +08:00
Perfare
e001dff3de fixed bug 2019-06-14 16:17:56 +08:00
Perfare
3a0100ed37 update 2019-06-14 12:47:22 +08:00
Perfare
58ab3116db Implemented AnimationEvent 2019-06-14 11:58:59 +08:00
Perfare
6b93df41f2 fixed bug 2019-06-09 07:44:50 +08:00
Perfare
b9cf7d5874 fixed bug 2019-06-04 18:56:18 +08:00
Perfare
da4eb15d6b Fixed #400 2019-06-04 13:34:59 +08:00
Perfare
378840bc1b improved Texture2D convert 2019-06-04 13:05:49 +08:00
Perfare
3441135b2f Change the way rename same name assets 2019-06-02 14:36:35 +08:00
Perfare
afcbba8182 fixed SpriteAtlas 2019-04-26 10:48:24 +08:00
Perfare
cefdf08873 Fixed #390 2019-04-26 09:51:02 +08:00
Perfare
59be547a82 fixed bug 2019-04-18 14:07:17 +08:00
Perfare
a2be5ebdac fixed bug 2019-04-18 13:58:06 +08:00
Perfare
f76d3d8fcd fixed bugs 2019-04-18 12:31:16 +08:00
Perfare
edb6256fc9 fixed bugs 2019-04-18 11:07:51 +08:00
Perfare
8946a4fba5 2019.1 support 2019-04-18 10:46:06 +08:00
Perfare
87e1739208 Fixed #386 2019-04-14 20:17:38 +08:00
Perfare
10f4aaa39f Update README.md 2019-04-05 01:59:18 +08:00
Perfare
957073b041 move file 2019-04-04 21:14:52 +08:00
Perfare
e1bb9a6cf0 Fixed ASTC Decoding 2019-04-04 21:05:44 +08:00
Perfare
558adb0b66 Fixed #376 2019-03-28 02:55:58 +08:00
Perfare
6a4979f999 fixed bugs 2019-03-07 04:50:36 +08:00
Perfare
9e76d94eea Remove SharpDX 2019-01-24 01:03:45 +08:00
Perfare
fa91820016 FIxed #351 2019-01-24 00:35:42 +08:00
Perfare
be091ecebb Fixed #344 2019-01-15 07:37:30 +08:00
Perfare
903be743ac Fixed #345
Fixed bug
2019-01-13 23:21:45 +08:00
Perfare
c3c4697562 small fixed 2019-01-03 09:02:12 +08:00
Perfare
e6ed312de2 change math library
fixed bug
2019-01-03 08:55:43 +08:00
Perfare
33461e068f small improved 2018-12-28 10:24:32 +08:00
Perfare
7f13c90189 small improved 2018-12-24 17:38:12 +08:00
Perfare
54ed3971a2 small improved 2018-12-24 17:31:35 +08:00
Perfare
e602a5cf3b Fixed #332 2018-12-24 08:46:20 +08:00
Perfare
dec0a22ffe Fixed #297 2018-12-24 08:28:26 +08:00
Perfare
911272167a Fixed #331 2018-12-24 04:47:12 +08:00
Perfare
54d78d55a0 Fixed #326 2018-12-24 04:25:55 +08:00
Perfare
ff550b457f improved mesh read 2018-12-23 23:17:01 +08:00
Perfare
f449d7a8ab improved script dump 2018-12-23 15:51:00 +08:00
Perfare
761579ab1a Fixed bug 2018-12-18 09:59:48 +08:00
Perfare
5cd4cf67cf Update README.md 2018-12-18 02:08:55 +08:00
Perfare
fabfc77a52 improved console shader export 2018-12-17 23:12:24 +08:00
Perfare
f8ffaa0400 Fixed bug 2018-12-11 23:36:15 +08:00
Perfare
d156b5d947 small fixed 2018-12-11 15:24:49 +08:00
Perfare
d7551bdeb2 small fixed 2018-12-11 15:21:23 +08:00
Perfare
7d5e06bce4 improved shader export 2018-12-11 13:01:10 +08:00
Perfare
0bc17f0ff5 Fixed bug 2018-12-11 10:47:35 +08:00
Perfare
9edc268cd4 small improvement 2018-12-11 05:22:39 +08:00
Perfare
356d5fa8a4 Fixed Sprite read
improved script dump
2018-12-11 04:50:38 +08:00
Perfare
eb170d4f34 minor improvements 2018-12-09 11:56:24 +08:00
Perfare
324c5ec7a2 Fixed bug 2018-12-05 23:16:02 +08:00
Perfare
ae155ca603 Fixed bug 2018-12-05 23:08:39 +08:00
Perfare
eb13585174 2018.3.0b support
Refactor mesh read
Fixed bug
2018-12-05 22:35:05 +08:00
Perfare
98c9eea58a Improved file reading 2018-12-03 02:42:07 +08:00
John Lyu
067517740f try to fix IO exceptions with valid assetsFile. (#317) 2018-11-28 20:16:18 +08:00
Perfare
3addb0e894 improve Sprite export 2018-11-28 15:02:31 +08:00
Perfare
7452d4275e minor improvements 2018-11-26 08:47:20 +08:00
Perfare
96ea522e83 minor improvements 2018-11-25 15:50:28 +08:00
Perfare
ab24f049cf Completed tight Sprite export 2018-11-25 12:37:55 +08:00
Perfare
ec9184ba93 Fixed #302 2018-11-24 23:30:04 +08:00
Perfare
0a5b866a03 rename
move files
improve Sprite read
2018-11-24 23:02:05 +08:00
Perfare
58d5a3fc37 minor fixes 2018-11-24 04:42:45 +08:00
Perfare
19534ebb4d minor fixes 2018-11-22 14:45:28 +08:00
Perfare
0a764c74d6 Fixed #284 2018-11-22 13:38:07 +08:00
Perfare
ab5f5fbd9d Restore the extension of TextAsset
Export Animator to a separate folder
2018-11-22 12:17:16 +08:00
Perfare
7dbc2ff95d Fixed #311 2018-11-21 16:13:32 +08:00
Perfare
bfaa207853 Refactor read assets
Generic PPtr
Misc
2018-11-21 15:37:56 +08:00
Perfare
8c749e21e1 improve 2018-11-20 16:47:35 +08:00
125 changed files with 7573 additions and 4697 deletions

View File

@@ -7,7 +7,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioGUI", "AssetStud
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssetStudioFBX", "AssetStudioFBX\AssetStudioFBX.vcxproj", "{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioTools", "AssetStudioTools\AssetStudioTools.csproj", "{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioUtility", "AssetStudioUtility\AssetStudioUtility.csproj", "{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudio", "AssetStudio\AssetStudio.csproj", "{AF56B63C-1764-41B7-9E60-8D485422AC3B}"
EndProject

View File

@@ -31,15 +31,9 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="SharpDX.Mathematics">
<HintPath>Libraries\SharpDX.Mathematics.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Half">
<HintPath>Libraries\System.Half.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@@ -62,7 +56,18 @@
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBit.cs" />
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBitTree.cs" />
<Compile Include="7zip\ICoder.cs" />
<Compile Include="Utility\IImported.cs" />
<Compile Include="Classes\RuntimeAnimatorController.cs" />
<Compile Include="Math\Color.cs" />
<Compile Include="Math\Half.cs" />
<Compile Include="Math\HalfHelper.cs" />
<Compile Include="Math\Matrix4x4.cs" />
<Compile Include="Math\Quaternion.cs" />
<Compile Include="Math\Vector2.cs" />
<Compile Include="Math\Vector3.cs" />
<Compile Include="Math\Vector4.cs" />
<Compile Include="UType.cs" />
<Compile Include="ResourceReader.cs" />
<Compile Include="IImported.cs" />
<Compile Include="SerializedFile.cs" />
<Compile Include="AssetsManager.cs" />
<Compile Include="Extensions\BinaryReaderExtensions.cs" />
@@ -124,18 +129,17 @@
<Compile Include="CommonString.cs" />
<Compile Include="EndianBinaryReader.cs" />
<Compile Include="FileIdentifier.cs" />
<Compile Include="Utility\ILogger.cs" />
<Compile Include="ILogger.cs" />
<Compile Include="ImportHelper.cs" />
<Compile Include="Utility\IProgress.cs" />
<Compile Include="IProgress.cs" />
<Compile Include="LocalSerializedObjectIdentifier.cs" />
<Compile Include="Utility\Logger.cs" />
<Compile Include="Logger.cs" />
<Compile Include="Lz4DecoderStream.cs" />
<Compile Include="ObjectInfo.cs" />
<Compile Include="ObjectReader.cs" />
<Compile Include="Classes\PPtr.cs" />
<Compile Include="Utility\Progress.cs" />
<Compile Include="Progress.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ResourcesHelper.cs" />
<Compile Include="SerializedFileHeader.cs" />
<Compile Include="SerializedType.cs" />
<Compile Include="SevenZipHelper.cs" />
@@ -144,5 +148,6 @@
<Compile Include="TypeTreeNode.cs" />
<Compile Include="WebFile.cs" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -13,9 +13,9 @@ namespace AssetStudio
private List<string> importFiles = new List<string>();
private HashSet<string> importFilesHash = new HashSet<string>();
private HashSet<string> assetsfileListHash = new HashSet<string>();
private HashSet<string> assetsFileListHash = new HashSet<string>();
public void LoadFiles(string[] files)
public void LoadFiles(params string[] files)
{
var path = Path.GetDirectoryName(files[0]);
MergeSplitAssets(path);
@@ -38,6 +38,7 @@ namespace AssetStudio
importFiles.Add(file);
importFilesHash.Add(Path.GetFileName(file).ToUpper());
}
Progress.Reset();
//use a for loop because list size can change
for (var i = 0; i < importFiles.Count; i++)
@@ -45,9 +46,13 @@ namespace AssetStudio
LoadFile(importFiles[i]);
Progress.Report(i + 1, importFiles.Count);
}
importFiles.Clear();
importFilesHash.Clear();
assetsfileListHash.Clear();
assetsFileListHash.Clear();
ReadAssets();
ProcessGameObject();
}
private void LoadFile(string fullName)
@@ -69,14 +74,14 @@ namespace AssetStudio
private void LoadAssetsFile(string fullName, EndianBinaryReader reader)
{
var fileName = Path.GetFileName(fullName);
if (!assetsfileListHash.Contains(fileName.ToUpper()))
if (!assetsFileListHash.Contains(fileName.ToUpper()))
{
Logger.Info($"Loading {fileName}");
var assetsFile = new SerializedFile(this, fullName, reader);
if (assetsFile.valid)
try
{
var assetsFile = new SerializedFile(this, fullName, reader);
assetsFileList.Add(assetsFile);
assetsfileListHash.Add(assetsFile.upperFileName);
assetsFileListHash.Add(assetsFile.upperFileName);
foreach (var sharedFile in assetsFile.m_Externals)
{
@@ -102,9 +107,10 @@ namespace AssetStudio
}
}
}
else
catch
{
reader.Dispose();
//Logger.Error($"Unable to load assets file {fileName}");
}
}
else
@@ -115,24 +121,27 @@ namespace AssetStudio
private void LoadAssetsFromMemory(string fullName, EndianBinaryReader reader, string originalPath, string unityVersion = null)
{
var fileName = Path.GetFileName(fullName);
if (!assetsfileListHash.Contains(fileName.ToUpper()))
var upperFileName = Path.GetFileName(fullName).ToUpper();
if (!assetsFileListHash.Contains(upperFileName))
{
Logger.Info($"Loading {fileName}");
var assetsFile = new SerializedFile(this, fullName, reader);
if (assetsFile.valid)
try
{
var assetsFile = new SerializedFile(this, fullName, reader);
assetsFile.originalPath = originalPath;
if (assetsFile.header.m_Version < 7)
{
assetsFile.SetVersion(unityVersion);
}
assetsFileList.Add(assetsFile);
assetsfileListHash.Add(assetsFile.upperFileName);
assetsFileListHash.Add(assetsFile.upperFileName);
}
else
catch
{
resourceFileReaders.Add(assetsFile.upperFileName, assetsFile.reader);
//Logger.Error($"Unable to load assets file {fileName} from {Path.GetFileName(originalPath)}");
}
finally
{
resourceFileReaders.Add(upperFileName, reader);
}
}
}
@@ -140,13 +149,28 @@ namespace AssetStudio
private void LoadBundleFile(string fullName, EndianBinaryReader reader, string parentPath = null)
{
var fileName = Path.GetFileName(fullName);
Logger.Info("Decompressing " + fileName);
var bundleFile = new BundleFile(reader, fullName);
reader.Dispose();
foreach (var file in bundleFile.fileList)
Logger.Info("Loading " + fileName);
try
{
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
LoadAssetsFromMemory(dummyPath, new EndianBinaryReader(file.stream), parentPath ?? fullName, bundleFile.versionEngine);
var bundleFile = new BundleFile(reader, fullName);
foreach (var file in bundleFile.fileList)
{
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
LoadAssetsFromMemory(dummyPath, new EndianBinaryReader(file.stream), parentPath ?? fullName, bundleFile.versionEngine);
}
}
catch
{
/*var str = $"Unable to load bundle file {fileName}";
if (parentPath != null)
{
str += $" from {Path.GetFileName(parentPath)}";
}
Logger.Error(str);*/
}
finally
{
reader.Dispose();
}
}
@@ -154,39 +178,200 @@ namespace AssetStudio
{
var fileName = Path.GetFileName(fullName);
Logger.Info("Loading " + fileName);
var webFile = new WebFile(reader);
reader.Dispose();
foreach (var file in webFile.fileList)
try
{
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
switch (CheckFileType(file.stream, out reader))
var webFile = new WebFile(reader);
foreach (var file in webFile.fileList)
{
case FileType.AssetsFile:
LoadAssetsFromMemory(dummyPath, reader, fullName);
break;
case FileType.BundleFile:
LoadBundleFile(dummyPath, reader, fullName);
break;
case FileType.WebFile:
LoadWebFile(dummyPath, reader);
break;
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
switch (CheckFileType(file.stream, out var fileReader))
{
case FileType.AssetsFile:
LoadAssetsFromMemory(dummyPath, fileReader, fullName);
break;
case FileType.BundleFile:
LoadBundleFile(dummyPath, fileReader, fullName);
break;
case FileType.WebFile:
LoadWebFile(dummyPath, fileReader);
break;
}
}
}
catch
{
//Logger.Error($"Unable to load web file {fileName}");
}
finally
{
reader.Dispose();
}
}
public void Clear()
{
foreach (var assetsFile in assetsFileList)
{
assetsFile.Objects.Clear();
assetsFile.reader.Close();
}
assetsFileList.Clear();
foreach (var resourceFileReader in resourceFileReaders)
{
resourceFileReader.Value.Close();
}
resourceFileReaders.Clear();
assetsFileIndexCache.Clear();
}
private void ReadAssets()
{
Logger.Info("Read assets...");
var progressCount = assetsFileList.Sum(x => x.m_Objects.Count);
int i = 0;
Progress.Reset();
foreach (var assetsFile in assetsFileList)
{
assetsFile.Objects = new Dictionary<long, Object>(assetsFile.m_Objects.Count);
foreach (var objectInfo in assetsFile.m_Objects)
{
var objectReader = new ObjectReader(assetsFile.reader, assetsFile, objectInfo);
switch (objectReader.type)
{
case ClassIDType.Animation:
assetsFile.Objects.Add(objectInfo.m_PathID, new Animation(objectReader));
break;
case ClassIDType.AnimationClip:
assetsFile.Objects.Add(objectInfo.m_PathID, new AnimationClip(objectReader));
break;
case ClassIDType.Animator:
assetsFile.Objects.Add(objectInfo.m_PathID, new Animator(objectReader));
break;
case ClassIDType.AnimatorController:
assetsFile.Objects.Add(objectInfo.m_PathID, new AnimatorController(objectReader));
break;
case ClassIDType.AnimatorOverrideController:
assetsFile.Objects.Add(objectInfo.m_PathID, new AnimatorOverrideController(objectReader));
break;
case ClassIDType.AssetBundle:
assetsFile.Objects.Add(objectInfo.m_PathID, new AssetBundle(objectReader));
break;
case ClassIDType.AudioClip:
assetsFile.Objects.Add(objectInfo.m_PathID, new AudioClip(objectReader));
break;
case ClassIDType.Avatar:
assetsFile.Objects.Add(objectInfo.m_PathID, new Avatar(objectReader));
break;
case ClassIDType.Font:
assetsFile.Objects.Add(objectInfo.m_PathID, new Font(objectReader));
break;
case ClassIDType.GameObject:
assetsFile.Objects.Add(objectInfo.m_PathID, new GameObject(objectReader));
break;
case ClassIDType.Material:
assetsFile.Objects.Add(objectInfo.m_PathID, new Material(objectReader));
break;
case ClassIDType.Mesh:
assetsFile.Objects.Add(objectInfo.m_PathID, new Mesh(objectReader));
break;
case ClassIDType.MeshFilter:
assetsFile.Objects.Add(objectInfo.m_PathID, new MeshFilter(objectReader));
break;
case ClassIDType.MeshRenderer:
assetsFile.Objects.Add(objectInfo.m_PathID, new MeshRenderer(objectReader));
break;
case ClassIDType.MonoBehaviour:
assetsFile.Objects.Add(objectInfo.m_PathID, new MonoBehaviour(objectReader));
break;
case ClassIDType.MonoScript:
assetsFile.Objects.Add(objectInfo.m_PathID, new MonoScript(objectReader));
break;
case ClassIDType.MovieTexture:
assetsFile.Objects.Add(objectInfo.m_PathID, new MovieTexture(objectReader));
break;
case ClassIDType.PlayerSettings:
assetsFile.Objects.Add(objectInfo.m_PathID, new PlayerSettings(objectReader));
break;
case ClassIDType.RectTransform:
assetsFile.Objects.Add(objectInfo.m_PathID, new RectTransform(objectReader));
break;
case ClassIDType.Shader:
assetsFile.Objects.Add(objectInfo.m_PathID, new Shader(objectReader));
break;
case ClassIDType.SkinnedMeshRenderer:
assetsFile.Objects.Add(objectInfo.m_PathID, new SkinnedMeshRenderer(objectReader));
break;
case ClassIDType.Sprite:
assetsFile.Objects.Add(objectInfo.m_PathID, new Sprite(objectReader));
break;
case ClassIDType.SpriteAtlas:
assetsFile.Objects.Add(objectInfo.m_PathID, new SpriteAtlas(objectReader));
break;
case ClassIDType.TextAsset:
assetsFile.Objects.Add(objectInfo.m_PathID, new TextAsset(objectReader));
break;
case ClassIDType.Texture2D:
assetsFile.Objects.Add(objectInfo.m_PathID, new Texture2D(objectReader));
break;
case ClassIDType.Transform:
assetsFile.Objects.Add(objectInfo.m_PathID, new Transform(objectReader));
break;
case ClassIDType.VideoClip:
assetsFile.Objects.Add(objectInfo.m_PathID, new VideoClip(objectReader));
break;
default:
assetsFile.Objects.Add(objectInfo.m_PathID, new Object(objectReader));
break;
}
Progress.Report(++i, progressCount);
}
}
}
private void ProcessGameObject()
{
Logger.Info("Process GameObject...");
foreach (var assetsFile in assetsFileList)
{
foreach (var obj in assetsFile.Objects.Values)
{
if (obj is GameObject m_GameObject)
{
foreach (var pptr in m_GameObject.m_Components)
{
if (pptr.TryGet(out var m_Component))
{
switch (m_Component)
{
case Transform m_Transform:
m_GameObject.m_Transform = m_Transform;
break;
case MeshRenderer m_MeshRenderer:
m_GameObject.m_MeshRenderer = m_MeshRenderer;
break;
case MeshFilter m_MeshFilter:
m_GameObject.m_MeshFilter = m_MeshFilter;
break;
case SkinnedMeshRenderer m_SkinnedMeshRenderer:
m_GameObject.m_SkinnedMeshRenderer = m_SkinnedMeshRenderer;
break;
case Animator m_Animator:
m_GameObject.m_Animator = m_Animator;
break;
case Animation m_Animation:
m_GameObject.m_Animation = m_Animation;
break;
}
}
}
}
}
}
}
}
}
}

View File

@@ -7,16 +7,16 @@ namespace AssetStudio
{
public sealed class Animation : Behaviour
{
public List<PPtr> m_Animations;
public PPtr<AnimationClip>[] m_Animations;
public Animation(ObjectReader reader) : base(reader)
{
var m_Animation = reader.ReadPPtr();
var m_Animation = new PPtr<AnimationClip>(reader);
int numAnimations = reader.ReadInt32();
m_Animations = new List<PPtr>(numAnimations);
m_Animations = new PPtr<AnimationClip>[numAnimations];
for (int i = 0; i < numAnimations; i++)
{
m_Animations.Add(reader.ReadPPtr());
m_Animations[i] = new PPtr<AnimationClip>(reader);
}
}
}

View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using SharpDX;
using System.Linq;
namespace AssetStudio
{
@@ -22,7 +22,7 @@ namespace AssetStudio
value = readerFunc();
inSlope = readerFunc();
outSlope = readerFunc();
if (reader.version[0] >= 2018)
if (reader.version[0] >= 2018) //2018 and up
{
weightedMode = reader.ReadInt32();
inWeight = readerFunc();
@@ -33,7 +33,7 @@ namespace AssetStudio
public class AnimationCurve<T>
{
public List<Keyframe<T>> m_Curve;
public Keyframe<T>[] m_Curve;
public int m_PreInfinity;
public int m_PostInfinity;
public int m_RotationOrder;
@@ -42,10 +42,10 @@ namespace AssetStudio
{
var version = reader.version;
int numCurves = reader.ReadInt32();
m_Curve = new List<Keyframe<T>>(numCurves);
m_Curve = new Keyframe<T>[numCurves];
for (int i = 0; i < numCurves; i++)
{
m_Curve.Add(new Keyframe<T>(reader, readerFunc));
m_Curve[i] = new Keyframe<T>(reader, readerFunc);
}
m_PreInfinity = reader.ReadInt32();
@@ -85,10 +85,10 @@ namespace AssetStudio
int numData = reader.ReadInt32();
m_Data = reader.ReadBytes(numData);
reader.AlignStream(4);
reader.AlignStream();
m_BitSize = reader.ReadByte();
reader.AlignStream(4);
reader.AlignStream();
}
public float[] UnpackFloats(int itemCountInChunk, int chunkStride, int start = 0, int numChunks = -1)
@@ -142,10 +142,10 @@ namespace AssetStudio
int numData = reader.ReadInt32();
m_Data = reader.ReadBytes(numData);
reader.AlignStream(4);
reader.AlignStream();
m_BitSize = reader.ReadByte();
reader.AlignStream(4);
reader.AlignStream();
}
public int[] UnpackInts()
@@ -187,7 +187,7 @@ namespace AssetStudio
int numData = reader.ReadInt32();
m_Data = reader.ReadBytes(numData);
reader.AlignStream(4);
reader.AlignStream();
}
public Quaternion[] UnpackQuats()
@@ -293,7 +293,7 @@ namespace AssetStudio
public string attribute;
public string path;
public int classID;
public PPtr script;
public PPtr<MonoScript> script;
public FloatCurve(ObjectReader reader)
@@ -302,72 +302,72 @@ namespace AssetStudio
attribute = reader.ReadAlignedString();
path = reader.ReadAlignedString();
classID = reader.ReadInt32();
script = reader.ReadPPtr();
script = new PPtr<MonoScript>(reader);
}
}
public class PPtrKeyframe
{
public float time;
public PPtr value;
public PPtr<Object> value;
public PPtrKeyframe(ObjectReader reader)
{
time = reader.ReadSingle();
value = reader.ReadPPtr();
value = new PPtr<Object>(reader);
}
}
public class PPtrCurve
{
public List<PPtrKeyframe> curve;
public PPtrKeyframe[] curve;
public string attribute;
public string path;
public int classID;
public PPtr script;
public PPtr<MonoScript> script;
public PPtrCurve(ObjectReader reader)
{
int numCurves = reader.ReadInt32();
curve = new List<PPtrKeyframe>(numCurves);
curve = new PPtrKeyframe[numCurves];
for (int i = 0; i < numCurves; i++)
{
curve.Add(new PPtrKeyframe(reader));
curve[i] = new PPtrKeyframe(reader);
}
attribute = reader.ReadAlignedString();
path = reader.ReadAlignedString();
classID = reader.ReadInt32();
script = reader.ReadPPtr();
script = new PPtr<MonoScript>(reader);
}
}
public class AABB
{
public Vector3 m_Center;
public Vector3 m_Extend;
public Vector3 m_Extent;
public AABB(ObjectReader reader)
{
m_Center = reader.ReadVector3();
m_Extend = reader.ReadVector3();
m_Extent = reader.ReadVector3();
}
}
public class xform
{
public object t;
public Vector3 t;
public Quaternion q;
public object s;
public Vector3 s;
public xform(ObjectReader reader)
{
var version = reader.version;
t = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)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();
s = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)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
}
}
@@ -383,10 +383,7 @@ namespace AssetStudio
public HandPose(ObjectReader reader)
{
m_GrabX = new xform(reader);
int numDoFs = reader.ReadInt32();
m_DoFArray = reader.ReadSingleArray(numDoFs);
m_DoFArray = reader.ReadSingleArray();
m_Override = reader.ReadSingle();
m_CloseOpen = reader.ReadSingle();
m_InOut = reader.ReadSingle();
@@ -399,7 +396,7 @@ namespace AssetStudio
public xform m_X;
public float m_WeightT;
public float m_WeightR;
public object m_HintT;
public Vector3 m_HintT;
public float m_HintWeightT;
public HumanGoal(ObjectReader reader)
@@ -410,7 +407,7 @@ namespace AssetStudio
m_WeightR = reader.ReadSingle();
if (version[0] >= 5)//5.0 and up
{
m_HintT = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)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();
}
}
@@ -419,41 +416,40 @@ namespace AssetStudio
public class HumanPose
{
public xform m_RootX;
public object m_LookAtPosition;
public Vector3 m_LookAtPosition;
public Vector4 m_LookAtWeight;
public List<HumanGoal> m_GoalArray;
public HumanGoal[] m_GoalArray;
public HandPose m_LeftHandPose;
public HandPose m_RightHandPose;
public float[] m_DoFArray;
public object[] m_TDoFArray;
public Vector3[] m_TDoFArray;
public HumanPose(ObjectReader reader)
{
var version = reader.version;
m_RootX = new xform(reader);
m_LookAtPosition = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)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();
int numGoals = reader.ReadInt32();
m_GoalArray = new List<HumanGoal>(numGoals);
m_GoalArray = new HumanGoal[numGoals];
for (int i = 0; i < numGoals; i++)
{
m_GoalArray.Add(new HumanGoal(reader));
m_GoalArray[i] = new HumanGoal(reader);
}
m_LeftHandPose = new HandPose(reader);
m_RightHandPose = new HandPose(reader);
int numDoFs = reader.ReadInt32();
m_DoFArray = reader.ReadSingleArray(numDoFs);
m_DoFArray = reader.ReadSingleArray();
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2))//5.2 and up
{
int numTDof = reader.ReadInt32();
m_TDoFArray = new object[numTDof];
m_TDoFArray = new Vector3[numTDof];
for (int i = 0; i < numTDof; i++)
{
m_TDoFArray[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)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
}
}
}
@@ -466,8 +462,7 @@ namespace AssetStudio
public StreamedClip(ObjectReader reader)
{
int numData = reader.ReadInt32();
data = reader.ReadUInt32Array(numData);
data = reader.ReadUInt32Array();
curveCount = reader.ReadUInt32();
}
@@ -509,17 +504,17 @@ namespace AssetStudio
public class StreamedFrame
{
public float time;
public List<StreamedCurveKey> keyList;
public StreamedCurveKey[] keyList;
public StreamedFrame(BinaryReader reader)
{
time = reader.ReadSingle();
int numKeys = reader.ReadInt32();
keyList = new List<StreamedCurveKey>(numKeys);
keyList = new StreamedCurveKey[numKeys];
for (int i = 0; i < numKeys; i++)
{
keyList.Add(new StreamedCurveKey(reader));
keyList[i] = new StreamedCurveKey(reader);
}
}
}
@@ -527,14 +522,13 @@ namespace AssetStudio
public List<StreamedFrame> ReadData()
{
var frameList = new List<StreamedFrame>();
using (Stream stream = new MemoryStream())
var buffer = new byte[data.Length * 4];
Buffer.BlockCopy(data, 0, buffer, 0, buffer.Length);
using (var reader = new BinaryReader(new MemoryStream(buffer)))
{
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(data);
stream.Position = 0;
while (stream.Position < stream.Length)
while (reader.BaseStream.Position < reader.BaseStream.Length)
{
frameList.Add(new StreamedFrame(new BinaryReader(stream)));
frameList.Add(new StreamedFrame(reader));
}
}
@@ -546,7 +540,7 @@ namespace AssetStudio
for (int i = frameIndex - 1; i >= 0; i--)
{
var preFrame = frameList[i];
var preCurveKey = preFrame.keyList.Find(x => x.index == curveKey.index);
var preCurveKey = preFrame.keyList.FirstOrDefault(x => x.index == curveKey.index);
if (preCurveKey != null)
{
curveKey.inSlope = preCurveKey.CalculateNextInSlope(frame.time - preFrame.time, curveKey);
@@ -573,9 +567,7 @@ namespace AssetStudio
m_CurveCount = reader.ReadUInt32();
m_SampleRate = reader.ReadSingle();
m_BeginTime = reader.ReadSingle();
int numSamples = reader.ReadInt32();
m_SampleArray = reader.ReadSingleArray(numSamples);
m_SampleArray = reader.ReadSingleArray();
}
}
@@ -585,8 +577,7 @@ namespace AssetStudio
public ConstantClip(ObjectReader reader)
{
int numData = reader.ReadInt32();
data = reader.ReadSingleArray(numData);
data = reader.ReadSingleArray();
}
}
@@ -612,15 +603,15 @@ namespace AssetStudio
public class ValueArrayConstant
{
public List<ValueConstant> m_ValueArray;
public ValueConstant[] m_ValueArray;
public ValueArrayConstant(ObjectReader reader)
{
int numVals = reader.ReadInt32();
m_ValueArray = new List<ValueConstant>(numVals);
m_ValueArray = new ValueConstant[numVals];
for (int i = 0; i < numVals; i++)
{
m_ValueArray.Add(new ValueConstant(reader));
m_ValueArray[i] = new ValueConstant(reader);
}
}
}
@@ -641,7 +632,10 @@ namespace AssetStudio
{
m_ConstantClip = new ConstantClip(reader);
}
m_Binding = new ValueArrayConstant(reader);
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 3)) //2018.3 down
{
m_Binding = new ValueArrayConstant(reader);
}
}
}
@@ -666,7 +660,7 @@ namespace AssetStudio
public xform m_RightFootStartX;
public xform m_MotionStartX;
public xform m_MotionStopX;
public object m_AverageSpeed;
public Vector3 m_AverageSpeed;
public Clip m_Clip;
public float m_StartTime;
public float m_StopTime;
@@ -675,7 +669,7 @@ namespace AssetStudio
public float m_CycleOffset;
public float m_AverageAngularSpeed;
public int[] m_IndexArray;
public List<ValueDelta> m_ValueArrayDelta;
public ValueDelta[] m_ValueArrayDelta;
public float[] m_ValueArrayReferencePose;
public bool m_Mirror;
public bool m_LoopTime;
@@ -705,7 +699,7 @@ namespace AssetStudio
m_MotionStartX = new xform(reader);
m_MotionStopX = new xform(reader);
}
m_AverageSpeed = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)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 Clip(reader);
m_StartTime = reader.ReadSingle();
m_StopTime = reader.ReadSingle();
@@ -714,30 +708,27 @@ namespace AssetStudio
m_CycleOffset = reader.ReadSingle();
m_AverageAngularSpeed = reader.ReadSingle();
int numIndices = reader.ReadInt32();
m_IndexArray = reader.ReadInt32Array(numIndices);
m_IndexArray = reader.ReadInt32Array();
if (version[0] < 4 || (version[0] == 4 && version[1] < 3)) //4.3 down
{
int numAdditionalCurveIndexs = reader.ReadInt32();
var m_AdditionalCurveIndexArray = new List<int>(numAdditionalCurveIndexs);
for (int i = 0; i < numAdditionalCurveIndexs; i++)
{
m_AdditionalCurveIndexArray.Add(reader.ReadInt32());
}
var m_AdditionalCurveIndexArray = reader.ReadInt32Array();
}
int numDeltas = reader.ReadInt32();
m_ValueArrayDelta = new List<ValueDelta>(numDeltas);
m_ValueArrayDelta = new ValueDelta[numDeltas];
for (int i = 0; i < numDeltas; i++)
{
m_ValueArrayDelta.Add(new ValueDelta(reader));
m_ValueArrayDelta[i] = new ValueDelta(reader);
}
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3))//5.3 and up
{
m_ValueArrayReferencePose = reader.ReadSingleArray(reader.ReadInt32());
m_ValueArrayReferencePose = reader.ReadSingleArray();
}
m_Mirror = reader.ReadBoolean();
m_LoopTime = reader.ReadBoolean();
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
m_LoopTime = reader.ReadBoolean();
}
m_LoopBlend = reader.ReadBoolean();
m_LoopBlendOrientation = reader.ReadBoolean();
m_LoopBlendPositionY = reader.ReadBoolean();
@@ -750,7 +741,7 @@ namespace AssetStudio
m_KeepOriginalPositionY = reader.ReadBoolean();
m_KeepOriginalPositionXZ = reader.ReadBoolean();
m_HeightFromFeet = reader.ReadBoolean();
reader.AlignStream(4);
reader.AlignStream();
}
}
@@ -758,7 +749,7 @@ namespace AssetStudio
{
public uint path;
public uint attribute;
public PPtr script;
public PPtr<Object> script;
public ClassIDType typeID;
public byte customType;
public byte isPPtrCurve;
@@ -768,7 +759,7 @@ namespace AssetStudio
var version = reader.version;
path = reader.ReadUInt32();
attribute = reader.ReadUInt32();
script = reader.ReadPPtr();
script = new PPtr<Object>(reader);
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
typeID = (ClassIDType)reader.ReadInt32();
@@ -779,29 +770,29 @@ namespace AssetStudio
}
customType = reader.ReadByte();
isPPtrCurve = reader.ReadByte();
reader.AlignStream(4);
reader.AlignStream();
}
}
public class AnimationClipBindingConstant
{
public List<GenericBinding> genericBindings;
public List<PPtr> pptrCurveMapping;
public GenericBinding[] genericBindings;
public PPtr<Object>[] pptrCurveMapping;
public AnimationClipBindingConstant(ObjectReader reader)
{
int numBindings = reader.ReadInt32();
genericBindings = new List<GenericBinding>(numBindings);
genericBindings = new GenericBinding[numBindings];
for (int i = 0; i < numBindings; i++)
{
genericBindings.Add(new GenericBinding(reader));
genericBindings[i] = new GenericBinding(reader);
}
int numMappings = reader.ReadInt32();
pptrCurveMapping = new List<PPtr>(numMappings);
pptrCurveMapping = new PPtr<Object>[numMappings];
for (int i = 0; i < numMappings; i++)
{
pptrCurveMapping.Add(reader.ReadPPtr());
pptrCurveMapping[i] = new PPtr<Object>(reader);
}
}
@@ -841,6 +832,33 @@ namespace AssetStudio
}
}
public class AnimationEvent
{
public float time;
public string functionName;
public string data;
public PPtr<Object> objectReferenceParameter;
public float floatParameter;
public int intParameter;
public int messageOptions;
public AnimationEvent(ObjectReader reader)
{
var version = reader.version;
time = reader.ReadSingle();
functionName = reader.ReadAlignedString();
data = reader.ReadAlignedString();
objectReferenceParameter = new PPtr<Object>(reader);
floatParameter = reader.ReadSingle();
if (version[0] >= 3) //3 and up
{
intParameter = reader.ReadInt32();
}
messageOptions = reader.ReadInt32();
}
}
public enum AnimationType
{
kLegacy = 1,
@@ -854,20 +872,20 @@ namespace AssetStudio
public bool m_Legacy;
public bool m_Compressed;
public bool m_UseHighQualityCurve;
public List<QuaternionCurve> m_RotationCurves;
public List<CompressedAnimationCurve> m_CompressedRotationCurves;
public List<Vector3Curve> m_EulerCurves;
public List<Vector3Curve> m_PositionCurves;
public List<Vector3Curve> m_ScaleCurves;
public List<FloatCurve> m_FloatCurves;
public List<PPtrCurve> m_PPtrCurves;
public QuaternionCurve[] m_RotationCurves;
public CompressedAnimationCurve[] m_CompressedRotationCurves;
public Vector3Curve[] m_EulerCurves;
public Vector3Curve[] m_PositionCurves;
public Vector3Curve[] m_ScaleCurves;
public FloatCurve[] m_FloatCurves;
public PPtrCurve[] m_PPtrCurves;
public float m_SampleRate;
public int m_WrapMode;
public AABB m_Bounds;
public uint m_MuscleClipSize;
public ClipMuscleConstant m_MuscleClip;
public AnimationClipBindingConstant m_ClipBindingConstant;
//public List<AnimationEvent> m_Events;
public AnimationEvent[] m_Events;
public AnimationClip(ObjectReader reader) : base(reader)
@@ -891,59 +909,59 @@ namespace AssetStudio
{
m_UseHighQualityCurve = reader.ReadBoolean();
}
reader.AlignStream(4);
reader.AlignStream();
int numRCurves = reader.ReadInt32();
m_RotationCurves = new List<QuaternionCurve>(numRCurves);
m_RotationCurves = new QuaternionCurve[numRCurves];
for (int i = 0; i < numRCurves; i++)
{
m_RotationCurves.Add(new QuaternionCurve(reader));
m_RotationCurves[i] = new QuaternionCurve(reader);
}
int numCRCurves = reader.ReadInt32();
m_CompressedRotationCurves = new List<CompressedAnimationCurve>(numCRCurves);
m_CompressedRotationCurves = new CompressedAnimationCurve[numCRCurves];
for (int i = 0; i < numCRCurves; i++)
{
m_CompressedRotationCurves.Add(new CompressedAnimationCurve(reader));
m_CompressedRotationCurves[i] = new CompressedAnimationCurve(reader);
}
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3))//5.3 and up
{
int numEulerCurves = reader.ReadInt32();
m_EulerCurves = new List<Vector3Curve>(numEulerCurves);
m_EulerCurves = new Vector3Curve[numEulerCurves];
for (int i = 0; i < numEulerCurves; i++)
{
m_EulerCurves.Add(new Vector3Curve(reader));
m_EulerCurves[i] = new Vector3Curve(reader);
}
}
int numPCurves = reader.ReadInt32();
m_PositionCurves = new List<Vector3Curve>(numPCurves);
m_PositionCurves = new Vector3Curve[numPCurves];
for (int i = 0; i < numPCurves; i++)
{
m_PositionCurves.Add(new Vector3Curve(reader));
m_PositionCurves[i] = new Vector3Curve(reader);
}
int numSCurves = reader.ReadInt32();
m_ScaleCurves = new List<Vector3Curve>(numSCurves);
m_ScaleCurves = new Vector3Curve[numSCurves];
for (int i = 0; i < numSCurves; i++)
{
m_ScaleCurves.Add(new Vector3Curve(reader));
m_ScaleCurves[i] = new Vector3Curve(reader);
}
int numFCurves = reader.ReadInt32();
m_FloatCurves = new List<FloatCurve>(numFCurves);
m_FloatCurves = new FloatCurve[numFCurves];
for (int i = 0; i < numFCurves; i++)
{
m_FloatCurves.Add(new FloatCurve(reader));
m_FloatCurves[i] = new FloatCurve(reader);
}
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
int numPtrCurves = reader.ReadInt32();
m_PPtrCurves = new List<PPtrCurve>(numPtrCurves);
m_PPtrCurves = new PPtrCurve[numPtrCurves];
for (int i = 0; i < numPtrCurves; i++)
{
m_PPtrCurves.Add(new PPtrCurve(reader));
m_PPtrCurves[i] = new PPtrCurve(reader);
}
}
@@ -962,12 +980,22 @@ namespace AssetStudio
{
m_ClipBindingConstant = new AnimationClipBindingConstant(reader);
}
/*int numEvents = reader.ReadInt32();
m_Events = new List<AnimationEvent>(numEvents);
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 3)) //2018.3 and up
{
var m_HasGenericRootTransform = reader.ReadBoolean();
var m_HasMotionFloatCurves = reader.ReadBoolean();
reader.AlignStream();
}
int numEvents = reader.ReadInt32();
m_Events = new AnimationEvent[numEvents];
for (int i = 0; i < numEvents; i++)
{
m_Events.Add(new AnimationEvent(stream, file.Version[0] - '0'));
}*/
m_Events[i] = new AnimationEvent(reader);
}
if (version[0] >= 2017) //2017 and up
{
reader.AlignStream();
}
}
}
}

View File

@@ -7,14 +7,14 @@ namespace AssetStudio
{
public sealed class Animator : Behaviour
{
public PPtr m_Avatar;
public PPtr m_Controller;
public bool m_HasTransformHierarchy;
public PPtr<Avatar> m_Avatar;
public PPtr<RuntimeAnimatorController> m_Controller;
public bool m_HasTransformHierarchy = true;
public Animator(ObjectReader reader) : base(reader)
{
m_Avatar = reader.ReadPPtr();
m_Controller = reader.ReadPPtr();
m_Avatar = new PPtr<Avatar>(reader);
m_Controller = new PPtr<RuntimeAnimatorController>(reader);
var m_CullingMode = reader.ReadInt32();
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
@@ -25,13 +25,13 @@ namespace AssetStudio
var m_ApplyRootMotion = reader.ReadBoolean();
if (version[0] == 4 && version[1] >= 5) //4.5 and up - 5.0 down
{
reader.AlignStream(4);
reader.AlignStream();
}
if (version[0] >= 5) //5.0 and up
{
var m_LinearVelocityBlending = reader.ReadBoolean();
reader.AlignStream(4);
reader.AlignStream();
}
if (version[0] < 4 || (version[0] == 4 && version[1] < 5)) //4.5 down
@@ -50,13 +50,13 @@ namespace AssetStudio
}
if (version[0] >= 5 && version[0] < 2018) //5.0 and up - 2018 down
{
reader.AlignStream(4);
reader.AlignStream();
}
if (version[0] >= 2018) //2018 and up
{
var m_KeepAnimatorControllerStateOnDisable = reader.ReadBoolean();
reader.AlignStream(4);
reader.AlignStream();
}
}
}

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpDX;
namespace AssetStudio
{
@@ -14,9 +13,11 @@ namespace AssetStudio
public HumanPoseMask(ObjectReader reader)
{
var version = reader.version;
word0 = reader.ReadUInt32();
word1 = reader.ReadUInt32();
if (reader.version[0] >= 5) //5.0 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up
{
word2 = reader.ReadUInt32();
}
@@ -64,16 +65,24 @@ namespace AssetStudio
public LayerConstant(ObjectReader reader)
{
var version = reader.version;
m_StateMachineIndex = reader.ReadUInt32();
m_StateMachineMotionSetIndex = reader.ReadUInt32();
m_BodyMask = new HumanPoseMask(reader);
m_SkeletonMask = new SkeletonMask(reader);
m_Binding = reader.ReadUInt32();
m_LayerBlendingMode = reader.ReadInt32();
m_DefaultWeight = reader.ReadSingle();
if (version[0] > 4 || (version[0] == 4 && version[1] >= 2)) //4.2 and up
{
m_DefaultWeight = reader.ReadSingle();
}
m_IKPass = reader.ReadBoolean();
m_SyncedLayerAffectsTiming = reader.ReadBoolean();
reader.AlignStream(4);
if (version[0] > 4 || (version[0] == 4 && version[1] >= 2)) //4.2 and up
{
m_SyncedLayerAffectsTiming = reader.ReadBoolean();
}
reader.AlignStream();
}
}
@@ -113,6 +122,7 @@ namespace AssetStudio
public TransitionConstant(ObjectReader reader)
{
var version = reader.version;
int numConditions = reader.ReadInt32();
m_ConditionConstantArray = new ConditionConstant[numConditions];
for (int i = 0; i < numConditions; i++)
@@ -135,7 +145,7 @@ namespace AssetStudio
m_ExitTime = reader.ReadSingle();
m_HasExitTime = reader.ReadBoolean();
m_HasFixedDuration = reader.ReadBoolean();
reader.AlignStream(4);
reader.AlignStream();
m_InterruptionSource = reader.ReadInt32();
m_OrderedInterruption = reader.ReadBoolean();
}
@@ -144,8 +154,12 @@ namespace AssetStudio
m_Atomic = reader.ReadBoolean();
}
m_CanTransitionToSelf = reader.ReadBoolean();
reader.AlignStream(4);
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
{
m_CanTransitionToSelf = reader.ReadBoolean();
}
reader.AlignStream();
}
}
@@ -156,7 +170,7 @@ namespace AssetStudio
public LeafInfoConstant(ObjectReader reader)
{
m_IDArray = reader.ReadUInt32Array(reader.ReadInt32());
m_IDArray = reader.ReadUInt32Array();
m_IndexOffset = reader.ReadUInt32();
}
}
@@ -167,7 +181,7 @@ namespace AssetStudio
public MotionNeighborList(ObjectReader reader)
{
m_NeighborArray = reader.ReadUInt32Array(reader.ReadInt32());
m_NeighborArray = reader.ReadUInt32Array();
}
}
@@ -181,10 +195,10 @@ namespace AssetStudio
public Blend2dDataConstant(ObjectReader reader)
{
m_ChildPositionArray = reader.ReadVector2Array(reader.ReadInt32());
m_ChildMagnitudeArray = reader.ReadSingleArray(reader.ReadInt32());
m_ChildPairVectorArray = reader.ReadVector2Array(reader.ReadInt32());
m_ChildPairAvgMagInvArray = reader.ReadSingleArray(reader.ReadInt32());
m_ChildPositionArray = reader.ReadVector2Array();
m_ChildMagnitudeArray = reader.ReadSingleArray();
m_ChildPairVectorArray = reader.ReadVector2Array();
m_ChildPairAvgMagInvArray = reader.ReadSingleArray();
int numNeighbours = reader.ReadInt32();
m_ChildNeighborListArray = new MotionNeighborList[numNeighbours];
@@ -201,7 +215,7 @@ namespace AssetStudio
public Blend1dDataConstant(ObjectReader reader)
{
m_ChildThresholdArray = reader.ReadSingleArray(reader.ReadInt32());
m_ChildThresholdArray = reader.ReadSingleArray();
}
}
@@ -212,9 +226,9 @@ namespace AssetStudio
public BlendDirectDataConstant(ObjectReader reader)
{
m_ChildBlendEventIDArray = reader.ReadUInt32Array(reader.ReadInt32());
m_ChildBlendEventIDArray = reader.ReadUInt32Array();
m_NormalizedBlendValues = reader.ReadBoolean();
reader.AlignStream(4);
reader.AlignStream();
}
}
@@ -224,6 +238,7 @@ namespace AssetStudio
public uint m_BlendEventID;
public uint m_BlendEventYID;
public uint[] m_ChildIndices;
public float[] m_ChildThresholdArray;
public Blend1dDataConstant m_Blend1dData;
public Blend2dDataConstant m_Blend2dData;
public BlendDirectDataConstant m_BlendDirectData;
@@ -236,42 +251,72 @@ namespace AssetStudio
public BlendTreeNodeConstant(ObjectReader reader)
{
var version = reader.version;
m_BlendType = reader.ReadUInt32();
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
{
m_BlendType = reader.ReadUInt32();
}
m_BlendEventID = reader.ReadUInt32();
m_BlendEventYID = reader.ReadUInt32();
m_ChildIndices = reader.ReadUInt32Array(reader.ReadInt32());
m_Blend1dData = new Blend1dDataConstant(reader);
m_Blend2dData = new Blend2dDataConstant(reader);
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
{
m_BlendEventYID = reader.ReadUInt32();
}
m_ChildIndices = reader.ReadUInt32Array();
if (version[0] < 4 || (version[0] == 4 && version[1] < 1)) //4.1 down
{
m_ChildThresholdArray = reader.ReadSingleArray();
}
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
{
m_Blend1dData = new Blend1dDataConstant(reader);
m_Blend2dData = new Blend2dDataConstant(reader);
}
if (version[0] >= 5) //5.0 and up
{
m_BlendDirectData = new BlendDirectDataConstant(reader);
}
m_ClipID = reader.ReadUInt32();
if (version[0] < 5) //5.0 down
if (version[0] == 4 && version[1] >= 5) //4.5 - 5.0
{
m_ClipIndex = reader.ReadUInt32();
}
m_Duration = reader.ReadSingle();
m_CycleOffset = reader.ReadSingle();
m_Mirror = reader.ReadBoolean();
reader.AlignStream(4);
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_Mirror = reader.ReadBoolean();
reader.AlignStream();
}
}
}
public class BlendTreeConstant
{
public BlendTreeNodeConstant[] m_NodeArray;
public ValueArrayConstant m_BlendEventArrayConstant;
public BlendTreeConstant(ObjectReader reader)
{
var version = reader.version;
int numNodes = reader.ReadInt32();
m_NodeArray = new BlendTreeNodeConstant[numNodes];
for (int i = 0; i < numNodes; i++)
{
m_NodeArray[i] = new BlendTreeNodeConstant(reader);
}
if (version[0] < 4 || (version[0] == 4 && version[1] < 5)) //4.5 down
{
m_BlendEventArrayConstant = new ValueArrayConstant(reader);
}
}
}
@@ -299,6 +344,7 @@ namespace AssetStudio
public StateConstant(ObjectReader reader)
{
var version = reader.version;
int numTransistions = reader.ReadInt32();
m_TransitionConstantArray = new TransitionConstant[numTransistions];
for (int i = 0; i < numTransistions; i++)
@@ -306,14 +352,9 @@ namespace AssetStudio
m_TransitionConstantArray[i] = new TransitionConstant(reader);
}
int numBlendIndices = reader.ReadInt32();
m_BlendTreeConstantIndexArray = new int[numBlendIndices];
for (int i = 0; i < numBlendIndices; i++)
{
m_BlendTreeConstantIndexArray[i] = reader.ReadInt32();
}
m_BlendTreeConstantIndexArray = reader.ReadInt32Array();
if (version[0] < 5) //5.0 down
if (version[0] < 5 || (version[0] == 5 && version[1] < 2)) //5.2 down
{
int numInfos = reader.ReadInt32();
m_LeafInfoArray = new LeafInfoConstant[numInfos];
@@ -331,14 +372,17 @@ namespace AssetStudio
}
m_NameID = reader.ReadUInt32();
m_PathID = reader.ReadUInt32();
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
m_PathID = reader.ReadUInt32();
}
if (version[0] >= 5) //5.0 and up
{
m_FullPathID = reader.ReadUInt32();
}
m_TagID = reader.ReadUInt32();
if (version[0] >= 5) //5.0 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 1)) //5.1 and up
{
m_SpeedParamID = reader.ReadUInt32();
m_MirrorParamID = reader.ReadUInt32();
@@ -351,7 +395,10 @@ namespace AssetStudio
}
m_Speed = reader.ReadSingle();
m_CycleOffset = reader.ReadSingle();
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
{
m_CycleOffset = reader.ReadSingle();
}
m_IKOnFeet = reader.ReadBoolean();
if (version[0] >= 5) //5.0 and up
{
@@ -359,8 +406,12 @@ namespace AssetStudio
}
m_Loop = reader.ReadBoolean();
m_Mirror = reader.ReadBoolean();
reader.AlignStream(4);
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
{
m_Mirror = reader.ReadBoolean();
}
reader.AlignStream();
}
}
@@ -399,7 +450,7 @@ namespace AssetStudio
m_FullPathID = reader.ReadUInt32();
m_isEntry = reader.ReadBoolean();
reader.AlignStream(4);
reader.AlignStream();
}
}
@@ -414,6 +465,7 @@ namespace AssetStudio
public StateMachineConstant(ObjectReader reader)
{
var version = reader.version;
int numStates = reader.ReadInt32();
m_StateConstantArray = new StateConstant[numStates];
for (int i = 0; i < numStates; i++)
@@ -448,57 +500,52 @@ namespace AssetStudio
public bool[] m_BoolValues;
public int[] m_IntValues;
public float[] m_FloatValues;
public object[] m_PositionValues;
public Vector4[] m_VectorValues;
public Vector3[] m_PositionValues;
public Vector4[] m_QuaternionValues;
public object[] m_ScaleValues;
public Vector3[] m_ScaleValues;
public ValueArray(ObjectReader reader)
{
var version = reader.version;
if (version[0] < 5 || (version[0] == 5 && version[1] < 5)) //5.5 down
{
int numBools = reader.ReadInt32();
m_BoolValues = new bool[numBools];
for (int i = 0; i < numBools; i++)
m_BoolValues = reader.ReadBooleanArray();
reader.AlignStream();
m_IntValues = reader.ReadInt32Array();
m_FloatValues = reader.ReadSingleArray();
}
if (version[0] < 4 || (version[0] == 4 && version[1] < 3)) //4.3 down
{
m_VectorValues = reader.ReadVector4Array();
}
else
{
int numPosValues = reader.ReadInt32();
m_PositionValues = new Vector3[numPosValues];
for (int i = 0; i < numPosValues; i++)
{
m_BoolValues[i] = reader.ReadBoolean();
m_PositionValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4(); //5.4 and up
}
reader.AlignStream(4);
m_QuaternionValues = reader.ReadVector4Array();
m_IntValues = reader.ReadInt32Array(reader.ReadInt32());
m_FloatValues = reader.ReadSingleArray(reader.ReadInt32());
}
int numPosValues = reader.ReadInt32();
m_PositionValues = new object[numPosValues];
for (int i = 0; i < numPosValues; i++)
{
m_PositionValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4(); //5.4 and up
}
m_QuaternionValues = reader.ReadVector4Array(reader.ReadInt32());
int numScaleValues = reader.ReadInt32();
m_ScaleValues = new object[numScaleValues];
for (int i = 0; i < numScaleValues; i++)
{
m_ScaleValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4(); //5.4 adn up
}
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5)) //5.5 and up
{
m_FloatValues = reader.ReadSingleArray(reader.ReadInt32());
m_IntValues = reader.ReadInt32Array(reader.ReadInt32());
int numBools = reader.ReadInt32();
m_BoolValues = new bool[numBools];
for (int i = 0; i < numBools; i++)
int numScaleValues = reader.ReadInt32();
m_ScaleValues = new Vector3[numScaleValues];
for (int i = 0; i < numScaleValues; i++)
{
m_BoolValues[i] = reader.ReadBoolean();
m_ScaleValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4(); //5.4 and up
}
reader.AlignStream(4);
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5)) //5.5 and up
{
m_FloatValues = reader.ReadSingleArray();
m_IntValues = reader.ReadInt32Array();
m_BoolValues = reader.ReadBooleanArray();
reader.AlignStream();
}
}
}
}
@@ -531,9 +578,9 @@ namespace AssetStudio
}
}
public sealed class AnimatorController : NamedObject
public sealed class AnimatorController : RuntimeAnimatorController
{
public PPtr[] m_AnimationClips;
public PPtr<AnimationClip>[] m_AnimationClips;
public AnimatorController(ObjectReader reader) : base(reader)
{
@@ -541,17 +588,17 @@ namespace AssetStudio
var m_Controller = new ControllerConstant(reader);
int tosSize = reader.ReadInt32();
var m_TOS = new List<KeyValuePair<uint, string>>(tosSize);
var m_TOS = new KeyValuePair<uint, string>[tosSize];
for (int i = 0; i < tosSize; i++)
{
m_TOS.Add(new KeyValuePair<uint, string>(reader.ReadUInt32(), reader.ReadAlignedString()));
m_TOS[i] = new KeyValuePair<uint, string>(reader.ReadUInt32(), reader.ReadAlignedString());
}
int numClips = reader.ReadInt32();
m_AnimationClips = new PPtr[numClips];
m_AnimationClips = new PPtr<AnimationClip>[numClips];
for (int i = 0; i < numClips; i++)
{
m_AnimationClips[i] = reader.ReadPPtr();
m_AnimationClips[i] = new PPtr<AnimationClip>(reader);
}
}
}

View File

@@ -5,22 +5,32 @@ using System.Text;
namespace AssetStudio
{
public class AnimatorOverrideController : NamedObject
public class AnimationClipOverride
{
public PPtr m_Controller;
public PPtr[][] m_Clips;
public PPtr<AnimationClip> m_OriginalClip;
public PPtr<AnimationClip> m_OverrideClip;
public AnimationClipOverride(ObjectReader reader)
{
m_OriginalClip = new PPtr<AnimationClip>(reader);
m_OverrideClip = new PPtr<AnimationClip>(reader);
}
}
public sealed class AnimatorOverrideController : RuntimeAnimatorController
{
public PPtr<RuntimeAnimatorController> m_Controller;
public AnimationClipOverride[] m_Clips;
public AnimatorOverrideController(ObjectReader reader) : base(reader)
{
m_Controller = reader.ReadPPtr();
m_Controller = new PPtr<RuntimeAnimatorController>(reader);
int numOverrides = reader.ReadInt32();
m_Clips = new PPtr[numOverrides][];
m_Clips = new AnimationClipOverride[numOverrides];
for (int i = 0; i < numOverrides; i++)
{
m_Clips[i] = new PPtr[2];
m_Clips[i][0] = reader.ReadPPtr();
m_Clips[i][1] = reader.ReadPPtr();
m_Clips[i] = new AnimationClipOverride(reader);
}
}
}

View File

@@ -5,41 +5,39 @@ using System.Text;
namespace AssetStudio
{
public class AssetInfo
{
public int preloadIndex;
public int preloadSize;
public PPtr<Object> asset;
public AssetInfo(ObjectReader reader)
{
preloadIndex = reader.ReadInt32();
preloadSize = reader.ReadInt32();
asset = new PPtr<Object>(reader);
}
}
public sealed class AssetBundle : NamedObject
{
public class AssetInfo
{
public int preloadIndex;
public int preloadSize;
public PPtr asset;
}
public class ContainerData
{
public string first;
public AssetInfo second;
}
public List<ContainerData> m_Container = new List<ContainerData>();
public PPtr<Object>[] m_PreloadTable;
public KeyValuePair<string, AssetInfo>[] m_Container;
public AssetBundle(ObjectReader reader) : base(reader)
{
var size = reader.ReadInt32();
for (int i = 0; i < size; i++)
var m_PreloadTableSize = reader.ReadInt32();
m_PreloadTable = new PPtr<Object>[m_PreloadTableSize];
for (int i = 0; i < m_PreloadTableSize; i++)
{
reader.ReadPPtr();
m_PreloadTable[i] = new PPtr<Object>(reader);
}
size = reader.ReadInt32();
for (int i = 0; i < size; i++)
var m_ContainerSize = reader.ReadInt32();
m_Container = new KeyValuePair<string, AssetInfo>[m_ContainerSize];
for (int i = 0; i < m_ContainerSize; i++)
{
var temp = new ContainerData();
temp.first = reader.ReadAlignedString();
temp.second = new AssetInfo();
temp.second.preloadIndex = reader.ReadInt32();
temp.second.preloadSize = reader.ReadInt32();
temp.second.asset = reader.ReadPPtr();
m_Container.Add(temp);
m_Container[i] = new KeyValuePair<string, AssetInfo>(reader.ReadAlignedString(), new AssetInfo(reader));
}
}
}

View File

@@ -29,9 +29,9 @@ namespace AssetStudio
public string m_Source;
public long m_Offset;
public long m_Size;
public byte[] m_AudioData;
public Lazy<byte[]> m_AudioData;
public AudioClip(ObjectReader reader, bool readData) : base(reader)
public AudioClip(ObjectReader reader) : base(reader)
{
if (version[0] < 5)
{
@@ -39,7 +39,7 @@ namespace AssetStudio
m_Type = (AudioType)reader.ReadInt32();
m_3D = reader.ReadBoolean();
m_UseHardware = reader.ReadBoolean();
reader.AlignStream(4);
reader.AlignStream();
if (version[0] >= 4 || (version[0] == 3 && version[1] >= 2)) //3.2.0 to 5
{
@@ -49,7 +49,7 @@ namespace AssetStudio
if (reader.byteSize + reader.byteStart - reader.Position != tsize)
{
m_Offset = reader.ReadInt32();
m_Source = sourceFile.fullName + ".resS";
m_Source = assetsFile.fullName + ".resS";
}
}
else
@@ -65,13 +65,12 @@ namespace AssetStudio
m_BitsPerSample = reader.ReadInt32();
m_Length = reader.ReadSingle();
m_IsTrackerFormat = reader.ReadBoolean();
reader.AlignStream(4);
reader.AlignStream();
m_SubsoundIndex = reader.ReadInt32();
m_PreloadAudioData = reader.ReadBoolean();
m_LoadInBackground = reader.ReadBoolean();
m_Legacy3D = reader.ReadBoolean();
reader.AlignStream(4);
m_3D = m_Legacy3D;
reader.AlignStream();
m_Source = reader.ReadAlignedString();
m_Offset = reader.ReadInt64();
@@ -79,18 +78,16 @@ namespace AssetStudio
m_CompressionFormat = (AudioCompressionFormat)reader.ReadInt32();
}
if (readData)
ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_Source))
{
if (!string.IsNullOrEmpty(m_Source))
{
m_AudioData = ResourcesHelper.GetData(m_Source, sourceFile, m_Offset, (int)m_Size);
}
else
{
if (m_Size > 0)
m_AudioData = reader.ReadBytes((int)m_Size);
}
resourceReader = new ResourceReader(m_Source, assetsFile, m_Offset, (int)m_Size);
}
else
{
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, (int)m_Size);
}
m_AudioData = new Lazy<byte[]>(resourceReader.GetData);
}
}

View File

@@ -1,5 +1,5 @@
using SharpDX;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
namespace AssetStudio
{
@@ -66,68 +66,53 @@ namespace AssetStudio
public class Skeleton
{
public List<Node> m_Node;
public List<uint> m_ID;
public List<Axes> m_AxesArray;
public Node[] m_Node;
public uint[] m_ID;
public Axes[] m_AxesArray;
public Skeleton(ObjectReader reader)
{
int numNodes = reader.ReadInt32();
m_Node = new List<Node>(numNodes);
m_Node = new Node[numNodes];
for (int i = 0; i < numNodes; i++)
{
m_Node.Add(new Node(reader));
m_Node[i] = new Node(reader);
}
int numIDs = reader.ReadInt32();
m_ID = new List<uint>(numIDs);
for (int i = 0; i < numIDs; i++)
{
m_ID.Add(reader.ReadUInt32());
}
m_ID = reader.ReadUInt32Array();
int numAxes = reader.ReadInt32();
m_AxesArray = new List<Axes>(numAxes);
m_AxesArray = new Axes[numAxes];
for (int i = 0; i < numAxes; i++)
{
m_AxesArray.Add(new Axes(reader));
m_AxesArray[i] = new Axes(reader);
}
}
}
public class SkeletonPose
{
public List<xform> m_X;
public SkeletonPose()
{
m_X = new List<xform>();
}
public xform[] m_X;
public SkeletonPose(ObjectReader reader)
{
int numXforms = reader.ReadInt32();
m_X = new List<xform>(numXforms);
m_X = new xform[numXforms];
for (int i = 0; i < numXforms; i++)
{
m_X.Add(new xform(reader));
m_X[i] = new xform(reader);
}
}
}
public class Hand
{
public List<int> m_HandBoneIndex;
public int[] m_HandBoneIndex;
public Hand(ObjectReader reader)
{
int numIndexes = reader.ReadInt32();
m_HandBoneIndex = new List<int>(numIndexes);
for (int i = 0; i < numIndexes; i++)
{
m_HandBoneIndex.Add(reader.ReadInt32());
}
m_HandBoneIndex = reader.ReadInt32Array();
}
}
@@ -178,11 +163,11 @@ namespace AssetStudio
public SkeletonPose m_SkeletonPose;
public Hand m_LeftHand;
public Hand m_RightHand;
public List<Handle> m_Handles;
public List<Collider> m_ColliderArray;
public List<int> m_HumanBoneIndex;
public List<float> m_HumanBoneMass;
public List<int> m_ColliderIndex;
public Handle[] m_Handles;
public Collider[] m_ColliderArray;
public int[] m_HumanBoneIndex;
public float[] m_HumanBoneMass;
public int[] m_ColliderIndex;
public float m_Scale;
public float m_ArmTwist;
public float m_ForeArmTwist;
@@ -207,42 +192,27 @@ namespace AssetStudio
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 2)) //2018.2 down
{
int numHandles = reader.ReadInt32();
m_Handles = new List<Handle>(numHandles);
m_Handles = new Handle[numHandles];
for (int i = 0; i < numHandles; i++)
{
m_Handles.Add(new Handle(reader));
m_Handles[i] = new Handle(reader);
}
int numColliders = reader.ReadInt32();
m_ColliderArray = new List<Collider>(numColliders);
m_ColliderArray = new Collider[numColliders];
for (int i = 0; i < numColliders; i++)
{
m_ColliderArray.Add(new Collider(reader));
m_ColliderArray[i] = new Collider(reader);
}
}
int numIndexes = reader.ReadInt32();
m_HumanBoneIndex = new List<int>(numIndexes);
for (int i = 0; i < numIndexes; i++)
{
m_HumanBoneIndex.Add(reader.ReadInt32());
}
m_HumanBoneIndex = reader.ReadInt32Array();
int numMasses = reader.ReadInt32();
m_HumanBoneMass = new List<float>(numMasses);
for (int i = 0; i < numMasses; i++)
{
m_HumanBoneMass.Add(reader.ReadSingle());
}
m_HumanBoneMass = reader.ReadSingleArray();
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 2)) //2018.2 down
{
int numColliderIndexes = reader.ReadInt32();
m_ColliderIndex = new List<int>(numColliderIndexes);
for (int i = 0; i < numColliderIndexes; i++)
{
m_ColliderIndex.Add(reader.ReadInt32());
}
m_ColliderIndex = reader.ReadInt32Array();
}
m_Scale = reader.ReadSingle();
@@ -255,8 +225,11 @@ namespace AssetStudio
m_FeetSpacing = reader.ReadSingle();
m_HasLeftHand = reader.ReadBoolean();
m_HasRightHand = reader.ReadBoolean();
m_HasTDoF = reader.ReadBoolean();
reader.AlignStream(4);
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up
{
m_HasTDoF = reader.ReadBoolean();
}
reader.AlignStream();
}
}
@@ -265,15 +238,15 @@ namespace AssetStudio
public Skeleton m_AvatarSkeleton;
public SkeletonPose m_AvatarSkeletonPose;
public SkeletonPose m_DefaultPose;
public List<uint> m_SkeletonNameIDArray;
public uint[] m_SkeletonNameIDArray;
public Human m_Human;
public List<int> m_HumanSkeletonIndexArray;
public List<int> m_HumanSkeletonReverseIndexArray;
public int[] m_HumanSkeletonIndexArray;
public int[] m_HumanSkeletonReverseIndexArray;
public int m_RootMotionBoneIndex;
public xform m_RootMotionBoneX;
public Skeleton m_RootMotionSkeleton;
public SkeletonPose m_RootMotionSkeletonPose;
public List<int> m_RootMotionSkeletonIndexArray;
public int[] m_RootMotionSkeletonIndexArray;
public AvatarConstant(ObjectReader reader)
{
@@ -284,31 +257,17 @@ namespace AssetStudio
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
m_DefaultPose = new SkeletonPose(reader);
int numIDs = reader.ReadInt32();
m_SkeletonNameIDArray = new List<uint>(numIDs);
for (int i = 0; i < numIDs; i++)
{
m_SkeletonNameIDArray.Add(reader.ReadUInt32());
}
m_SkeletonNameIDArray = reader.ReadUInt32Array();
}
m_Human = new Human(reader);
int numIndexes = reader.ReadInt32();
m_HumanSkeletonIndexArray = new List<int>(numIndexes);
for (int i = 0; i < numIndexes; i++)
{
m_HumanSkeletonIndexArray.Add(reader.ReadInt32());
}
m_HumanSkeletonIndexArray = reader.ReadInt32Array();
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
int numReverseIndexes = reader.ReadInt32();
m_HumanSkeletonReverseIndexArray = new List<int>(numReverseIndexes);
for (int i = 0; i < numReverseIndexes; i++)
{
m_HumanSkeletonReverseIndexArray.Add(reader.ReadInt32());
}
m_HumanSkeletonReverseIndexArray = reader.ReadInt32Array();
}
m_RootMotionBoneIndex = reader.ReadInt32();
@@ -319,12 +278,7 @@ namespace AssetStudio
m_RootMotionSkeleton = new Skeleton(reader);
m_RootMotionSkeletonPose = new SkeletonPose(reader);
int numMotionIndexes = reader.ReadInt32();
m_RootMotionSkeletonIndexArray = new List<int>(numMotionIndexes);
for (int i = 0; i < numMotionIndexes; i++)
{
m_RootMotionSkeletonIndexArray.Add(reader.ReadInt32());
}
m_RootMotionSkeletonIndexArray = reader.ReadInt32Array();
}
}
}
@@ -333,7 +287,7 @@ namespace AssetStudio
{
public uint m_AvatarSize;
public AvatarConstant m_Avatar;
public List<KeyValuePair<uint, string>> m_TOS;
public KeyValuePair<uint, string>[] m_TOS;
public Avatar(ObjectReader reader) : base(reader)
{
@@ -341,28 +295,18 @@ namespace AssetStudio
m_Avatar = new AvatarConstant(reader);
int numTOS = reader.ReadInt32();
m_TOS = new List<KeyValuePair<uint, string>>(numTOS);
m_TOS = new KeyValuePair<uint, string>[numTOS];
for (int i = 0; i < numTOS; i++)
{
m_TOS.Add(new KeyValuePair<uint, string>(reader.ReadUInt32(), reader.ReadAlignedString()));
m_TOS[i] = new KeyValuePair<uint, string>(reader.ReadUInt32(), reader.ReadAlignedString());
}
}
public string FindBoneName(uint hash)
{
foreach (var pair in m_TOS)
{
if (pair.Key == hash)
{
return pair.Value.Substring(pair.Value.LastIndexOf('/') + 1);
}
}
return null;
//HumanDescription m_HumanDescription 2019 and up
}
public string FindBonePath(uint hash)
{
return m_TOS.Find(pair => pair.Key == hash).Value;
return m_TOS.FirstOrDefault(pair => pair.Key == hash).Value;
}
}
}

View File

@@ -12,7 +12,7 @@ namespace AssetStudio
protected Behaviour(ObjectReader reader) : base(reader)
{
m_Enabled = reader.ReadByte();
reader.AlignStream(4);
reader.AlignStream();
}
}
}

View File

@@ -11,11 +11,7 @@ namespace AssetStudio
public BuildSettings(ObjectReader reader) : base(reader)
{
int levelsNum = reader.ReadInt32();
for (int i = 0; i < levelsNum; i++)
{
var level = reader.ReadAlignedString();
}
var levels = reader.ReadStringArray();
var hasRenderTexture = reader.ReadBoolean();
var hasPROVersion = reader.ReadBoolean();

View File

@@ -7,11 +7,11 @@ namespace AssetStudio
{
public abstract class Component : EditorExtension
{
public PPtr m_GameObject;
public PPtr<GameObject> m_GameObject;
protected Component(ObjectReader reader) : base(reader)
{
m_GameObject = reader.ReadPPtr();
m_GameObject = new PPtr<GameObject>(reader);
}
}
}

View File

@@ -11,8 +11,8 @@ namespace AssetStudio
{
if (platform == BuildTarget.NoTarget)
{
var m_PrefabParentObject = reader.ReadPPtr();
var m_PrefabInternal = reader.ReadPPtr();
var m_PrefabParentObject = new PPtr<EditorExtension>(reader);
var m_PrefabInternal = new PPtr<Object>(reader); //PPtr<Prefab>
}
}
}

View File

@@ -14,9 +14,9 @@ namespace AssetStudio
if ((version[0] == 5 && version[1] >= 5) || version[0] > 5)//5.5 and up
{
var m_LineSpacing = reader.ReadSingle();
var m_DefaultMaterial = reader.ReadPPtr();
var m_DefaultMaterial = new PPtr<Material>(reader);
var m_FontSize = reader.ReadSingle();
var m_Texture = reader.ReadPPtr();
var m_Texture = new PPtr<Texture>(reader);
int m_AsciiStartOffset = reader.ReadInt32();
var m_Tracking = reader.ReadSingle();
var m_CharacterSpacing = reader.ReadInt32();
@@ -68,7 +68,7 @@ namespace AssetStudio
}
int m_ConvertCase = reader.ReadInt32();
PPtr m_DefaultMaterial = reader.ReadPPtr();
var m_DefaultMaterial = new PPtr<Material>(reader);
int m_CharacterRects_size = reader.ReadInt32();
for (int i = 0; i < m_CharacterRects_size; i++)
@@ -89,11 +89,11 @@ namespace AssetStudio
if (version[0] >= 4)
{
var flipped = reader.ReadBoolean();
reader.AlignStream(4);
reader.AlignStream();
}
}
PPtr m_Texture = reader.ReadPPtr();
var m_Texture = new PPtr<Texture>(reader);
int m_KerningValues_size = reader.ReadInt32();
for (int i = 0; i < m_KerningValues_size; i++)
@@ -106,7 +106,7 @@ namespace AssetStudio
if (version[0] <= 3)
{
var m_GridFont = reader.ReadBoolean();
reader.AlignStream(4);
reader.AlignStream();
}
else { float m_PixelScale = reader.ReadSingle(); }

View File

@@ -7,29 +7,27 @@ namespace AssetStudio
{
public sealed class GameObject : EditorExtension
{
public List<PPtr> m_Components;
public PPtr<Component>[] m_Components;
public string m_Name;
public PPtr m_Transform;
public PPtr m_MeshRenderer;
public PPtr m_MeshFilter;
public PPtr m_SkinnedMeshRenderer;
public PPtr m_Animator;
public Transform m_Transform;
public MeshRenderer m_MeshRenderer;
public MeshFilter m_MeshFilter;
public SkinnedMeshRenderer m_SkinnedMeshRenderer;
public Animator m_Animator;
public Animation m_Animation;
public GameObject(ObjectReader reader) : base(reader)
{
int m_Component_size = reader.ReadInt32();
m_Components = new List<PPtr>(m_Component_size);
for (int j = 0; j < m_Component_size; j++)
m_Components = new PPtr<Component>[m_Component_size];
for (int i = 0; i < m_Component_size; i++)
{
if ((version[0] == 5 && version[1] >= 5) || version[0] > 5)//5.5.0 and up
{
m_Components.Add(reader.ReadPPtr());
}
else
if ((version[0] == 5 && version[1] < 5) || version[0] < 5) //5.5 down
{
int first = reader.ReadInt32();
m_Components.Add(reader.ReadPPtr());
}
m_Components[i] = new PPtr<Component>(reader);
}
var m_Layer = reader.ReadInt32();

View File

@@ -1,117 +1,100 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Generic;
namespace AssetStudio
{
public class TexEnv
public class UnityTexEnv
{
public string name;
public PPtr m_Texture;
public float[] m_Scale;
public float[] m_Offset;
public PPtr<Texture> m_Texture;
public Vector2 m_Scale;
public Vector2 m_Offset;
public UnityTexEnv(ObjectReader reader)
{
m_Texture = new PPtr<Texture>(reader);
m_Scale = reader.ReadVector2();
m_Offset = reader.ReadVector2();
}
}
public class strFloatPair
public class UnityPropertySheet
{
public string first;
public float second;
}
public KeyValuePair<string, UnityTexEnv>[] m_TexEnvs;
public KeyValuePair<string, float>[] m_Floats;
public KeyValuePair<string, Color>[] m_Colors;
public class strColorPair
{
public string first;
public float[] second;
public UnityPropertySheet(ObjectReader reader)
{
int m_TexEnvsSize = reader.ReadInt32();
m_TexEnvs = new KeyValuePair<string, UnityTexEnv>[m_TexEnvsSize];
for (int i = 0; i < m_TexEnvsSize; i++)
{
m_TexEnvs[i] = new KeyValuePair<string, UnityTexEnv>(reader.ReadAlignedString(), new UnityTexEnv(reader));
}
int m_FloatsSize = reader.ReadInt32();
m_Floats = new KeyValuePair<string, float>[m_FloatsSize];
for (int i = 0; i < m_FloatsSize; i++)
{
m_Floats[i] = new KeyValuePair<string, float>(reader.ReadAlignedString(), reader.ReadSingle());
}
int m_ColorsSize = reader.ReadInt32();
m_Colors = new KeyValuePair<string, Color>[m_ColorsSize];
for (int i = 0; i < m_ColorsSize; i++)
{
m_Colors[i] = new KeyValuePair<string, Color>(reader.ReadAlignedString(), reader.ReadColor4());
}
}
}
public sealed class Material : NamedObject
{
public PPtr m_Shader;
public string[] m_ShaderKeywords;
public int m_CustomRenderQueue;
public TexEnv[] m_TexEnvs;
public strFloatPair[] m_Floats;
public strColorPair[] m_Colors;
public PPtr<Shader> m_Shader;
public UnityPropertySheet m_SavedProperties;
public Material(ObjectReader reader) : base(reader)
{
m_Shader = reader.ReadPPtr();
m_Shader = new PPtr<Shader>(reader);
if (version[0] == 4 && (version[1] >= 2 || (version[1] == 1 && !buildType.IsAlpha)))
if (version[0] == 4 && version[1] >= 1) //4.x
{
m_ShaderKeywords = new string[reader.ReadInt32()];
for (int i = 0; i < m_ShaderKeywords.Length; i++)
{
m_ShaderKeywords[i] = reader.ReadAlignedString();
}
var m_ShaderKeywords = reader.ReadStringArray();
}
else if (version[0] >= 5)//5.0 and up
if (version[0] >= 5) //5.0 and up
{
m_ShaderKeywords = new[] { reader.ReadAlignedString() };
uint m_LightmapFlags = reader.ReadUInt32();
if (version[0] == 5 && version[1] >= 6 || version[0] > 5)//5.6.0 and up
var m_ShaderKeywords = reader.ReadAlignedString();
var m_LightmapFlags = reader.ReadUInt32();
}
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
var m_EnableInstancingVariants = reader.ReadBoolean();
//var m_DoubleSidedGI = a_Stream.ReadBoolean(); //2017 and up
reader.AlignStream();
}
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
var m_CustomRenderQueue = reader.ReadInt32();
}
if (version[0] > 5 || (version[0] == 5 && version[1] >= 1)) //5.1 and up
{
var stringTagMapSize = reader.ReadInt32();
for (int i = 0; i < stringTagMapSize; i++)
{
var m_EnableInstancingVariants = reader.ReadBoolean();
//var m_DoubleSidedGI = a_Stream.ReadBoolean();//2017.x
reader.AlignStream(4);
var first = reader.ReadAlignedString();
var second = reader.ReadAlignedString();
}
}
if (version[0] > 4 || version[0] == 4 && version[1] >= 3) { m_CustomRenderQueue = reader.ReadInt32(); }
if (version[0] == 5 && version[1] >= 1 || version[0] > 5)//5.1 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
string[][] stringTagMap = new string[reader.ReadInt32()][];
for (int i = 0; i < stringTagMap.Length; i++)
{
stringTagMap[i] = new[] { reader.ReadAlignedString(), reader.ReadAlignedString() };
}
}
//disabledShaderPasses
if ((version[0] == 5 && version[1] >= 6) || version[0] > 5)//5.6.0 and up
{
var size = reader.ReadInt32();
for (int i = 0; i < size; i++)
{
reader.ReadAlignedString();
}
}
//m_SavedProperties
m_TexEnvs = new TexEnv[reader.ReadInt32()];
for (int i = 0; i < m_TexEnvs.Length; i++)
{
TexEnv m_TexEnv = new TexEnv()
{
name = reader.ReadAlignedString(),
m_Texture = reader.ReadPPtr(),
m_Scale = new[] { reader.ReadSingle(), reader.ReadSingle() },
m_Offset = new[] { reader.ReadSingle(), reader.ReadSingle() }
};
m_TexEnvs[i] = m_TexEnv;
var disabledShaderPasses = reader.ReadStringArray();
}
m_Floats = new strFloatPair[reader.ReadInt32()];
for (int i = 0; i < m_Floats.Length; i++)
{
strFloatPair m_Float = new strFloatPair()
{
first = reader.ReadAlignedString(),
second = reader.ReadSingle()
};
m_Floats[i] = m_Float;
}
m_Colors = new strColorPair[reader.ReadInt32()];
for (int i = 0; i < m_Colors.Length; i++)
{
strColorPair m_Color = new strColorPair()
{
first = reader.ReadAlignedString(),
second = new[] { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() }
};
m_Colors[i] = m_Color;
}
m_SavedProperties = new UnityPropertySheet(reader);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -7,12 +7,11 @@ namespace AssetStudio
{
public sealed class MeshFilter : Component
{
public long preloadIndex;
public PPtr m_Mesh;
public PPtr<Mesh> m_Mesh;
public MeshFilter(ObjectReader reader) : base(reader)
{
m_Mesh = reader.ReadPPtr();
m_Mesh = new PPtr<Mesh>(reader);
}
}
}

View File

@@ -7,12 +7,12 @@ namespace AssetStudio
{
public sealed class MonoBehaviour : Behaviour
{
public PPtr m_Script;
public PPtr<MonoScript> m_Script;
public string m_Name;
public MonoBehaviour(ObjectReader reader) : base(reader)
{
m_Script = reader.ReadPPtr();
m_Script = new PPtr<MonoScript>(reader);
m_Name = reader.ReadAlignedString();
}
}

View File

@@ -8,13 +8,13 @@ namespace AssetStudio
public sealed class MovieTexture : Texture
{
public byte[] m_MovieData;
public PPtr<AudioClip> m_AudioClip;
public MovieTexture(ObjectReader reader) : base(reader)
{
var m_Loop = reader.ReadBoolean();
reader.AlignStream(4);
//PPtr<AudioClip>
reader.ReadPPtr();
reader.AlignStream();
m_AudioClip = new PPtr<AudioClip>(reader);
m_MovieData = reader.ReadBytes(reader.ReadInt32());
}
}

View File

@@ -9,7 +9,7 @@ namespace AssetStudio
{
public string m_Name;
public NamedObject(ObjectReader reader) : base(reader)
protected NamedObject(ObjectReader reader) : base(reader)
{
m_Name = reader.ReadAlignedString();
}

View File

@@ -5,27 +5,58 @@ using System.Text;
namespace AssetStudio
{
public abstract class Object
public class Object
{
protected SerializedFile sourceFile;
public SerializedFile assetsFile;
public ObjectReader reader;
public long m_PathID;
public int[] version;
protected BuildType buildType;
public BuildTarget platform;
public ClassIDType type;
public SerializedType serializedType;
public uint byteSize;
protected Object(ObjectReader reader)
public Object(ObjectReader reader)
{
this.reader = reader;
reader.Reset();
sourceFile = reader.assetsFile;
assetsFile = reader.assetsFile;
type = reader.type;
m_PathID = reader.m_PathID;
version = reader.version;
buildType = reader.buildType;
platform = reader.platform;
serializedType = reader.serializedType;
byteSize = reader.byteSize;
if (platform == BuildTarget.NoTarget)
{
var m_ObjectHideFlags = reader.ReadUInt32();
}
}
protected bool HasStructMember(string name)
{
return serializedType?.m_Nodes != null && serializedType.m_Nodes.Any(x => x.m_Name == name);
}
public string Dump()
{
reader.Reset();
if (serializedType?.m_Nodes != null)
{
var sb = new StringBuilder();
TypeTreeHelper.ReadTypeString(sb, serializedType.m_Nodes, reader);
return sb.ToString();
}
return null;
}
public byte[] GetRawData()
{
reader.Reset();
return reader.ReadBytes((int)byteSize);
}
}
}

View File

@@ -1,12 +1,21 @@
namespace AssetStudio
using System;
namespace AssetStudio
{
public class PPtr
public sealed class PPtr<T> where T : Object
{
public int m_FileID;
public long m_PathID;
public SerializedFile assetsFile;
public int index = -2; //-2 - Prepare, -1 - Missing
private SerializedFile assetsFile;
private int index = -2; //-2 - Prepare, -1 - Missing
public PPtr(ObjectReader reader)
{
m_FileID = reader.ReadInt32();
m_PathID = reader.m_Version < 14 ? reader.ReadInt32() : reader.ReadInt64();
assetsFile = reader.assetsFile;
}
private bool TryGetAssetsFile(out SerializedFile result)
{
@@ -20,7 +29,7 @@
if (m_FileID > 0 && m_FileID - 1 < assetsFile.m_Externals.Count)
{
var assetsManager = assetsFile.assetsManager;
var assetsfileList = assetsManager.assetsFileList;
var assetsFileList = assetsManager.assetsFileList;
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
if (index == -2)
@@ -29,14 +38,14 @@
var name = m_External.fileName.ToUpper();
if (!assetsFileIndexCache.TryGetValue(name, out index))
{
index = assetsfileList.FindIndex(x => x.upperFileName == name);
index = assetsFileList.FindIndex(x => x.upperFileName == name);
assetsFileIndexCache.Add(name, index);
}
}
if (index >= 0)
{
result = assetsfileList[index];
result = assetsFileList[index];
return true;
}
}
@@ -44,46 +53,79 @@
return false;
}
public bool TryGet(out ObjectReader result)
public bool TryGet(out T result)
{
if (TryGetAssetsFile(out var sourceFile))
{
if (sourceFile.Objects.TryGetValue(m_PathID, out var obj))
{
if (obj is T variable)
{
result = variable;
return true;
}
}
}
result = null;
if (TryGetAssetsFile(out var sourceFile))
{
if (sourceFile.ObjectReaders.TryGetValue(m_PathID, out result))
{
return true;
}
}
return false;
}
public bool TryGetTransform(out Transform m_Transform)
public bool TryGet<T2>(out T2 result) where T2 : Object
{
if (TryGetAssetsFile(out var sourceFile))
{
if (sourceFile.Transforms.TryGetValue(m_PathID, out m_Transform))
if (sourceFile.Objects.TryGetValue(m_PathID, out var obj))
{
return true;
if (obj is T2 variable)
{
result = variable;
return true;
}
}
}
m_Transform = null;
result = null;
return false;
}
public bool TryGetGameObject(out GameObject m_GameObject)
public void Set(T m_Object)
{
if (TryGetAssetsFile(out var sourceFile))
var name = m_Object.assetsFile.upperFileName;
if (string.Equals(assetsFile.upperFileName, name, StringComparison.Ordinal))
{
if (sourceFile.GameObjects.TryGetValue(m_PathID, out m_GameObject))
m_FileID = 0;
}
else
{
m_FileID = assetsFile.m_Externals.FindIndex(x => string.Equals(x.fileName, name, StringComparison.OrdinalIgnoreCase));
if (m_FileID == -1)
{
return true;
assetsFile.m_Externals.Add(new FileIdentifier
{
fileName = m_Object.assetsFile.fileName
});
m_FileID = assetsFile.m_Externals.Count;
}
else
{
m_FileID += 1;
}
}
m_GameObject = null;
return false;
var assetsManager = assetsFile.assetsManager;
var assetsFileList = assetsManager.assetsFileList;
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
if (!assetsFileIndexCache.TryGetValue(name, out index))
{
index = assetsFileList.FindIndex(x => x.upperFileName == name);
assetsFileIndexCache.Add(name, index);
}
m_PathID = m_Object.m_PathID;
}
public bool IsNull() => m_PathID == 0 || m_FileID < 0;
}
}

View File

@@ -20,7 +20,7 @@ namespace AssetStudio
var AndroidProfiler = reader.ReadBoolean();
//bool AndroidFilterTouchesWhenObscured 2017.2 and up
//bool AndroidEnableSustainedPerformanceMode 2018 and up
reader.AlignStream(4);
reader.AlignStream();
int defaultScreenOrientation = reader.ReadInt32();
int targetDevice = reader.ReadInt32();
if (version[0] < 5 || (version[0] == 5 && version[1] < 3)) //5.3 down
@@ -38,7 +38,7 @@ namespace AssetStudio
else
{
var useOnDemandResources = reader.ReadBoolean();
reader.AlignStream(4);
reader.AlignStream();
}
if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5 and up
{

View File

@@ -9,107 +9,135 @@ namespace AssetStudio
{
public ushort firstSubMesh;
public ushort subMeshCount;
public StaticBatchInfo(ObjectReader reader)
{
firstSubMesh = reader.ReadUInt16();
subMeshCount = reader.ReadUInt16();
}
}
public abstract class Renderer : Component
{
public PPtr[] m_Materials;
public PPtr<Material>[] m_Materials;
public StaticBatchInfo m_StaticBatchInfo;
public uint[] m_SubsetIndices;
protected Renderer(ObjectReader reader) : base(reader)
{
if (version[0] < 5)
if (version[0] < 5) //5.0 down
{
var m_Enabled = reader.ReadBoolean();
var m_CastShadows = reader.ReadByte();
var m_CastShadows = reader.ReadBoolean();
var m_ReceiveShadows = reader.ReadBoolean();
var m_LightmapIndex = reader.ReadByte();
}
else
else //5.0 and up
{
var m_Enabled = reader.ReadBoolean();
reader.AlignStream(4);
var m_CastShadows = reader.ReadByte();
var m_ReceiveShadows = reader.ReadBoolean();
reader.AlignStream(4);
if (version[0] >= 2018)//2018 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4 and up
{
var m_Enabled = reader.ReadBoolean();
var m_CastShadows = reader.ReadByte();
var m_ReceiveShadows = reader.ReadByte();
if (version[0] > 2017 || (version[0] == 2017 && version[0] >= 2)) //2017.2 and up
{
var m_DynamicOccludee = reader.ReadByte();
}
var m_MotionVectors = reader.ReadByte();
var m_LightProbeUsage = reader.ReadByte();
var m_ReflectionProbeUsage = reader.ReadByte();
reader.AlignStream();
}
else
{
var m_Enabled = reader.ReadBoolean();
reader.AlignStream();
var m_CastShadows = reader.ReadByte();
var m_ReceiveShadows = reader.ReadBoolean();
reader.AlignStream();
}
if (version[0] >= 2018) //2018 and up
{
var m_RenderingLayerMask = reader.ReadUInt32();
}
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 3)) //2018.3 and up
{
var m_RendererPriority = reader.ReadInt32();
}
var m_LightmapIndex = reader.ReadUInt16();
var m_LightmapIndexDynamic = reader.ReadUInt16();
}
if (version[0] >= 3)
if (version[0] >= 3) //3.0 and up
{
reader.Position += 16;//Vector4f m_LightmapTilingOffset
var m_LightmapTilingOffset = reader.ReadVector4();
}
if (version[0] >= 5)
if (version[0] >= 5) //5.0 and up
{
reader.Position += 16;//Vector4f m_LightmapTilingOffsetDynamic
var m_LightmapTilingOffsetDynamic = reader.ReadVector4();
}
m_Materials = new PPtr[reader.ReadInt32()];
for (int m = 0; m < m_Materials.Length; m++)
var m_MaterialsSize = reader.ReadInt32();
m_Materials = new PPtr<Material>[m_MaterialsSize];
for (int i = 0; i < m_MaterialsSize; i++)
{
m_Materials[m] = reader.ReadPPtr();
m_Materials[i] = new PPtr<Material>(reader);
}
if (version[0] < 3)
if (version[0] < 3) //3.0 down
{
reader.Position += 16;//m_LightmapTilingOffset vector4d
var m_LightmapTilingOffset = reader.ReadVector4();
}
else
else //3.0 and up
{
if ((version[0] == 5 && version[1] >= 5) || version[0] > 5)//5.5.0 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5)) //5.5 and up
{
m_StaticBatchInfo = new StaticBatchInfo
{
firstSubMesh = reader.ReadUInt16(),
subMeshCount = reader.ReadUInt16()
};
m_StaticBatchInfo = new StaticBatchInfo(reader);
}
else
{
int numSubsetIndices = reader.ReadInt32();
m_SubsetIndices = reader.ReadUInt32Array(numSubsetIndices);
m_SubsetIndices = reader.ReadUInt32Array();
}
var m_StaticBatchRoot = reader.ReadPPtr();
var m_StaticBatchRoot = new PPtr<Transform>(reader);
}
if ((version[0] == 5 && version[1] >= 4) || version[0] > 5)//5.4.0 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_LightProbeVolumeOverride = new PPtr<GameObject>(reader);
}
else if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5 - 5.3
{
var m_UseLightProbes = reader.ReadBoolean();
reader.AlignStream();
if (version[0] >= 5)//5.0 and up
{
var m_ProbeAnchor = reader.ReadPPtr();
var m_LightProbeVolumeOverride = reader.ReadPPtr();
}
else if (version[0] >= 4 || (version[0] == 3 && version[1] >= 5))//3.5 - 5.3
{
var m_UseLightProbes = reader.ReadBoolean();
reader.AlignStream(4);
if (version[0] == 5)//5.0 and up
{
int m_ReflectionProbeUsage = reader.ReadInt32();
}
var m_LightProbeAnchor = reader.ReadPPtr();
var m_ReflectionProbeUsage = reader.ReadInt32();
}
if (version[0] >= 5 || (version[0] == 4 && version[1] >= 3))//4.3 and up
{
if (version[0] == 4 && version[1] == 3)//4.3
{
int m_SortingLayer = reader.ReadInt16();
}
else
{
int m_SortingLayerID = reader.ReadInt32();
//SInt16 m_SortingOrder 5.6 and up
}
var m_LightProbeAnchor = new PPtr<Transform>(reader); //5.0 and up m_ProbeAnchor
}
int m_SortingOrder = reader.ReadInt16();
reader.AlignStream(4);
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
if (version[0] == 4 && version[1] == 3) //4.3
{
var m_SortingLayer = reader.ReadInt16();
}
else
{
var m_SortingLayerID = reader.ReadUInt32();
}
//SInt16 m_SortingLayer 5.6 and up
var m_SortingOrder = reader.ReadInt16();
reader.AlignStream();
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public abstract class RuntimeAnimatorController : NamedObject
{
protected RuntimeAnimatorController(ObjectReader reader) : base(reader)
{
}
}
}

View File

@@ -1,13 +1,14 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace AssetStudio
{
public class StructParameter
{
public List<MatrixParameter> m_MatrixParams;
public List<VectorParameter> m_VectorParams;
public MatrixParameter[] m_MatrixParams;
public VectorParameter[] m_VectorParams;
public StructParameter(BinaryReader reader)
{
@@ -17,17 +18,17 @@ namespace AssetStudio
var m_StructSize = reader.ReadInt32();
int numVectorParams = reader.ReadInt32();
m_VectorParams = new List<VectorParameter>(numVectorParams);
m_VectorParams = new VectorParameter[numVectorParams];
for (int i = 0; i < numVectorParams; i++)
{
m_VectorParams.Add(new VectorParameter(reader));
m_VectorParams[i] = new VectorParameter(reader);
}
int numMatrixParams = reader.ReadInt32();
m_MatrixParams = new List<MatrixParameter>(numMatrixParams);
m_MatrixParams = new MatrixParameter[numMatrixParams];
for (int i = 0; i < numMatrixParams; i++)
{
m_MatrixParams.Add(new MatrixParameter(reader));
m_MatrixParams[i] = new MatrixParameter(reader);
}
}
}
@@ -81,49 +82,35 @@ namespace AssetStudio
{
public string m_Name;
public string m_Description;
public List<string> m_Attributes;
public string[] m_Attributes;
public SerializedPropertyType m_Type;
public uint m_Flags;
public List<float> m_DefValue;
public float[] m_DefValue;
public SerializedTextureProperty m_DefTexture;
public SerializedProperty(BinaryReader reader)
{
m_Name = reader.ReadAlignedString();
m_Description = reader.ReadAlignedString();
int numAttributes = reader.ReadInt32();
m_Attributes = new List<string>(numAttributes);
for (int i = 0; i < numAttributes; i++)
{
m_Attributes.Add(reader.ReadAlignedString());
}
m_Attributes = reader.ReadStringArray();
m_Type = (SerializedPropertyType)reader.ReadInt32();
m_Flags = reader.ReadUInt32();
int numValues = 4;
m_DefValue = new List<float>(numValues);
for (int i = 0; i < numValues; i++)
{
m_DefValue.Add(reader.ReadSingle());
}
m_DefValue = reader.ReadSingleArray(4);
m_DefTexture = new SerializedTextureProperty(reader);
}
}
public class SerializedProperties
{
public List<SerializedProperty> m_Props;
public SerializedProperty[] m_Props;
public SerializedProperties(BinaryReader reader)
{
int numProps = reader.ReadInt32();
m_Props = new List<SerializedProperty>(numProps);
m_Props = new SerializedProperty[numProps];
for (int i = 0; i < numProps; i++)
{
m_Props.Add(new SerializedProperty(reader));
m_Props[i] = new SerializedProperty(reader);
}
}
}
@@ -202,21 +189,13 @@ namespace AssetStudio
kFogDisabled = 0,
kFogLinear = 1,
kFogExp = 2,
kFogExp2 = 3,
kFogModeCount = 4
kFogExp2 = 3
};
public class SerializedShaderState
{
public string m_Name;
public SerializedShaderRTBlendState rtBlend0;
public SerializedShaderRTBlendState rtBlend1;
public SerializedShaderRTBlendState rtBlend2;
public SerializedShaderRTBlendState rtBlend3;
public SerializedShaderRTBlendState rtBlend4;
public SerializedShaderRTBlendState rtBlend5;
public SerializedShaderRTBlendState rtBlend6;
public SerializedShaderRTBlendState rtBlend7;
public SerializedShaderRTBlendState[] rtBlend;
public bool rtSeparateBlend;
public SerializedShaderFloatValue zClip;
public SerializedShaderFloatValue zTest;
@@ -246,16 +225,13 @@ namespace AssetStudio
var version = reader.version;
m_Name = reader.ReadAlignedString();
rtBlend0 = new SerializedShaderRTBlendState(reader);
rtBlend1 = new SerializedShaderRTBlendState(reader);
rtBlend2 = new SerializedShaderRTBlendState(reader);
rtBlend3 = new SerializedShaderRTBlendState(reader);
rtBlend4 = new SerializedShaderRTBlendState(reader);
rtBlend5 = new SerializedShaderRTBlendState(reader);
rtBlend6 = new SerializedShaderRTBlendState(reader);
rtBlend7 = new SerializedShaderRTBlendState(reader);
rtBlend = new SerializedShaderRTBlendState[8];
for (int i = 0; i < 8; i++)
{
rtBlend[i] = new SerializedShaderRTBlendState(reader);
}
rtSeparateBlend = reader.ReadBoolean();
reader.AlignStream(4);
reader.AlignStream();
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
{
zClip = new SerializedShaderFloatValue(reader);
@@ -281,7 +257,7 @@ namespace AssetStudio
m_Tags = new SerializedTagMap(reader);
m_LOD = reader.ReadInt32();
lighting = reader.ReadBoolean();
reader.AlignStream(4);
reader.AlignStream();
}
}
@@ -299,18 +275,18 @@ namespace AssetStudio
public class ParserBindChannels
{
public List<ShaderBindChannel> m_Channels;
public ShaderBindChannel[] m_Channels;
public uint m_SourceMap;
public ParserBindChannels(BinaryReader reader)
{
int numChannels = reader.ReadInt32();
m_Channels = new List<ShaderBindChannel>(numChannels);
m_Channels = new ShaderBindChannel[numChannels];
for (int i = 0; i < numChannels; i++)
{
m_Channels.Add(new ShaderBindChannel(reader));
m_Channels[i] = new ShaderBindChannel(reader);
}
reader.AlignStream(4);
reader.AlignStream();
m_SourceMap = reader.ReadUInt32();
}
@@ -331,7 +307,7 @@ namespace AssetStudio
m_ArraySize = reader.ReadInt32();
m_Type = reader.ReadSByte();
m_Dim = reader.ReadSByte();
reader.AlignStream(4);
reader.AlignStream();
}
}
@@ -350,7 +326,7 @@ namespace AssetStudio
m_ArraySize = reader.ReadInt32();
m_Type = reader.ReadSByte();
m_RowCount = reader.ReadSByte();
reader.AlignStream(4);
reader.AlignStream();
}
}
@@ -373,7 +349,7 @@ namespace AssetStudio
var m_MultiSampled = reader.ReadBoolean();
}
m_Dim = reader.ReadSByte();
reader.AlignStream(4);
reader.AlignStream();
}
}
@@ -392,9 +368,9 @@ namespace AssetStudio
public class ConstantBuffer
{
public int m_NameIndex;
public List<MatrixParameter> m_MatrixParams;
public List<VectorParameter> m_VectorParams;
public List<StructParameter> m_StructParams;
public MatrixParameter[] m_MatrixParams;
public VectorParameter[] m_VectorParams;
public StructParameter[] m_StructParams;
public int m_Size;
public ConstantBuffer(ObjectReader reader)
@@ -404,25 +380,25 @@ namespace AssetStudio
m_NameIndex = reader.ReadInt32();
int numMatrixParams = reader.ReadInt32();
m_MatrixParams = new List<MatrixParameter>(numMatrixParams);
m_MatrixParams = new MatrixParameter[numMatrixParams];
for (int i = 0; i < numMatrixParams; i++)
{
m_MatrixParams.Add(new MatrixParameter(reader));
m_MatrixParams[i] = new MatrixParameter(reader);
}
int numVectorParams = reader.ReadInt32();
m_VectorParams = new List<VectorParameter>(numVectorParams);
m_VectorParams = new VectorParameter[numVectorParams];
for (int i = 0; i < numVectorParams; i++)
{
m_VectorParams.Add(new VectorParameter(reader));
m_VectorParams[i] = new VectorParameter(reader);
}
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
{
int numStructParams = reader.ReadInt32();
m_StructParams = new List<StructParameter>(numStructParams);
m_StructParams = new StructParameter[numStructParams];
for (int i = 0; i < numStructParams; i++)
{
m_StructParams.Add(new StructParameter(reader));
m_StructParams[i] = new StructParameter(reader);
}
}
m_Size = reader.ReadInt32();
@@ -471,24 +447,24 @@ namespace AssetStudio
kShaderGpuProgramMetalVS = 23,
kShaderGpuProgramMetalFS = 24,
kShaderGpuProgramSPIRV = 25,
kShaderGpuProgramConsole = 26,
kShaderGpuProgramConsole = 26
};
public class SerializedSubProgram
{
public uint m_BlobIndex;
public ParserBindChannels m_Channels;
public List<ushort> m_KeywordIndices;
public ushort[] m_KeywordIndices;
public sbyte m_ShaderHardwareTier;
public ShaderGpuProgramType m_GpuProgramType;
public List<VectorParameter> m_VectorParams;
public List<MatrixParameter> m_MatrixParams;
public List<TextureParameter> m_TextureParams;
public List<BufferBinding> m_BufferParams;
public List<ConstantBuffer> m_ConstantBuffers;
public List<BufferBinding> m_ConstantBufferBindings;
public List<UAVParameter> m_UAVParams;
public List<SamplerParameter> m_Samplers;
public VectorParameter[] m_VectorParams;
public MatrixParameter[] m_MatrixParams;
public TextureParameter[] m_TextureParams;
public BufferBinding[] m_BufferParams;
public ConstantBuffer[] m_ConstantBuffers;
public BufferBinding[] m_ConstantBufferBindings;
public UAVParameter[] m_UAVParams;
public SamplerParameter[] m_Samplers;
public SerializedSubProgram(ObjectReader reader)
{
@@ -497,76 +473,82 @@ namespace AssetStudio
m_BlobIndex = reader.ReadUInt32();
m_Channels = new ParserBindChannels(reader);
int numIndices = reader.ReadInt32();
m_KeywordIndices = new List<ushort>(numIndices);
for (int i = 0; i < numIndices; i++)
if (version[0] >= 2019) //2019 and up
{
m_KeywordIndices.Add(reader.ReadUInt16());
var m_GlobalKeywordIndices = reader.ReadUInt16Array();
reader.AlignStream();
var m_LocalKeywordIndices = reader.ReadUInt16Array();
reader.AlignStream();
}
if (version[0] >= 2017) //2017 and up
else
{
reader.AlignStream(4);
m_KeywordIndices = reader.ReadUInt16Array();
if (version[0] >= 2017) //2017 and up
{
reader.AlignStream();
}
}
m_ShaderHardwareTier = reader.ReadSByte();
m_GpuProgramType = (ShaderGpuProgramType)reader.ReadSByte();
reader.AlignStream(4);
reader.AlignStream();
int numVectorParams = reader.ReadInt32();
m_VectorParams = new List<VectorParameter>(numVectorParams);
m_VectorParams = new VectorParameter[numVectorParams];
for (int i = 0; i < numVectorParams; i++)
{
m_VectorParams.Add(new VectorParameter(reader));
m_VectorParams[i] = new VectorParameter(reader);
}
int numMatrixParams = reader.ReadInt32();
m_MatrixParams = new List<MatrixParameter>(numMatrixParams);
m_MatrixParams = new MatrixParameter[numMatrixParams];
for (int i = 0; i < numMatrixParams; i++)
{
m_MatrixParams.Add(new MatrixParameter(reader));
m_MatrixParams[i] = new MatrixParameter(reader);
}
int numTextureParams = reader.ReadInt32();
m_TextureParams = new List<TextureParameter>(numTextureParams);
m_TextureParams = new TextureParameter[numTextureParams];
for (int i = 0; i < numTextureParams; i++)
{
m_TextureParams.Add(new TextureParameter(reader));
m_TextureParams[i] = new TextureParameter(reader);
}
int numBufferParams = reader.ReadInt32();
m_BufferParams = new List<BufferBinding>(numBufferParams);
m_BufferParams = new BufferBinding[numBufferParams];
for (int i = 0; i < numBufferParams; i++)
{
m_BufferParams.Add(new BufferBinding(reader));
m_BufferParams[i] = new BufferBinding(reader);
}
int numConstantBuffers = reader.ReadInt32();
m_ConstantBuffers = new List<ConstantBuffer>(numConstantBuffers);
m_ConstantBuffers = new ConstantBuffer[numConstantBuffers];
for (int i = 0; i < numConstantBuffers; i++)
{
m_ConstantBuffers.Add(new ConstantBuffer(reader));
m_ConstantBuffers[i] = new ConstantBuffer(reader);
}
int numConstantBufferBindings = reader.ReadInt32();
m_ConstantBufferBindings = new List<BufferBinding>(numConstantBufferBindings);
m_ConstantBufferBindings = new BufferBinding[numConstantBufferBindings];
for (int i = 0; i < numConstantBufferBindings; i++)
{
m_ConstantBufferBindings.Add(new BufferBinding(reader));
m_ConstantBufferBindings[i] = new BufferBinding(reader);
}
int numUAVParams = reader.ReadInt32();
m_UAVParams = new List<UAVParameter>(numUAVParams);
m_UAVParams = new UAVParameter[numUAVParams];
for (int i = 0; i < numUAVParams; i++)
{
m_UAVParams.Add(new UAVParameter(reader));
m_UAVParams[i] = new UAVParameter(reader);
}
if (version[0] >= 2017) //2017 and up
{
int numSamplers = reader.ReadInt32();
m_Samplers = new List<SamplerParameter>(numSamplers);
m_Samplers = new SamplerParameter[numSamplers];
for (int i = 0; i < numSamplers; i++)
{
m_Samplers.Add(new SamplerParameter(reader));
m_Samplers[i] = new SamplerParameter(reader);
}
}
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
@@ -578,15 +560,15 @@ namespace AssetStudio
public class SerializedProgram
{
public List<SerializedSubProgram> m_SubPrograms;
public SerializedSubProgram[] m_SubPrograms;
public SerializedProgram(ObjectReader reader)
{
int numSubPrograms = reader.ReadInt32();
m_SubPrograms = new List<SerializedSubProgram>(numSubPrograms);
m_SubPrograms = new SerializedSubProgram[numSubPrograms];
for (int i = 0; i < numSubPrograms; i++)
{
m_SubPrograms.Add(new SerializedSubProgram(reader));
m_SubPrograms[i] = new SerializedSubProgram(reader);
}
}
}
@@ -600,7 +582,7 @@ namespace AssetStudio
public class SerializedPass
{
public List<KeyValuePair<string, int>> m_NameIndices;
public KeyValuePair<string, int>[] m_NameIndices;
public PassType m_Type;
public SerializedShaderState m_State;
public uint m_ProgramMask;
@@ -620,10 +602,10 @@ namespace AssetStudio
var version = reader.version;
int numIndices = reader.ReadInt32();
m_NameIndices = new List<KeyValuePair<string, int>>(numIndices);
m_NameIndices = new KeyValuePair<string, int>[numIndices];
for (int i = 0; i < numIndices; i++)
{
m_NameIndices.Add(new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32()));
m_NameIndices[i] = new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32());
}
m_Type = (PassType)reader.ReadInt32();
@@ -639,7 +621,7 @@ namespace AssetStudio
{
var m_HasProceduralInstancingVariant = reader.ReadBoolean();
}
reader.AlignStream(4);
reader.AlignStream();
m_UseName = reader.ReadAlignedString();
m_Name = reader.ReadAlignedString();
m_TextureName = reader.ReadAlignedString();
@@ -649,32 +631,32 @@ namespace AssetStudio
public class SerializedTagMap
{
public List<KeyValuePair<string, string>> tags;
public KeyValuePair<string, string>[] tags;
public SerializedTagMap(BinaryReader reader)
{
int numTags = reader.ReadInt32();
tags = new List<KeyValuePair<string, string>>(numTags);
tags = new KeyValuePair<string, string>[numTags];
for (int i = 0; i < numTags; i++)
{
tags.Add(new KeyValuePair<string, string>(reader.ReadAlignedString(), reader.ReadAlignedString()));
tags[i] = new KeyValuePair<string, string>(reader.ReadAlignedString(), reader.ReadAlignedString());
}
}
}
public class SerializedSubShader
{
public List<SerializedPass> m_Passes;
public SerializedPass[] m_Passes;
public SerializedTagMap m_Tags;
public int m_LOD;
public SerializedSubShader(ObjectReader reader)
{
int numPasses = reader.ReadInt32();
m_Passes = new List<SerializedPass>(numPasses);
m_Passes = new SerializedPass[numPasses];
for (int i = 0; i < numPasses; i++)
{
m_Passes.Add(new SerializedPass(reader));
m_Passes[i] = new SerializedPass(reader);
}
m_Tags = new SerializedTagMap(reader);
@@ -697,11 +679,11 @@ namespace AssetStudio
public class SerializedShader
{
public SerializedProperties m_PropInfo;
public List<SerializedSubShader> m_SubShaders;
public SerializedSubShader[] m_SubShaders;
public string m_Name;
public string m_CustomEditorName;
public string m_FallbackName;
public List<SerializedShaderDependency> m_Dependencies;
public SerializedShaderDependency[] m_Dependencies;
public bool m_DisableNoSubshadersMessage;
public SerializedShader(ObjectReader reader)
@@ -709,10 +691,10 @@ namespace AssetStudio
m_PropInfo = new SerializedProperties(reader);
int numSubShaders = reader.ReadInt32();
m_SubShaders = new List<SerializedSubShader>(numSubShaders);
m_SubShaders = new SerializedSubShader[numSubShaders];
for (int i = 0; i < numSubShaders; i++)
{
m_SubShaders.Add(new SerializedSubShader(reader));
m_SubShaders[i] = new SerializedSubShader(reader);
}
m_Name = reader.ReadAlignedString();
@@ -720,17 +702,43 @@ namespace AssetStudio
m_FallbackName = reader.ReadAlignedString();
int numDependencies = reader.ReadInt32();
m_Dependencies = new List<SerializedShaderDependency>(numDependencies);
m_Dependencies = new SerializedShaderDependency[numDependencies];
for (int i = 0; i < numDependencies; i++)
{
m_Dependencies.Add(new SerializedShaderDependency(reader));
m_Dependencies[i] = new SerializedShaderDependency(reader);
}
m_DisableNoSubshadersMessage = reader.ReadBoolean();
reader.AlignStream(4);
reader.AlignStream();
}
}
public enum ShaderCompilerPlatform
{
kShaderCompPlatformNone = -1,
kShaderCompPlatformGL = 0,
kShaderCompPlatformD3D9 = 1,
kShaderCompPlatformXbox360 = 2,
kShaderCompPlatformPS3 = 3,
kShaderCompPlatformD3D11 = 4,
kShaderCompPlatformGLES20 = 5,
kShaderCompPlatformNaCl = 6,
kShaderCompPlatformFlash = 7,
kShaderCompPlatformD3D11_9x = 8,
kShaderCompPlatformGLES3Plus = 9,
kShaderCompPlatformPSP2 = 10,
kShaderCompPlatformPS4 = 11,
kShaderCompPlatformXboxOne = 12,
kShaderCompPlatformPSM = 13,
kShaderCompPlatformMetal = 14,
kShaderCompPlatformOpenGLCore = 15,
kShaderCompPlatformN3DS = 16,
kShaderCompPlatformWiiU = 17,
kShaderCompPlatformVulkan = 18,
kShaderCompPlatformSwitch = 19,
kShaderCompPlatformXboxOneD3D12 = 20
};
public class Shader : NamedObject
{
public byte[] m_Script;
@@ -739,10 +747,10 @@ namespace AssetStudio
public byte[] m_SubProgramBlob;
//5.5 and up
public SerializedShader m_ParsedForm;
public List<uint> platforms;
public List<uint> offsets;
public List<uint> compressedLengths;
public List<uint> decompressedLengths;
public ShaderCompilerPlatform[] platforms;
public uint[] offsets;
public uint[] compressedLengths;
public uint[] decompressedLengths;
public byte[] compressedBlob;
public Shader(ObjectReader reader) : base(reader)
@@ -750,40 +758,16 @@ namespace AssetStudio
if (version[0] == 5 && version[1] >= 5 || version[0] > 5) //5.5 and up
{
m_ParsedForm = new SerializedShader(reader);
int numPlatforms = reader.ReadInt32();
platforms = new List<uint>(numPlatforms);
for (int i = 0; i < numPlatforms; i++)
{
platforms.Add(reader.ReadUInt32());
}
int numOffsets = reader.ReadInt32();
offsets = new List<uint>(numOffsets);
for (int i = 0; i < numOffsets; i++)
{
offsets.Add(reader.ReadUInt32());
}
int numCompressedLengths = reader.ReadInt32();
compressedLengths = new List<uint>(numCompressedLengths);
for (int i = 0; i < numCompressedLengths; i++)
{
compressedLengths.Add(reader.ReadUInt32());
}
int numDecompressedLengths = reader.ReadInt32();
decompressedLengths = new List<uint>(numDecompressedLengths);
for (int i = 0; i < numDecompressedLengths; i++)
{
decompressedLengths.Add(reader.ReadUInt32());
}
platforms = reader.ReadUInt32Array().Select(x => (ShaderCompilerPlatform)x).ToArray();
offsets = reader.ReadUInt32Array();
compressedLengths = reader.ReadUInt32Array();
decompressedLengths = reader.ReadUInt32Array();
compressedBlob = reader.ReadBytes(reader.ReadInt32());
}
else
{
m_Script = reader.ReadBytes(reader.ReadInt32());
reader.AlignStream(4);
reader.AlignStream();
var m_PathName = reader.ReadAlignedString();
if (version[0] == 5 && version[1] >= 3) //5.3 - 5.4
{

View File

@@ -7,46 +7,33 @@ namespace AssetStudio
{
public sealed class SkinnedMeshRenderer : Renderer
{
public PPtr m_Mesh;
public PPtr[] m_Bones;
public List<float> m_BlendShapeWeights;
public PPtr<Mesh> m_Mesh;
public PPtr<Transform>[] m_Bones;
public float[] m_BlendShapeWeights;
public SkinnedMeshRenderer(ObjectReader reader) : base(reader)
{
int m_Quality = reader.ReadInt32();
var m_UpdateWhenOffscreen = reader.ReadBoolean();
var m_SkinNormals = reader.ReadBoolean(); //3.1.0 and below
reader.AlignStream(4);
reader.AlignStream();
if (version[0] == 2 && version[1] < 6)//2.6 down
if (version[0] == 2 && version[1] < 6) //2.6 down
{
var m_DisableAnimationWhenOffscreen = reader.ReadPPtr();
var m_DisableAnimationWhenOffscreen = new PPtr<Animation>(reader);
}
m_Mesh = reader.ReadPPtr();
m_Mesh = new PPtr<Mesh>(reader);
m_Bones = new PPtr[reader.ReadInt32()];
m_Bones = new PPtr<Transform>[reader.ReadInt32()];
for (int b = 0; b < m_Bones.Length; b++)
{
m_Bones[b] = reader.ReadPPtr();
m_Bones[b] = new PPtr<Transform>(reader);
}
if (version[0] < 3)
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
int m_BindPose = reader.ReadInt32();
reader.Position += m_BindPose * 16 * 4;//Matrix4x4f
}
else
{
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3))//4.3 and up
{
int numBSWeights = reader.ReadInt32();
m_BlendShapeWeights = new List<float>(numBSWeights);
for (int i = 0; i < numBSWeights; i++)
{
m_BlendShapeWeights.Add(reader.ReadSingle());
}
}
m_BlendShapeWeights = reader.ReadSingleArray();
}
}
}

View File

@@ -1,13 +1,22 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using SharpDX;
using RectangleF = System.Drawing.RectangleF;
using System.IO;
namespace AssetStudio
{
public class SecondarySpriteTexture
{
public PPtr<Texture2D> texture;
public string name;
public SecondarySpriteTexture(ObjectReader reader)
{
texture = new PPtr<Texture2D>(reader);
name = reader.ReadStringToNull();
}
}
public enum SpritePackingRotation
{
kSPRNone = 0,
@@ -31,7 +40,7 @@ namespace AssetStudio
public SpritePackingMode packingMode;
public SpritePackingRotation packingRotation;
public SpriteSettings(ObjectReader reader)
public SpriteSettings(BinaryReader reader)
{
settingsRaw = reader.ReadUInt32();
@@ -44,171 +53,186 @@ namespace AssetStudio
}
}
public class SpriteVertex
{
public Vector3 pos;
public Vector2 uv;
public SpriteVertex(ObjectReader reader)
{
var version = reader.version;
pos = reader.ReadVector3();
if (version[0] < 4 || (version[0] == 4 && version[1] <= 3)) //4.3 and down
{
uv = reader.ReadVector2();
}
}
}
public class SpriteRenderData
{
public PPtr<Texture2D> texture;
public PPtr<Texture2D> alphaTexture;
public SecondarySpriteTexture[] secondaryTextures;
public SubMesh[] m_SubMeshes;
public byte[] m_IndexBuffer;
public VertexData m_VertexData;
public SpriteVertex[] vertices;
public ushort[] indices;
public Matrix4x4[] m_Bindpose;
public BoneWeights4[] m_SourceSkin;
public RectangleF textureRect;
public Vector2 textureRectOffset;
public Vector2 atlasRectOffset;
public SpriteSettings settingsRaw;
public Vector4 uvTransform;
public float downscaleMultiplier;
public SpriteRenderData(ObjectReader reader)
{
var version = reader.version;
texture = new PPtr<Texture2D>(reader);
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up
{
alphaTexture = new PPtr<Texture2D>(reader);
}
if (version[0] >= 2019) //2019 and up
{
var secondaryTexturesSize = reader.ReadInt32();
secondaryTextures = new SecondarySpriteTexture[secondaryTexturesSize];
for (int i = 0; i < secondaryTexturesSize; i++)
{
secondaryTextures[i] = new SecondarySpriteTexture(reader);
}
}
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
var m_SubMeshesSize = reader.ReadInt32();
m_SubMeshes = new SubMesh[m_SubMeshesSize];
for (int i = 0; i < m_SubMeshesSize; i++)
{
m_SubMeshes[i] = new SubMesh(reader);
}
m_IndexBuffer = reader.ReadBytes(reader.ReadInt32());
reader.AlignStream();
m_VertexData = new VertexData(reader);
}
else
{
var verticesSize = reader.ReadInt32();
vertices = new SpriteVertex[verticesSize];
for (int i = 0; i < verticesSize; i++)
{
vertices[i] = new SpriteVertex(reader);
}
indices = reader.ReadUInt16Array();
reader.AlignStream();
}
if (version[0] >= 2018) //2018 and up
{
m_Bindpose = reader.ReadMatrixArray();
if (version[0] == 2018 && version[1] < 2) //2018.2 down
{
var m_SourceSkinSize = reader.ReadInt32();
for (int i = 0; i < m_SourceSkinSize; i++)
{
m_SourceSkin[i] = new BoneWeights4(reader);
}
}
}
textureRect = reader.ReadRectangleF();
textureRectOffset = reader.ReadVector2();
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
atlasRectOffset = reader.ReadVector2();
}
settingsRaw = new SpriteSettings(reader);
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
{
uvTransform = reader.ReadVector4();
}
if (version[0] >= 2017) //2017 and up
{
downscaleMultiplier = reader.ReadSingle();
}
}
}
public sealed class Sprite : NamedObject
{
public RectangleF m_Rect;
public Vector2 m_Offset;
public Vector4 m_Border;
public float m_PixelsToUnits;
public Vector2 m_Pivot;
public Tuple<Guid, long> m_RenderDataKey;
public PPtr texture;
public PPtr m_SpriteAtlas;
public RectangleF textureRect;
public SpriteSettings settingsRaw;
public PointF[][] m_PhysicsShape; //Vector2[][]
public uint m_Extrude;
public bool m_IsPolygon;
public KeyValuePair<Guid, long> m_RenderDataKey;
public string[] m_AtlasTags;
public PPtr<SpriteAtlas> m_SpriteAtlas;
public SpriteRenderData m_RD;
public Vector2[][] m_PhysicsShape;
public Sprite(ObjectReader reader) : base(reader)
{
//Rectf m_Rect
m_Rect = reader.ReadRectangleF();
//Vector2f m_Offset
reader.Position += 8;
m_Offset = reader.ReadVector2();
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
{
//Vector4f m_Border
reader.Position += 16;
m_Border = reader.ReadVector4();
}
m_PixelsToUnits = reader.ReadSingle();
if (version[0] > 5
|| (version[0] == 5 && version[1] > 4)
|| (version[0] == 5 && version[1] == 4 && version[2] >= 2)) //5.4.2 and up
|| (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
{
//Vector2f m_Pivot
m_Pivot = reader.ReadVector2();
}
var m_Extrude = reader.ReadUInt32();
m_Extrude = reader.ReadUInt32();
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3)) //5.3 and up
{
var m_IsPolygon = reader.ReadBoolean();
reader.AlignStream(4);
m_IsPolygon = reader.ReadBoolean();
reader.AlignStream();
}
if (version[0] >= 2017) //2017 and up
{
//pair m_RenderDataKey
var first = new Guid(reader.ReadBytes(16));
var second = reader.ReadInt64();
m_RenderDataKey = new Tuple<Guid, long>(first, second);
//vector m_AtlasTags
var size = reader.ReadInt32();
for (int i = 0; i < size; i++)
{
var data = reader.ReadAlignedString();
}
m_RenderDataKey = new KeyValuePair<Guid, long>(first, second);
//PPtr<SpriteAtlas> m_SpriteAtlas
m_SpriteAtlas = reader.ReadPPtr();
m_AtlasTags = reader.ReadStringArray();
m_SpriteAtlas = new PPtr<SpriteAtlas>(reader);
}
//SpriteRenderData m_RD
// PPtr<Texture2D> texture
texture = reader.ReadPPtr();
// PPtr<Texture2D> alphaTexture
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up
{
var alphaTexture = reader.ReadPPtr();
}
m_RD = new SpriteRenderData(reader);
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
// vector m_SubMeshes
var size = reader.ReadInt32();
// SubMesh data
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
{
reader.Position += 48 * size;
}
else
{
reader.Position += 44 * size;
}
// vector m_IndexBuffer
size = reader.ReadInt32();
reader.Position += size; //UInt8 data
reader.AlignStream(4);
// VertexData m_VertexData
if (version[0] < 2018)//2018 down
{
var m_CurrentChannels = reader.ReadInt32();
}
var m_VertexCount = reader.ReadUInt32();
// vector m_Channels
size = reader.ReadInt32();
reader.Position += size * 4; //ChannelInfo data
// TypelessData m_DataSize
size = reader.ReadInt32();
reader.Position += size; //UInt8 data
reader.AlignStream(4);
if (version[0] >= 2018)//2018 and up
{
// vector m_Bindpose
// Matrix4x4f data
size = reader.ReadInt32();
reader.Position += size * 64;
if (version[0] == 2018 && version[1] < 2) //2018.2 down
{
// vector m_SourceSkin
// BoneWeights4 data
size = reader.ReadInt32();
reader.Position += size * 32;
}
}
}
else
{
// vector vertices
var size = reader.ReadInt32();
for (int i = 0; i < size; i++)
{
//SpriteVertex data
reader.Position += 12; //Vector3f pos
if (version[0] < 4 || (version[0] == 4 && version[1] <= 3)) //4.3 and down
reader.Position += 8; //Vector2f uv
}
// vector indices
size = reader.ReadInt32();
reader.Position += 2 * size; //UInt16 data
reader.AlignStream(4);
}
// Rectf textureRect
textureRect = reader.ReadRectangleF();
// Vector2f textureRectOffset
reader.Position += 8;
// Vector2f atlasRectOffset - 5.6 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
reader.Position += 8;
}
// unsigned int settingsRaw
settingsRaw = new SpriteSettings(reader);
// Vector4f uvTransform - 4.5 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
{
reader.Position += 16;
}
if (version[0] >= 2017) //2017 and up
{
// float downscaleMultiplier - 2017 and up
reader.Position += 4;
//vector m_PhysicsShape - 2017 and up
var m_PhysicsShape_size = reader.ReadInt32();
m_PhysicsShape = new PointF[m_PhysicsShape_size][];
for (int i = 0; i < m_PhysicsShape_size; i++)
var m_PhysicsShapeSize = reader.ReadInt32();
m_PhysicsShape = new Vector2[m_PhysicsShapeSize][];
for (int i = 0; i < m_PhysicsShapeSize; i++)
{
var data_size = reader.ReadInt32();
//Vector2f
m_PhysicsShape[i] = new PointF[data_size];
for (int j = 0; j < data_size; j++)
{
m_PhysicsShape[i][j] = new PointF(reader.ReadSingle(), reader.ReadSingle());
}
m_PhysicsShape[i] = reader.ReadVector2Array();
}
}
//vector m_Bones 2018 and up
}
}

View File

@@ -1,16 +1,12 @@
using SharpDX;
using System;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public class SpriteAtlasData
{
public PPtr texture;
public PPtr alphaTexture;
public PPtr<Texture2D> texture;
public PPtr<Texture2D> alphaTexture;
public System.Drawing.RectangleF textureRect;
public Vector2 textureRectOffset;
public Vector2 atlasRectOffset;
@@ -21,8 +17,8 @@ namespace AssetStudio
public SpriteAtlasData(ObjectReader reader)
{
var version = reader.version;
texture = reader.ReadPPtr();
alphaTexture = reader.ReadPPtr();
texture = new PPtr<Texture2D>(reader);
alphaTexture = new PPtr<Texture2D>(reader);
textureRect = reader.ReadRectangleF();
textureRectOffset = reader.ReadVector2();
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
@@ -37,30 +33,28 @@ namespace AssetStudio
public sealed class SpriteAtlas : NamedObject
{
public Dictionary<Tuple<Guid, long>, SpriteAtlasData> m_RenderDataMap;
public PPtr<Sprite>[] m_PackedSprites;
public Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData> m_RenderDataMap;
public SpriteAtlas(ObjectReader reader) : base(reader)
{
var m_PackedSpritesSize = reader.ReadInt32();
m_PackedSprites = new PPtr<Sprite>[m_PackedSpritesSize];
for (int i = 0; i < m_PackedSpritesSize; i++)
{
reader.ReadPPtr(); //PPtr<Sprite> data
m_PackedSprites[i] = new PPtr<Sprite>(reader);
}
var m_PackedSpriteNamesToIndexSize = reader.ReadInt32();
for (int i = 0; i < m_PackedSpriteNamesToIndexSize; i++)
{
reader.ReadAlignedString();
}
var m_PackedSpriteNamesToIndex = reader.ReadStringArray();
var m_RenderDataMapSize = reader.ReadInt32();
m_RenderDataMap = new Dictionary<Tuple<Guid, long>, SpriteAtlasData>(m_RenderDataMapSize);
m_RenderDataMap = new Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData>(m_RenderDataMapSize);
for (int i = 0; i < m_RenderDataMapSize; i++)
{
var first = new Guid(reader.ReadBytes(16));
var second = reader.ReadInt64();
var value = new SpriteAtlasData(reader);
m_RenderDataMap.Add(new Tuple<Guid, long>(first, second), value);
m_RenderDataMap.Add(new KeyValuePair<Guid, long>(first, second), value);
}
//string m_Tag
//bool m_IsVariant

View File

@@ -13,7 +13,7 @@ namespace AssetStudio
{
var m_ForcedFallbackFormat = reader.ReadInt32();
var m_DownscaleFallback = reader.ReadBoolean();
reader.AlignStream(4);
reader.AlignStream();
}
}
}

View File

@@ -7,74 +7,37 @@ using System.Runtime.InteropServices;
namespace AssetStudio
{
public sealed class Texture2D : Texture
public class StreamingInfo
{
public int m_Width;
public int m_Height;
public int m_CompleteImageSize;
public TextureFormat m_TextureFormat;
public bool m_MipMap;
public int m_MipCount;
public bool m_IsReadable;
public bool m_ReadAllowed;
public int m_ImageCount;
public int m_TextureDimension;
//m_TextureSettings
public int m_FilterMode;
public int m_Aniso;
public float m_MipBias;
public int m_WrapMode;
public int m_LightmapFormat;
public int m_ColorSpace;
//image dataa
public int image_data_size;
public byte[] image_data;
//m_StreamData
public uint offset;
public uint size;
public string path;
public Texture2D(ObjectReader reader, bool readData) : base(reader)
public StreamingInfo(ObjectReader reader)
{
m_Width = reader.ReadInt32();
m_Height = reader.ReadInt32();
m_CompleteImageSize = reader.ReadInt32();
m_TextureFormat = (TextureFormat)reader.ReadInt32();
offset = reader.ReadUInt32();
size = reader.ReadUInt32();
path = reader.ReadAlignedString();
}
}
if (version[0] < 5 || (version[0] == 5 && version[1] < 2))
{
m_MipMap = reader.ReadBoolean();
}
else
{
m_MipCount = reader.ReadInt32();
}
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_IsReadable = reader.ReadBoolean(); //2.6.0 and up
m_ReadAllowed = reader.ReadBoolean(); //3.0.0 - 5.4
//m_StreamingMipmaps 2018.2 and up
reader.AlignStream(4);
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
{
var m_StreamingMipmapsPriority = reader.ReadInt32();
}
else if (reader.HasStructMember("m_StreamingMipmapsPriority")) //will fix in some patch version bundle
{
var m_StreamingMipmapsPriority = reader.ReadInt32();
}
if (reader.HasStructMember("m_StreamingGroupID")) //What the hell is this?
{
var m_StreamingGroupID = reader.ReadUInt32();
}
m_ImageCount = reader.ReadInt32();
m_TextureDimension = reader.ReadInt32();
//m_TextureSettings
m_FilterMode = reader.ReadInt32();
m_Aniso = reader.ReadInt32();
m_MipBias = reader.ReadSingle();
if (version[0] >= 2017)//2017.x and up
{
int m_WrapU = reader.ReadInt32();
m_WrapMode = reader.ReadInt32(); //m_WrapU
int m_WrapV = reader.ReadInt32();
int m_WrapW = reader.ReadInt32();
}
@@ -82,36 +45,69 @@ namespace AssetStudio
{
m_WrapMode = reader.ReadInt32();
}
if (version[0] >= 3)
}
}
public sealed class Texture2D : Texture
{
public int m_Width;
public int m_Height;
public TextureFormat m_TextureFormat;
public bool m_MipMap;
public int m_MipCount;
public GLTextureSettings m_TextureSettings;
public Lazy<byte[]> image_data;
public StreamingInfo m_StreamData;
public Texture2D(ObjectReader reader) : base(reader)
{
m_Width = reader.ReadInt32();
m_Height = reader.ReadInt32();
var m_CompleteImageSize = reader.ReadInt32();
m_TextureFormat = (TextureFormat)reader.ReadInt32();
if (version[0] < 5 || (version[0] == 5 && version[1] < 2)) //5.2 down
{
m_LightmapFormat = reader.ReadInt32();
if (version[0] >= 4 || version[1] >= 5)//3.5.0 and up
{
m_ColorSpace = reader.ReadInt32();
}
m_MipMap = reader.ReadBoolean();
}
image_data_size = reader.ReadInt32();
else
{
m_MipCount = reader.ReadInt32();
}
var m_IsReadable = reader.ReadBoolean(); //2.6.0 and up
var m_ReadAllowed = reader.ReadBoolean(); //3.0.0 - 5.4
//bool m_StreamingMipmaps 2018.2 and up
reader.AlignStream();
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
{
var m_StreamingMipmapsPriority = reader.ReadInt32();
}
var m_ImageCount = reader.ReadInt32();
var m_TextureDimension = reader.ReadInt32();
m_TextureSettings = new GLTextureSettings(reader);
if (version[0] >= 3) //3.0 and up
{
var m_LightmapFormat = reader.ReadInt32();
}
if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5.0 and up
{
var m_ColorSpace = reader.ReadInt32();
}
var image_data_size = reader.ReadInt32();
if (image_data_size == 0 && ((version[0] == 5 && version[1] >= 3) || version[0] > 5))//5.3.0 and up
{
offset = reader.ReadUInt32();
size = reader.ReadUInt32();
image_data_size = (int)size;
path = reader.ReadAlignedString();
m_StreamData = new StreamingInfo(reader);
}
if (readData)
ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_StreamData?.path))
{
if (!string.IsNullOrEmpty(path))
{
image_data = ResourcesHelper.GetData(path, sourceFile, offset, image_data_size);
}
else
{
image_data = reader.ReadBytes(image_data_size);
}
resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, (int)m_StreamData.size);
}
else
{
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, image_data_size);
}
image_data = new Lazy<byte[]>(resourceReader.GetData);
}
}

View File

@@ -1,5 +1,4 @@
using SharpDX;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -8,24 +7,25 @@ namespace AssetStudio
{
public class Transform : Component
{
public float[] m_LocalRotation;
public float[] m_LocalPosition;
public float[] m_LocalScale;
public List<PPtr> m_Children;
public PPtr m_Father;
public Quaternion m_LocalRotation;
public Vector3 m_LocalPosition;
public Vector3 m_LocalScale;
public PPtr<Transform>[] m_Children;
public PPtr<Transform> m_Father;
public Transform(ObjectReader reader) : base(reader)
{
m_LocalRotation = new[] { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() };
m_LocalPosition = new[] { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() };
m_LocalScale = new[] { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() };
m_LocalRotation = reader.ReadQuaternion();
m_LocalPosition = reader.ReadVector3();
m_LocalScale = reader.ReadVector3();
int m_ChildrenCount = reader.ReadInt32();
m_Children = new List<PPtr>(m_ChildrenCount);
for (int j = 0; j < m_ChildrenCount; j++)
m_Children = new PPtr<Transform>[m_ChildrenCount];
for (int i = 0; i < m_ChildrenCount; i++)
{
m_Children.Add(reader.ReadPPtr());
m_Children[i] = new PPtr<Transform>(reader);
}
m_Father = reader.ReadPPtr();
m_Father = new PPtr<Transform>(reader);
}
}
}

View File

@@ -8,19 +8,19 @@ namespace AssetStudio
{
public sealed class VideoClip : NamedObject
{
public byte[] m_VideoData;
public Lazy<byte[]> m_VideoData;
public string m_OriginalPath;
public string m_Source;
public ulong m_Size;
public VideoClip(ObjectReader reader, bool readData) : base(reader)
public VideoClip(ObjectReader reader) : base(reader)
{
m_OriginalPath = reader.ReadAlignedString();
var m_ProxyWidth = reader.ReadUInt32();
var m_ProxyHeight = reader.ReadUInt32();
var Width = reader.ReadUInt32();
var Height = reader.ReadUInt32();
if (version[0] >= 2017)//2017.x and up
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
{
var m_PixelAspecRatioNum = reader.ReadUInt32();
var m_PixelAspecRatioDen = reader.ReadUInt32();
@@ -28,37 +28,26 @@ namespace AssetStudio
var m_FrameRate = reader.ReadDouble();
var m_FrameCount = reader.ReadUInt64();
var m_Format = reader.ReadInt32();
//m_AudioChannelCount
var size = reader.ReadInt32();
reader.Position += size * 2;
reader.AlignStream(4);
//m_AudioSampleRate
size = reader.ReadInt32();
reader.Position += size * 4;
//m_AudioLanguage
size = reader.ReadInt32();
for (int i = 0; i < size; i++)
{
reader.ReadAlignedString();
}
var m_AudioChannelCount = reader.ReadUInt16Array();
reader.AlignStream();
var m_AudioSampleRate = reader.ReadUInt32Array();
var m_AudioLanguage = reader.ReadStringArray();
//StreamedResource m_ExternalResources
m_Source = reader.ReadAlignedString();
var m_Offset = reader.ReadUInt64();
m_Size = reader.ReadUInt64();
var m_HasSplitAlpha = reader.ReadBoolean();
if (readData)
ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_Source))
{
if (!string.IsNullOrEmpty(m_Source))
{
m_VideoData = ResourcesHelper.GetData(m_Source, sourceFile, (long)m_Offset, (int)m_Size);
}
else
{
if (m_Size > 0)
m_VideoData = reader.ReadBytes((int)m_Size);
}
resourceReader = new ResourceReader(m_Source, assetsFile, (long)m_Offset, (int)m_Size);
}
else
{
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, (int)m_Size);
}
m_VideoData = new Lazy<byte[]>(resourceReader.GetData);
}
}
}

View File

@@ -4,7 +4,7 @@ namespace AssetStudio
{
public static class CommonString
{
public static readonly Dictionary<int, string> StringBuffer = new Dictionary<int, string>
public static readonly Dictionary<uint, string> StringBuffer = new Dictionary<uint, string>
{
{0, "AABB"},
{5, "AnimationClip"},
@@ -110,7 +110,9 @@ namespace AssetStudio
{1057, "int2_storage"},
{1070, "int3_storage"},
{1083, "BoundsInt"},
{1092, "m_CorrespondingSourceObject"}
{1093, "m_CorrespondingSourceObject"},
{1121, "m_PrefabInstance"},
{1138, "m_PrefabAsset"}
};
}
}

View File

@@ -2,12 +2,16 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using SharpDX;
namespace AssetStudio
{
public static class BinaryReaderExtensions
{
public static void AlignStream(this BinaryReader reader)
{
reader.AlignStream(4);
}
public static void AlignStream(this BinaryReader reader, int alignment)
{
var pos = reader.BaseStream.Position;
@@ -21,7 +25,7 @@ namespace AssetStudio
public static string ReadAlignedString(this BinaryReader reader)
{
var length = reader.ReadInt32();
if (length > 0 && length < (reader.BaseStream.Length - reader.BaseStream.Position))
if (length > 0 && length <= reader.BaseStream.Length - reader.BaseStream.Position)
{
var stringData = reader.ReadBytes(length);
var result = Encoding.UTF8.GetString(stringData);
@@ -31,12 +35,20 @@ namespace AssetStudio
return "";
}
public static string ReadStringToNull(this BinaryReader reader)
public static string ReadStringToNull(this BinaryReader reader, int maxLength = 32767)
{
var bytes = new List<byte>();
byte b;
while (reader.BaseStream.Position != reader.BaseStream.Length && (b = reader.ReadByte()) != 0)
int count = 0;
while (reader.BaseStream.Position != reader.BaseStream.Length && count < maxLength)
{
var b = reader.ReadByte();
if (b == 0)
{
break;
}
bytes.Add(b);
count++;
}
return Encoding.UTF8.GetString(bytes.ToArray());
}
@@ -65,39 +77,84 @@ namespace AssetStudio
return new System.Drawing.RectangleF(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
}
public static Color ReadColor4(this BinaryReader reader)
{
return new Color(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
}
public static Matrix4x4 ReadMatrix(this BinaryReader reader)
{
return new Matrix4x4(reader.ReadSingleArray(16));
}
private static T[] ReadArray<T>(Func<T> del, int length)
{
var array = new T[length];
for (int i = 0; i < array.Length; i++)
for (int i = 0; i < length; i++)
{
array[i] = del();
}
return array;
}
public static bool[] ReadBooleanArray(this BinaryReader reader)
{
return ReadArray(reader.ReadBoolean, reader.ReadInt32());
}
public static ushort[] ReadUInt16Array(this BinaryReader reader)
{
return ReadArray(reader.ReadUInt16, reader.ReadInt32());
}
public static int[] ReadInt32Array(this BinaryReader reader)
{
return ReadArray(reader.ReadInt32, reader.ReadInt32());
}
public static int[] ReadInt32Array(this BinaryReader reader, int length)
{
return ReadArray(reader.ReadInt32, length);
}
public static uint[] ReadUInt32Array(this BinaryReader reader)
{
return ReadArray(reader.ReadUInt32, reader.ReadInt32());
}
public static uint[] ReadUInt32Array(this BinaryReader reader, int length)
{
return ReadArray(reader.ReadUInt32, length);
}
public static float[] ReadSingleArray(this BinaryReader reader)
{
return ReadArray(reader.ReadSingle, reader.ReadInt32());
}
public static float[] ReadSingleArray(this BinaryReader reader, int length)
{
return ReadArray(reader.ReadSingle, length);
}
public static Vector2[] ReadVector2Array(this BinaryReader reader, int length)
public static string[] ReadStringArray(this BinaryReader reader)
{
return ReadArray(reader.ReadVector2, length);
return ReadArray(reader.ReadAlignedString, reader.ReadInt32());
}
public static Vector4[] ReadVector4Array(this BinaryReader reader, int length)
public static Vector2[] ReadVector2Array(this BinaryReader reader)
{
return ReadArray(reader.ReadVector4, length);
return ReadArray(reader.ReadVector2, reader.ReadInt32());
}
public static Vector4[] ReadVector4Array(this BinaryReader reader)
{
return ReadArray(reader.ReadVector4, reader.ReadInt32());
}
public static Matrix4x4[] ReadMatrixArray(this BinaryReader reader)
{
return ReadArray(reader.ReadMatrix, reader.ReadInt32());
}
}
}

View File

@@ -6,19 +6,6 @@ namespace AssetStudio
{
public static class BinaryWriterExtensions
{
private static void WriteArray<T>(Action<T> del, T[] array)
{
foreach (var item in array)
{
del(item);
}
}
public static void Write(this BinaryWriter writer, uint[] array)
{
WriteArray(writer.Write, array);
}
public static void AlignStream(this BinaryWriter writer, int alignment)
{
var pos = writer.BaseStream.Position;

View File

@@ -1,14 +1,12 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using SharpDX;
namespace AssetStudio
{
public interface IImported
{
List<ImportedFrame> FrameList { get; }
ImportedFrame RootFrame { get; }
List<ImportedMesh> MeshList { get; }
List<ImportedMaterial> MaterialList { get; }
List<ImportedTexture> TextureList { get; }
@@ -16,12 +14,12 @@ namespace AssetStudio
List<ImportedMorph> MorphList { get; }
}
public class ImportedFrame : IEnumerable<ImportedFrame>
public class ImportedFrame
{
public string Name { get; set; }
public float[] LocalRotation { get; set; }
public float[] LocalPosition { get; set; }
public float[] LocalScale { get; set; }
public Vector3 LocalRotation { get; set; }
public Vector3 LocalPosition { get; set; }
public Vector3 LocalScale { get; set; }
public ImportedFrame Parent { get; set; }
private List<ImportedFrame> children;
@@ -30,36 +28,110 @@ namespace AssetStudio
public int Count => children.Count;
public void InitChildren(int count)
public string Path
{
children = new List<ImportedFrame>(count);
get
{
var frame = this;
var path = frame.Name;
while (frame.Parent != null)
{
frame = frame.Parent;
path = frame.Name + "/" + path;
}
return path;
}
}
public ImportedFrame(int childrenCount = 0)
{
children = new List<ImportedFrame>(childrenCount);
}
public void AddChild(ImportedFrame obj)
{
children.Add(obj);
obj.Parent?.Remove(obj);
obj.Parent = this;
}
public void ClearChild()
public void Remove(ImportedFrame frame)
{
children.Clear();
children.Remove(frame);
}
public IEnumerator<ImportedFrame> GetEnumerator()
public ImportedFrame FindFrameByPath(string path)
{
return children.GetEnumerator();
var name = path.Substring(path.LastIndexOf('/') + 1);
foreach (var frame in FindChilds(name))
{
if (frame.Path.EndsWith(path, StringComparison.Ordinal))
{
return frame;
}
}
return null;
}
IEnumerator IEnumerable.GetEnumerator()
public ImportedFrame FindFrame(string name)
{
return GetEnumerator();
if (Name == name)
{
return this;
}
foreach (var child in children)
{
var frame = child.FindFrame(name);
if (frame != null)
{
return frame;
}
}
return null;
}
public ImportedFrame FindChild(string name, bool recursive = true)
{
foreach (var child in children)
{
if (recursive)
{
var frame = child.FindFrame(name);
if (frame != null)
{
return frame;
}
}
else
{
if (child.Name == name)
{
return child;
}
}
}
return null;
}
public IEnumerable<ImportedFrame> FindChilds(string name)
{
if (Name == name)
{
yield return this;
}
foreach (var child in children)
{
foreach (var item in child.FindChilds(name))
{
yield return item;
}
}
}
}
public class ImportedMesh
{
public string Name { get; set; }
public string Path { get; set; }
public List<ImportedSubmesh> SubmeshList { get; set; }
public List<ImportedBone> BoneList { get; set; }
}
@@ -75,7 +147,7 @@ namespace AssetStudio
{
public Vector3 Position { get; set; }
public float[] Weights { get; set; }
public byte[] BoneIndices { get; set; }
public int[] BoneIndices { get; set; }
public Vector3 Normal { get; set; }
public float[] UV { get; set; }
public Vector4 Tangent { get; set; }
@@ -83,7 +155,7 @@ namespace AssetStudio
public class ImportedVertexWithColour : ImportedVertex
{
public Color4 Colour { get; set; }
public Color Colour { get; set; }
}
public class ImportedFace
@@ -93,21 +165,29 @@ namespace AssetStudio
public class ImportedBone
{
public string Name { get; set; }
public float[,] Matrix { get; set; }
public string Path { get; set; }
public Matrix4x4 Matrix { get; set; }
}
public class ImportedMaterial
{
public string Name { get; set; }
public Color4 Diffuse { get; set; }
public Color4 Ambient { get; set; }
public Color4 Specular { get; set; }
public Color4 Emissive { get; set; }
public float Power { get; set; }
public string[] Textures { get; set; }
public Vector2[] TexOffsets { get; set; }
public Vector2[] TexScales { get; set; }
public Color Diffuse { get; set; }
public Color Ambient { get; set; }
public Color Specular { get; set; }
public Color Emissive { get; set; }
public Color Reflection { get; set; }
public float Shininess { get; set; }
public float Transparency { get; set; }
public List<ImportedMaterialTexture> Textures { get; set; }
}
public class ImportedMaterialTexture
{
public string Name { get; set; }
public int Dest { get; set; }
public Vector2 Offset { get; set; }
public Vector2 Scale { get; set; }
}
public class ImportedTexture
@@ -128,12 +208,12 @@ namespace AssetStudio
public List<ImportedAnimationKeyframedTrack> TrackList { get; set; }
public ImportedAnimationKeyframedTrack FindTrack(string name)
public ImportedAnimationKeyframedTrack FindTrack(string path)
{
var track = TrackList.Find(x => x.Name == name);
var track = TrackList.Find(x => x.Path == path);
if (track == null)
{
track = new ImportedAnimationKeyframedTrack { Name = name };
track = new ImportedAnimationKeyframedTrack { Path = path };
TrackList.Add(track);
}
@@ -143,11 +223,10 @@ namespace AssetStudio
public class ImportedAnimationKeyframedTrack
{
public string Name { get; set; }
public string Path { get; set; }
public List<ImportedKeyframe<Vector3>> Scalings = new List<ImportedKeyframe<Vector3>>();
public List<ImportedKeyframe<Vector3>> Rotations = new List<ImportedKeyframe<Vector3>>();
public List<ImportedKeyframe<Vector3>> Translations = new List<ImportedKeyframe<Vector3>>();
public List<ImportedKeyframe<float>> Curve = new List<ImportedKeyframe<float>>();
}
public class ImportedKeyframe<T>
@@ -166,7 +245,7 @@ namespace AssetStudio
public class ImportedMorph
{
public string Name { get; set; }
public string Path { get; set; }
public string ClipName { get; set; }
public List<Tuple<float, int, int>> Channels { get; set; }
public List<ImportedMorphKeyframe> KeyframeList { get; set; }
@@ -183,66 +262,11 @@ namespace AssetStudio
public static class ImportedHelpers
{
public static ImportedFrame FindFrame(string name, ImportedFrame root)
{
if (root.Name == name)
{
return root;
}
foreach (var child in root)
{
var frame = FindFrame(name, child);
if (frame != null)
{
return frame;
}
}
return null;
}
public static ImportedFrame FindChildOrRoot(string name, ImportedFrame root)
{
foreach (var child in root)
{
var frame = FindFrame(name, child);
if (frame != null)
{
return frame;
}
}
if (root.Name == name)
{
return root;
}
return null;
}
public static ImportedMesh FindMesh(string frameName, List<ImportedMesh> importedMeshList)
public static ImportedMesh FindMesh(string path, List<ImportedMesh> importedMeshList)
{
foreach (var mesh in importedMeshList)
{
if (mesh.Name == frameName)
{
return mesh;
}
}
return null;
}
public static ImportedMesh FindMesh(ImportedFrame frame, List<ImportedMesh> importedMeshList)
{
var framePath = frame.Name;
var root = frame;
while (root.Parent != null)
{
root = root.Parent;
framePath = root.Name + "/" + framePath;
}
foreach (var mesh in importedMeshList)
{
if (mesh.Name == framePath)
if (mesh.Path == path)
{
return mesh;
}

View File

@@ -70,7 +70,7 @@ namespace AssetStudio
private static FileType CheckFileType(EndianBinaryReader reader)
{
var signature = reader.ReadStringToNull();
var signature = reader.ReadStringToNull(20);
reader.Position = 0;
switch (signature)
{

Binary file not shown.

Binary file not shown.

Binary file not shown.

84
AssetStudio/Math/Color.cs Normal file
View File

@@ -0,0 +1,84 @@
using System;
using System.Runtime.InteropServices;
namespace AssetStudio
{
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct Color : IEquatable<Color>
{
public float R;
public float G;
public float B;
public float A;
public Color(float r, float g, float b, float a)
{
R = r;
G = g;
B = b;
A = a;
}
public override int GetHashCode()
{
return ((Vector4)this).GetHashCode();
}
public override bool Equals(object other)
{
if (!(other is Color))
return false;
return Equals((Color)other);
}
public bool Equals(Color other)
{
return R.Equals(other.R) && G.Equals(other.G) && B.Equals(other.B) && A.Equals(other.A);
}
public static Color operator +(Color a, Color b)
{
return new Color(a.R + b.R, a.G + b.G, a.B + b.B, a.A + b.A);
}
public static Color operator -(Color a, Color b)
{
return new Color(a.R - b.R, a.G - b.G, a.B - b.B, a.A - b.A);
}
public static Color operator *(Color a, Color b)
{
return new Color(a.R * b.R, a.G * b.G, a.B * b.B, a.A * b.A);
}
public static Color operator *(Color a, float b)
{
return new Color(a.R * b, a.G * b, a.B * b, a.A * b);
}
public static Color operator *(float b, Color a)
{
return new Color(a.R * b, a.G * b, a.B * b, a.A * b);
}
public static Color operator /(Color a, float b)
{
return new Color(a.R / b, a.G / b, a.B / b, a.A / b);
}
public static bool operator ==(Color lhs, Color rhs)
{
return (Vector4)lhs == (Vector4)rhs;
}
public static bool operator !=(Color lhs, Color rhs)
{
return !(lhs == rhs);
}
public static implicit operator Vector4(Color c)
{
return new Vector4(c.R, c.G, c.B, c.A);
}
}
}

888
AssetStudio/Math/Half.cs Normal file
View File

@@ -0,0 +1,888 @@
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
namespace System
{
/// <summary>
/// Represents a half-precision floating point number.
/// </summary>
/// <remarks>
/// Note:
/// Half is not fast enought and precision is also very bad,
/// so is should not be used for matemathical computation (use Single instead).
/// The main advantage of Half type is lower memory cost: two bytes per number.
/// Half is typically used in graphical applications.
///
/// Note:
/// All functions, where is used conversion half->float/float->half,
/// are approx. ten times slower than float->double/double->float, i.e. ~3ns on 2GHz CPU.
///
/// References:
/// - Fast Half Float Conversions, Jeroen van der Zijp, link: http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf
/// - IEEE 754 revision, link: http://grouper.ieee.org/groups/754/
/// </remarks>
[Serializable]
public struct Half : IComparable, IFormattable, IConvertible, IComparable<Half>, IEquatable<Half>
{
/// <summary>
/// Internal representation of the half-precision floating-point number.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
internal ushort value;
#region Constants
/// <summary>
/// Represents the smallest positive System.Half value greater than zero. This field is constant.
/// </summary>
public static readonly Half Epsilon = Half.ToHalf(0x0001);
/// <summary>
/// Represents the largest possible value of System.Half. This field is constant.
/// </summary>
public static readonly Half MaxValue = Half.ToHalf(0x7bff);
/// <summary>
/// Represents the smallest possible value of System.Half. This field is constant.
/// </summary>
public static readonly Half MinValue = Half.ToHalf(0xfbff);
/// <summary>
/// Represents not a number (NaN). This field is constant.
/// </summary>
public static readonly Half NaN = Half.ToHalf(0xfe00);
/// <summary>
/// Represents negative infinity. This field is constant.
/// </summary>
public static readonly Half NegativeInfinity = Half.ToHalf(0xfc00);
/// <summary>
/// Represents positive infinity. This field is constant.
/// </summary>
public static readonly Half PositiveInfinity = Half.ToHalf(0x7c00);
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of System.Half to the value of the specified single-precision floating-point number.
/// </summary>
/// <param name="value">The value to represent as a System.Half.</param>
public Half(float value) { this = HalfHelper.SingleToHalf(value); }
/// <summary>
/// Initializes a new instance of System.Half to the value of the specified 32-bit signed integer.
/// </summary>
/// <param name="value">The value to represent as a System.Half.</param>
public Half(int value) : this((float)value) { }
/// <summary>
/// Initializes a new instance of System.Half to the value of the specified 64-bit signed integer.
/// </summary>
/// <param name="value">The value to represent as a System.Half.</param>
public Half(long value) : this((float)value) { }
/// <summary>
/// Initializes a new instance of System.Half to the value of the specified double-precision floating-point number.
/// </summary>
/// <param name="value">The value to represent as a System.Half.</param>
public Half(double value) : this((float)value) { }
/// <summary>
/// Initializes a new instance of System.Half to the value of the specified decimal number.
/// </summary>
/// <param name="value">The value to represent as a System.Half.</param>
public Half(decimal value) : this((float)value) { }
/// <summary>
/// Initializes a new instance of System.Half to the value of the specified 32-bit unsigned integer.
/// </summary>
/// <param name="value">The value to represent as a System.Half.</param>
public Half(uint value) : this((float)value) { }
/// <summary>
/// Initializes a new instance of System.Half to the value of the specified 64-bit unsigned integer.
/// </summary>
/// <param name="value">The value to represent as a System.Half.</param>
public Half(ulong value) : this((float)value) { }
#endregion
#region Numeric operators
/// <summary>
/// Returns the result of multiplying the specified System.Half value by negative one.
/// </summary>
/// <param name="half">A System.Half.</param>
/// <returns>A System.Half with the value of half, but the opposite sign. -or- Zero, if half is zero.</returns>
public static Half Negate(Half half) { return -half; }
/// <summary>
/// Adds two specified System.Half values.
/// </summary>
/// <param name="half1">A System.Half.</param>
/// <param name="half2">A System.Half.</param>
/// <returns>A System.Half value that is the sum of half1 and half2.</returns>
public static Half Add(Half half1, Half half2) { return half1 + half2; }
/// <summary>
/// Subtracts one specified System.Half value from another.
/// </summary>
/// <param name="half1">A System.Half (the minuend).</param>
/// <param name="half2">A System.Half (the subtrahend).</param>
/// <returns>The System.Half result of subtracting half2 from half1.</returns>
public static Half Subtract(Half half1, Half half2) { return half1 - half2; }
/// <summary>
/// Multiplies two specified System.Half values.
/// </summary>
/// <param name="half1">A System.Half (the multiplicand).</param>
/// <param name="half2">A System.Half (the multiplier).</param>
/// <returns>A System.Half that is the result of multiplying half1 and half2.</returns>
public static Half Multiply(Half half1, Half half2) { return half1 * half2; }
/// <summary>
/// Divides two specified System.Half values.
/// </summary>
/// <param name="half1">A System.Half (the dividend).</param>
/// <param name="half2">A System.Half (the divisor).</param>
/// <returns>The System.Half that is the result of dividing half1 by half2.</returns>
/// <exception cref="System.DivideByZeroException">half2 is zero.</exception>
public static Half Divide(Half half1, Half half2) { return half1 / half2; }
/// <summary>
/// Returns the value of the System.Half operand (the sign of the operand is unchanged).
/// </summary>
/// <param name="half">The System.Half operand.</param>
/// <returns>The value of the operand, half.</returns>
public static Half operator +(Half half) { return half; }
/// <summary>
/// Negates the value of the specified System.Half operand.
/// </summary>
/// <param name="half">The System.Half operand.</param>
/// <returns>The result of half multiplied by negative one (-1).</returns>
public static Half operator -(Half half) { return HalfHelper.Negate(half); }
/// <summary>
/// Increments the System.Half operand by 1.
/// </summary>
/// <param name="half">The System.Half operand.</param>
/// <returns>The value of half incremented by 1.</returns>
public static Half operator ++(Half half) { return (Half)(half + 1f); }
/// <summary>
/// Decrements the System.Half operand by one.
/// </summary>
/// <param name="half">The System.Half operand.</param>
/// <returns>The value of half decremented by 1.</returns>
public static Half operator --(Half half) { return (Half)(half - 1f); }
/// <summary>
/// Adds two specified System.Half values.
/// </summary>
/// <param name="half1">A System.Half.</param>
/// <param name="half2">A System.Half.</param>
/// <returns>The System.Half result of adding half1 and half2.</returns>
public static Half operator +(Half half1, Half half2) { return (Half)((float)half1 + (float)half2); }
/// <summary>
/// Subtracts two specified System.Half values.
/// </summary>
/// <param name="half1">A System.Half.</param>
/// <param name="half2">A System.Half.</param>
/// <returns>The System.Half result of subtracting half1 and half2.</returns>
public static Half operator -(Half half1, Half half2) { return (Half)((float)half1 - (float)half2); }
/// <summary>
/// Multiplies two specified System.Half values.
/// </summary>
/// <param name="half1">A System.Half.</param>
/// <param name="half2">A System.Half.</param>
/// <returns>The System.Half result of multiplying half1 by half2.</returns>
public static Half operator *(Half half1, Half half2) { return (Half)((float)half1 * (float)half2); }
/// <summary>
/// Divides two specified System.Half values.
/// </summary>
/// <param name="half1">A System.Half (the dividend).</param>
/// <param name="half2">A System.Half (the divisor).</param>
/// <returns>The System.Half result of half1 by half2.</returns>
public static Half operator /(Half half1, Half half2) { return (Half)((float)half1 / (float)half2); }
/// <summary>
/// Returns a value indicating whether two instances of System.Half are equal.
/// </summary>
/// <param name="half1">A System.Half.</param>
/// <param name="half2">A System.Half.</param>
/// <returns>true if half1 and half2 are equal; otherwise, false.</returns>
public static bool operator ==(Half half1, Half half2) { return (!IsNaN(half1) && (half1.value == half2.value)); }
/// <summary>
/// Returns a value indicating whether two instances of System.Half are not equal.
/// </summary>
/// <param name="half1">A System.Half.</param>
/// <param name="half2">A System.Half.</param>
/// <returns>true if half1 and half2 are not equal; otherwise, false.</returns>
public static bool operator !=(Half half1, Half half2) { return !(half1.value == half2.value); }
/// <summary>
/// Returns a value indicating whether a specified System.Half is less than another specified System.Half.
/// </summary>
/// <param name="half1">A System.Half.</param>
/// <param name="half2">A System.Half.</param>
/// <returns>true if half1 is less than half1; otherwise, false.</returns>
public static bool operator <(Half half1, Half half2) { return (float)half1 < (float)half2; }
/// <summary>
/// Returns a value indicating whether a specified System.Half is greater than another specified System.Half.
/// </summary>
/// <param name="half1">A System.Half.</param>
/// <param name="half2">A System.Half.</param>
/// <returns>true if half1 is greater than half2; otherwise, false.</returns>
public static bool operator >(Half half1, Half half2) { return (float)half1 > (float)half2; }
/// <summary>
/// Returns a value indicating whether a specified System.Half is less than or equal to another specified System.Half.
/// </summary>
/// <param name="half1">A System.Half.</param>
/// <param name="half2">A System.Half.</param>
/// <returns>true if half1 is less than or equal to half2; otherwise, false.</returns>
public static bool operator <=(Half half1, Half half2) { return (half1 == half2) || (half1 < half2); }
/// <summary>
/// Returns a value indicating whether a specified System.Half is greater than or equal to another specified System.Half.
/// </summary>
/// <param name="half1">A System.Half.</param>
/// <param name="half2">A System.Half.</param>
/// <returns>true if half1 is greater than or equal to half2; otherwise, false.</returns>
public static bool operator >=(Half half1, Half half2) { return (half1 == half2) || (half1 > half2); }
#endregion
#region Type casting operators
/// <summary>
/// Converts an 8-bit unsigned integer to a System.Half.
/// </summary>
/// <param name="value">An 8-bit unsigned integer.</param>
/// <returns>A System.Half that represents the converted 8-bit unsigned integer.</returns>
public static implicit operator Half(byte value) { return new Half((float)value); }
/// <summary>
/// Converts a 16-bit signed integer to a System.Half.
/// </summary>
/// <param name="value">A 16-bit signed integer.</param>
/// <returns>A System.Half that represents the converted 16-bit signed integer.</returns>
public static implicit operator Half(short value) { return new Half((float)value); }
/// <summary>
/// Converts a Unicode character to a System.Half.
/// </summary>
/// <param name="value">A Unicode character.</param>
/// <returns>A System.Half that represents the converted Unicode character.</returns>
public static implicit operator Half(char value) { return new Half((float)value); }
/// <summary>
/// Converts a 32-bit signed integer to a System.Half.
/// </summary>
/// <param name="value">A 32-bit signed integer.</param>
/// <returns>A System.Half that represents the converted 32-bit signed integer.</returns>
public static implicit operator Half(int value) { return new Half((float)value); }
/// <summary>
/// Converts a 64-bit signed integer to a System.Half.
/// </summary>
/// <param name="value">A 64-bit signed integer.</param>
/// <returns>A System.Half that represents the converted 64-bit signed integer.</returns>
public static implicit operator Half(long value) { return new Half((float)value); }
/// <summary>
/// Converts a single-precision floating-point number to a System.Half.
/// </summary>
/// <param name="value">A single-precision floating-point number.</param>
/// <returns>A System.Half that represents the converted single-precision floating point number.</returns>
public static explicit operator Half(float value) { return new Half((float)value); }
/// <summary>
/// Converts a double-precision floating-point number to a System.Half.
/// </summary>
/// <param name="value">A double-precision floating-point number.</param>
/// <returns>A System.Half that represents the converted double-precision floating point number.</returns>
public static explicit operator Half(double value) { return new Half((float)value); }
/// <summary>
/// Converts a decimal number to a System.Half.
/// </summary>
/// <param name="value">decimal number</param>
/// <returns>A System.Half that represents the converted decimal number.</returns>
public static explicit operator Half(decimal value) { return new Half((float)value); }
/// <summary>
/// Converts a System.Half to an 8-bit unsigned integer.
/// </summary>
/// <param name="value">A System.Half to convert.</param>
/// <returns>An 8-bit unsigned integer that represents the converted System.Half.</returns>
public static explicit operator byte(Half value) { return (byte)(float)value; }
/// <summary>
/// Converts a System.Half to a Unicode character.
/// </summary>
/// <param name="value">A System.Half to convert.</param>
/// <returns>A Unicode character that represents the converted System.Half.</returns>
public static explicit operator char(Half value) { return (char)(float)value; }
/// <summary>
/// Converts a System.Half to a 16-bit signed integer.
/// </summary>
/// <param name="value">A System.Half to convert.</param>
/// <returns>A 16-bit signed integer that represents the converted System.Half.</returns>
public static explicit operator short(Half value) { return (short)(float)value; }
/// <summary>
/// Converts a System.Half to a 32-bit signed integer.
/// </summary>
/// <param name="value">A System.Half to convert.</param>
/// <returns>A 32-bit signed integer that represents the converted System.Half.</returns>
public static explicit operator int(Half value) { return (int)(float)value; }
/// <summary>
/// Converts a System.Half to a 64-bit signed integer.
/// </summary>
/// <param name="value">A System.Half to convert.</param>
/// <returns>A 64-bit signed integer that represents the converted System.Half.</returns>
public static explicit operator long(Half value) { return (long)(float)value; }
/// <summary>
/// Converts a System.Half to a single-precision floating-point number.
/// </summary>
/// <param name="value">A System.Half to convert.</param>
/// <returns>A single-precision floating-point number that represents the converted System.Half.</returns>
public static implicit operator float(Half value) { return (float)HalfHelper.HalfToSingle(value); }
/// <summary>
/// Converts a System.Half to a double-precision floating-point number.
/// </summary>
/// <param name="value">A System.Half to convert.</param>
/// <returns>A double-precision floating-point number that represents the converted System.Half.</returns>
public static implicit operator double(Half value) { return (double)(float)value; }
/// <summary>
/// Converts a System.Half to a decimal number.
/// </summary>
/// <param name="value">A System.Half to convert.</param>
/// <returns>A decimal number that represents the converted System.Half.</returns>
public static explicit operator decimal(Half value) { return (decimal)(float)value; }
/// <summary>
/// Converts an 8-bit signed integer to a System.Half.
/// </summary>
/// <param name="value">An 8-bit signed integer.</param>
/// <returns>A System.Half that represents the converted 8-bit signed integer.</returns>
public static implicit operator Half(sbyte value) { return new Half((float)value); }
/// <summary>
/// Converts a 16-bit unsigned integer to a System.Half.
/// </summary>
/// <param name="value">A 16-bit unsigned integer.</param>
/// <returns>A System.Half that represents the converted 16-bit unsigned integer.</returns>
public static implicit operator Half(ushort value) { return new Half((float)value); }
/// <summary>
/// Converts a 32-bit unsigned integer to a System.Half.
/// </summary>
/// <param name="value">A 32-bit unsigned integer.</param>
/// <returns>A System.Half that represents the converted 32-bit unsigned integer.</returns>
public static implicit operator Half(uint value) { return new Half((float)value); }
/// <summary>
/// Converts a 64-bit unsigned integer to a System.Half.
/// </summary>
/// <param name="value">A 64-bit unsigned integer.</param>
/// <returns>A System.Half that represents the converted 64-bit unsigned integer.</returns>
public static implicit operator Half(ulong value) { return new Half((float)value); }
/// <summary>
/// Converts a System.Half to an 8-bit signed integer.
/// </summary>
/// <param name="value">A System.Half to convert.</param>
/// <returns>An 8-bit signed integer that represents the converted System.Half.</returns>
public static explicit operator sbyte(Half value) { return (sbyte)(float)value; }
/// <summary>
/// Converts a System.Half to a 16-bit unsigned integer.
/// </summary>
/// <param name="value">A System.Half to convert.</param>
/// <returns>A 16-bit unsigned integer that represents the converted System.Half.</returns>
public static explicit operator ushort(Half value) { return (ushort)(float)value; }
/// <summary>
/// Converts a System.Half to a 32-bit unsigned integer.
/// </summary>
/// <param name="value">A System.Half to convert.</param>
/// <returns>A 32-bit unsigned integer that represents the converted System.Half.</returns>
public static explicit operator uint(Half value) { return (uint)(float)value; }
/// <summary>
/// Converts a System.Half to a 64-bit unsigned integer.
/// </summary>
/// <param name="value">A System.Half to convert.</param>
/// <returns>A 64-bit unsigned integer that represents the converted System.Half.</returns>
public static explicit operator ulong(Half value) { return (ulong)(float)value; }
#endregion
/// <summary>
/// Compares this instance to a specified System.Half object.
/// </summary>
/// <param name="other">A System.Half object.</param>
/// <returns>
/// A signed number indicating the relative values of this instance and value.
/// Return Value Meaning Less than zero This instance is less than value. Zero
/// This instance is equal to value. Greater than zero This instance is greater than value.
/// </returns>
public int CompareTo(Half other)
{
int result = 0;
if (this < other)
{
result = -1;
}
else if (this > other)
{
result = 1;
}
else if (this != other)
{
if (!IsNaN(this))
{
result = 1;
}
else if (!IsNaN(other))
{
result = -1;
}
}
return result;
}
/// <summary>
/// Compares this instance to a specified System.Object.
/// </summary>
/// <param name="obj">An System.Object or null.</param>
/// <returns>
/// A signed number indicating the relative values of this instance and value.
/// Return Value Meaning Less than zero This instance is less than value. Zero
/// This instance is equal to value. Greater than zero This instance is greater
/// than value. -or- value is null.
/// </returns>
/// <exception cref="System.ArgumentException">value is not a System.Half</exception>
public int CompareTo(object obj)
{
int result = 0;
if (obj == null)
{
result = 1;
}
else
{
if (obj is Half)
{
result = CompareTo((Half)obj);
}
else
{
throw new ArgumentException("Object must be of type Half.");
}
}
return result;
}
/// <summary>
/// Returns a value indicating whether this instance and a specified System.Half object represent the same value.
/// </summary>
/// <param name="other">A System.Half object to compare to this instance.</param>
/// <returns>true if value is equal to this instance; otherwise, false.</returns>
public bool Equals(Half other)
{
return ((other == this) || (IsNaN(other) && IsNaN(this)));
}
/// <summary>
/// Returns a value indicating whether this instance and a specified System.Object
/// represent the same type and value.
/// </summary>
/// <param name="obj">An System.Object.</param>
/// <returns>true if value is a System.Half and equal to this instance; otherwise, false.</returns>
public override bool Equals(object obj)
{
bool result = false;
if (obj is Half)
{
Half half = (Half)obj;
if ((half == this) || (IsNaN(half) && IsNaN(this)))
{
result = true;
}
}
return result;
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
/// <returns>A 32-bit signed integer hash code.</returns>
public override int GetHashCode()
{
return value.GetHashCode();
}
/// <summary>
/// Returns the System.TypeCode for value type System.Half.
/// </summary>
/// <returns>The enumerated constant (TypeCode)255.</returns>
public TypeCode GetTypeCode()
{
return (TypeCode)255;
}
#region BitConverter & Math methods for Half
/// <summary>
/// Returns the specified half-precision floating point value as an array of bytes.
/// </summary>
/// <param name="value">The number to convert.</param>
/// <returns>An array of bytes with length 2.</returns>
public static byte[] GetBytes(Half value)
{
return BitConverter.GetBytes(value.value);
}
/// <summary>
/// Converts the value of a specified instance of System.Half to its equivalent binary representation.
/// </summary>
/// <param name="value">A System.Half value.</param>
/// <returns>A 16-bit unsigned integer that contain the binary representation of value.</returns>
public static ushort GetBits(Half value)
{
return value.value;
}
/// <summary>
/// Returns a half-precision floating point number converted from two bytes
/// at a specified position in a byte array.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within value.</param>
/// <returns>A half-precision floating point number formed by two bytes beginning at startIndex.</returns>
/// <exception cref="System.ArgumentException">
/// startIndex is greater than or equal to the length of value minus 1, and is
/// less than or equal to the length of value minus 1.
/// </exception>
/// <exception cref="System.ArgumentNullException">value is null.</exception>
/// <exception cref="System.ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>
public static Half ToHalf(byte[] value, int startIndex)
{
return Half.ToHalf((ushort)BitConverter.ToInt16(value, startIndex));
}
/// <summary>
/// Returns a half-precision floating point number converted from its binary representation.
/// </summary>
/// <param name="bits">Binary representation of System.Half value</param>
/// <returns>A half-precision floating point number formed by its binary representation.</returns>
public static Half ToHalf(ushort bits)
{
return new Half { value = bits };
}
/// <summary>
/// Returns a value indicating the sign of a half-precision floating-point number.
/// </summary>
/// <param name="value">A signed number.</param>
/// <returns>
/// A number indicating the sign of value. Number Description -1 value is less
/// than zero. 0 value is equal to zero. 1 value is greater than zero.
/// </returns>
/// <exception cref="System.ArithmeticException">value is equal to System.Half.NaN.</exception>
public static int Sign(Half value)
{
if (value < 0)
{
return -1;
}
else if (value > 0)
{
return 1;
}
else
{
if (value != 0)
{
throw new ArithmeticException("Function does not accept floating point Not-a-Number values.");
}
}
return 0;
}
/// <summary>
/// Returns the absolute value of a half-precision floating-point number.
/// </summary>
/// <param name="value">A number in the range System.Half.MinValue ≤ value ≤ System.Half.MaxValue.</param>
/// <returns>A half-precision floating-point number, x, such that 0 ≤ x ≤System.Half.MaxValue.</returns>
public static Half Abs(Half value)
{
return HalfHelper.Abs(value);
}
/// <summary>
/// Returns the larger of two half-precision floating-point numbers.
/// </summary>
/// <param name="value1">The first of two half-precision floating-point numbers to compare.</param>
/// <param name="value2">The second of two half-precision floating-point numbers to compare.</param>
/// <returns>
/// Parameter value1 or value2, whichever is larger. If value1, or value2, or both val1
/// and value2 are equal to System.Half.NaN, System.Half.NaN is returned.
/// </returns>
public static Half Max(Half value1, Half value2)
{
return (value1 < value2) ? value2 : value1;
}
/// <summary>
/// Returns the smaller of two half-precision floating-point numbers.
/// </summary>
/// <param name="value1">The first of two half-precision floating-point numbers to compare.</param>
/// <param name="value2">The second of two half-precision floating-point numbers to compare.</param>
/// <returns>
/// Parameter value1 or value2, whichever is smaller. If value1, or value2, or both val1
/// and value2 are equal to System.Half.NaN, System.Half.NaN is returned.
/// </returns>
public static Half Min(Half value1, Half value2)
{
return (value1 < value2) ? value1 : value2;
}
#endregion
/// <summary>
/// Returns a value indicating whether the specified number evaluates to not a number (System.Half.NaN).
/// </summary>
/// <param name="half">A half-precision floating-point number.</param>
/// <returns>true if value evaluates to not a number (System.Half.NaN); otherwise, false.</returns>
public static bool IsNaN(Half half)
{
return HalfHelper.IsNaN(half);
}
/// <summary>
/// Returns a value indicating whether the specified number evaluates to negative or positive infinity.
/// </summary>
/// <param name="half">A half-precision floating-point number.</param>
/// <returns>true if half evaluates to System.Half.PositiveInfinity or System.Half.NegativeInfinity; otherwise, false.</returns>
public static bool IsInfinity(Half half)
{
return HalfHelper.IsInfinity(half);
}
/// <summary>
/// Returns a value indicating whether the specified number evaluates to negative infinity.
/// </summary>
/// <param name="half">A half-precision floating-point number.</param>
/// <returns>true if half evaluates to System.Half.NegativeInfinity; otherwise, false.</returns>
public static bool IsNegativeInfinity(Half half)
{
return HalfHelper.IsNegativeInfinity(half);
}
/// <summary>
/// Returns a value indicating whether the specified number evaluates to positive infinity.
/// </summary>
/// <param name="half">A half-precision floating-point number.</param>
/// <returns>true if half evaluates to System.Half.PositiveInfinity; otherwise, false.</returns>
public static bool IsPositiveInfinity(Half half)
{
return HalfHelper.IsPositiveInfinity(half);
}
#region String operations (Parse and ToString)
/// <summary>
/// Converts the string representation of a number to its System.Half equivalent.
/// </summary>
/// <param name="value">The string representation of the number to convert.</param>
/// <returns>The System.Half number equivalent to the number contained in value.</returns>
/// <exception cref="System.ArgumentNullException">value is null.</exception>
/// <exception cref="System.FormatException">value is not in the correct format.</exception>
/// <exception cref="System.OverflowException">value represents a number less than System.Half.MinValue or greater than System.Half.MaxValue.</exception>
public static Half Parse(string value)
{
return (Half)float.Parse(value, CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the string representation of a number to its System.Half equivalent
/// using the specified culture-specific format information.
/// </summary>
/// <param name="value">The string representation of the number to convert.</param>
/// <param name="provider">An System.IFormatProvider that supplies culture-specific parsing information about value.</param>
/// <returns>The System.Half number equivalent to the number contained in s as specified by provider.</returns>
/// <exception cref="System.ArgumentNullException">value is null.</exception>
/// <exception cref="System.FormatException">value is not in the correct format.</exception>
/// <exception cref="System.OverflowException">value represents a number less than System.Half.MinValue or greater than System.Half.MaxValue.</exception>
public static Half Parse(string value, IFormatProvider provider)
{
return (Half)float.Parse(value, provider);
}
/// <summary>
/// Converts the string representation of a number in a specified style to its System.Half equivalent.
/// </summary>
/// <param name="value">The string representation of the number to convert.</param>
/// <param name="style">
/// A bitwise combination of System.Globalization.NumberStyles values that indicates
/// the style elements that can be present in value. A typical value to specify is
/// System.Globalization.NumberStyles.Number.
/// </param>
/// <returns>The System.Half number equivalent to the number contained in s as specified by style.</returns>
/// <exception cref="System.ArgumentNullException">value is null.</exception>
/// <exception cref="System.ArgumentException">
/// style is not a System.Globalization.NumberStyles value. -or- style is the
/// System.Globalization.NumberStyles.AllowHexSpecifier value.
/// </exception>
/// <exception cref="System.FormatException">value is not in the correct format.</exception>
/// <exception cref="System.OverflowException">value represents a number less than System.Half.MinValue or greater than System.Half.MaxValue.</exception>
public static Half Parse(string value, NumberStyles style)
{
return (Half)float.Parse(value, style, CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the string representation of a number to its System.Half equivalent
/// using the specified style and culture-specific format.
/// </summary>
/// <param name="value">The string representation of the number to convert.</param>
/// <param name="style">
/// A bitwise combination of System.Globalization.NumberStyles values that indicates
/// the style elements that can be present in value. A typical value to specify is
/// System.Globalization.NumberStyles.Number.
/// </param>
/// <param name="provider">An System.IFormatProvider object that supplies culture-specific information about the format of value.</param>
/// <returns>The System.Half number equivalent to the number contained in s as specified by style and provider.</returns>
/// <exception cref="System.ArgumentNullException">value is null.</exception>
/// <exception cref="System.ArgumentException">
/// style is not a System.Globalization.NumberStyles value. -or- style is the
/// System.Globalization.NumberStyles.AllowHexSpecifier value.
/// </exception>
/// <exception cref="System.FormatException">value is not in the correct format.</exception>
/// <exception cref="System.OverflowException">value represents a number less than System.Half.MinValue or greater than System.Half.MaxValue.</exception>
public static Half Parse(string value, NumberStyles style, IFormatProvider provider)
{
return (Half)float.Parse(value, style, provider);
}
/// <summary>
/// Converts the string representation of a number to its System.Half equivalent.
/// A return value indicates whether the conversion succeeded or failed.
/// </summary>
/// <param name="value">The string representation of the number to convert.</param>
/// <param name="result">
/// When this method returns, contains the System.Half number that is equivalent
/// to the numeric value contained in value, if the conversion succeeded, or is zero
/// if the conversion failed. The conversion fails if the s parameter is null,
/// is not a number in a valid format, or represents a number less than System.Half.MinValue
/// or greater than System.Half.MaxValue. This parameter is passed uninitialized.
/// </param>
/// <returns>true if s was converted successfully; otherwise, false.</returns>
public static bool TryParse(string value, out Half result)
{
float f;
if (float.TryParse(value, out f))
{
result = (Half)f;
return true;
}
result = new Half();
return false;
}
/// <summary>
/// Converts the string representation of a number to its System.Half equivalent
/// using the specified style and culture-specific format. A return value indicates
/// whether the conversion succeeded or failed.
/// </summary>
/// <param name="value">The string representation of the number to convert.</param>
/// <param name="style">
/// A bitwise combination of System.Globalization.NumberStyles values that indicates
/// the permitted format of value. A typical value to specify is System.Globalization.NumberStyles.Number.
/// </param>
/// <param name="provider">An System.IFormatProvider object that supplies culture-specific parsing information about value.</param>
/// <param name="result">
/// When this method returns, contains the System.Half number that is equivalent
/// to the numeric value contained in value, if the conversion succeeded, or is zero
/// if the conversion failed. The conversion fails if the s parameter is null,
/// is not in a format compliant with style, or represents a number less than
/// System.Half.MinValue or greater than System.Half.MaxValue. This parameter is passed uninitialized.
/// </param>
/// <returns>true if s was converted successfully; otherwise, false.</returns>
/// <exception cref="System.ArgumentException">
/// style is not a System.Globalization.NumberStyles value. -or- style
/// is the System.Globalization.NumberStyles.AllowHexSpecifier value.
/// </exception>
public static bool TryParse(string value, NumberStyles style, IFormatProvider provider, out Half result)
{
bool parseResult = false;
float f;
if (float.TryParse(value, style, provider, out f))
{
result = (Half)f;
parseResult = true;
}
else
{
result = new Half();
}
return parseResult;
}
/// <summary>
/// Converts the numeric value of this instance to its equivalent string representation.
/// </summary>
/// <returns>A string that represents the value of this instance.</returns>
public override string ToString()
{
return ((float)this).ToString(CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the numeric value of this instance to its equivalent string representation
/// using the specified culture-specific format information.
/// </summary>
/// <param name="formatProvider">An System.IFormatProvider that supplies culture-specific formatting information.</param>
/// <returns>The string representation of the value of this instance as specified by provider.</returns>
public string ToString(IFormatProvider formatProvider)
{
return ((float)this).ToString(formatProvider);
}
/// <summary>
/// Converts the numeric value of this instance to its equivalent string representation, using the specified format.
/// </summary>
/// <param name="format">A numeric format string.</param>
/// <returns>The string representation of the value of this instance as specified by format.</returns>
public string ToString(string format)
{
return ((float)this).ToString(format, CultureInfo.InvariantCulture);
}
/// <summary>
/// Converts the numeric value of this instance to its equivalent string representation
/// using the specified format and culture-specific format information.
/// </summary>
/// <param name="format">A numeric format string.</param>
/// <param name="formatProvider">An System.IFormatProvider that supplies culture-specific formatting information.</param>
/// <returns>The string representation of the value of this instance as specified by format and provider.</returns>
/// <exception cref="System.FormatException">format is invalid.</exception>
public string ToString(string format, IFormatProvider formatProvider)
{
return ((float)this).ToString(format, formatProvider);
}
#endregion
#region IConvertible Members
float IConvertible.ToSingle(IFormatProvider provider)
{
return (float)this;
}
TypeCode IConvertible.GetTypeCode()
{
return GetTypeCode();
}
bool IConvertible.ToBoolean(IFormatProvider provider)
{
return Convert.ToBoolean((float)this);
}
byte IConvertible.ToByte(IFormatProvider provider)
{
return Convert.ToByte((float)this);
}
char IConvertible.ToChar(IFormatProvider provider)
{
throw new InvalidCastException(string.Format(CultureInfo.CurrentCulture, "Invalid cast from '{0}' to '{1}'.", "Half", "Char"));
}
DateTime IConvertible.ToDateTime(IFormatProvider provider)
{
throw new InvalidCastException(string.Format(CultureInfo.CurrentCulture, "Invalid cast from '{0}' to '{1}'.", "Half", "DateTime"));
}
decimal IConvertible.ToDecimal(IFormatProvider provider)
{
return Convert.ToDecimal((float)this);
}
double IConvertible.ToDouble(IFormatProvider provider)
{
return Convert.ToDouble((float)this);
}
short IConvertible.ToInt16(IFormatProvider provider)
{
return Convert.ToInt16((float)this);
}
int IConvertible.ToInt32(IFormatProvider provider)
{
return Convert.ToInt32((float)this);
}
long IConvertible.ToInt64(IFormatProvider provider)
{
return Convert.ToInt64((float)this);
}
sbyte IConvertible.ToSByte(IFormatProvider provider)
{
return Convert.ToSByte((float)this);
}
string IConvertible.ToString(IFormatProvider provider)
{
return Convert.ToString((float)this, CultureInfo.InvariantCulture);
}
object IConvertible.ToType(Type conversionType, IFormatProvider provider)
{
return (((float)this) as IConvertible).ToType(conversionType, provider);
}
ushort IConvertible.ToUInt16(IFormatProvider provider)
{
return Convert.ToUInt16((float)this);
}
uint IConvertible.ToUInt32(IFormatProvider provider)
{
return Convert.ToUInt32((float)this);
}
ulong IConvertible.ToUInt64(IFormatProvider provider)
{
return Convert.ToUInt64((float)this);
}
#endregion
}
}

View File

@@ -0,0 +1,211 @@
using System.Runtime.InteropServices;
namespace System
{
/// <summary>
/// Helper class for Half conversions and some low level operations.
/// This class is internally used in the Half class.
/// </summary>
/// <remarks>
/// References:
/// - Fast Half Float Conversions, Jeroen van der Zijp, link: http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf
/// </remarks>
[ComVisible(false)]
internal static class HalfHelper
{
private static uint[] mantissaTable = GenerateMantissaTable();
private static uint[] exponentTable = GenerateExponentTable();
private static ushort[] offsetTable = GenerateOffsetTable();
private static ushort[] baseTable = GenerateBaseTable();
private static sbyte[] shiftTable = GenerateShiftTable();
// Transforms the subnormal representation to a normalized one.
private static uint ConvertMantissa(int i)
{
uint m = (uint)(i << 13); // Zero pad mantissa bits
uint e = 0; // Zero exponent
// While not normalized
while ((m & 0x00800000) == 0)
{
e -= 0x00800000; // Decrement exponent (1<<23)
m <<= 1; // Shift mantissa
}
m &= unchecked((uint)~0x00800000); // Clear leading 1 bit
e += 0x38800000; // Adjust bias ((127-14)<<23)
return m | e; // Return combined number
}
private static uint[] GenerateMantissaTable()
{
uint[] mantissaTable = new uint[2048];
mantissaTable[0] = 0;
for (int i = 1; i < 1024; i++)
{
mantissaTable[i] = ConvertMantissa(i);
}
for (int i = 1024; i < 2048; i++)
{
mantissaTable[i] = (uint)(0x38000000 + ((i - 1024) << 13));
}
return mantissaTable;
}
private static uint[] GenerateExponentTable()
{
uint[] exponentTable = new uint[64];
exponentTable[0] = 0;
for (int i = 1; i < 31; i++)
{
exponentTable[i] = (uint)(i << 23);
}
exponentTable[31] = 0x47800000;
exponentTable[32] = 0x80000000;
for (int i = 33; i < 63; i++)
{
exponentTable[i] = (uint)(0x80000000 + ((i - 32) << 23));
}
exponentTable[63] = 0xc7800000;
return exponentTable;
}
private static ushort[] GenerateOffsetTable()
{
ushort[] offsetTable = new ushort[64];
offsetTable[0] = 0;
for (int i = 1; i < 32; i++)
{
offsetTable[i] = 1024;
}
offsetTable[32] = 0;
for (int i = 33; i < 64; i++)
{
offsetTable[i] = 1024;
}
return offsetTable;
}
private static ushort[] GenerateBaseTable()
{
ushort[] baseTable = new ushort[512];
for (int i = 0; i < 256; ++i)
{
sbyte e = (sbyte)(127 - i);
if (e > 24)
{ // Very small numbers map to zero
baseTable[i | 0x000] = 0x0000;
baseTable[i | 0x100] = 0x8000;
}
else if (e > 14)
{ // Small numbers map to denorms
baseTable[i | 0x000] = (ushort)(0x0400 >> (18 + e));
baseTable[i | 0x100] = (ushort)((0x0400 >> (18 + e)) | 0x8000);
}
else if (e >= -15)
{ // Normal numbers just lose precision
baseTable[i | 0x000] = (ushort)((15 - e) << 10);
baseTable[i | 0x100] = (ushort)(((15 - e) << 10) | 0x8000);
}
else if (e > -128)
{ // Large numbers map to Infinity
baseTable[i | 0x000] = 0x7c00;
baseTable[i | 0x100] = 0xfc00;
}
else
{ // Infinity and NaN's stay Infinity and NaN's
baseTable[i | 0x000] = 0x7c00;
baseTable[i | 0x100] = 0xfc00;
}
}
return baseTable;
}
private static sbyte[] GenerateShiftTable()
{
sbyte[] shiftTable = new sbyte[512];
for (int i = 0; i < 256; ++i)
{
sbyte e = (sbyte)(127 - i);
if (e > 24)
{ // Very small numbers map to zero
shiftTable[i | 0x000] = 24;
shiftTable[i | 0x100] = 24;
}
else if (e > 14)
{ // Small numbers map to denorms
shiftTable[i | 0x000] = (sbyte)(e - 1);
shiftTable[i | 0x100] = (sbyte)(e - 1);
}
else if (e >= -15)
{ // Normal numbers just lose precision
shiftTable[i | 0x000] = 13;
shiftTable[i | 0x100] = 13;
}
else if (e > -128)
{ // Large numbers map to Infinity
shiftTable[i | 0x000] = 24;
shiftTable[i | 0x100] = 24;
}
else
{ // Infinity and NaN's stay Infinity and NaN's
shiftTable[i | 0x000] = 13;
shiftTable[i | 0x100] = 13;
}
}
return shiftTable;
}
/*public static unsafe float HalfToSingle(Half half)
{
uint result = mantissaTable[offsetTable[half.value >> 10] + (half.value & 0x3ff)] + exponentTable[half.value >> 10];
return *((float*)&result);
}
public static unsafe Half SingleToHalf(float single)
{
uint value = *((uint*)&single);
ushort result = (ushort)(baseTable[(value >> 23) & 0x1ff] + ((value & 0x007fffff) >> shiftTable[value >> 23]));
return Half.ToHalf(result);
}*/
public static float HalfToSingle(Half half)
{
uint result = mantissaTable[offsetTable[half.value >> 10] + (half.value & 0x3ff)] + exponentTable[half.value >> 10];
byte[] uintBytes = BitConverter.GetBytes(result);
return BitConverter.ToSingle(uintBytes, 0);
}
public static Half SingleToHalf(float single)
{
byte[] singleBytes = BitConverter.GetBytes(single);
uint value = BitConverter.ToUInt32(singleBytes, 0);
ushort result = (ushort)(baseTable[(value >> 23) & 0x1ff] + ((value & 0x007fffff) >> shiftTable[value >> 23]));
return Half.ToHalf(result);
}
public static Half Negate(Half half)
{
return Half.ToHalf((ushort)(half.value ^ 0x8000));
}
public static Half Abs(Half half)
{
return Half.ToHalf((ushort)(half.value & 0x7fff));
}
public static bool IsNaN(Half half)
{
return ((half.value & 0x7fff) > 0x7c00);
}
public static bool IsInfinity(Half half)
{
return ((half.value & 0x7fff) == 0x7c00);
}
public static bool IsPositiveInfinity(Half half)
{
return (half.value == 0x7c00);
}
public static bool IsNegativeInfinity(Half half)
{
return (half.value == 0xfc00);
}
}
}

View File

@@ -0,0 +1,241 @@
using System;
using System.Runtime.InteropServices;
namespace AssetStudio
{
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct Matrix4x4 : IEquatable<Matrix4x4>
{
public float M00;
public float M10;
public float M20;
public float M30;
public float M01;
public float M11;
public float M21;
public float M31;
public float M02;
public float M12;
public float M22;
public float M32;
public float M03;
public float M13;
public float M23;
public float M33;
public Matrix4x4(float[] values)
{
if (values == null)
throw new ArgumentNullException(nameof(values));
if (values.Length != 16)
throw new ArgumentOutOfRangeException(nameof(values), "There must be sixteen and only sixteen input values for Matrix.");
M00 = values[0];
M10 = values[1];
M20 = values[2];
M30 = values[3];
M01 = values[4];
M11 = values[5];
M21 = values[6];
M31 = values[7];
M02 = values[8];
M12 = values[9];
M22 = values[10];
M32 = values[11];
M03 = values[12];
M13 = values[13];
M23 = values[14];
M33 = values[15];
}
public float this[int row, int column]
{
get => this[row + column * 4];
set => this[row + column * 4] = value;
}
public float this[int index]
{
get
{
switch (index)
{
case 0: return M00;
case 1: return M10;
case 2: return M20;
case 3: return M30;
case 4: return M01;
case 5: return M11;
case 6: return M21;
case 7: return M31;
case 8: return M02;
case 9: return M12;
case 10: return M22;
case 11: return M32;
case 12: return M03;
case 13: return M13;
case 14: return M23;
case 15: return M33;
default: throw new ArgumentOutOfRangeException(nameof(index), "Invalid Matrix4x4 index!");
}
}
set
{
switch (index)
{
case 0: M00 = value; break;
case 1: M10 = value; break;
case 2: M20 = value; break;
case 3: M30 = value; break;
case 4: M01 = value; break;
case 5: M11 = value; break;
case 6: M21 = value; break;
case 7: M31 = value; break;
case 8: M02 = value; break;
case 9: M12 = value; break;
case 10: M22 = value; break;
case 11: M32 = value; break;
case 12: M03 = value; break;
case 13: M13 = value; break;
case 14: M23 = value; break;
case 15: M33 = value; break;
default: throw new ArgumentOutOfRangeException(nameof(index), "Invalid Matrix4x4 index!");
}
}
}
public override int GetHashCode()
{
return GetColumn(0).GetHashCode() ^ (GetColumn(1).GetHashCode() << 2) ^ (GetColumn(2).GetHashCode() >> 2) ^ (GetColumn(3).GetHashCode() >> 1);
}
public override bool Equals(object other)
{
if (!(other is Matrix4x4))
return false;
return Equals((Matrix4x4)other);
}
public bool Equals(Matrix4x4 other)
{
return GetColumn(0).Equals(other.GetColumn(0))
&& GetColumn(1).Equals(other.GetColumn(1))
&& GetColumn(2).Equals(other.GetColumn(2))
&& GetColumn(3).Equals(other.GetColumn(3));
}
public Vector4 GetColumn(int index)
{
switch (index)
{
case 0: return new Vector4(M00, M10, M20, M30);
case 1: return new Vector4(M01, M11, M21, M31);
case 2: return new Vector4(M02, M12, M22, M32);
case 3: return new Vector4(M03, M13, M23, M33);
default: throw new IndexOutOfRangeException("Invalid column index!");
}
}
public Vector4 GetRow(int index)
{
switch (index)
{
case 0: return new Vector4(M00, M01, M02, M03);
case 1: return new Vector4(M10, M11, M12, M13);
case 2: return new Vector4(M20, M21, M22, M23);
case 3: return new Vector4(M30, M31, M32, M33);
default: throw new IndexOutOfRangeException("Invalid row index!");
}
}
public static Matrix4x4 operator *(Matrix4x4 lhs, Matrix4x4 rhs)
{
Matrix4x4 res;
res.M00 = lhs.M00 * rhs.M00 + lhs.M01 * rhs.M10 + lhs.M02 * rhs.M20 + lhs.M03 * rhs.M30;
res.M01 = lhs.M00 * rhs.M01 + lhs.M01 * rhs.M11 + lhs.M02 * rhs.M21 + lhs.M03 * rhs.M31;
res.M02 = lhs.M00 * rhs.M02 + lhs.M01 * rhs.M12 + lhs.M02 * rhs.M22 + lhs.M03 * rhs.M32;
res.M03 = lhs.M00 * rhs.M03 + lhs.M01 * rhs.M13 + lhs.M02 * rhs.M23 + lhs.M03 * rhs.M33;
res.M10 = lhs.M10 * rhs.M00 + lhs.M11 * rhs.M10 + lhs.M12 * rhs.M20 + lhs.M13 * rhs.M30;
res.M11 = lhs.M10 * rhs.M01 + lhs.M11 * rhs.M11 + lhs.M12 * rhs.M21 + lhs.M13 * rhs.M31;
res.M12 = lhs.M10 * rhs.M02 + lhs.M11 * rhs.M12 + lhs.M12 * rhs.M22 + lhs.M13 * rhs.M32;
res.M13 = lhs.M10 * rhs.M03 + lhs.M11 * rhs.M13 + lhs.M12 * rhs.M23 + lhs.M13 * rhs.M33;
res.M20 = lhs.M20 * rhs.M00 + lhs.M21 * rhs.M10 + lhs.M22 * rhs.M20 + lhs.M23 * rhs.M30;
res.M21 = lhs.M20 * rhs.M01 + lhs.M21 * rhs.M11 + lhs.M22 * rhs.M21 + lhs.M23 * rhs.M31;
res.M22 = lhs.M20 * rhs.M02 + lhs.M21 * rhs.M12 + lhs.M22 * rhs.M22 + lhs.M23 * rhs.M32;
res.M23 = lhs.M20 * rhs.M03 + lhs.M21 * rhs.M13 + lhs.M22 * rhs.M23 + lhs.M23 * rhs.M33;
res.M30 = lhs.M30 * rhs.M00 + lhs.M31 * rhs.M10 + lhs.M32 * rhs.M20 + lhs.M33 * rhs.M30;
res.M31 = lhs.M30 * rhs.M01 + lhs.M31 * rhs.M11 + lhs.M32 * rhs.M21 + lhs.M33 * rhs.M31;
res.M32 = lhs.M30 * rhs.M02 + lhs.M31 * rhs.M12 + lhs.M32 * rhs.M22 + lhs.M33 * rhs.M32;
res.M33 = lhs.M30 * rhs.M03 + lhs.M31 * rhs.M13 + lhs.M32 * rhs.M23 + lhs.M33 * rhs.M33;
return res;
}
public static bool operator ==(Matrix4x4 lhs, Matrix4x4 rhs)
{
return lhs.GetColumn(0) == rhs.GetColumn(0)
&& lhs.GetColumn(1) == rhs.GetColumn(1)
&& lhs.GetColumn(2) == rhs.GetColumn(2)
&& lhs.GetColumn(3) == rhs.GetColumn(3);
}
public static bool operator !=(Matrix4x4 lhs, Matrix4x4 rhs)
{
return !(lhs == rhs);
}
public static Matrix4x4 Scale(Vector3 vector)
{
Matrix4x4 m;
m.M00 = vector.X; m.M01 = 0F; m.M02 = 0F; m.M03 = 0F;
m.M10 = 0F; m.M11 = vector.Y; m.M12 = 0F; m.M13 = 0F;
m.M20 = 0F; m.M21 = 0F; m.M22 = vector.Z; m.M23 = 0F;
m.M30 = 0F; m.M31 = 0F; m.M32 = 0F; m.M33 = 1F;
return m;
}
public static Matrix4x4 Translate(Vector3 vector)
{
Matrix4x4 m;
m.M00 = 1F; m.M01 = 0F; m.M02 = 0F; m.M03 = vector.X;
m.M10 = 0F; m.M11 = 1F; m.M12 = 0F; m.M13 = vector.Y;
m.M20 = 0F; m.M21 = 0F; m.M22 = 1F; m.M23 = vector.Z;
m.M30 = 0F; m.M31 = 0F; m.M32 = 0F; m.M33 = 1F;
return m;
}
public static Matrix4x4 Rotate(Quaternion q)
{
float x = q.X * 2.0F;
float y = q.Y * 2.0F;
float z = q.Z * 2.0F;
float xx = q.X * x;
float yy = q.Y * y;
float zz = q.Z * z;
float xy = q.X * y;
float xz = q.X * z;
float yz = q.Y * z;
float wx = q.W * x;
float wy = q.W * y;
float wz = q.W * z;
Matrix4x4 m;
m.M00 = 1.0f - (yy + zz); m.M10 = xy + wz; m.M20 = xz - wy; m.M30 = 0.0F;
m.M01 = xy - wz; m.M11 = 1.0f - (xx + zz); m.M21 = yz + wx; m.M31 = 0.0F;
m.M02 = xz + wy; m.M12 = yz - wx; m.M22 = 1.0f - (xx + yy); m.M32 = 0.0F;
m.M03 = 0.0F; m.M13 = 0.0F; m.M23 = 0.0F; m.M33 = 1.0F;
return m;
}
}
}

View File

@@ -0,0 +1,88 @@
using System;
using System.Runtime.InteropServices;
namespace AssetStudio
{
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct Quaternion : IEquatable<Quaternion>
{
public float X;
public float Y;
public float Z;
public float W;
public Quaternion(float x, float y, float z, float w)
{
X = x;
Y = y;
Z = z;
W = w;
}
public float this[int index]
{
get
{
switch (index)
{
case 0: return X;
case 1: return Y;
case 2: return Z;
case 3: return W;
default: throw new ArgumentOutOfRangeException(nameof(index), "Invalid Quaternion index!");
}
}
set
{
switch (index)
{
case 0: X = value; break;
case 1: Y = value; break;
case 2: Z = value; break;
case 3: W = value; break;
default: throw new ArgumentOutOfRangeException(nameof(index), "Invalid Quaternion index!");
}
}
}
public override int GetHashCode()
{
return X.GetHashCode() ^ (Y.GetHashCode() << 2) ^ (Z.GetHashCode() >> 2) ^ (W.GetHashCode() >> 1);
}
public override bool Equals(object other)
{
if (!(other is Quaternion))
return false;
return Equals((Quaternion)other);
}
public bool Equals(Quaternion other)
{
return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z) && W.Equals(other.W);
}
public static float Dot(Quaternion a, Quaternion b)
{
return a.X * b.X + a.Y * b.Y + a.Z * b.Z + a.W * b.W;
}
private static bool IsEqualUsingDot(float dot)
{
return dot > 1.0f - kEpsilon;
}
public static bool operator ==(Quaternion lhs, Quaternion rhs)
{
return IsEqualUsingDot(Dot(lhs, rhs));
}
public static bool operator !=(Quaternion lhs, Quaternion rhs)
{
return !(lhs == rhs);
}
private const float kEpsilon = 0.000001F;
}
}

148
AssetStudio/Math/Vector2.cs Normal file
View File

@@ -0,0 +1,148 @@
using System;
using System.Runtime.InteropServices;
namespace AssetStudio
{
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct Vector2 : IEquatable<Vector2>
{
public float X;
public float Y;
public Vector2(float x, float y)
{
X = x;
Y = y;
}
public float this[int index]
{
get
{
switch (index)
{
case 0: return X;
case 1: return Y;
default: throw new ArgumentOutOfRangeException(nameof(index), "Invalid Vector2 index!");
}
}
set
{
switch (index)
{
case 0: X = value; break;
case 1: Y = value; break;
default: throw new ArgumentOutOfRangeException(nameof(index), "Invalid Vector2 index!");
}
}
}
public override int GetHashCode()
{
return X.GetHashCode() ^ (Y.GetHashCode() << 2);
}
public override bool Equals(object other)
{
if (!(other is Vector2))
return false;
return Equals((Vector2)other);
}
public bool Equals(Vector2 other)
{
return X.Equals(other.X) && Y.Equals(other.Y);
}
public void Normalize()
{
var length = Length();
if (length > kEpsilon)
{
var invNorm = 1.0f / length;
X *= invNorm;
Y *= invNorm;
}
else
{
X = 0;
Y = 0;
}
}
public float Length()
{
return (float)Math.Sqrt(LengthSquared());
}
public float LengthSquared()
{
return X * X + Y * Y;
}
public static Vector2 Zero => new Vector2();
public static Vector2 operator +(Vector2 a, Vector2 b)
{
return new Vector2(a.X + b.X, a.Y + b.Y);
}
public static Vector2 operator -(Vector2 a, Vector2 b)
{
return new Vector2(a.X - b.X, a.Y - b.Y);
}
public static Vector2 operator *(Vector2 a, Vector2 b)
{
return new Vector2(a.X * b.X, a.Y * b.Y);
}
public static Vector2 operator /(Vector2 a, Vector2 b)
{
return new Vector2(a.X / b.X, a.Y / b.Y);
}
public static Vector2 operator -(Vector2 a)
{
return new Vector2(-a.X, -a.Y);
}
public static Vector2 operator *(Vector2 a, float d)
{
return new Vector2(a.X * d, a.Y * d);
}
public static Vector2 operator *(float d, Vector2 a)
{
return new Vector2(a.X * d, a.Y * d);
}
public static Vector2 operator /(Vector2 a, float d)
{
return new Vector2(a.X / d, a.Y / d);
}
public static bool operator ==(Vector2 lhs, Vector2 rhs)
{
return (lhs - rhs).LengthSquared() < kEpsilon * kEpsilon;
}
public static bool operator !=(Vector2 lhs, Vector2 rhs)
{
return !(lhs == rhs);
}
public static implicit operator Vector3(Vector2 v)
{
return new Vector3(v.X, v.Y, 0);
}
public static implicit operator Vector4(Vector2 v)
{
return new Vector4(v.X, v.Y, 0.0F, 0.0F);
}
private const float kEpsilon = 0.00001F;
}
}

144
AssetStudio/Math/Vector3.cs Normal file
View File

@@ -0,0 +1,144 @@
using System;
using System.Runtime.InteropServices;
namespace AssetStudio
{
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct Vector3 : IEquatable<Vector3>
{
public float X;
public float Y;
public float Z;
public Vector3(float x, float y, float z)
{
X = x;
Y = y;
Z = z;
}
public float this[int index]
{
get
{
switch (index)
{
case 0: return X;
case 1: return Y;
case 2: return Z;
default: throw new ArgumentOutOfRangeException(nameof(index), "Invalid Vector3 index!");
}
}
set
{
switch (index)
{
case 0: X = value; break;
case 1: Y = value; break;
case 2: Z = value; break;
default: throw new ArgumentOutOfRangeException(nameof(index), "Invalid Vector3 index!");
}
}
}
public override int GetHashCode()
{
return X.GetHashCode() ^ (Y.GetHashCode() << 2) ^ (Z.GetHashCode() >> 2);
}
public override bool Equals(object other)
{
if (!(other is Vector3))
return false;
return Equals((Vector3)other);
}
public bool Equals(Vector3 other)
{
return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z);
}
public void Normalize()
{
var length = Length();
if (length > kEpsilon)
{
var invNorm = 1.0f / length;
X *= invNorm;
Y *= invNorm;
Z *= invNorm;
}
else
{
X = 0;
Y = 0;
Z = 0;
}
}
public float Length()
{
return (float)Math.Sqrt(LengthSquared());
}
public float LengthSquared()
{
return X * X + Y * Y + Z * Z;
}
public static Vector3 Zero => new Vector3();
public static Vector3 operator +(Vector3 a, Vector3 b)
{
return new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
}
public static Vector3 operator -(Vector3 a, Vector3 b)
{
return new Vector3(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
}
public static Vector3 operator -(Vector3 a)
{
return new Vector3(-a.X, -a.Y, -a.Z);
}
public static Vector3 operator *(Vector3 a, float d)
{
return new Vector3(a.X * d, a.Y * d, a.Z * d);
}
public static Vector3 operator *(float d, Vector3 a)
{
return new Vector3(a.X * d, a.Y * d, a.Z * d);
}
public static Vector3 operator /(Vector3 a, float d)
{
return new Vector3(a.X / d, a.Y / d, a.Z / d);
}
public static bool operator ==(Vector3 lhs, Vector3 rhs)
{
return (lhs - rhs).LengthSquared() < kEpsilon * kEpsilon;
}
public static bool operator !=(Vector3 lhs, Vector3 rhs)
{
return !(lhs == rhs);
}
public static implicit operator Vector2(Vector3 v)
{
return new Vector2(v.X, v.Y);
}
public static implicit operator Vector4(Vector3 v)
{
return new Vector4(v.X, v.Y, v.Z, 0.0F);
}
private const float kEpsilon = 0.00001F;
}
}

163
AssetStudio/Math/Vector4.cs Normal file
View File

@@ -0,0 +1,163 @@
using System;
using System.Runtime.InteropServices;
namespace AssetStudio
{
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct Vector4 : IEquatable<Vector4>
{
public float X;
public float Y;
public float Z;
public float W;
public Vector4(float x, float y, float z, float w)
{
X = x;
Y = y;
Z = z;
W = w;
}
public Vector4(Vector3 value, float w)
{
X = value.X;
Y = value.Y;
Z = value.Z;
W = w;
}
public float this[int index]
{
get
{
switch (index)
{
case 0: return X;
case 1: return Y;
case 2: return Z;
case 3: return W;
default: throw new ArgumentOutOfRangeException(nameof(index), "Invalid Vector4 index!");
}
}
set
{
switch (index)
{
case 0: X = value; break;
case 1: Y = value; break;
case 2: Z = value; break;
case 3: W = value; break;
default: throw new ArgumentOutOfRangeException(nameof(index), "Invalid Vector4 index!");
}
}
}
public override int GetHashCode()
{
return X.GetHashCode() ^ (Y.GetHashCode() << 2) ^ (Z.GetHashCode() >> 2) ^ (W.GetHashCode() >> 1);
}
public override bool Equals(object other)
{
if (!(other is Vector4))
return false;
return Equals((Vector4)other);
}
public bool Equals(Vector4 other)
{
return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z) && W.Equals(other.W);
}
public void Normalize()
{
var length = Length();
if (length > kEpsilon)
{
var invNorm = 1.0f / length;
X *= invNorm;
Y *= invNorm;
Z *= invNorm;
W *= invNorm;
}
else
{
X = 0;
Y = 0;
Z = 0;
W = 0;
}
}
public float Length()
{
return (float)Math.Sqrt(LengthSquared());
}
public float LengthSquared()
{
return X * X + Y * Y + Z * Z + W * W;
}
public static Vector4 Zero => new Vector4();
public static Vector4 operator +(Vector4 a, Vector4 b)
{
return new Vector4(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W);
}
public static Vector4 operator -(Vector4 a, Vector4 b)
{
return new Vector4(a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W);
}
public static Vector4 operator -(Vector4 a)
{
return new Vector4(-a.X, -a.Y, -a.Z, -a.W);
}
public static Vector4 operator *(Vector4 a, float d)
{
return new Vector4(a.X * d, a.Y * d, a.Z * d, a.W * d);
}
public static Vector4 operator *(float d, Vector4 a)
{
return new Vector4(a.X * d, a.Y * d, a.Z * d, a.W * d);
}
public static Vector4 operator /(Vector4 a, float d)
{
return new Vector4(a.X / d, a.Y / d, a.Z / d, a.W / d);
}
public static bool operator ==(Vector4 lhs, Vector4 rhs)
{
return (lhs - rhs).LengthSquared() < kEpsilon * kEpsilon;
}
public static bool operator !=(Vector4 lhs, Vector4 rhs)
{
return !(lhs == rhs);
}
public static implicit operator Vector2(Vector4 v)
{
return new Vector2(v.X, v.Y);
}
public static implicit operator Vector3(Vector4 v)
{
return new Vector3(v.X, v.Y, v.Z);
}
public static implicit operator Color(Vector4 v)
{
return new Color(v.X, v.Y, v.Z, v.W);
}
private const float kEpsilon = 0.00001F;
}
}

View File

@@ -11,9 +11,7 @@ namespace AssetStudio
public uint byteSize;
public int typeID;
public int classID;
public ushort isDestroyed;
//custom
public long m_PathID;
public SerializedType serializedType;
}

View File

@@ -15,7 +15,7 @@ namespace AssetStudio
public ClassIDType type;
public SerializedType serializedType;
public BuildTarget platform;
private uint m_Version;
public uint m_Version;
public int[] version => assetsFile.version;
public BuildType buildType => assetsFile.buildType;
@@ -43,38 +43,5 @@ namespace AssetStudio
{
Position = byteStart;
}
public string Dump()
{
Reset();
if (serializedType?.m_Nodes != null)
{
var sb = new StringBuilder();
TypeTreeHelper.ReadTypeString(sb, serializedType.m_Nodes, this);
return sb.ToString();
}
return null;
}
public bool HasStructMember(string name)
{
return serializedType?.m_Nodes != null && serializedType.m_Nodes.Any(x => x.m_Name == name);
}
public PPtr ReadPPtr()
{
return new PPtr
{
m_FileID = ReadInt32(),
m_PathID = m_Version < 14 ? ReadInt32() : ReadInt64(),
assetsFile = assetsFile
};
}
public byte[] GetRawData()
{
Reset();
return ReadBytes((int)byteSize);
}
}
}

View File

@@ -0,0 +1,69 @@
using System.IO;
namespace AssetStudio
{
public class ResourceReader
{
private bool needSearch;
private string path;
private SerializedFile assetsFile;
private long offset;
private int size;
private BinaryReader reader;
public ResourceReader(string path, SerializedFile assetsFile, long offset, int size)
{
needSearch = true;
this.path = path;
this.assetsFile = assetsFile;
this.offset = offset;
this.size = size;
}
public ResourceReader(BinaryReader reader, long offset, int size)
{
this.reader = reader;
this.offset = offset;
this.size = size;
}
public byte[] GetData()
{
if (needSearch)
{
var resourceFileName = Path.GetFileName(path);
if (assetsFile.assetsManager.resourceFileReaders.TryGetValue(resourceFileName.ToUpper(), out var reader))
{
reader.Position = offset;
return reader.ReadBytes(size);
}
var currentDirectory = Path.GetDirectoryName(assetsFile.fullName);
var resourceFilePath = currentDirectory + "\\" + resourceFileName;
if (!File.Exists(resourceFilePath))
{
var findFiles = Directory.GetFiles(currentDirectory, resourceFileName, SearchOption.AllDirectories);
if (findFiles.Length > 0)
{
resourceFilePath = findFiles[0];
}
}
if (File.Exists(resourceFilePath))
{
using (var resourceReader = new BinaryReader(File.OpenRead(resourceFilePath)))
{
resourceReader.BaseStream.Position = offset;
return resourceReader.ReadBytes(size);
}
}
throw new FileNotFoundException($"Can't find the resource file {resourceFileName}");
}
reader.BaseStream.Position = offset;
return reader.ReadBytes(size);
}
}
}

View File

@@ -1,43 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace AssetStudio
{
internal static class ResourcesHelper
{
public static byte[] GetData(string path, SerializedFile assetsFile, long offset, int size)
{
var resourceFileName = Path.GetFileName(path);
if (assetsFile.assetsManager.resourceFileReaders.TryGetValue(resourceFileName.ToUpper(), out var reader))
{
reader.Position = offset;
return reader.ReadBytes(size);
}
var currentDirectory = Path.GetDirectoryName(assetsFile.fullName);
var resourceFilePath = currentDirectory + "\\" + resourceFileName;
if (!File.Exists(resourceFilePath))
{
var findFiles = Directory.GetFiles(currentDirectory, resourceFileName, SearchOption.AllDirectories);
if (findFiles.Length > 0)
{
resourceFilePath = findFiles[0];
}
}
if (File.Exists(resourceFilePath))
{
using (var resourceReader = new BinaryReader(File.OpenRead(resourceFilePath)))
{
resourceReader.BaseStream.Position = offset;
return resourceReader.ReadBytes(size);
}
}
throw new FileNotFoundException($"Can't find the resource file {resourceFileName}");
}
}
}

View File

@@ -16,10 +16,7 @@ namespace AssetStudio
public string upperFileName;
public int[] version = { 0, 0, 0, 0 };
public BuildType buildType;
public bool valid;
public Dictionary<long, ObjectReader> ObjectReaders = new Dictionary<long, ObjectReader>();
public Dictionary<long, GameObject> GameObjects = new Dictionary<long, GameObject>();
public Dictionary<long, Transform> Transforms = new Dictionary<long, Transform>();
public Dictionary<long, Object> Objects;
public SerializedFileHeader header;
private EndianType m_FileEndianess;
@@ -27,7 +24,7 @@ namespace AssetStudio
public BuildTarget m_TargetPlatform = BuildTarget.UnknownPlatform;
private bool m_EnableTypeTree = true;
public List<SerializedType> m_Types;
private List<ObjectInfo> m_Objects;
public List<ObjectInfo> m_Objects;
private List<LocalSerializedObjectIdentifier> m_ScriptTypes;
public List<FileIdentifier> m_Externals;
@@ -38,160 +35,149 @@ namespace AssetStudio
this.fullName = fullName;
fileName = Path.GetFileName(fullName);
upperFileName = fileName.ToUpper();
try
{
//ReadHeader
header = new SerializedFileHeader();
header.m_MetadataSize = reader.ReadUInt32();
header.m_FileSize = reader.ReadUInt32();
header.m_Version = reader.ReadUInt32();
header.m_DataOffset = reader.ReadUInt32();
if (header.m_Version >= 9)
//ReadHeader
header = new SerializedFileHeader();
header.m_MetadataSize = reader.ReadUInt32();
header.m_FileSize = reader.ReadUInt32();
header.m_Version = reader.ReadUInt32();
header.m_DataOffset = reader.ReadUInt32();
if (header.m_Version >= 9)
{
header.m_Endianess = reader.ReadByte();
header.m_Reserved = reader.ReadBytes(3);
m_FileEndianess = (EndianType)header.m_Endianess;
}
else
{
reader.Position = header.m_FileSize - header.m_MetadataSize;
m_FileEndianess = (EndianType)reader.ReadByte();
}
//ReadMetadata
if (m_FileEndianess == EndianType.LittleEndian)
{
reader.endian = EndianType.LittleEndian;
}
if (header.m_Version >= 7)
{
unityVersion = reader.ReadStringToNull();
SetVersion(unityVersion);
}
if (header.m_Version >= 8)
{
m_TargetPlatform = (BuildTarget)reader.ReadInt32();
if (!Enum.IsDefined(typeof(BuildTarget), m_TargetPlatform))
{
header.m_Endianess = reader.ReadByte();
header.m_Reserved = reader.ReadBytes(3);
m_FileEndianess = (EndianType)header.m_Endianess;
m_TargetPlatform = BuildTarget.UnknownPlatform;
}
}
if (header.m_Version >= 13)
{
m_EnableTypeTree = reader.ReadBoolean();
}
//ReadTypes
int typeCount = reader.ReadInt32();
m_Types = new List<SerializedType>(typeCount);
for (int i = 0; i < typeCount; i++)
{
m_Types.Add(ReadSerializedType());
}
if (header.m_Version >= 7 && header.m_Version < 14)
{
var bigIDEnabled = reader.ReadInt32();
}
//ReadObjects
int objectCount = reader.ReadInt32();
m_Objects = new List<ObjectInfo>(objectCount);
for (int i = 0; i < objectCount; i++)
{
var objectInfo = new ObjectInfo();
if (header.m_Version < 14)
{
objectInfo.m_PathID = reader.ReadInt32();
}
else
{
reader.Position = header.m_FileSize - header.m_MetadataSize;
m_FileEndianess = (EndianType)reader.ReadByte();
reader.AlignStream();
objectInfo.m_PathID = reader.ReadInt64();
}
objectInfo.byteStart = reader.ReadUInt32();
objectInfo.byteStart += header.m_DataOffset;
objectInfo.byteSize = reader.ReadUInt32();
objectInfo.typeID = reader.ReadInt32();
if (header.m_Version < 16)
{
objectInfo.classID = reader.ReadUInt16();
objectInfo.serializedType = m_Types.Find(x => x.classID == objectInfo.typeID);
var isDestroyed = reader.ReadUInt16();
}
else
{
var type = m_Types[objectInfo.typeID];
objectInfo.serializedType = type;
objectInfo.classID = type.classID;
}
if (header.m_Version == 15 || header.m_Version == 16)
{
var stripped = reader.ReadByte();
}
m_Objects.Add(objectInfo);
}
//ReadMetadata
if (m_FileEndianess == EndianType.LittleEndian)
if (header.m_Version >= 11)
{
int scriptCount = reader.ReadInt32();
m_ScriptTypes = new List<LocalSerializedObjectIdentifier>(scriptCount);
for (int i = 0; i < scriptCount; i++)
{
reader.endian = EndianType.LittleEndian;
}
if (header.m_Version >= 7)
{
unityVersion = reader.ReadStringToNull();
SetVersion(unityVersion);
}
if (header.m_Version >= 8)
{
m_TargetPlatform = (BuildTarget)reader.ReadInt32();
if (!Enum.IsDefined(typeof(BuildTarget), m_TargetPlatform))
{
m_TargetPlatform = BuildTarget.UnknownPlatform;
}
}
if (header.m_Version >= 13)
{
m_EnableTypeTree = reader.ReadBoolean();
}
//ReadTypes
int typeCount = reader.ReadInt32();
m_Types = new List<SerializedType>(typeCount);
for (int i = 0; i < typeCount; i++)
{
m_Types.Add(ReadSerializedType());
}
if (header.m_Version >= 7 && header.m_Version < 14)
{
var bigIDEnabled = reader.ReadInt32();
}
//ReadObjects
int objectCount = reader.ReadInt32();
m_Objects = new List<ObjectInfo>(objectCount);
for (int i = 0; i < objectCount; i++)
{
var objectInfo = new ObjectInfo();
var m_ScriptType = new LocalSerializedObjectIdentifier();
m_ScriptType.localSerializedFileIndex = reader.ReadInt32();
if (header.m_Version < 14)
{
objectInfo.m_PathID = reader.ReadInt32();
m_ScriptType.localIdentifierInFile = reader.ReadInt32();
}
else
{
reader.AlignStream(4);
objectInfo.m_PathID = reader.ReadInt64();
reader.AlignStream();
m_ScriptType.localIdentifierInFile = reader.ReadInt64();
}
objectInfo.byteStart = reader.ReadUInt32();
objectInfo.byteStart += header.m_DataOffset;
objectInfo.byteSize = reader.ReadUInt32();
objectInfo.typeID = reader.ReadInt32();
if (header.m_Version < 16)
{
objectInfo.classID = reader.ReadUInt16();
objectInfo.serializedType = m_Types.Find(x => x.classID == objectInfo.typeID);
objectInfo.isDestroyed = reader.ReadUInt16();
}
else
{
var type = m_Types[objectInfo.typeID];
objectInfo.serializedType = type;
objectInfo.classID = type.classID;
}
if (header.m_Version == 15 || header.m_Version == 16)
{
var stripped = reader.ReadByte();
}
m_Objects.Add(objectInfo);
//Create Reader
var objectReader = new ObjectReader(reader, this, objectInfo);
ObjectReaders.Add(objectInfo.m_PathID, objectReader);
m_ScriptTypes.Add(m_ScriptType);
}
}
if (header.m_Version >= 11)
int externalsCount = reader.ReadInt32();
m_Externals = new List<FileIdentifier>(externalsCount);
for (int i = 0; i < externalsCount; i++)
{
var m_External = new FileIdentifier();
if (header.m_Version >= 6)
{
int scriptCount = reader.ReadInt32();
m_ScriptTypes = new List<LocalSerializedObjectIdentifier>(scriptCount);
for (int i = 0; i < scriptCount; i++)
{
var m_ScriptType = new LocalSerializedObjectIdentifier();
m_ScriptType.localSerializedFileIndex = reader.ReadInt32();
if (header.m_Version < 14)
{
m_ScriptType.localIdentifierInFile = reader.ReadInt32();
}
else
{
reader.AlignStream(4);
m_ScriptType.localIdentifierInFile = reader.ReadInt64();
}
m_ScriptTypes.Add(m_ScriptType);
}
var tempEmpty = reader.ReadStringToNull();
}
int externalsCount = reader.ReadInt32();
m_Externals = new List<FileIdentifier>(externalsCount);
for (int i = 0; i < externalsCount; i++)
{
var m_External = new FileIdentifier();
if (header.m_Version >= 6)
{
var tempEmpty = reader.ReadStringToNull();
}
if (header.m_Version >= 5)
{
m_External.guid = new Guid(reader.ReadBytes(16));
m_External.type = reader.ReadInt32();
}
m_External.pathName = reader.ReadStringToNull();
m_External.fileName = Path.GetFileName(m_External.pathName);
m_Externals.Add(m_External);
}
if (header.m_Version >= 5)
{
//var userInformation = reader.ReadStringToNull();
m_External.guid = new Guid(reader.ReadBytes(16));
m_External.type = reader.ReadInt32();
}
valid = true;
m_External.pathName = reader.ReadStringToNull();
m_External.fileName = Path.GetFileName(m_External.pathName);
m_Externals.Add(m_External);
}
catch
if (header.m_Version >= 5)
{
// ignored
//var userInformation = reader.ReadStringToNull();
}
}
public void SetVersion(string stringVersion)
{
unityVersion = stringVersion;
var buildSplit = Regex.Replace(stringVersion, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
buildType = new BuildType(buildSplit[0]);
var versionSplit = Regex.Replace(stringVersion, @"\D", ".").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
@@ -241,11 +227,11 @@ namespace AssetStudio
return type;
}
private void ReadTypeTree(List<TypeTreeNode> typeTree, int depth = 0)
private void ReadTypeTree(List<TypeTreeNode> typeTree, int level = 0)
{
var typeTreeNode = new TypeTreeNode();
typeTree.Add(typeTreeNode);
typeTreeNode.m_Level = depth;
typeTreeNode.m_Level = level;
typeTreeNode.m_Type = reader.ReadStringToNull();
typeTreeNode.m_Name = reader.ReadStringToNull();
typeTreeNode.m_ByteSize = reader.ReadInt32();
@@ -267,7 +253,7 @@ namespace AssetStudio
int childrenCount = reader.ReadInt32();
for (int i = 0; i < childrenCount; i++)
{
ReadTypeTree(typeTree, depth + 1);
ReadTypeTree(typeTree, level + 1);
}
}
@@ -276,10 +262,15 @@ namespace AssetStudio
int numberOfNodes = reader.ReadInt32();
int stringBufferSize = reader.ReadInt32();
reader.Position += numberOfNodes * 24;
var nodeSize = 24;
if (header.m_Version > 17)
{
nodeSize = 32;
}
reader.Position += numberOfNodes * nodeSize;
using (var stringBufferReader = new BinaryReader(new MemoryStream(reader.ReadBytes(stringBufferSize))))
{
reader.Position -= numberOfNodes * 24 + stringBufferSize;
reader.Position -= numberOfNodes * nodeSize + stringBufferSize;
for (int i = 0; i < numberOfNodes; i++)
{
var typeTreeNode = new TypeTreeNode();
@@ -287,37 +278,38 @@ namespace AssetStudio
typeTreeNode.m_Version = reader.ReadUInt16();
typeTreeNode.m_Level = reader.ReadByte();
typeTreeNode.m_IsArray = reader.ReadBoolean() ? 1 : 0;
var m_TypeStrOffset = reader.ReadUInt16();
var temp = reader.ReadUInt16();
if (temp == 0)
{
stringBufferReader.BaseStream.Position = m_TypeStrOffset;
typeTreeNode.m_Type = stringBufferReader.ReadStringToNull();
}
else
{
typeTreeNode.m_Type = CommonString.StringBuffer.ContainsKey(m_TypeStrOffset) ? CommonString.StringBuffer[m_TypeStrOffset] : m_TypeStrOffset.ToString();
}
var m_NameStrOffset = reader.ReadUInt16();
temp = reader.ReadUInt16();
if (temp == 0)
{
stringBufferReader.BaseStream.Position = m_NameStrOffset;
typeTreeNode.m_Name = stringBufferReader.ReadStringToNull();
}
else
{
typeTreeNode.m_Name = CommonString.StringBuffer.ContainsKey(m_NameStrOffset) ? CommonString.StringBuffer[m_NameStrOffset] : m_NameStrOffset.ToString();
}
typeTreeNode.m_TypeStrOffset = reader.ReadUInt32();
typeTreeNode.m_NameStrOffset = reader.ReadUInt32();
typeTreeNode.m_ByteSize = reader.ReadInt32();
typeTreeNode.m_Index = reader.ReadInt32();
typeTreeNode.m_MetaFlag = reader.ReadInt32();
if (header.m_Version > 17)
{
reader.Position += 8;
}
typeTreeNode.m_Type = ReadString(stringBufferReader, typeTreeNode.m_TypeStrOffset);
typeTreeNode.m_Name = ReadString(stringBufferReader, typeTreeNode.m_NameStrOffset);
}
reader.Position += stringBufferSize;
}
string ReadString(BinaryReader stringBufferReader, uint value)
{
var isOffset = (value & 0x80000000) == 0;
if (isOffset)
{
stringBufferReader.BaseStream.Position = value;
return stringBufferReader.ReadStringToNull();
}
var offset = value & 0x7FFFFFFF;
if (CommonString.StringBuffer.TryGetValue(offset, out var str))
{
return str;
}
return offset.ToString();
}
}
}
}

View File

@@ -8,7 +8,7 @@ namespace AssetStudio
{
public static class TypeTreeHelper
{
public static void ReadTypeString(StringBuilder sb, List<TypeTreeNode> members, EndianBinaryReader reader)
public static void ReadTypeString(StringBuilder sb, List<TypeTreeNode> members, BinaryReader reader)
{
for (int i = 0; i < members.Count; i++)
{
@@ -16,7 +16,7 @@ namespace AssetStudio
}
}
private static void ReadStringValue(StringBuilder sb, List<TypeTreeNode> members, EndianBinaryReader reader, ref int i)
private static void ReadStringValue(StringBuilder sb, List<TypeTreeNode> members, BinaryReader reader, ref int i)
{
var member = members[i];
var level = member.m_Level;
@@ -150,13 +150,13 @@ namespace AssetStudio
if (append)
sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), varTypeStr, varNameStr, value);
if (align)
reader.AlignStream(4);
reader.AlignStream();
}
public static Dictionary<string, object> ReadBoxingType(List<TypeTreeNode> members, EndianBinaryReader reader)
public static UType ReadUType(List<TypeTreeNode> members, BinaryReader reader)
{
var obj = new Dictionary<string, object>();
for (int i = 0; i < members.Count; i++)
var obj = new UType();
for (int i = 1; i < members.Count; i++)
{
var member = members[i];
var varNameStr = member.m_Name;
@@ -165,7 +165,7 @@ namespace AssetStudio
return obj;
}
private static object ReadValue(List<TypeTreeNode> members, EndianBinaryReader reader, ref int i)
private static object ReadValue(List<TypeTreeNode> members, BinaryReader reader, ref int i)
{
var member = members[i];
var level = member.m_Level;
@@ -218,23 +218,6 @@ namespace AssetStudio
value = reader.ReadAlignedString();
i += 3;
break;
case "vector":
{
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
align = true;
var size = reader.ReadInt32();
var list = new List<object>(size);
var vector = GetMembers(members, level, i);
i += vector.Count - 1;
vector.RemoveRange(0, 3);
for (int j = 0; j < size; j++)
{
int tmp = 0;
list.Add(ReadValue(vector, reader, ref tmp));
}
value = list;
break;
}
case "map":
{
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
@@ -265,26 +248,42 @@ namespace AssetStudio
}
default:
{
if (i != members.Count && members[i + 1].m_Type == "Array")
if (i != members.Count && members[i + 1].m_Type == "Array") //Array
{
goto case "vector";
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
align = true;
var size = reader.ReadInt32();
var list = new List<object>(size);
var vector = GetMembers(members, level, i);
i += vector.Count - 1;
vector.RemoveRange(0, 3);
for (int j = 0; j < size; j++)
{
int tmp = 0;
list.Add(ReadValue(vector, reader, ref tmp));
}
value = list;
break;
}
var @class = GetMembers(members, level, i);
@class.RemoveAt(0);
i += @class.Count;
var obj = new Dictionary<string, object>();
for (int j = 0; j < @class.Count; j++)
else //Class
{
var classmember = @class[j];
var name = classmember.m_Name;
obj[name] = ReadValue(@class, reader, ref j);
var @class = GetMembers(members, level, i);
@class.RemoveAt(0);
i += @class.Count;
var obj = new UType();
for (int j = 0; j < @class.Count; j++)
{
var classmember = @class[j];
var name = classmember.m_Name;
obj[name] = ReadValue(@class, reader, ref j);
}
value = obj;
break;
}
value = obj;
break;
}
}
if (align)
reader.AlignStream(4);
reader.AlignStream();
return value;
}
@@ -305,7 +304,7 @@ namespace AssetStudio
return member2;
}
public static byte[] WriteBoxingType(Dictionary<string, object> obj, List<TypeTreeNode> members)
public static byte[] WriteUType(UType obj, List<TypeTreeNode> members)
{
var stream = new MemoryStream();
var write = new BinaryWriter(stream);
@@ -370,23 +369,6 @@ namespace AssetStudio
write.WriteAlignedString((string)value);
i += 3;
break;
case "vector":
{
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
align = true;
var list = (List<object>)value;
var size = list.Count;
write.Write(size);
var vector = GetMembers(members, level, i);
i += vector.Count - 1;
vector.RemoveRange(0, 3);
for (int j = 0; j < size; j++)
{
int tmp = 0;
WriteValue(list[j], vector, write, ref tmp);
}
break;
}
case "map":
{
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
@@ -420,21 +402,37 @@ namespace AssetStudio
}
default:
{
if (i != members.Count && members[i + 1].m_Type == "Array")
if (i != members.Count && members[i + 1].m_Type == "Array") //Array
{
goto case "vector";
if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
align = true;
var list = (List<object>)value;
var size = list.Count;
write.Write(size);
var vector = GetMembers(members, level, i);
i += vector.Count - 1;
vector.RemoveRange(0, 3);
for (int j = 0; j < size; j++)
{
int tmp = 0;
WriteValue(list[j], vector, write, ref tmp);
}
break;
}
var @class = GetMembers(members, level, i);
@class.RemoveAt(0);
i += @class.Count;
var obj = (Dictionary<string, object>)value;
for (int j = 0; j < @class.Count; j++)
else //Class
{
var classmember = @class[j];
var name = classmember.m_Name;
WriteValue(obj[name], @class, write, ref j);
var @class = GetMembers(members, level, i);
@class.RemoveAt(0);
i += @class.Count;
var obj = (UType)value;
for (int j = 0; j < @class.Count; j++)
{
var classmember = @class[j];
var name = classmember.m_Name;
WriteValue(obj[name], @class, write, ref j);
}
break;
}
break;
}
}
if (align)

View File

@@ -15,5 +15,7 @@ namespace AssetStudio
public int m_Version;
public int m_MetaFlag;
public int m_Level;
public uint m_TypeStrOffset;
public uint m_NameStrOffset;
}
}

155
AssetStudio/UType.cs Normal file
View File

@@ -0,0 +1,155 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public class UType : IDictionary<string, object>
{
private List<string> keys;
private List<object> values;
public UType()
{
keys = new List<string>();
values = new List<object>();
}
private int GetValueIndex(string name)
{
for (int i = 0, n = keys.Count; i < n; i++)
{
if (string.Equals(keys[i], name, StringComparison.Ordinal))
{
return i;
}
}
return -1;
}
public bool TryGetValue<T>(string key, out T value)
{
var index = GetValueIndex(key);
if (index != -1)
{
value = (T)values[index];
return true;
}
else
{
value = default(T);
return false;
}
}
public object this[string key]
{
get
{
var index = GetValueIndex(key);
if (index != -1)
{
return values[index];
}
else
{
return null;
}
}
set
{
var index = GetValueIndex(key);
if (index == -1)
{
keys.Add(key);
values.Add(value);
}
else
{
values[index] = value;
}
}
}
public ICollection<string> Keys => keys;
public ICollection<object> Values => values;
public int Count => keys.Count;
public bool IsReadOnly => false;
public void Add(string key, object value)
{
keys.Add(key);
values.Add(value);
}
public void Add(KeyValuePair<string, object> item)
{
keys.Add(item.Key);
values.Add(item.Value);
}
public void Clear()
{
keys.Clear();
values.Clear();
}
public bool Contains(KeyValuePair<string, object> item)
{
throw new NotImplementedException();
}
public bool ContainsKey(string key)
{
return GetValueIndex(key) != -1;
}
public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
for (int i = 0, n = keys.Count; i < n; i++)
{
yield return new KeyValuePair<string, object>(keys[i], values[i]);
}
}
public bool Remove(string key)
{
throw new NotImplementedException();
}
public bool Remove(KeyValuePair<string, object> item)
{
throw new NotImplementedException();
}
public bool TryGetValue(string key, out object value)
{
var index = GetValueIndex(key);
if (index != -1)
{
value = values[index];
return true;
}
else
{
value = null;
return false;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}

View File

@@ -1,5 +1,3 @@
#include <fbxsdk.h>
#include <fbxsdk/fileio/fbxiosettings.h>
#include "AssetStudioFBX.h"
namespace AssetStudio

View File

@@ -1,5 +1,7 @@
#pragma once
#include <fbxsdk.h>
#ifdef IOS_REF
#undef IOS_REF
#define IOS_REF (*(pSdkManager->GetIOSettings()))
@@ -9,7 +11,6 @@ using namespace System;
using namespace System::Collections::Generic;
using namespace System::IO;
using namespace System::Runtime::InteropServices;
using namespace SharpDX;
#define WITH_MARSHALLED_STRING(name,str,block)\
{ \
@@ -49,14 +50,14 @@ namespace AssetStudio {
{
public:
static void Export(String^ path, IImported^ imported, bool eulerFilter, float filterPrecision, bool allFrames, bool allBones, bool skins, float boneSize, float scaleFactor, bool flatInbetween, int versionIndex, bool isAscii);
static void ExportMorph(String^ path, IImported^ imported, bool morphMask, bool flatInbetween, bool skins, float boneSize, float scaleFactor, int versionIndex, bool isAscii);
private:
HashSet<String^>^ frameNames;
bool exportSkins;
float boneSize;
IImported^ imported;
HashSet<String^>^ framePaths;
Dictionary<ImportedFrame^, size_t>^ frameToNode;
List<ImportedFrame^>^ meshFrames;
char* cDest;
FbxManager* pSdkManager;
@@ -64,22 +65,22 @@ namespace AssetStudio {
FbxExporter* pExporter;
FbxArray<FbxSurfacePhong*>* pMaterials;
FbxArray<FbxFileTexture*>* pTextures;
FbxArray<FbxNode*>* pMeshNodes;
FbxPose* pBindPose;
Exporter(String^ path, IImported^ imported, bool allFrames, bool allBones, bool skins, float boneSize, float scaleFactor, int versionIndex, bool isAscii, bool normals);
Exporter(String^ path, IImported^ imported, bool allFrames, bool allBones, bool skins, float boneSize, float scaleFactor, int versionIndex, bool isAscii);
~Exporter();
void Exporter::LinkTexture(ImportedMaterial^ mat, int attIndex, FbxFileTexture* pTexture, FbxProperty& prop);
void SetJointsNode(FbxNode* pNode, HashSet<String^>^ boneNames, bool allBones);
void Exporter::LinkTexture(ImportedMaterialTexture^ texture, FbxFileTexture* pTexture, FbxProperty& prop);
void SetJointsNode(ImportedFrame^ frame, HashSet<String^>^ bonePaths, bool allBones);
HashSet<String^>^ SearchHierarchy();
void SearchHierarchy(ImportedFrame^ frame, HashSet<String^>^ exportFrames);
void SetJointsFromImportedMeshes(bool allBones);
void ExportFrame(FbxNode* pParentNode, ImportedFrame^ frame);
void ExportMesh(FbxNode* pFrameNode, ImportedMesh^ meshList, bool normals);
FbxFileTexture* ExportTexture(ImportedTexture^ matTex, FbxMesh* pMesh);
void ExportMesh(FbxNode* pFrameNode, ImportedMesh^ meshList);
FbxFileTexture* ExportTexture(ImportedTexture^ matTex);
void ExportAnimations(bool eulerFilter, float filterValue, bool flatInbetween);
void ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* eulerFilter, float filterPrecision, bool flatInbetween);
void ExportMorphs(IImported^ imported, bool morphMask, bool flatInbetween);
void ExportMorphs(bool morphMask, bool flatInbetween);
};
};
}

View File

@@ -140,12 +140,6 @@
<ClInclude Include="AssetStudioFBX.h" />
</ItemGroup>
<ItemGroup>
<Reference Include="SharpDX">
<HintPath>..\AssetStudio\Libraries\SharpDX.dll</HintPath>
</Reference>
<Reference Include="SharpDX.Mathematics">
<HintPath>..\AssetStudio\Libraries\SharpDX.Mathematics.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>

File diff suppressed because it is too large Load Diff

View File

@@ -73,20 +73,11 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="dnlib, Version=3.0.0.0, Culture=neutral, PublicKeyToken=50e96378b6e77999, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\AssetStudio\Libraries\dnlib.dll</HintPath>
<Private>False</Private>
<Reference Include="OpenTK">
<HintPath>Libraries\OpenTK.dll</HintPath>
</Reference>
<Reference Include="OpenTK, Version=3.0.1.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\AssetStudio\Libraries\OpenTK.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="OpenTK.GLControl, Version=3.0.1.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\AssetStudio\Libraries\OpenTK.GLControl.dll</HintPath>
<Private>False</Private>
<Reference Include="OpenTK.GLControl">
<HintPath>Libraries\OpenTK.GLControl.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
@@ -177,9 +168,9 @@
<None Include="Resources\as.ico" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AssetStudioTools\AssetStudioTools.csproj">
<ProjectReference Include="..\AssetStudioUtility\AssetStudioUtility.csproj">
<Project>{9131c403-7fe8-444d-9af5-5fe5df76ff24}</Project>
<Name>AssetStudioTools</Name>
<Name>AssetStudioUtility</Name>
</ProjectReference>
<ProjectReference Include="..\AssetStudio\AssetStudio.csproj">
<Project>{af56b63c-1764-41b7-9e60-8d485422ac3b}</Project>
@@ -188,8 +179,8 @@
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>xcopy /y "$(SolutionDir)AssetStudio\Libraries" "$(TargetDir)"
xcopy /y "$(SolutionDir)AssetStudio\Libraries\$(PlatformName)" "$(TargetDir)"</PostBuildEvent>
<PostBuildEvent>xcopy /y "$(ProjectDir)Libraries" "$(TargetDir)"
xcopy /y "$(ProjectDir)Libraries\$(PlatformName)" "$(TargetDir)"</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

File diff suppressed because it is too large Load Diff

View File

@@ -5,21 +5,23 @@ namespace AssetStudioGUI
{
internal class AssetItem : ListViewItem
{
public SerializedFile sourceFile;
public ObjectReader reader;
public Object Asset;
public SerializedFile SourceFile;
public long FullSize;
public ClassIDType Type;
public string TypeString;
public string Extension;
public string InfoText;
public string UniqueID;
public GameObject gameObject;
public GameObjectTreeNode TreeNode;
public AssetItem(ObjectReader reader)
public AssetItem(Object asset)
{
sourceFile = reader.assetsFile;
this.reader = reader;
FullSize = reader.byteSize;
Type = reader.type;
Asset = asset;
SourceFile = asset.assetsFile;
FullSize = asset.byteSize;
Type = asset.type;
TypeString = Type.ToString();
}
}

View File

@@ -11,10 +11,7 @@ namespace AssetStudioGUI
{
public static bool ExportTexture2D(AssetItem item, string exportPathName)
{
var m_Texture2D = new Texture2D(item.reader, true);
if (m_Texture2D.image_data == null || m_Texture2D.image_data.Length == 0)
return false;
var converter = new Texture2DConverter(m_Texture2D);
var converter = new Texture2DConverter((Texture2D)item.Asset);
var convertTexture = (bool)Properties.Settings.Default["convertTexture"];
if (convertTexture)
{
@@ -54,8 +51,9 @@ namespace AssetStudioGUI
public static bool ExportAudioClip(AssetItem item, string exportPath)
{
var m_AudioClip = new AudioClip(item.reader, true);
if (m_AudioClip.m_AudioData == null)
var m_AudioClip = (AudioClip)item.Asset;
var m_AudioData = m_AudioClip.m_AudioData.Value;
if (m_AudioData == null || m_AudioData.Length == 0)
return false;
var convertAudio = (bool)Properties.Settings.Default["convertAudio"];
var converter = new AudioClipConverter(m_AudioClip);
@@ -74,26 +72,38 @@ namespace AssetStudioGUI
var exportFullName = exportPath + item.Text + converter.GetExtensionName();
if (ExportFileExists(exportFullName))
return false;
File.WriteAllBytes(exportFullName, m_AudioClip.m_AudioData);
File.WriteAllBytes(exportFullName, m_AudioData);
}
return true;
}
public static bool ExportShader(AssetItem item, string exportPath)
{
var m_Shader = new Shader(item.reader);
var exportFullName = exportPath + item.Text + ".shader";
if (ExportFileExists(exportFullName))
return false;
var str = ShaderConverter.Convert(m_Shader);
File.WriteAllText(exportFullName, str ?? "Serialized Shader can't be read");
var m_Shader = (Shader) item.Asset;
if (m_Shader.compressedBlob != null) //5.5 and up
{
var strs = ShaderConverter.ConvertMultiple(m_Shader);
for (int i = 0; i < strs.Length; i++)
{
var platformName = ShaderConverter.GetPlatformString(m_Shader.platforms[i]);
File.WriteAllText($"{exportPath}{item.Text}_{platformName}.shader", strs[i]);
}
}
else
{
var str = ShaderConverter.Convert(m_Shader);
File.WriteAllText(exportFullName, str);
}
return true;
}
public static bool ExportTextAsset(AssetItem item, string exportPath)
{
var m_TextAsset = new TextAsset(item.reader);
var exportFullName = exportPath + item.Text + ".txt";
var m_TextAsset = (TextAsset)(item.Asset);
var exportFullName = exportPath + item.Text + (item.Extension ?? ".txt");
if (ExportFileExists(exportFullName))
return false;
File.WriteAllBytes(exportFullName, m_TextAsset.m_Script);
@@ -105,23 +115,15 @@ namespace AssetStudioGUI
var exportFullName = exportPath + item.Text + ".txt";
if (ExportFileExists(exportFullName))
return false;
var reader = item.reader;
string str;
if (reader.serializedType?.m_Nodes != null)
{
str = reader.Dump();
}
else
{
str = Studio.GetScriptString(reader);
}
var m_MonoBehaviour = (MonoBehaviour)item.Asset;
var str = m_MonoBehaviour.Dump() ?? Studio.GetScriptString(item.Asset.reader);
File.WriteAllText(exportFullName, str);
return true;
}
public static bool ExportFont(AssetItem item, string exportPath)
{
var m_Font = new Font(item.reader);
var m_Font = (Font)item.Asset;
if (m_Font.m_FontData != null)
{
var extension = ".ttf";
@@ -140,7 +142,7 @@ namespace AssetStudioGUI
public static bool ExportMesh(AssetItem item, string exportPath)
{
var m_Mesh = new Mesh(item.reader);
var m_Mesh = (Mesh)item.Asset;
if (m_Mesh.m_VertexCount <= 0)
return false;
var exportFullName = exportPath + item.Text + ".obj";
@@ -201,7 +203,7 @@ namespace AssetStudioGUI
#region Face
int sum = 0;
for (var i = 0; i < m_Mesh.m_SubMeshes.Count; i++)
for (var i = 0; i < m_Mesh.m_SubMeshes.Length; i++)
{
sb.AppendLine($"g {m_Mesh.m_Name}_{i}");
int indexCount = (int)m_Mesh.m_SubMeshes[i].indexCount;
@@ -221,13 +223,14 @@ namespace AssetStudioGUI
public static bool ExportVideoClip(AssetItem item, string exportPath)
{
var m_VideoClip = new VideoClip(item.reader, true);
if (m_VideoClip.m_VideoData != null)
var m_VideoClip = (VideoClip)item.Asset;
var m_VideoData = m_VideoClip.m_VideoData.Value;
if (m_VideoData != null && m_VideoData.Length != 0)
{
var exportFullName = exportPath + item.Text + Path.GetExtension(m_VideoClip.m_OriginalPath);
if (ExportFileExists(exportFullName))
return false;
File.WriteAllBytes(exportFullName, m_VideoClip.m_VideoData);
File.WriteAllBytes(exportFullName, m_VideoData);
return true;
}
return false;
@@ -235,7 +238,7 @@ namespace AssetStudioGUI
public static bool ExportMovieTexture(AssetItem item, string exportPath)
{
var m_MovieTexture = new MovieTexture(item.reader);
var m_MovieTexture = (MovieTexture)item.Asset;
var exportFullName = exportPath + item.Text + ".ogv";
if (ExportFileExists(exportFullName))
return false;
@@ -262,7 +265,7 @@ namespace AssetStudioGUI
var exportFullName = exportPath + item.Text + "." + type.ToLower();
if (ExportFileExists(exportFullName))
return false;
var bitmap = SpriteHelper.GetImageFromSprite(new Sprite(item.reader));
var bitmap = SpriteHelper.GetImageFromSprite((Sprite)item.Asset);
if (bitmap != null)
{
bitmap.Save(exportFullName, format);
@@ -277,7 +280,7 @@ namespace AssetStudioGUI
var exportFullName = exportPath + item.Text + ".dat";
if (ExportFileExists(exportFullName))
return false;
File.WriteAllBytes(exportFullName, item.reader.GetRawData());
File.WriteAllBytes(exportFullName, item.Asset.GetRawData());
return true;
}
@@ -293,15 +296,15 @@ namespace AssetStudioGUI
public static bool ExportAnimator(AssetItem item, string exportPath, List<AssetItem> animationList = null)
{
var m_Animator = new Animator(item.reader);
var convert = animationList != null ? new ModelConverter(m_Animator, animationList.Select(x => x.reader).ToArray()) : new ModelConverter(m_Animator);
exportPath = exportPath + item.Text + ".fbx";
var m_Animator = (Animator)item.Asset;
var convert = animationList != null ? new ModelConverter(m_Animator, animationList.Select(x => (AnimationClip)x.Asset).ToArray()) : new ModelConverter(m_Animator);
exportPath = $"{exportPath}{item.Text}\\{item.Text}.fbx";
return ExportFbx(convert, exportPath);
}
public static bool ExportGameObject(GameObject gameObject, string exportPath, List<AssetItem> animationList = null)
{
var convert = animationList != null ? new ModelConverter(gameObject, animationList.Select(x => x.reader).ToArray()) : new ModelConverter(gameObject);
var convert = animationList != null ? new ModelConverter(gameObject, animationList.Select(x => (AnimationClip)x.Asset).ToArray()) : new ModelConverter(gameObject);
exportPath = exportPath + Studio.FixFileName(gameObject.m_Name) + ".fbx";
return ExportFbx(convert, exportPath);
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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