From bb19dd50192cdd1fff8cb3fd924905c97da62d3b Mon Sep 17 00:00:00 2001 From: VaDiM Date: Wed, 1 Nov 2023 06:34:01 +0300 Subject: [PATCH] Add support for avg sprite without separate alpha tex --- .../Components/Arknights/AkSpriteHelper.cs | 19 ++++++++++++++++++- .../Components/Arknights/AvgSprite.cs | 4 ++-- AssetStudioGUI/AssetStudioGUIForm.Designer.cs | 18 +++++++++--------- AssetStudioGUI/AssetStudioGUIForm.cs | 6 ++---- .../Components/Arknights/AkSpriteHelper.cs | 19 ++++++++++++++++++- .../Components/Arknights/AvgSprite.cs | 4 ++-- 6 files changed, 51 insertions(+), 19 deletions(-) diff --git a/AssetStudioCLI/Components/Arknights/AkSpriteHelper.cs b/AssetStudioCLI/Components/Arknights/AkSpriteHelper.cs index 5d8ef2b..b0d6e2b 100644 --- a/AssetStudioCLI/Components/Arknights/AkSpriteHelper.cs +++ b/AssetStudioCLI/Components/Arknights/AkSpriteHelper.cs @@ -34,7 +34,7 @@ namespace Arknights { if (item.Container.Contains(imgType) && item.Container.Contains($"illust_{m_Sprite.m_Name}_material") && item.Text.Contains("[alpha]")) return (Texture2D)item.Asset; - else if (item.Container.Contains(imgType) && item.Container.Contains(spriteFullName) && item.Text == $"{m_Sprite.m_Name}[alpha]") + if (item.Container.Contains(imgType) && item.Container.Contains(spriteFullName) && item.Text == $"{m_Sprite.m_Name}[alpha]") return (Texture2D)item.Asset; } } @@ -78,6 +78,23 @@ namespace Arknights tex.ApplyRGBMask(alphaTex); return tex; } + else if (m_Sprite.m_RD.texture.TryGet(out m_Texture2D) && avgSprite != null && avgSprite.IsHubParsed) + { + if (!avgSprite.IsFaceSprite) + { + return m_Texture2D.ConvertToImage(true); + } + + var faceImage = m_Texture2D.ConvertToImage(true); + var tex = avgSprite.FullTexture.ConvertToImage(true); + if (faceImage.Size() != avgSprite.FaceSize) + { + faceImage.Mutate(x => x.Resize(new ResizeOptions { Size = avgSprite.FaceSize, Sampler = KnownResamplers.Lanczos3, Mode = ResizeMode.Stretch })); + } + tex.Mutate(x => x.DrawImage(faceImage, location: avgSprite.FacePos, opacity: 1f)); + + return tex; + } else if (m_Sprite.m_RD.texture.TryGet(out m_Texture2D)) { return CutImage(m_Texture2D.ConvertToImage(false), m_Sprite.m_RD.textureRect, m_Sprite.m_RD.downscaleMultiplier); diff --git a/AssetStudioCLI/Components/Arknights/AvgSprite.cs b/AssetStudioCLI/Components/Arknights/AvgSprite.cs index 9f69cad..65d1dcc 100644 --- a/AssetStudioCLI/Components/Arknights/AvgSprite.cs +++ b/AssetStudioCLI/Components/Arknights/AvgSprite.cs @@ -103,14 +103,14 @@ namespace Arknights else { var faceAlphaID = curSpriteData.AlphaTex.m_PathID; - FaceSpriteAlphaTexture = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == faceAlphaID).Asset; + FaceSpriteAlphaTexture = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == faceAlphaID)?.Asset; } var fullTexSpriteID = fullTexSpriteData.Sprite.m_PathID; var fullTexAlphaID = fullTexSpriteData.AlphaTex.m_PathID; var fullTexSprite = (Sprite)Studio.loadedAssetsList.Find(x => x.m_PathID == fullTexSpriteID).Asset; FullTexture = fullTexSprite.m_RD.texture.TryGet(out var fullTex) ? fullTex : null; - FullAlphaTexture = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == fullTexAlphaID).Asset; + FullAlphaTexture = (Texture2D)Studio.loadedAssetsList.Find(x => x.m_PathID == fullTexAlphaID)?.Asset; FacePos = new Point((int)Math.Round(spriteHubData.FacePos.X), (int)Math.Round(spriteHubData.FacePos.Y)); FaceSize = new Size((int)Math.Round(spriteHubData.FaceSize.X), (int)Math.Round(spriteHubData.FaceSize.Y)); IsFaceSprite = assetItem.m_PathID != fullTexSpriteID; diff --git a/AssetStudioGUI/AssetStudioGUIForm.Designer.cs b/AssetStudioGUI/AssetStudioGUIForm.Designer.cs index 0653839..46f952b 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.Designer.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.Designer.cs @@ -251,7 +251,7 @@ // this.displayAll.CheckOnClick = true; this.displayAll.Name = "displayAll"; - this.displayAll.Size = new System.Drawing.Size(265, 22); + this.displayAll.Size = new System.Drawing.Size(252, 22); this.displayAll.Text = "Display all assets"; this.displayAll.ToolTipText = "Check this option will display all types assets. Not extractable assets can expor" + "t the RAW file."; @@ -263,7 +263,7 @@ this.enablePreview.CheckOnClick = true; this.enablePreview.CheckState = System.Windows.Forms.CheckState.Checked; this.enablePreview.Name = "enablePreview"; - this.enablePreview.Size = new System.Drawing.Size(265, 22); + this.enablePreview.Size = new System.Drawing.Size(252, 22); this.enablePreview.Text = "Enable preview"; this.enablePreview.ToolTipText = "Toggle the loading and preview of readable assets, such as images, sounds, text, " + "etc.\r\nDisable preview if you have performance or compatibility issues."; @@ -275,7 +275,7 @@ this.displayInfo.CheckOnClick = true; this.displayInfo.CheckState = System.Windows.Forms.CheckState.Checked; this.displayInfo.Name = "displayInfo"; - this.displayInfo.Size = new System.Drawing.Size(265, 22); + this.displayInfo.Size = new System.Drawing.Size(252, 22); this.displayInfo.Text = "Display asset information"; this.displayInfo.ToolTipText = "Toggle the overlay that shows information about each asset, eg. image size, forma" + "t, audio bitrate, etc."; @@ -284,7 +284,7 @@ // akSeparator1 // this.akSeparator1.Name = "akSeparator1"; - this.akSeparator1.Size = new System.Drawing.Size(262, 6); + this.akSeparator1.Size = new System.Drawing.Size(249, 6); // // akTitleMenuItem // @@ -292,7 +292,7 @@ this.akTitleMenuItem.Enabled = false; this.akTitleMenuItem.Name = "akTitleMenuItem"; this.akTitleMenuItem.ShowShortcutKeys = false; - this.akTitleMenuItem.Size = new System.Drawing.Size(265, 22); + this.akTitleMenuItem.Size = new System.Drawing.Size(252, 22); this.akTitleMenuItem.Text = "Arknights"; // // akFixFaceSpriteNamesToolStripMenuItem @@ -301,7 +301,7 @@ this.akFixFaceSpriteNamesToolStripMenuItem.CheckOnClick = true; this.akFixFaceSpriteNamesToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked; this.akFixFaceSpriteNamesToolStripMenuItem.Name = "akFixFaceSpriteNamesToolStripMenuItem"; - this.akFixFaceSpriteNamesToolStripMenuItem.Size = new System.Drawing.Size(265, 22); + this.akFixFaceSpriteNamesToolStripMenuItem.Size = new System.Drawing.Size(252, 22); this.akFixFaceSpriteNamesToolStripMenuItem.Text = "Fix names of avg character sprites"; this.akFixFaceSpriteNamesToolStripMenuItem.ToolTipText = "Rename face sprites with numeric names to correct ones"; this.akFixFaceSpriteNamesToolStripMenuItem.CheckedChanged += new System.EventHandler(this.akFixFaceSpriteNamesToolStripMenuItem_Check); @@ -321,14 +321,14 @@ // akSeparator2 // this.akSeparator2.Name = "akSeparator2"; - this.akSeparator2.Size = new System.Drawing.Size(262, 6); + this.akSeparator2.Size = new System.Drawing.Size(249, 6); // // toolStripMenuItem14 // this.toolStripMenuItem14.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.specifyUnityVersion}); this.toolStripMenuItem14.Name = "toolStripMenuItem14"; - this.toolStripMenuItem14.Size = new System.Drawing.Size(265, 22); + this.toolStripMenuItem14.Size = new System.Drawing.Size(252, 22); this.toolStripMenuItem14.Text = "Specify Unity version"; // // specifyUnityVersion @@ -342,7 +342,7 @@ // showExpOpt // this.showExpOpt.Name = "showExpOpt"; - this.showExpOpt.Size = new System.Drawing.Size(265, 22); + this.showExpOpt.Size = new System.Drawing.Size(252, 22); this.showExpOpt.Text = "Export options"; this.showExpOpt.Click += new System.EventHandler(this.showExpOpt_Click); // diff --git a/AssetStudioGUI/AssetStudioGUIForm.cs b/AssetStudioGUI/AssetStudioGUIForm.cs index 5f97f0f..5da45fe 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.cs @@ -1284,12 +1284,10 @@ namespace AssetStudioGUI bool isCharAvgSprite = assetItem.Container.Contains("avg/characters"); bool isCharArt = assetItem.Container.Contains("arts/characters"); - if (isCharAvgSprite) - { - avgSprite = new AvgSprite(assetItem); - } if (akUseExternalAlphaToolStripMenuItem.Checked && (isCharAvgSprite || isCharArt)) { + avgSprite = isCharAvgSprite ? new AvgSprite(assetItem) : null; + if (m_Sprite.m_RD.alphaTexture.IsNull) { var charAlphaTex = AkSpriteHelper.TryFindAlphaTex(assetItem, avgSprite, isCharAvgSprite); diff --git a/AssetStudioGUI/Components/Arknights/AkSpriteHelper.cs b/AssetStudioGUI/Components/Arknights/AkSpriteHelper.cs index a7989ff..caebfd7 100644 --- a/AssetStudioGUI/Components/Arknights/AkSpriteHelper.cs +++ b/AssetStudioGUI/Components/Arknights/AkSpriteHelper.cs @@ -35,7 +35,7 @@ namespace Arknights { if (item.Container.Contains(imgType) && item.Container.Contains($"illust_{m_Sprite.m_Name}_material") && item.Text.Contains("[alpha]")) return (Texture2D)item.Asset; - else if (item.Container.Contains(imgType) && item.Container.Contains(spriteFullName) && item.Text == $"{m_Sprite.m_Name}[alpha]") + if (item.Container.Contains(imgType) && item.Container.Contains(spriteFullName) && item.Text == $"{m_Sprite.m_Name}[alpha]") return (Texture2D)item.Asset; } } @@ -82,6 +82,23 @@ namespace Arknights return ImageRender(tex, alphaTex, spriteMaskMode); } + else if (m_Sprite.m_RD.texture.TryGet(out m_Texture2D) && avgSprite != null && avgSprite.IsHubParsed) + { + if (!avgSprite.IsFaceSprite) + { + return m_Texture2D.ConvertToImage(true); + } + + var faceImage = m_Texture2D.ConvertToImage(true); + var tex = avgSprite.FullTexture.ConvertToImage(true); + if (faceImage.Size() != avgSprite.FaceSize) + { + faceImage.Mutate(x => x.Resize(new ResizeOptions {Size = avgSprite.FaceSize, Sampler = KnownResamplers.Lanczos3, Mode = ResizeMode.Stretch})); + } + tex.Mutate(x => x.DrawImage(faceImage, location: avgSprite.FacePos, opacity: 1f)); + + return tex; + } else if (m_Sprite.m_RD.texture.TryGet(out m_Texture2D)) { return CutImage(m_Texture2D.ConvertToImage(false), m_Sprite.m_RD.textureRect, m_Sprite.m_RD.downscaleMultiplier); diff --git a/AssetStudioGUI/Components/Arknights/AvgSprite.cs b/AssetStudioGUI/Components/Arknights/AvgSprite.cs index 2a7e97d..f805019 100644 --- a/AssetStudioGUI/Components/Arknights/AvgSprite.cs +++ b/AssetStudioGUI/Components/Arknights/AvgSprite.cs @@ -103,14 +103,14 @@ namespace Arknights else { var faceAlphaID = curSpriteData.AlphaTex.m_PathID; - FaceSpriteAlphaTexture = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == faceAlphaID).Asset; + FaceSpriteAlphaTexture = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == faceAlphaID)?.Asset; } var fullTexSpriteID = fullTexSpriteData.Sprite.m_PathID; var fullTexAlphaID = fullTexSpriteData.AlphaTex.m_PathID; var fullTexSprite = (Sprite)Studio.exportableAssets.Find(x => x.m_PathID == fullTexSpriteID).Asset; FullTexture = fullTexSprite.m_RD.texture.TryGet(out var fullTex) ? fullTex : null; - FullAlphaTexture = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == fullTexAlphaID).Asset; + FullAlphaTexture = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == fullTexAlphaID)?.Asset; FacePos = new Point((int)Math.Round(spriteHubData.FacePos.X), (int)Math.Round(spriteHubData.FacePos.Y)); FaceSize = new Size((int)Math.Round(spriteHubData.FaceSize.X), (int)Math.Round(spriteHubData.FaceSize.Y)); IsFaceSprite = assetItem.m_PathID != fullTexSpriteID;