diff --git a/AssetStudio.sln b/AssetStudio.sln index bd189c4..1f8b678 100644 --- a/AssetStudio.sln +++ b/AssetStudio.sln @@ -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 diff --git a/AssetStudio/AssetStudio.csproj b/AssetStudio/AssetStudio.csproj index 559390f..8ce33cc 100644 --- a/AssetStudio/AssetStudio.csproj +++ b/AssetStudio/AssetStudio.csproj @@ -64,7 +64,7 @@ - + @@ -126,16 +126,16 @@ - + - + - + - + diff --git a/AssetStudio/Classes/Sprite.cs b/AssetStudio/Classes/Sprite.cs index 7b0c071..750a557 100644 --- a/AssetStudio/Classes/Sprite.cs +++ b/AssetStudio/Classes/Sprite.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Text; using SharpDX; using RectangleF = System.Drawing.RectangleF; @@ -44,28 +41,280 @@ 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 BoneWeights4 + { + public float[] weight; + public int[] boneIndex; + + public BoneWeights4(ObjectReader reader) + { + weight = reader.ReadSingleArray(4); + boneIndex = reader.ReadInt32Array(4); + } + } + + public class StreamInfo + { + public uint channelMask; + public uint offset; + public uint stride; + public uint align; + public byte dividerOp; + public ushort frequency; + + public StreamInfo(ObjectReader reader) + { + var version = reader.version; + + channelMask = reader.ReadUInt32(); + offset = reader.ReadUInt32(); + + if (version[0] < 4) + { + stride = reader.ReadUInt32(); + align = reader.ReadUInt32(); + } + else + { + stride = reader.ReadByte(); + dividerOp = reader.ReadByte(); + frequency = reader.ReadUInt16(); + } + } + } + + public class ChannelInfo + { + public byte stream; + public byte offset; + public byte format; + public byte dimension; + + public ChannelInfo(ObjectReader reader) + { + stream = reader.ReadByte(); + offset = reader.ReadByte(); + format = reader.ReadByte(); + dimension = reader.ReadByte(); + } + } + + public class VertexData + { + public uint m_CurrentChannels; + public uint m_VertexCount; + public ChannelInfo[] m_Channels; + public StreamInfo[] m_Streams; + public byte[] m_DataSize; + + public VertexData(ObjectReader reader) + { + var version = reader.version; + + if (version[0] < 2018)//2018 down + { + m_CurrentChannels = reader.ReadUInt32(); + } + m_VertexCount = reader.ReadUInt32(); + + if (version[0] >= 4) + { + var m_ChannelsSize = reader.ReadInt32(); + m_Channels = new ChannelInfo[m_ChannelsSize]; + for (int i = 0; i < m_ChannelsSize; i++) + { + m_Channels[i] = new ChannelInfo(reader); + } + } + + if (version[0] < 5) //5.0 down + { + if (version[0] < 4) + { + m_Streams = new StreamInfo[4]; + } + else + { + m_Streams = new StreamInfo[reader.ReadInt32()]; + } + + for (int i = 0; i < m_Streams.Length; i++) + { + m_Streams[i] = new StreamInfo(reader); + } + } + + m_DataSize = reader.ReadBytes(reader.ReadInt32()); + reader.AlignStream(4); + } + } + + public class SubMesh + { + public uint firstByte; + public uint indexCount; + public int topology; + public uint triangleCount; + public uint baseVertex; + public uint firstVertex; + public uint vertexCount; + public AABB localAABB; + + public SubMesh(ObjectReader reader) + { + var version = reader.version; + + firstByte = reader.ReadUInt32(); + indexCount = reader.ReadUInt32(); + topology = reader.ReadInt32(); + + if (version[0] < 4) //4.0 down + { + triangleCount = reader.ReadUInt32(); + } + + if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up + { + baseVertex = reader.ReadUInt32(); + } + + if (version[0] >= 3) //3.0 and up + { + firstVertex = reader.ReadUInt32(); + vertexCount = reader.ReadUInt32(); + localAABB = new AABB(reader); + } + } + } + + public class SpriteRenderData + { + public PPtr texture; + public PPtr alphaTexture; + public SubMesh[] m_SubMeshes; + public byte[] m_IndexBuffer; + public VertexData m_VertexData; + public SpriteVertex[] vertices; + public ushort[] indices; + public Matrix[] 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(reader); + if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up + { + alphaTexture = new PPtr(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(4); + + 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.ReadInt32()); + reader.AlignStream(4); + } + + if (version[0] >= 2018) //2018 and up + { + m_Bindpose = reader.ReadMatrixArray(reader.ReadInt32()); + + 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 m_RenderDataKey; - public PPtr texture; + public uint m_Extrude; + public bool m_IsPolygon; + public KeyValuePair m_RenderDataKey; + public string[] m_AtlasTags; public PPtr m_SpriteAtlas; - public RectangleF textureRect; - public SpriteSettings settingsRaw; - public PointF[][] m_PhysicsShape; //Vector2[][] + 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(); @@ -73,142 +322,44 @@ namespace AssetStudio || (version[0] == 5 && version[1] > 4) || (version[0] == 5 && version[1] == 4 && version[2] >= 2)) //5.4.2 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(); + m_IsPolygon = reader.ReadBoolean(); reader.AlignStream(4); } 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(first, second); - //vector m_AtlasTags - var size = reader.ReadInt32(); - for (int i = 0; i < size; i++) + m_RenderDataKey = new KeyValuePair(first, second); + + var m_AtlasTagsSize = reader.ReadInt32(); + m_AtlasTags = new string[m_AtlasTagsSize]; + for (int i = 0; i < m_AtlasTagsSize; i++) { - var data = reader.ReadAlignedString(); + m_AtlasTags[i] = reader.ReadAlignedString(); } - //PPtr m_SpriteAtlas m_SpriteAtlas = new PPtr(reader); } - //SpriteRenderData m_RD - // PPtr texture - texture = new PPtr(reader); - // PPtr alphaTexture - if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up - { - var alphaTexture = new PPtr(reader); - } + 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(reader.ReadInt32()); } } + //vector m_Bones 2018 and up } } diff --git a/AssetStudio/Classes/SpriteAtlas.cs b/AssetStudio/Classes/SpriteAtlas.cs index 0f52ea3..a3d1a08 100644 --- a/AssetStudio/Classes/SpriteAtlas.cs +++ b/AssetStudio/Classes/SpriteAtlas.cs @@ -1,9 +1,6 @@ using SharpDX; using System; using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Text; namespace AssetStudio { @@ -37,7 +34,7 @@ namespace AssetStudio public sealed class SpriteAtlas : NamedObject { - public Dictionary, SpriteAtlasData> m_RenderDataMap; + public Dictionary, SpriteAtlasData> m_RenderDataMap; public SpriteAtlas(ObjectReader reader) : base(reader) { @@ -54,13 +51,13 @@ namespace AssetStudio } var m_RenderDataMapSize = reader.ReadInt32(); - m_RenderDataMap = new Dictionary, SpriteAtlasData>(m_RenderDataMapSize); + m_RenderDataMap = new Dictionary, 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(first, second), value); + m_RenderDataMap.Add(new KeyValuePair(first, second), value); } //string m_Tag //bool m_IsVariant diff --git a/AssetStudio/Extensions/BinaryReaderExtensions.cs b/AssetStudio/Extensions/BinaryReaderExtensions.cs index 6345f04..8bec001 100644 --- a/AssetStudio/Extensions/BinaryReaderExtensions.cs +++ b/AssetStudio/Extensions/BinaryReaderExtensions.cs @@ -65,6 +65,19 @@ namespace AssetStudio return new System.Drawing.RectangleF(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } + public static Matrix ReadMatrix(this BinaryReader reader) + { + var m = new Matrix(); + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 4; j++) + { + m[i, j] = reader.ReadSingle(); + } + } + return m; + } + private static T[] ReadArray(Func del, int length) { var array = new T[length]; @@ -99,5 +112,15 @@ namespace AssetStudio { return ReadArray(reader.ReadVector4, length); } + + public static ushort[] ReadUInt16Array(this BinaryReader reader, int length) + { + return ReadArray(reader.ReadUInt16, length); + } + + public static Matrix[] ReadMatrixArray(this BinaryReader reader, int length) + { + return ReadArray(reader.ReadMatrix, length); + } } } diff --git a/AssetStudio/Extensions/BinaryWriterExtensions.cs b/AssetStudio/Extensions/BinaryWriterExtensions.cs index 2557813..fcaac82 100644 --- a/AssetStudio/Extensions/BinaryWriterExtensions.cs +++ b/AssetStudio/Extensions/BinaryWriterExtensions.cs @@ -6,14 +6,6 @@ namespace AssetStudio { public static class BinaryWriterExtensions { - private static void WriteArray(Action del, T[] array) - { - foreach (var item in array) - { - del(item); - } - } - public static void AlignStream(this BinaryWriter writer, int alignment) { var pos = writer.BaseStream.Position; diff --git a/AssetStudio/Utility/IImported.cs b/AssetStudio/IImported.cs similarity index 100% rename from AssetStudio/Utility/IImported.cs rename to AssetStudio/IImported.cs diff --git a/AssetStudio/Utility/ILogger.cs b/AssetStudio/ILogger.cs similarity index 100% rename from AssetStudio/Utility/ILogger.cs rename to AssetStudio/ILogger.cs diff --git a/AssetStudio/Utility/IProgress.cs b/AssetStudio/IProgress.cs similarity index 100% rename from AssetStudio/Utility/IProgress.cs rename to AssetStudio/IProgress.cs diff --git a/AssetStudio/Utility/Logger.cs b/AssetStudio/Logger.cs similarity index 100% rename from AssetStudio/Utility/Logger.cs rename to AssetStudio/Logger.cs diff --git a/AssetStudio/Utility/Progress.cs b/AssetStudio/Progress.cs similarity index 100% rename from AssetStudio/Utility/Progress.cs rename to AssetStudio/Progress.cs diff --git a/AssetStudioGUI/AssetStudioGUI.csproj b/AssetStudioGUI/AssetStudioGUI.csproj index 39c15a4..575ca1b 100644 --- a/AssetStudioGUI/AssetStudioGUI.csproj +++ b/AssetStudioGUI/AssetStudioGUI.csproj @@ -177,9 +177,9 @@ - + {9131c403-7fe8-444d-9af5-5fe5df76ff24} - AssetStudioTools + AssetStudioUtility {af56b63c-1764-41b7-9e60-8d485422ac3b} diff --git a/AssetStudioTools/AssetStudioTools.csproj b/AssetStudioUtility/AssetStudioUtility.csproj similarity index 98% rename from AssetStudioTools/AssetStudioTools.csproj rename to AssetStudioUtility/AssetStudioUtility.csproj index cd99bec..bf0950a 100644 --- a/AssetStudioTools/AssetStudioTools.csproj +++ b/AssetStudioUtility/AssetStudioUtility.csproj @@ -8,7 +8,7 @@ Library Properties AssetStudio - AssetStudioTools + AssetStudioUtility v4.0 512 diff --git a/AssetStudioTools/AudioClipConverter.cs b/AssetStudioUtility/AudioClipConverter.cs similarity index 100% rename from AssetStudioTools/AudioClipConverter.cs rename to AssetStudioUtility/AudioClipConverter.cs diff --git a/AssetStudioTools/FMOD Studio API/fmod.cs b/AssetStudioUtility/FMOD Studio API/fmod.cs similarity index 100% rename from AssetStudioTools/FMOD Studio API/fmod.cs rename to AssetStudioUtility/FMOD Studio API/fmod.cs diff --git a/AssetStudioTools/FMOD Studio API/fmod_dsp.cs b/AssetStudioUtility/FMOD Studio API/fmod_dsp.cs similarity index 100% rename from AssetStudioTools/FMOD Studio API/fmod_dsp.cs rename to AssetStudioUtility/FMOD Studio API/fmod_dsp.cs diff --git a/AssetStudioTools/FMOD Studio API/fmod_errors.cs b/AssetStudioUtility/FMOD Studio API/fmod_errors.cs similarity index 100% rename from AssetStudioTools/FMOD Studio API/fmod_errors.cs rename to AssetStudioUtility/FMOD Studio API/fmod_errors.cs diff --git a/AssetStudioTools/ModelConverter.cs b/AssetStudioUtility/ModelConverter.cs similarity index 100% rename from AssetStudioTools/ModelConverter.cs rename to AssetStudioUtility/ModelConverter.cs diff --git a/AssetStudioTools/ModelExporter.cs b/AssetStudioUtility/ModelExporter.cs similarity index 100% rename from AssetStudioTools/ModelExporter.cs rename to AssetStudioUtility/ModelExporter.cs diff --git a/AssetStudioTools/Properties/AssemblyInfo.cs b/AssetStudioUtility/Properties/AssemblyInfo.cs similarity index 100% rename from AssetStudioTools/Properties/AssemblyInfo.cs rename to AssetStudioUtility/Properties/AssemblyInfo.cs diff --git a/AssetStudioTools/ScriptHelper.cs b/AssetStudioUtility/ScriptHelper.cs similarity index 100% rename from AssetStudioTools/ScriptHelper.cs rename to AssetStudioUtility/ScriptHelper.cs diff --git a/AssetStudioTools/ShaderConverter.cs b/AssetStudioUtility/ShaderConverter.cs similarity index 100% rename from AssetStudioTools/ShaderConverter.cs rename to AssetStudioUtility/ShaderConverter.cs diff --git a/AssetStudioTools/SpriteHelper.cs b/AssetStudioUtility/SpriteHelper.cs similarity index 91% rename from AssetStudioTools/SpriteHelper.cs rename to AssetStudioUtility/SpriteHelper.cs index f8f1221..eb3595b 100644 --- a/AssetStudioTools/SpriteHelper.cs +++ b/AssetStudioUtility/SpriteHelper.cs @@ -1,6 +1,7 @@ using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; +using System.Linq; namespace AssetStudio { @@ -17,9 +18,9 @@ namespace AssetStudio } else { - if (m_Sprite.texture.TryGet(out var m_Texture2D)) + if (m_Sprite.m_RD.texture.TryGet(out var m_Texture2D)) { - return CutImage(m_Texture2D, m_Sprite.textureRect, m_Sprite, m_Sprite.settingsRaw); + return CutImage(m_Texture2D, m_Sprite.m_RD.textureRect, m_Sprite, m_Sprite.m_RD.settingsRaw); } } return null; @@ -65,7 +66,8 @@ namespace AssetStudio { using (var path = new GraphicsPath()) { - foreach (var p in m_Sprite.m_PhysicsShape) + var points = m_Sprite.m_PhysicsShape.Select(x => x.Select(y => new PointF(y.X, y.Y)).ToArray()); + foreach (var p in points) { path.AddPolygon(p); } diff --git a/AssetStudioTools/Texture2DConverter.cs b/AssetStudioUtility/Texture2DConverter.cs similarity index 100% rename from AssetStudioTools/Texture2DConverter.cs rename to AssetStudioUtility/Texture2DConverter.cs