From 8218662548f2d6680c89783d65c6de6a750fbd47 Mon Sep 17 00:00:00 2001 From: Perfare Date: Thu, 3 May 2018 02:41:47 +0800 Subject: [PATCH] support 2018.1.0 some improvements --- AssetStudio/AssetStudioForm.cs | 11 +- AssetStudio/Classes/AnimationClip.cs | 24 ++- AssetStudio/Classes/AudioClip.cs | 6 +- AssetStudio/Classes/Font.cs | 79 +++------ AssetStudio/Classes/Mesh.cs | 93 +++++----- AssetStudio/Classes/MeshRenderer.cs | 44 ++--- AssetStudio/Classes/PlayerSettings.cs | 41 ++++- AssetStudio/Classes/SkinnedMeshRenderer.cs | 96 +++++----- AssetStudio/Classes/Sprite.cs | 20 ++- AssetStudio/StudioClasses/AssetPreloadData.cs | 2 +- AssetStudio/StudioClasses/AssetsFile.cs | 165 +++++++++--------- AssetStudio/StudioClasses/Importer.cs | 2 +- AssetStudio/StudioClasses/PPtrHelpers.cs | 2 +- AssetStudio/StudioClasses/Studio.cs | 17 +- 14 files changed, 323 insertions(+), 279 deletions(-) diff --git a/AssetStudio/AssetStudioForm.cs b/AssetStudio/AssetStudioForm.cs index ae99a71..23ba74b 100644 --- a/AssetStudio/AssetStudioForm.cs +++ b/AssetStudio/AssetStudioForm.cs @@ -1303,7 +1303,7 @@ namespace AssetStudio { var savePath = saveFolderDialog1.Folder + "\\"; progressBar1.Value = 0; - progressBar1.Maximum = sceneTreeView.Nodes.Count; + progressBar1.Maximum = sceneTreeView.Nodes.Cast().Sum(x => x.Nodes.Count); ExportSplitObjects(savePath, sceneTreeView.Nodes); } } @@ -1343,9 +1343,9 @@ namespace AssetStudio toolStripStatusLabel1.Text = "Nothing exported."; return; } - toolStripStatusLabel1.Text = $"Exporting {Path.GetFileName(saveFileDialog1.FileName)}.fbx"; + toolStripStatusLabel1.Text = $"Exporting {Path.GetFileName(saveFileDialog1.FileName)}"; FBXExporter.WriteFBX(saveFileDialog1.FileName, gameObjects); - toolStripStatusLabel1.Text = $"Finished exporting {Path.GetFileName(saveFileDialog1.FileName)}.fbx"; + toolStripStatusLabel1.Text = $"Finished exporting {Path.GetFileName(saveFileDialog1.FileName)}"; progressBar1.PerformStep(); if (openAfterExport.Checked && File.Exists(saveFileDialog1.FileName)) { @@ -1637,7 +1637,7 @@ namespace AssetStudio importFiles.Clear(); foreach (var assetsFile in assetsfileList) { - assetsFile.assetsFileReader.Dispose(); + assetsFile.reader.Dispose(); } assetsfileList.Clear(); exportableAssets.Clear(); @@ -1814,7 +1814,7 @@ namespace AssetStudio { var savePath = saveFolderDialog1.Folder + "\\"; progressBar1.Value = 0; - progressBar1.Maximum = sceneTreeView.Nodes.Count; + progressBar1.Maximum = sceneTreeView.Nodes.Cast().Sum(x => x.Nodes.Count); ; ExportSplitObjects(savePath, sceneTreeView.Nodes, true); } } @@ -1839,7 +1839,6 @@ namespace AssetStudio { assetListView.BeginUpdate(); assetListView.SelectedIndices.Clear(); - visibleAssets.Clear(); var show = new List(); if (!allToolStripMenuItem.Checked) { diff --git a/AssetStudio/Classes/AnimationClip.cs b/AssetStudio/Classes/AnimationClip.cs index bf218da..6e876b8 100644 --- a/AssetStudio/Classes/AnimationClip.cs +++ b/AssetStudio/Classes/AnimationClip.cs @@ -14,13 +14,23 @@ namespace AssetStudio public T value { get; set; } public T inSlope { get; set; } public T outSlope { get; set; } + public int weightedMode { get; set; } + public T inWeight { get; set; } + public T outWeight { get; set; } - public Keyframe(EndianBinaryReader reader, Func readerFunc) + + public Keyframe(EndianBinaryReader reader, Func readerFunc, int[] version) { time = reader.ReadSingle(); value = readerFunc(); inSlope = readerFunc(); outSlope = readerFunc(); + if (version[0] >= 2018) + { + weightedMode = reader.ReadInt32(); + inWeight = readerFunc(); + outWeight = readerFunc(); + } } } @@ -37,7 +47,7 @@ namespace AssetStudio m_Curve = new List>(numCurves); for (int i = 0; i < numCurves; i++) { - m_Curve.Add(new Keyframe(reader, readerFunc)); + m_Curve.Add(new Keyframe(reader, readerFunc, version)); } m_PreInfinity = reader.ReadInt32(); @@ -162,7 +172,7 @@ namespace AssetStudio public FloatCurve(AssetPreloadData preloadData) { - var reader = preloadData.sourceFile.assetsFileReader; + var reader = preloadData.sourceFile.reader; curve = new AnimationCurve(reader, reader.ReadSingle, preloadData.sourceFile.version); attribute = reader.ReadAlignedString(); path = reader.ReadAlignedString(); @@ -179,7 +189,7 @@ namespace AssetStudio public PPtrKeyframe(AssetPreloadData preloadData) { - var reader = preloadData.sourceFile.assetsFileReader; + var reader = preloadData.sourceFile.reader; time = reader.ReadSingle(); value = preloadData.sourceFile.ReadPPtr(); } @@ -196,7 +206,7 @@ namespace AssetStudio public PPtrCurve(AssetPreloadData preloadData) { - var reader = preloadData.sourceFile.assetsFileReader; + var reader = preloadData.sourceFile.reader; int numCurves = reader.ReadInt32(); curve = new List(numCurves); @@ -576,7 +586,7 @@ namespace AssetStudio public GenericBinding(AssetPreloadData preloadData) { - var reader = preloadData.sourceFile.assetsFileReader; + var reader = preloadData.sourceFile.reader; var version = preloadData.sourceFile.version; path = reader.ReadUInt32(); attribute = reader.ReadUInt32(); @@ -602,7 +612,7 @@ namespace AssetStudio public AnimationClipBindingConstant(AssetPreloadData preloadData) { - var reader = preloadData.sourceFile.assetsFileReader; + var reader = preloadData.sourceFile.reader; int numBindings = reader.ReadInt32(); genericBindings = new List(numBindings); for (int i = 0; i < numBindings; i++) diff --git a/AssetStudio/Classes/AudioClip.cs b/AssetStudio/Classes/AudioClip.cs index fd9d893..a70108c 100644 --- a/AssetStudio/Classes/AudioClip.cs +++ b/AssetStudio/Classes/AudioClip.cs @@ -49,7 +49,7 @@ namespace AssetStudio m_Type = (AudioType)reader.ReadInt32(); m_3D = reader.ReadBoolean(); m_UseHardware = reader.ReadBoolean(); - reader.Position += 2; //4 byte alignment + reader.AlignStream(4); if (sourceFile.version[0] >= 4 || (sourceFile.version[0] == 3 && sourceFile.version[1] >= 2)) //3.2.0 to 5 { @@ -76,12 +76,12 @@ namespace AssetStudio m_BitsPerSample = reader.ReadInt32(); m_Length = reader.ReadSingle(); m_IsTrackerFormat = reader.ReadBoolean(); - reader.Position += 3; + reader.AlignStream(4); m_SubsoundIndex = reader.ReadInt32(); m_PreloadAudioData = reader.ReadBoolean(); m_LoadInBackground = reader.ReadBoolean(); m_Legacy3D = reader.ReadBoolean(); - reader.Position += 1; + reader.AlignStream(4); m_3D = m_Legacy3D; m_Source = reader.ReadAlignedString(); diff --git a/AssetStudio/Classes/Font.cs b/AssetStudio/Classes/Font.cs index fe37e97..f990254 100644 --- a/AssetStudio/Classes/Font.cs +++ b/AssetStudio/Classes/Font.cs @@ -13,13 +13,14 @@ namespace AssetStudio public UFont(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; + var version = sourceFile.version; var reader = preloadData.InitReader(); m_Name = reader.ReadAlignedString(); if (readSwitch) { - if ((sourceFile.version[0] == 5 && sourceFile.version[1] >= 5) || sourceFile.version[0] > 5) + if ((version[0] == 5 && version[1] >= 5) || version[0] > 5)//5.5 and up { var m_LineSpacing = reader.ReadSingle(); var m_DefaultMaterial = sourceFile.ReadPPtr(); @@ -33,48 +34,33 @@ namespace AssetStudio int m_CharacterRects_size = reader.ReadInt32(); for (int i = 0; i < m_CharacterRects_size; i++) { - int index = reader.ReadInt32(); - //Rectf uv - float uvx = reader.ReadSingle(); - float uvy = reader.ReadSingle(); - float uvwidth = reader.ReadSingle(); - float uvheight = reader.ReadSingle(); - //Rectf vert - float vertx = reader.ReadSingle(); - float verty = reader.ReadSingle(); - float vertwidth = reader.ReadSingle(); - float vertheight = reader.ReadSingle(); - float width = reader.ReadSingle(); - - if (sourceFile.version[0] >= 4) - { - bool flipped = reader.ReadBoolean(); - reader.Position += 3; - } + reader.Position += 44;//CharacterInfo data 41 } int m_KerningValues_size = reader.ReadInt32(); for (int i = 0; i < m_KerningValues_size; i++) { - int pairfirst = reader.ReadInt16(); - int pairsecond = reader.ReadInt16(); - float second = reader.ReadSingle(); + reader.Position += 8; } var m_PixelScale = reader.ReadSingle(); int m_FontData_size = reader.ReadInt32(); if (m_FontData_size > 0) { m_FontData = reader.ReadBytes(m_FontData_size); - if (m_FontData[0] == 79 && m_FontData[1] == 84 && m_FontData[2] == 84 && m_FontData[3] == 79) - { preloadData.extension = ".otf"; } - else { preloadData.extension = ".ttf"; } + { + preloadData.extension = ".otf"; + } + else + { + preloadData.extension = ".ttf"; + } } } else { int m_AsciiStartOffset = reader.ReadInt32(); - if (sourceFile.version[0] <= 3) + if (version[0] <= 3) { int m_FontCountX = reader.ReadInt32(); int m_FontCountY = reader.ReadInt32(); @@ -83,7 +69,7 @@ namespace AssetStudio float m_Kerning = reader.ReadSingle(); float m_LineSpacing = reader.ReadSingle(); - if (sourceFile.version[0] <= 3) + if (version[0] <= 3) { int m_PerCharacterKerning_size = reader.ReadInt32(); for (int i = 0; i < m_PerCharacterKerning_size; i++) @@ -117,10 +103,10 @@ namespace AssetStudio float vertheight = reader.ReadSingle(); float width = reader.ReadSingle(); - if (sourceFile.version[0] >= 4) + if (version[0] >= 4) { - bool flipped = reader.ReadBoolean(); - reader.Position += 3; + var flipped = reader.ReadBoolean(); + reader.AlignStream(4); } } @@ -134,10 +120,10 @@ namespace AssetStudio float second = reader.ReadSingle(); } - if (sourceFile.version[0] <= 3) + if (version[0] <= 3) { - bool m_GridFont = reader.ReadBoolean(); - reader.Position += 3; //4 byte alignment + var m_GridFont = reader.ReadBoolean(); + reader.AlignStream(4); } else { float m_PixelScale = reader.ReadSingle(); } @@ -147,30 +133,13 @@ namespace AssetStudio m_FontData = reader.ReadBytes(m_FontData_size); if (m_FontData[0] == 79 && m_FontData[1] == 84 && m_FontData[2] == 84 && m_FontData[3] == 79) - { preloadData.extension = ".otf"; } - else { preloadData.extension = ".ttf"; } - - } - - float m_FontSize = reader.ReadSingle();//problem here in minifootball - float m_Ascent = reader.ReadSingle(); - uint m_DefaultStyle = reader.ReadUInt32(); - - int m_FontNames = reader.ReadInt32(); - for (int i = 0; i < m_FontNames; i++) - { - string m_FontName = reader.ReadAlignedString(); - } - - if (sourceFile.version[0] >= 4) - { - int m_FallbackFonts = reader.ReadInt32(); - for (int i = 0; i < m_FallbackFonts; i++) { - PPtr m_FallbackFont = sourceFile.ReadPPtr(); + preloadData.extension = ".otf"; + } + else + { + preloadData.extension = ".ttf"; } - - int m_FontRenderingMode = reader.ReadInt32(); } } } diff --git a/AssetStudio/Classes/Mesh.cs b/AssetStudio/Classes/Mesh.cs index dd0a911..37facae 100644 --- a/AssetStudio/Classes/Mesh.cs +++ b/AssetStudio/Classes/Mesh.cs @@ -670,7 +670,11 @@ namespace AssetStudio } } - BitArray m_CurrentChannels = new BitArray(new int[1] { reader.ReadInt32() }); + if (version[0] < 2018)//2018 down + { + var m_CurrentChannels = reader.ReadInt32(); + } + m_VertexCount = reader.ReadInt32(); //int singleStreamStride = 0;//used tor version 5 int streamCount = 0; @@ -730,46 +734,50 @@ namespace AssetStudio } #endregion - //actual Vertex Buffer - byte[] m_DataSize = new byte[reader.ReadInt32()]; - reader.Read(m_DataSize, 0, m_DataSize.Length); - - if (version[0] >= 5) //create streams + if (version[0] >= 5) //ComputeCompressedStreams { - m_Streams = new StreamInfo[streamCount]; - for (int s = 0; s < streamCount; s++) + int maxStream = 0; + foreach (var m_Channel in m_Channels) { - m_Streams[s] = new StreamInfo(); - m_Streams[s].channelMask = new BitArray(new int[1] { 0 }); - m_Streams[s].offset = 0; - m_Streams[s].stride = 0; - - foreach (var m_Channel in m_Channels) + if (m_Channel.stream > maxStream) { - if (m_Channel.stream == s) { m_Streams[s].stride += m_Channel.dimension * (4 / (int)Math.Pow(2, m_Channel.format)); } - } - - if (s > 0) - { - m_Streams[s].offset = m_Streams[s - 1].offset + m_Streams[s - 1].stride * m_VertexCount; - //sometimes there are 8 bytes between streams - //this is NOT an alignment, even if sometimes it may seem so - - if (streamCount == 2) { m_Streams[s].offset = m_DataSize.Length - m_Streams[s].stride * m_VertexCount; } - else - { - m_VertexCount = 0; - return; - } - - /*var absoluteOffset = a_Stream.Position + 4 + m_Streams[s].offset; - if ((absoluteOffset % m_Streams[s].stride) != 0) - { - m_Streams[s].offset += m_Streams[s].stride - (int)(absoluteOffset % m_Streams[s].stride); - }*/ + maxStream = m_Channel.stream; } } + var streamList = new List(maxStream + 1); + uint offset = 0; + for (int str = 0; str <= maxStream; str++) + { + uint chnMask = 0; + byte stride = 0; + for (int chn = 0; chn < m_Channels.Length; chn++) + { + if (m_Channels[chn].dimension > 0 && m_Channels[chn].stream == str) + { + chnMask |= 1u << chn; + stride += (byte)(m_Channels[chn].dimension * (m_Channels[chn].format == 0 ? 4 : 1)); + } + } + + var streamInfo = new StreamInfo + { + channelMask = new BitArray(new[] { (int)chnMask }), + offset = (int)offset, + stride = stride, + dividerOp = 0, + frequency = 0 + }; + streamList.Add(streamInfo); + offset += (uint)m_VertexCount * stride + (((uint)m_VertexCount & 1) != 0 ? (uint)8 : 0); + } + + m_Streams = streamList.ToArray(); } + + + //actual Vertex Buffer + var m_DataSize = new byte[reader.ReadInt32()]; + reader.Read(m_DataSize, 0, m_DataSize.Length); #endregion #region compute FvF @@ -790,11 +798,13 @@ namespace AssetStudio for (int b = 0; b < 8; b++) { - //in the future, try to use only m_CurrentChannels - if ((version[0] < 5 && m_Stream.channelMask.Get(b)) || (version[0] >= 5 && m_CurrentChannels.Get(b))) + if (m_Stream.channelMask.Get(b)) { // in version 4.x the colors channel has 1 dimension, as in 1 color with 4 components - if (b == 2 && m_Channel.format == 2) { m_Channel.dimension = 4; } + if (b == 2 && m_Channel.format == 2) + { + m_Channel.dimension = 4; + } componentByteSize = 4 / (int)Math.Pow(2, m_Channel.format); @@ -834,7 +844,7 @@ namespace AssetStudio case 3: m_UV1 = componentsArray; break; case 4: m_UV2 = componentsArray; break; case 5: - if (version[0] == 5) { m_UV3 = componentsArray; } + if (version[0] >= 5) { m_UV3 = componentsArray; } else { m_Tangents = componentsArray; } break; case 6: m_UV4 = componentsArray; break; @@ -842,10 +852,7 @@ namespace AssetStudio } m_Stream.channelMask.Set(b, false); - m_CurrentChannels.Set(b, false); - componentBytes = null; - componentsArray = null; - break; //go to next channel + break; } } } diff --git a/AssetStudio/Classes/MeshRenderer.cs b/AssetStudio/Classes/MeshRenderer.cs index cea7f61..102fa8b 100644 --- a/AssetStudio/Classes/MeshRenderer.cs +++ b/AssetStudio/Classes/MeshRenderer.cs @@ -8,11 +8,6 @@ namespace AssetStudio public class MeshRenderer { public PPtr m_GameObject; - public bool m_Enabled; - public byte m_CastShadows; //bool prior to version 5 - public bool m_ReceiveShadows; - public ushort m_LightmapIndex; - public ushort m_LightmapIndexDynamic; public PPtr[] m_Materials; protected MeshRenderer() { } @@ -20,38 +15,47 @@ namespace AssetStudio public MeshRenderer(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; + var version = sourceFile.version; var reader = preloadData.InitReader(); m_GameObject = sourceFile.ReadPPtr(); - - if (sourceFile.version[0] < 5) + if (version[0] < 5) { - m_Enabled = reader.ReadBoolean(); - m_CastShadows = reader.ReadByte(); - m_ReceiveShadows = reader.ReadBoolean(); - m_LightmapIndex = reader.ReadByte(); + var m_Enabled = reader.ReadBoolean(); + var m_CastShadows = reader.ReadByte(); + var m_ReceiveShadows = reader.ReadBoolean(); + var m_LightmapIndex = reader.ReadByte(); } else { - m_Enabled = reader.ReadBoolean(); + var m_Enabled = reader.ReadBoolean(); reader.AlignStream(4); - m_CastShadows = reader.ReadByte(); - m_ReceiveShadows = reader.ReadBoolean(); + var m_CastShadows = reader.ReadByte(); + var m_ReceiveShadows = reader.ReadBoolean(); reader.AlignStream(4); - - m_LightmapIndex = reader.ReadUInt16(); - m_LightmapIndexDynamic = reader.ReadUInt16(); + if (version[0] >= 2018)//2018 and up + { + var m_RenderingLayerMask = reader.ReadUInt32(); + } + var m_LightmapIndex = reader.ReadUInt16(); + var m_LightmapIndexDynamic = reader.ReadUInt16(); } - if (sourceFile.version[0] >= 3) { reader.Position += 16; } //Vector4f m_LightmapTilingOffset - if (sourceFile.version[0] >= 5) { reader.Position += 16; } //Vector4f m_LightmapTilingOffsetDynamic + if (version[0] >= 3) + { + reader.Position += 16;//Vector4f m_LightmapTilingOffset + } + + if (version[0] >= 5) + { + reader.Position += 16;//Vector4f m_LightmapTilingOffsetDynamic + } m_Materials = new PPtr[reader.ReadInt32()]; for (int m = 0; m < m_Materials.Length; m++) { m_Materials[m] = sourceFile.ReadPPtr(); } - } } } diff --git a/AssetStudio/Classes/PlayerSettings.cs b/AssetStudio/Classes/PlayerSettings.cs index 0a7c010..d0a440a 100644 --- a/AssetStudio/Classes/PlayerSettings.cs +++ b/AssetStudio/Classes/PlayerSettings.cs @@ -26,27 +26,50 @@ namespace AssetStudio } if (sourceFile.version[0] >= 3) { - if (sourceFile.version[0] == 3 && sourceFile.version[1] < 2) { string AndroidLicensePublicKey = reader.ReadAlignedString(); } - else { bool AndroidProfiler = reader.ReadBoolean(); reader.AlignStream(4); } + if (sourceFile.version[0] == 3 && sourceFile.version[1] < 2) + { + string AndroidLicensePublicKey = reader.ReadAlignedString(); + } + else + { + bool AndroidProfiler = reader.ReadBoolean(); reader.AlignStream(4); + } int defaultScreenOrientation = reader.ReadInt32(); int targetDevice = reader.ReadInt32(); if (sourceFile.version[0] < 5 || (sourceFile.version[0] == 5 && sourceFile.version[1] < 1)) - { int targetGlesGraphics = reader.ReadInt32(); } + { + int targetGlesGraphics = reader.ReadInt32(); + } if ((sourceFile.version[0] == 5 && sourceFile.version[1] < 1) || (sourceFile.version[0] == 4 && sourceFile.version[1] == 6 && sourceFile.version[2] >= 3)) - { int targetIOSGraphics = reader.ReadInt32(); } + { + int targetIOSGraphics = reader.ReadInt32(); + } if (sourceFile.version[0] >= 5 || sourceFile.version[0] == 5 && (sourceFile.version[1] > 2 || (sourceFile.version[1] == 2 && sourceFile.version[2] >= 1))) - { bool useOnDemandResources = reader.ReadBoolean(); reader.AlignStream(4); } + { + bool useOnDemandResources = reader.ReadBoolean(); reader.AlignStream(4); + } if (sourceFile.version[0] < 5 || (sourceFile.version[0] == 5 && sourceFile.version[1] < 3)) - { int targetResolution = reader.ReadInt32(); } + { + int targetResolution = reader.ReadInt32(); + } - if (sourceFile.version[0] == 3 && sourceFile.version[1] <= 1) { bool OverrideIPodMusic = reader.ReadBoolean(); reader.AlignStream(4); } - else if (sourceFile.version[0] == 3 && sourceFile.version[1] <= 4) { } - else { int accelerometerFrequency = reader.ReadInt32(); }//3.5.0 and up + if (sourceFile.version[0] == 3 && sourceFile.version[1] <= 1) + { + bool OverrideIPodMusic = reader.ReadBoolean(); reader.AlignStream(4); + } + else if (sourceFile.version[0] == 3 && sourceFile.version[1] <= 4) + { + + } + else//3.5.0 and up + { + int accelerometerFrequency = reader.ReadInt32(); + } } //fail in version 5 beta companyName = reader.ReadAlignedString(); diff --git a/AssetStudio/Classes/SkinnedMeshRenderer.cs b/AssetStudio/Classes/SkinnedMeshRenderer.cs index 1683096..e05cdf7 100644 --- a/AssetStudio/Classes/SkinnedMeshRenderer.cs +++ b/AssetStudio/Classes/SkinnedMeshRenderer.cs @@ -14,31 +14,41 @@ namespace AssetStudio public SkinnedMeshRenderer(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; - var version = preloadData.sourceFile.version; + var version = sourceFile.version; var reader = preloadData.InitReader(); m_GameObject = sourceFile.ReadPPtr(); - if (sourceFile.version[0] < 5) + if (version[0] < 5) { - m_Enabled = reader.ReadBoolean(); - m_CastShadows = reader.ReadByte();//bool - m_ReceiveShadows = reader.ReadBoolean(); - m_LightmapIndex = reader.ReadByte(); + var m_Enabled = reader.ReadBoolean(); + var m_CastShadows = reader.ReadByte(); + var m_ReceiveShadows = reader.ReadBoolean(); + var m_LightmapIndex = reader.ReadByte(); } else { - m_Enabled = reader.ReadBoolean(); + var m_Enabled = reader.ReadBoolean(); reader.AlignStream(4); - m_CastShadows = reader.ReadByte(); - m_ReceiveShadows = reader.ReadBoolean(); + var m_CastShadows = reader.ReadByte(); + var m_ReceiveShadows = reader.ReadBoolean(); reader.AlignStream(4); - - m_LightmapIndex = reader.ReadUInt16(); - m_LightmapIndexDynamic = reader.ReadUInt16(); + if (version[0] >= 2018)//2018 and up + { + var m_RenderingLayerMask = reader.ReadUInt32(); + } + var m_LightmapIndex = reader.ReadUInt16(); + var m_LightmapIndexDynamic = reader.ReadUInt16(); } - if (version[0] >= 3) { reader.Position += 16; } //m_LightmapTilingOffset vector4d - if (sourceFile.version[0] >= 5) { reader.Position += 16; } //Vector4f m_LightmapTilingOffsetDynamic + if (version[0] >= 3) + { + reader.Position += 16;//Vector4f m_LightmapTilingOffset + } + + if (version[0] >= 5) + { + reader.Position += 16;//Vector4f m_LightmapTilingOffsetDynamic + } m_Materials = new PPtr[reader.ReadInt32()]; for (int m = 0; m < m_Materials.Length; m++) @@ -61,26 +71,36 @@ namespace AssetStudio int m_SubsetIndices_size = reader.ReadInt32(); reader.Position += m_SubsetIndices_size * 4; } - PPtr m_StaticBatchRoot = sourceFile.ReadPPtr(); + + var m_StaticBatchRoot = sourceFile.ReadPPtr(); if ((sourceFile.version[0] == 5 && sourceFile.version[1] >= 4) || sourceFile.version[0] > 5)//5.4.0 and up { - PPtr m_ProbeAnchor = sourceFile.ReadPPtr(); - PPtr m_LightProbeVolumeOverride = sourceFile.ReadPPtr(); + var m_ProbeAnchor = sourceFile.ReadPPtr(); + var m_LightProbeVolumeOverride = sourceFile.ReadPPtr(); } - else if (version[0] >= 4 || (version[0] == 3 && version[1] >= 5)) + else if (version[0] >= 4 || (version[0] == 3 && version[1] >= 5))//3.5 - 5.3 { - bool m_UseLightProbes = reader.ReadBoolean(); - reader.Position += 3; //alignment - if (version[0] == 5) { int m_ReflectionProbeUsage = reader.ReadInt32(); } - //did I ever check if the anchor is conditioned by the bool? - PPtr m_LightProbeAnchor = sourceFile.ReadPPtr(); + var m_UseLightProbes = reader.ReadBoolean(); + reader.AlignStream(4); + if (version[0] == 5)//5.0 and up + { + int m_ReflectionProbeUsage = reader.ReadInt32(); + } + var m_LightProbeAnchor = sourceFile.ReadPPtr(); } - if (version[0] >= 5 || (version[0] == 4 && version[1] >= 3)) + if (version[0] >= 5 || (version[0] == 4 && version[1] >= 3))//4.3 and up { - if (version[0] == 4 && version[1] <= 3) { int m_SortingLayer = reader.ReadInt16(); } - else { int m_SortingLayer = reader.ReadInt32(); } + 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 + } int m_SortingOrder = reader.ReadInt16(); reader.AlignStream(4); @@ -88,14 +108,13 @@ namespace AssetStudio } int m_Quality = reader.ReadInt32(); - bool m_UpdateWhenOffscreen = reader.ReadBoolean(); - bool m_SkinNormals = reader.ReadBoolean(); //3.1.0 and below - reader.Position += 2; + var m_UpdateWhenOffscreen = reader.ReadBoolean(); + var m_SkinNormals = reader.ReadBoolean(); //3.1.0 and below + reader.AlignStream(4); - if (version[0] == 2 && version[1] < 6) + if (version[0] == 2 && version[1] < 6)//2.6 down { - //this would be the only error if mainVersion is not read in time for a version 2.x game - PPtr m_DisableAnimationWhenOffscreen = sourceFile.ReadPPtr(); + var m_DisableAnimationWhenOffscreen = sourceFile.ReadPPtr(); } m_Mesh = sourceFile.ReadPPtr(); @@ -122,19 +141,6 @@ namespace AssetStudio m_BlendShapeWeights.Add(reader.ReadSingle()); } } - - /*if (version[0] > 4 || (version[0] >= 3 && version[1] >= 5)) - { - PPtr m_RootBone = sourceFile.ReadPPtr(); - } - - if (version[0] > 4 || (version[0] == 3 && version[1] >= 4)) - { - //AABB - float[] m_Center = { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() }; - float[] m_Extent = { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() }; - bool m_DirtyAABB = reader.ReadBoolean(); - }*/ } } } diff --git a/AssetStudio/Classes/Sprite.cs b/AssetStudio/Classes/Sprite.cs index 8e652df..6d49f08 100644 --- a/AssetStudio/Classes/Sprite.cs +++ b/AssetStudio/Classes/Sprite.cs @@ -47,7 +47,7 @@ namespace AssetStudio } var m_Extrude = reader.ReadUInt32(); - if (version[0] > 5 || (version[0] == 5 && version[1] >= 3)) //5.3 and up TODO need more test + if (version[0] > 5 || (version[0] == 5 && version[1] >= 3)) //5.3 and up { var m_IsPolygon = reader.ReadBoolean(); reader.AlignStream(4); @@ -97,7 +97,10 @@ namespace AssetStudio reader.Position += size; //UInt8 data reader.AlignStream(4); // VertexData m_VertexData - var m_CurrentChannels = reader.ReadInt32(); + if (version[0] < 2018)//2018 down + { + var m_CurrentChannels = reader.ReadInt32(); + } var m_VertexCount = reader.ReadUInt32(); // vector m_Channels size = reader.ReadInt32(); @@ -106,6 +109,18 @@ namespace AssetStudio 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; + // vector m_SourceSkin + // BoneWeights4 data + size = reader.ReadInt32(); + reader.Position += size * 32; + } } else { @@ -159,6 +174,7 @@ namespace AssetStudio } } } + //vector m_Bones 2018 and up } else { diff --git a/AssetStudio/StudioClasses/AssetPreloadData.cs b/AssetStudio/StudioClasses/AssetPreloadData.cs index 187d0fa..c5e4db8 100644 --- a/AssetStudio/StudioClasses/AssetPreloadData.cs +++ b/AssetStudio/StudioClasses/AssetPreloadData.cs @@ -26,7 +26,7 @@ namespace AssetStudio public EndianBinaryReader InitReader() { - var reader = sourceFile.assetsFileReader; + var reader = sourceFile.reader; reader.Position = Offset; return reader; } diff --git a/AssetStudio/StudioClasses/AssetsFile.cs b/AssetStudio/StudioClasses/AssetsFile.cs index 43cbd4c..6fe4ef9 100644 --- a/AssetStudio/StudioClasses/AssetsFile.cs +++ b/AssetStudio/StudioClasses/AssetsFile.cs @@ -10,7 +10,7 @@ namespace AssetStudio { public class AssetsFile { - public EndianBinaryReader assetsFileReader; + public EndianBinaryReader reader; public string filePath; public string parentPath; public string fileName; @@ -151,46 +151,46 @@ namespace AssetStudio public AssetsFile(string fullName, EndianBinaryReader reader) { - assetsFileReader = reader; + this.reader = reader; filePath = fullName; fileName = Path.GetFileName(fullName); upperFileName = fileName.ToUpper(); try { - int tableSize = assetsFileReader.ReadInt32(); - int dataEnd = assetsFileReader.ReadInt32(); - fileGen = assetsFileReader.ReadInt32(); - uint dataOffset = assetsFileReader.ReadUInt32(); + int tableSize = this.reader.ReadInt32(); + int dataEnd = this.reader.ReadInt32(); + fileGen = this.reader.ReadInt32(); + uint dataOffset = this.reader.ReadUInt32(); sharedAssetsList[0].fileName = fileName; //reference itself because sharedFileIDs start from 1 switch (fileGen) { case 6: //2.5.0 - 2.6.1 { - assetsFileReader.Position = (dataEnd - tableSize); - assetsFileReader.Position += 1; + this.reader.Position = (dataEnd - tableSize); + this.reader.Position += 1; break; } case 7: //3.0.0 beta { - assetsFileReader.Position = (dataEnd - tableSize); - assetsFileReader.Position += 1; - m_Version = assetsFileReader.ReadStringToNull(); + this.reader.Position = (dataEnd - tableSize); + this.reader.Position += 1; + m_Version = this.reader.ReadStringToNull(); break; } case 8: //3.0.0 - 3.4.2 { - assetsFileReader.Position = (dataEnd - tableSize); - assetsFileReader.Position += 1; - m_Version = assetsFileReader.ReadStringToNull(); - platform = assetsFileReader.ReadInt32(); + this.reader.Position = (dataEnd - tableSize); + this.reader.Position += 1; + m_Version = this.reader.ReadStringToNull(); + platform = this.reader.ReadInt32(); break; } case 9: //3.5.0 - 4.6.x { - assetsFileReader.Position += 4; //azero - m_Version = assetsFileReader.ReadStringToNull(); - platform = assetsFileReader.ReadInt32(); + this.reader.Position += 4; //azero + m_Version = this.reader.ReadStringToNull(); + platform = this.reader.ReadInt32(); break; } case 14: //5.0.0 beta and final @@ -198,10 +198,10 @@ namespace AssetStudio case 16: //??.. no sure case 17: //5.5.0 and up { - assetsFileReader.Position += 4; //azero - m_Version = assetsFileReader.ReadStringToNull(); - platform = assetsFileReader.ReadInt32(); - baseDefinitions = assetsFileReader.ReadBoolean(); + this.reader.Position += 4; //azero + m_Version = this.reader.ReadStringToNull(); + platform = this.reader.ReadInt32(); + baseDefinitions = this.reader.ReadBoolean(); break; } default: @@ -216,21 +216,21 @@ namespace AssetStudio byte[] b32 = BitConverter.GetBytes(platform); Array.Reverse(b32); platform = BitConverter.ToInt32(b32, 0); - assetsFileReader.endian = EndianType.LittleEndian; + this.reader.endian = EndianType.LittleEndian; } platformStr = Enum.IsDefined(typeof(BuildTarget), platform) ? ((BuildTarget)platform).ToString() : "Unknown Platform"; - int baseCount = assetsFileReader.ReadInt32(); + int baseCount = this.reader.ReadInt32(); for (int i = 0; i < baseCount; i++) { if (fileGen < 14) { - int classID = assetsFileReader.ReadInt32(); - string baseType = assetsFileReader.ReadStringToNull(); - string baseName = assetsFileReader.ReadStringToNull(); - assetsFileReader.Position += 20; - int memberCount = assetsFileReader.ReadInt32(); + int classID = this.reader.ReadInt32(); + string baseType = this.reader.ReadStringToNull(); + string baseName = this.reader.ReadStringToNull(); + this.reader.Position += 20; + int memberCount = this.reader.ReadInt32(); var cb = new List(); for (int m = 0; m < memberCount; m++) @@ -250,10 +250,10 @@ namespace AssetStudio if (fileGen >= 7 && fileGen < 14) { - assetsFileReader.Position += 4; //azero + this.reader.Position += 4; //azero } - int assetCount = assetsFileReader.ReadInt32(); + int assetCount = this.reader.ReadInt32(); #region asset preload table string assetIDfmt = "D" + assetCount.ToString().Length; //format for unique ID @@ -263,29 +263,29 @@ namespace AssetStudio //each table entry is aligned individually, not the whole table if (fileGen >= 14) { - assetsFileReader.AlignStream(4); + this.reader.AlignStream(4); } AssetPreloadData asset = new AssetPreloadData(); - asset.m_PathID = fileGen < 14 ? assetsFileReader.ReadInt32() : assetsFileReader.ReadInt64(); - asset.Offset = assetsFileReader.ReadUInt32(); + asset.m_PathID = fileGen < 14 ? this.reader.ReadInt32() : this.reader.ReadInt64(); + asset.Offset = this.reader.ReadUInt32(); asset.Offset += dataOffset; - asset.Size = assetsFileReader.ReadInt32(); + asset.Size = this.reader.ReadInt32(); if (fileGen > 15) { - int index = assetsFileReader.ReadInt32(); + int index = this.reader.ReadInt32(); asset.Type1 = classIDs[index][0]; asset.Type2 = classIDs[index][1]; } else { - asset.Type1 = assetsFileReader.ReadInt32(); - asset.Type2 = assetsFileReader.ReadUInt16(); - assetsFileReader.Position += 2; + asset.Type1 = this.reader.ReadInt32(); + asset.Type2 = this.reader.ReadUInt16(); + this.reader.Position += 2; } if (fileGen == 15) { - byte unknownByte = assetsFileReader.ReadByte(); + byte unknownByte = this.reader.ReadByte(); //this is a single byte, not an int32 //the next entry is aligned after this //but not the last! @@ -312,45 +312,46 @@ namespace AssetStudio #region read BuildSettings to get version for version 2.x files if (asset.Type == ClassIDReference.BuildSettings && fileGen == 6) { - long nextAsset = assetsFileReader.Position; + long nextAsset = this.reader.Position; BuildSettings BSettings = new BuildSettings(asset); m_Version = BSettings.m_Version; - assetsFileReader.Position = nextAsset; + this.reader.Position = nextAsset; } #endregion } #endregion buildType = Regex.Replace(m_Version, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries); + var firstVersion = int.Parse(m_Version.Split('.')[0]); version = Regex.Matches(m_Version, @"\d").Cast().Select(m => int.Parse(m.Value)).ToArray(); - if (version[0] == 2 && version[1] == 0 && version[2] == 1 && version[3] == 7)//2017.x + if (firstVersion > 5)//2017 and up { var nversion = new int[version.Length - 3]; - nversion[0] = 2017; + nversion[0] = firstVersion; Array.Copy(version, 4, nversion, 1, version.Length - 4); version = nversion; } if (fileGen >= 14) { //this looks like a list of assets that need to be preloaded in memory before anytihng else - int someCount = assetsFileReader.ReadInt32(); + int someCount = this.reader.ReadInt32(); for (int i = 0; i < someCount; i++) { - int num1 = assetsFileReader.ReadInt32(); - assetsFileReader.AlignStream(4); - long m_PathID = assetsFileReader.ReadInt64(); + int num1 = this.reader.ReadInt32(); + this.reader.AlignStream(4); + long m_PathID = this.reader.ReadInt64(); } } - int sharedFileCount = assetsFileReader.ReadInt32(); + int sharedFileCount = this.reader.ReadInt32(); for (int i = 0; i < sharedFileCount; i++) { var shared = new SharedAssets(); - shared.aName = assetsFileReader.ReadStringToNull(); - assetsFileReader.Position += 20; - var sharedFilePath = assetsFileReader.ReadStringToNull(); //relative path + shared.aName = this.reader.ReadStringToNull(); + this.reader.Position += 20; + var sharedFilePath = this.reader.ReadStringToNull(); //relative path shared.fileName = Path.GetFileName(sharedFilePath); sharedAssetsList.Add(shared); } @@ -363,14 +364,14 @@ namespace AssetStudio private void readBase(List cb, int level) { - string varType = assetsFileReader.ReadStringToNull(); - string varName = assetsFileReader.ReadStringToNull(); - int size = assetsFileReader.ReadInt32(); - int index = assetsFileReader.ReadInt32(); - int isArray = assetsFileReader.ReadInt32(); - int num0 = assetsFileReader.ReadInt32(); - int flag = assetsFileReader.ReadInt32(); - int childrenCount = assetsFileReader.ReadInt32(); + string varType = reader.ReadStringToNull(); + string varName = reader.ReadStringToNull(); + int size = reader.ReadInt32(); + int index = reader.ReadInt32(); + int isArray = reader.ReadInt32(); + int num0 = reader.ReadInt32(); + int flag = reader.ReadInt32(); + int childrenCount = reader.ReadInt32(); cb.Add(new ClassMember { @@ -385,12 +386,12 @@ namespace AssetStudio private void readBase5() { - int classID = assetsFileReader.ReadInt32(); + int classID = reader.ReadInt32(); if (fileGen > 15)//5.5.0 and up { - assetsFileReader.ReadByte(); + reader.ReadByte(); int type1; - if ((type1 = assetsFileReader.ReadInt16()) >= 0) + if ((type1 = reader.ReadInt16()) >= 0) { type1 = -1 - type1; } @@ -401,36 +402,36 @@ namespace AssetStudio classIDs.Add(new[] { type1, classID }); if (classID == 114) { - assetsFileReader.Position += 16; + reader.Position += 16; } classID = type1; } else if (classID < 0) { - assetsFileReader.Position += 16; + reader.Position += 16; } - assetsFileReader.Position += 16; + reader.Position += 16; if (baseDefinitions) { - int varCount = assetsFileReader.ReadInt32(); - int stringSize = assetsFileReader.ReadInt32(); + int varCount = reader.ReadInt32(); + int stringSize = reader.ReadInt32(); - assetsFileReader.Position += varCount * 24; - using (var stringReader = new BinaryReader(new MemoryStream(assetsFileReader.ReadBytes(stringSize)))) + reader.Position += varCount * 24; + using (var stringReader = new BinaryReader(new MemoryStream(reader.ReadBytes(stringSize)))) { string className = ""; var classVar = new List(); //build Class Structures - assetsFileReader.Position -= varCount * 24 + stringSize; + reader.Position -= varCount * 24 + stringSize; for (int i = 0; i < varCount; i++) { - ushort num0 = assetsFileReader.ReadUInt16(); - byte level = assetsFileReader.ReadByte(); - bool isArray = assetsFileReader.ReadBoolean(); + ushort num0 = reader.ReadUInt16(); + byte level = reader.ReadByte(); + bool isArray = reader.ReadBoolean(); - ushort varTypeIndex = assetsFileReader.ReadUInt16(); - ushort test = assetsFileReader.ReadUInt16(); + ushort varTypeIndex = reader.ReadUInt16(); + ushort test = reader.ReadUInt16(); string varTypeStr; if (test == 0) //varType is an offset in the string block { @@ -442,8 +443,8 @@ namespace AssetStudio varTypeStr = baseStrings.ContainsKey(varTypeIndex) ? baseStrings[varTypeIndex] : varTypeIndex.ToString(); } - ushort varNameIndex = assetsFileReader.ReadUInt16(); - test = assetsFileReader.ReadUInt16(); + ushort varNameIndex = reader.ReadUInt16(); + test = reader.ReadUInt16(); string varNameStr; if (test == 0) { @@ -455,9 +456,9 @@ namespace AssetStudio varNameStr = baseStrings.ContainsKey(varNameIndex) ? baseStrings[varNameIndex] : varNameIndex.ToString(); } - int size = assetsFileReader.ReadInt32(); - int index = assetsFileReader.ReadInt32(); - int flag = assetsFileReader.ReadInt32(); + int size = reader.ReadInt32(); + int index = reader.ReadInt32(); + int flag = reader.ReadInt32(); if (index == 0) { @@ -475,7 +476,7 @@ namespace AssetStudio }); } } - assetsFileReader.Position += stringSize; + reader.Position += stringSize; var aClass = new ClassStruct { ID = classID, Text = className, members = classVar }; aClass.SubItems.Add(classID.ToString()); ClassStructures[classID] = aClass; diff --git a/AssetStudio/StudioClasses/Importer.cs b/AssetStudio/StudioClasses/Importer.cs index a066f19..659bfad 100644 --- a/AssetStudio/StudioClasses/Importer.cs +++ b/AssetStudio/StudioClasses/Importer.cs @@ -125,7 +125,7 @@ namespace AssetStudio } else { - resourceFileReaders.Add(assetsFile.upperFileName, assetsFile.assetsFileReader); + resourceFileReaders.Add(assetsFile.upperFileName, assetsFile.reader); } } } diff --git a/AssetStudio/StudioClasses/PPtrHelpers.cs b/AssetStudio/StudioClasses/PPtrHelpers.cs index a574b7d..48e9cd3 100644 --- a/AssetStudio/StudioClasses/PPtrHelpers.cs +++ b/AssetStudio/StudioClasses/PPtrHelpers.cs @@ -19,7 +19,7 @@ namespace AssetStudio public static PPtr ReadPPtr(this AssetsFile sourceFile) { var result = new PPtr(); - var reader = sourceFile.assetsFileReader; + var reader = sourceFile.reader; int FileID = reader.ReadInt32(); if (FileID >= 0 && FileID < sourceFile.sharedAssetsList.Count) diff --git a/AssetStudio/StudioClasses/Studio.cs b/AssetStudio/StudioClasses/Studio.cs index e5355ad..5be7ed0 100644 --- a/AssetStudio/StudioClasses/Studio.cs +++ b/AssetStudio/StudioClasses/Studio.cs @@ -273,7 +273,7 @@ namespace AssetStudio case ClassIDReference.AnimationClip: { exportable = true; - var reader = asset.sourceFile.assetsFileReader; + var reader = asset.sourceFile.reader; reader.Position = asset.Offset; asset.Text = reader.ReadAlignedString(); break; @@ -316,7 +316,7 @@ namespace AssetStudio exportableAssets.AddRange(assetsFile.exportableAssets); } - visibleAssets = exportableAssets.ToList(); + visibleAssets = exportableAssets; exportableAssetsHash.Clear(); } #endregion @@ -619,12 +619,21 @@ namespace AssetStudio //导出FBX StatusStripUpdate($"Exporting {filename}.fbx"); if (isNew) - ExportGameObject((GameObject)j, targetPath); + { + try + { + ExportGameObject((GameObject)j, targetPath); + } + catch (Exception ex) + { + MessageBox.Show($"{ex.Message}\r\n{ex.StackTrace}"); + } + } else FBXExporter.WriteFBX($"{targetPath}{filename}.fbx", gameObjects); StatusStripUpdate($"Finished exporting {filename}.fbx"); + ProgressBarPerformStep(); } - ProgressBarPerformStep(); } }); }