diff --git a/PCK-Studio/Extensions/PckAssetExtensions.cs b/PCK-Studio/Extensions/PckAssetExtensions.cs index afeee3a9..6e61a707 100644 --- a/PCK-Studio/Extensions/PckAssetExtensions.cs +++ b/PCK-Studio/Extensions/PckAssetExtensions.cs @@ -94,9 +94,9 @@ namespace PckStudio.Extensions if (asset.Type != PckAssetType.SkinFile) throw new InvalidOperationException("Asset is not a skin file"); - asset.SetTexture(skin.Model.Texture); + asset.SetTexture(skin.Texture); - string skinId = skin.MetaData.Id.ToString("d08"); + string skinId = skin.Identifier.ToString("d08"); // TODO: keep filepath asset.Filename = $"dlcskin{skinId}.png"; @@ -118,7 +118,7 @@ namespace PckStudio.Extensions asset.SetProperty("CAPEPATH", $"dlccape{skinId}.png"); } - asset.SetProperty("ANIM", skin.Model.ANIM.ToString()); + asset.SetProperty("ANIM", skin.ANIM.ToString()); asset.SetProperty("GAME_FLAGS", "0x18"); asset.SetProperty("FREE", "1"); diff --git a/PCK-Studio/Extensions/SkinExtensions.cs b/PCK-Studio/Extensions/SkinExtensions.cs index 4f17b689..08c74ee0 100644 --- a/PCK-Studio/Extensions/SkinExtensions.cs +++ b/PCK-Studio/Extensions/SkinExtensions.cs @@ -15,7 +15,7 @@ namespace PckStudio.Extensions { public static PckAsset CreateFile(this Skin skin, LOCFile localizationFile) { - string skinId = skin.MetaData.Id.ToString("d08"); + string skinId = skin.Identifier.ToString("d08"); PckAsset skinFile = new PckAsset($"dlcskin{skinId}.png", PckAssetType.SkinFile); skinFile.AddProperty("DISPLAYNAME", skin.MetaData.Name); @@ -41,7 +41,7 @@ namespace PckStudio.Extensions skinFile.AddProperty("CAPEPATH", $"dlccape{skinId}.png"); } - skinFile.AddProperty("ANIM", skin.Model.ANIM); + skinFile.AddProperty("ANIM", skin.ANIM); skinFile.AddProperty("GAME_FLAGS", "0x18"); skinFile.AddProperty("FREE", "1"); @@ -54,7 +54,7 @@ namespace PckStudio.Extensions skinFile.AddProperty(offset.ToProperty()); } - skinFile.SetTexture(skin.Model.Texture); + skinFile.SetTexture(skin.Texture); return skinFile; } @@ -63,7 +63,7 @@ namespace PckStudio.Extensions { if (!skin.HasCape) throw new InvalidOperationException("Skin does not contain a cape."); - string skinId = skin.MetaData.Id.ToString("d08"); + string skinId = skin.Identifier.ToString("d08"); PckAsset capeFile = new PckAsset($"dlccape{skinId}.png", PckAssetType.CapeFile); capeFile.SetTexture(skin.CapeTexture); return capeFile; diff --git a/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.cs b/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.cs index b5351f04..b03ee595 100644 --- a/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.cs +++ b/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.cs @@ -33,18 +33,16 @@ namespace PckStudio.Forms.Additional_Popups private void SetNewTexture(Image img) { - if (img is null) - { - Debug.Assert(false, "Image is null."); - } + Debug.Assert(img is not null, "Image is null."); + if (img.Width != img.Height && img.Height != img.Width / 2) { MessageBox.Show("The selected image does not suit a skin texture.", "Invalid image dimensions.", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } - newSkin.Model.ANIM.SetFlag(SkinAnimFlag.RESOLUTION_64x64, img.Width == img.Height); + newSkin.ANIM.SetFlag(SkinAnimFlag.RESOLUTION_64x64, img.Width == img.Height); - skinPictureBox.Image = newSkin.Model.Texture = img; + skinPictureBox.Image = newSkin.Texture = img; labelSelectTexture.Visible = false; capePictureBox.Visible = true; buttonCape.Visible = true; @@ -55,43 +53,43 @@ namespace PckStudio.Forms.Additional_Popups private void DrawModel() { - bool isSlim = newSkin.Model.ANIM.GetFlag(SkinAnimFlag.SLIM_MODEL); + bool isSlim = newSkin.ANIM.GetFlag(SkinAnimFlag.SLIM_MODEL); Pen outlineColor = Pens.LightGray; Brush fillColor = Brushes.Gray; Image previewTexture = new Bitmap(displayBox.Width, displayBox.Height); using (Graphics g = Graphics.FromImage(previewTexture)) { - if(!newSkin.Model.ANIM.GetFlag(SkinAnimFlag.HEAD_DISABLED)) + if(!newSkin.ANIM.GetFlag(SkinAnimFlag.HEAD_DISABLED)) { //Head g.DrawRectangle(outlineColor, 70, 15, 40, 40); g.FillRectangle(fillColor, 71, 16, 39, 39); } - if (!newSkin.Model.ANIM.GetFlag(SkinAnimFlag.BODY_DISABLED)) + if (!newSkin.ANIM.GetFlag(SkinAnimFlag.BODY_DISABLED)) { //Body g.DrawRectangle(outlineColor, 70, 55, 40, 60); g.FillRectangle(fillColor, 71, 56, 39, 59); } - if (!newSkin.Model.ANIM.GetFlag(SkinAnimFlag.RIGHT_ARM_DISABLED)) + if (!newSkin.ANIM.GetFlag(SkinAnimFlag.RIGHT_ARM_DISABLED)) { //Arm0 g.DrawRectangle(outlineColor, isSlim ? 55 : 50, 55, isSlim ? 15 : 20, 60); g.FillRectangle(fillColor , isSlim ? 56 : 51, 56, isSlim ? 14 : 19, 59); } - if (!newSkin.Model.ANIM.GetFlag(SkinAnimFlag.LEFT_ARM_DISABLED)) + if (!newSkin.ANIM.GetFlag(SkinAnimFlag.LEFT_ARM_DISABLED)) { //Arm1 g.DrawRectangle(outlineColor, 110, 55, isSlim ? 15 : 20, 60); g.FillRectangle(fillColor, 111, 56, isSlim ? 14 : 19, 59); } - if (!newSkin.Model.ANIM.GetFlag(SkinAnimFlag.RIGHT_LEG_DISABLED)) + if (!newSkin.ANIM.GetFlag(SkinAnimFlag.RIGHT_LEG_DISABLED)) { //Leg0 g.DrawRectangle(outlineColor, 70, 115, 20, 60); g.FillRectangle(fillColor, 71, 116, 19, 59); } - if (!newSkin.Model.ANIM.GetFlag(SkinAnimFlag.LEFT_LEG_DISABLED)) + if (!newSkin.ANIM.GetFlag(SkinAnimFlag.LEFT_LEG_DISABLED)) { //Leg1 g.DrawRectangle(outlineColor, 90, 115, 20, 60); @@ -157,7 +155,7 @@ namespace PckStudio.Forms.Additional_Popups return; } - var img = Image.FromFile(ofd.FileName).ReleaseFromFile(); + Image img = Image.FromFile(ofd.FileName).ReleaseFromFile(); SetNewTexture(img); } } @@ -184,7 +182,7 @@ namespace PckStudio.Forms.Additional_Popups ofd.Title = "Select a PNG File"; if (ofd.ShowDialog() == DialogResult.OK) { - var img = Image.FromFile(ofd.FileName).ReleaseFromFile(); + Image img = Image.FromFile(ofd.FileName).ReleaseFromFile(); if (img.RawFormat != ImageFormat.Png && img.Width != img.Height * 2) { MessageBox.Show(this, "Not a Valid Cape File"); @@ -207,7 +205,7 @@ namespace PckStudio.Forms.Additional_Popups MessageBox.Show("The Skin Id must be a unique 8 digit number that is not already in use", "Invalid Skin Id", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } - newSkin.MetaData.Id = _skinId; + newSkin.Identifier = new SkinIdentifier(_skinId); } newSkin.MetaData.Name = textSkinName.Text; newSkin.MetaData.Theme = textThemeName.Text; @@ -232,7 +230,7 @@ namespace PckStudio.Forms.Additional_Popups if (customSkinEditor.ShowDialog() == DialogResult.OK) { - skinPictureBox.Image = customSkinEditor.ResultSkin.Model.Texture; + skinPictureBox.Image = customSkinEditor.ResultSkin.Texture; newSkin = customSkinEditor.ResultSkin; buttonDone.Enabled = true; labelSelectTexture.Visible = false; @@ -244,8 +242,8 @@ namespace PckStudio.Forms.Additional_Popups { if (radioButtonAuto.Checked) { - newSkin.MetaData.Id = rng.Next(100000, 99999999); - textSkinID.Text = newSkin.MetaData.Id.ToString(); + newSkin.Identifier = new(rng.Next(100000, 99999999)); + textSkinID.Text = newSkin.Identifier.ToString(); textSkinID.Enabled = false; } } @@ -257,10 +255,10 @@ namespace PckStudio.Forms.Additional_Popups private void buttonAnimGen_Click(object sender, EventArgs e) { - using ANIMEditor diag = new ANIMEditor(newSkin.Model.ANIM); + using ANIMEditor diag = new ANIMEditor(newSkin.ANIM); if (diag.ShowDialog(this) == DialogResult.OK) { - newSkin.Model.ANIM = diag.ResultAnim; + newSkin.ANIM = diag.ResultAnim; DrawModel(); } } diff --git a/PCK-Studio/Forms/Editor/CustomSkinEditor.cs b/PCK-Studio/Forms/Editor/CustomSkinEditor.cs index b3d640f9..d9d738c6 100644 --- a/PCK-Studio/Forms/Editor/CustomSkinEditor.cs +++ b/PCK-Studio/Forms/Editor/CustomSkinEditor.cs @@ -74,10 +74,10 @@ namespace PckStudio.Forms.Editor { if (keyData == Keys.A) { - using var animeditor = new ANIMEditor(_skin.Model.ANIM); + using var animeditor = new ANIMEditor(_skin.ANIM); if (animeditor.ShowDialog() == DialogResult.OK) { - renderer3D1.ANIM = _skin.Model.ANIM = animeditor.ResultAnim; + renderer3D1.ANIM = _skin.ANIM = animeditor.ResultAnim; skinPartListBox_SelectedIndexChanged(this, EventArgs.Empty); } return true; @@ -87,12 +87,12 @@ namespace PckStudio.Forms.Editor private void LoadModelData() { - SkinModelInfo modelInfo = _skin.Model; + SkinModel modelInfo = _skin.Model; List boxProperties = modelInfo.AdditionalBoxes; List offsetProperties = modelInfo.PartOffsets; - renderer3D1.ANIM = modelInfo.ANIM; + renderer3D1.ANIM = _skin.ANIM; renderer3D1.ModelData.Clear(); foreach (SkinBOX box in boxProperties) @@ -105,14 +105,14 @@ namespace PckStudio.Forms.Editor renderer3D1.SetPartOffset(offset); } - if (modelInfo.Texture is not null) + if (_skin.Texture is not null) { - renderer3D1.Texture = modelInfo.Texture; + renderer3D1.Texture = _skin.Texture; } - if (modelInfo.Texture is null && renderer3D1.Texture is not null) + if (_skin.Texture is null && renderer3D1.Texture is not null) { - modelInfo.Texture = renderer3D1.Texture; + _skin.Texture = renderer3D1.Texture; } skinOffsetListBindingSource = new BindingSource(renderer3D1.GetOffsets().ToArray(), null); @@ -126,12 +126,12 @@ namespace PckStudio.Forms.Editor private void GenerateUVTextureMap(SkinBOX skinBox) { - if (_skin?.Model?.Texture is null) + if (_skin?.Texture is null) { Trace.TraceWarning($"[{nameof(CustomSkinEditor)}@{nameof(GenerateUVTextureMap)}] Failed to generate uv for {skinBox}. Reason: Model.Texture was null"); return; } - using (Graphics graphics = Graphics.FromImage(_skin.Model.Texture)) + using (Graphics graphics = Graphics.FromImage(_skin.Texture)) { graphics.ApplyConfig(_graphicsConfig); int argb = rng.Next(unchecked((int)0xFF000000), -1); @@ -139,7 +139,7 @@ namespace PckStudio.Forms.Editor Brush brush = new SolidBrush(color); graphics.FillPath(brush, skinBox.GetUVGraphicsPath()); } - renderer3D1.Texture = _skin.Model.Texture; + renderer3D1.Texture = _skin.Texture; } private void createToolStripMenuItem_Click(object sender, EventArgs e) @@ -158,7 +158,7 @@ namespace PckStudio.Forms.Editor private void exportTextureButton_Click(object sender, EventArgs e) { - if (_skin?.Model?.Texture is null) + if (_skin?.Texture is null) { Trace.TraceWarning($"[{nameof(CustomSkinEditor)}@{nameof(exportTextureButton_Click)}] Failed to export texture. Reason: skin.Model.Texture was null"); return; @@ -167,7 +167,7 @@ namespace PckStudio.Forms.Editor saveFileDialog.Filter = "PNG Image Files | *.png"; if (saveFileDialog.ShowDialog() == DialogResult.OK) { - _skin.Model.Texture.Save(saveFileDialog.FileName, ImageFormat.Png); + _skin.Texture.Save(saveFileDialog.FileName, ImageFormat.Png); } } @@ -191,7 +191,7 @@ namespace PckStudio.Forms.Editor _skin.Model.PartOffsets.Clear(); _skin.Model.PartOffsets.AddRange(renderer3D1.GetOffsets()); // just in case they're not the same instance - _skin.Model.ANIM = renderer3D1.ANIM; + _skin.ANIM = renderer3D1.ANIM; DialogResult = DialogResult.OK; } @@ -202,7 +202,7 @@ namespace PckStudio.Forms.Editor saveFileDialog.Filter = SkinModelImporter.Default.SupportedModelFileFormatsFilter; saveFileDialog.FileName = _skin.MetaData.Name.TrimEnd(new char[] { '\n', '\r' }).Replace(' ', '_'); if (saveFileDialog.ShowDialog() == DialogResult.OK) - SkinModelImporter.Default.Export(saveFileDialog.FileName, _skin.Model); + SkinModelImporter.Default.Export(saveFileDialog.FileName, _skin.GetModelInfo()); } private void importSkinButton_Click(object sender, EventArgs e) @@ -215,7 +215,7 @@ namespace PckStudio.Forms.Editor SkinModelInfo modelInfo = SkinModelImporter.Default.Import(openFileDialog.FileName); if (modelInfo is not null) { - _skin.Model = modelInfo; + _skin.SetModelInfo(modelInfo); LoadModelData(); } } @@ -268,7 +268,7 @@ namespace PckStudio.Forms.Editor MessageBox.Show("The selected image does not suit a skin texture.", "Invalid image dimensions.", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } - uvPictureBox.Image = _skin.Model.Texture = texture; + uvPictureBox.Image = _skin.Texture = texture; textureSizeLabel.Text = $"{texture.Width}x{texture.Height}"; } @@ -296,7 +296,7 @@ namespace PckStudio.Forms.Editor sizeLabel.Text = $"Size: {box.Size}"; positionLabel.Text = $"Position: {box.Pos}"; - Image uvArea = _skin.Model.Texture.GetArea(Rectangle.Truncate(new RectangleF(box.UV.X, box.UV.Y, box.Size.X * 2 + box.Size.Z * 2, box.Size.Z + box.Size.Y))); + Image uvArea = _skin.Texture.GetArea(Rectangle.Truncate(new RectangleF(box.UV.X, box.UV.Y, box.Size.X * 2 + box.Size.Z * 2, box.Size.Z + box.Size.Y))); Bitmap refImg = new Bitmap(1, 1); @@ -309,14 +309,14 @@ namespace PckStudio.Forms.Editor Color avgColor = refImg.GetPixel(0, 0); renderer3D1.HighlightlingColor = avgColor.Inversed(); - Size scaleSize = new Size(_skin.Model.Texture.Width * scale, _skin.Model.Texture.Height * scale); + Size scaleSize = new Size(_skin.Texture.Width * scale, _skin.Texture.Height * scale); uvPictureBox.Image = new Bitmap(scaleSize.Width, scaleSize.Height); using (Graphics g = Graphics.FromImage(uvPictureBox.Image)) { GraphicsPath graphicsPath = box.GetUVGraphicsPath(new System.Numerics.Vector2(scaleSize.Width * renderer3D1.TillingFactor.X, scaleSize.Height * renderer3D1.TillingFactor.Y)); var brush = new SolidBrush(Color.FromArgb(127, avgColor.GreyScaled())); g.ApplyConfig(_graphicsConfig); - g.DrawImage(_skin.Model.Texture, new Rectangle(Point.Empty, scaleSize), new Rectangle(Point.Empty, _skin.Model.Texture.Size), GraphicsUnit.Pixel); + g.DrawImage(_skin.Texture, new Rectangle(Point.Empty, scaleSize), new Rectangle(Point.Empty, _skin.Texture.Size), GraphicsUnit.Pixel); g.FillPath(brush, graphicsPath); } uvPictureBox.Invalidate(); @@ -410,7 +410,7 @@ namespace PckStudio.Forms.Editor private void ClearSelection() { skinPartListBox.ClearSelected(); - uvPictureBox.Image = _skin.Model.Texture; + uvPictureBox.Image = _skin.Texture; } @@ -451,7 +451,7 @@ namespace PckStudio.Forms.Editor saveFileDialog.FileName = templateFilename.TrimEnd(new char[] { '\n', '\r' }).Replace(' ', '_'); if (saveFileDialog.ShowDialog() == DialogResult.OK) { - SkinModelInfo modelInfo = new SkinModelInfo(templateTexture, new SkinANIM(templateAnimMask)); + SkinModelInfo modelInfo = new SkinModelInfo(templateTexture, templateAnimMask, new SkinModel()); SkinModelImporter.Default.Export(saveFileDialog.FileName, modelInfo); } } diff --git a/PCK-Studio/Internal/FileFormats/PSMFile.cs b/PCK-Studio/Internal/FileFormats/PSMFile.cs index 1a0f2088..314e9b0d 100644 --- a/PCK-Studio/Internal/FileFormats/PSMFile.cs +++ b/PCK-Studio/Internal/FileFormats/PSMFile.cs @@ -49,15 +49,6 @@ namespace PckStudio.Internal.FileFormats public readonly List Parts = new List(); public readonly List Offsets = new List(); - - public static PSMFile FromSkin(SkinModelInfo skin) - { - var csmb = new PSMFile(1); - csmb.SkinANIM = skin.ANIM; - csmb.Parts.AddRange(skin.AdditionalBoxes); - csmb.Offsets.AddRange(skin.PartOffsets); - return csmb; - } } public enum PSMOffsetType : byte diff --git a/PCK-Studio/Internal/Skin/Skin.cs b/PCK-Studio/Internal/Skin/Skin.cs index d123a820..b19cb71a 100644 --- a/PCK-Studio/Internal/Skin/Skin.cs +++ b/PCK-Studio/Internal/Skin/Skin.cs @@ -10,8 +10,17 @@ namespace PckStudio.Internal.Skin public sealed class Skin { public SkinMetaData MetaData { get; set; } - public SkinModelInfo Model { get; set; } + + public SkinIdentifier Identifier { get; set; } + + public SkinANIM ANIM { get; set; } + + public SkinModel Model { get; set; } + + public Image Texture { get; set; } + public Image CapeTexture { get; set; } + public bool HasCape => CapeTexture is not null; public Skin(string name, Image texture) @@ -19,9 +28,9 @@ namespace PckStudio.Internal.Skin MetaData = new SkinMetaData() { Name = name, - Id = 0, }; - Model = new SkinModelInfo(texture); + Texture = texture; + Model = new SkinModel(); } public Skin(string name, Image texture, Image capeTexture) @@ -35,14 +44,22 @@ namespace PckStudio.Internal.Skin { Model.AdditionalBoxes.AddRange(additionalBoxes); Model.PartOffsets.AddRange(partOffsets); - Model.ANIM = anim; + ANIM = anim; } internal Skin(string name, int id, Image texture, SkinANIM anim, IEnumerable additionalBoxes, IEnumerable partOffsets) : this(name, anim, texture, additionalBoxes, partOffsets) { - MetaData.Id = id; + Identifier = new(id); } + internal SkinModelInfo GetModelInfo() => new SkinModelInfo(Texture, ANIM, Model); + + internal void SetModelInfo(SkinModelInfo modelInfo) + { + Texture = modelInfo.Texture; + ANIM = modelInfo.Anim; + Model = modelInfo.Model; + } } } diff --git a/PCK-Studio/Internal/Skin/SkinMetaData.cs b/PCK-Studio/Internal/Skin/SkinMetaData.cs index 64ec92d1..c3df8276 100644 --- a/PCK-Studio/Internal/Skin/SkinMetaData.cs +++ b/PCK-Studio/Internal/Skin/SkinMetaData.cs @@ -4,6 +4,5 @@ { public string Name { get; set; } public string Theme { get; set; } - public int Id { get; set; } } } diff --git a/PCK-Studio/Internal/Skin/SkinModelInfo.cs b/PCK-Studio/Internal/Skin/SkinModelInfo.cs index 5b00baca..464f4b4d 100644 --- a/PCK-Studio/Internal/Skin/SkinModelInfo.cs +++ b/PCK-Studio/Internal/Skin/SkinModelInfo.cs @@ -3,41 +3,21 @@ using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; -using OMI.Formats.Pck; +using System.Threading.Tasks; namespace PckStudio.Internal.Skin { - public sealed class SkinModelInfo + internal sealed class SkinModelInfo { - public Image Texture { get; set; } - public SkinANIM ANIM { get; set; } - public readonly List AdditionalBoxes; - public readonly List PartOffsets; - - public SkinModelInfo() : this(null) - { - } + public SkinModel Model { get; } + public SkinANIM Anim { get; } + public Image Texture { get; } - public SkinModelInfo(Image texture) - : this(texture, SkinANIM.Empty) + public SkinModelInfo(Image texture, SkinANIM anim, SkinModel model) { Texture = texture; - } - - public SkinModelInfo(Image texture, SkinANIM anim) - { - Texture = texture; - ANIM = anim; - AdditionalBoxes = new List(); - PartOffsets = new List(5); - } - - public SkinModelInfo(Image texture, SkinANIM anim, IEnumerable additionalBoxes, IEnumerable partOffsets) - { - Texture = texture; - ANIM = anim; - AdditionalBoxes = new List(additionalBoxes); - PartOffsets = new List(partOffsets); + Anim = anim; + Model = model; } } } diff --git a/PCK-Studio/Internal/SkinModelImporter.cs b/PCK-Studio/Internal/SkinModelImporter.cs index 1cc3b160..29bf5614 100644 --- a/PCK-Studio/Internal/SkinModelImporter.cs +++ b/PCK-Studio/Internal/SkinModelImporter.cs @@ -51,14 +51,14 @@ namespace PckStudio.Internal { var reader = new PSMFileReader(); PSMFile csmbFile = reader.FromFile(filepath); - return new SkinModelInfo(null, csmbFile.SkinANIM, csmbFile.Parts, csmbFile.Offsets); + return new SkinModelInfo(null, csmbFile.SkinANIM, new(csmbFile.Parts, csmbFile.Offsets)); } internal static void ExportPsm(string filepath, SkinModelInfo modelInfo) { - PSMFile psmFile = new PSMFile(PSMFile.CurrentVersion, modelInfo.ANIM); - psmFile.Parts.AddRange(modelInfo.AdditionalBoxes); - psmFile.Offsets.AddRange(modelInfo.PartOffsets); + PSMFile psmFile = new PSMFile(PSMFile.CurrentVersion, modelInfo.Anim); + psmFile.Parts.AddRange(modelInfo.Model.AdditionalBoxes); + psmFile.Offsets.AddRange(modelInfo.Model.PartOffsets); var writer = new PSMFileWriter(psmFile); writer.WriteToFile(filepath); } @@ -80,22 +80,19 @@ namespace PckStudio.Internal IEnumerable boxes = ReadOutliner(null, blockBenchModel.Outliner, blockBenchModel.Elements); - SkinModelInfo modelInfo = CreateSkinModelInfo(boxes, partOffsets); - + Image texture = null; if (blockBenchModel.Textures.IndexInRange(0)) { - modelInfo.Texture = blockBenchModel.Textures[0]; - modelInfo.Texture = SwapBoxBottomTexture(modelInfo); - modelInfo.ANIM = modelInfo.ANIM.SetFlag(SkinAnimFlag.RESOLUTION_64x64, modelInfo.Texture.Size.Width == modelInfo.Texture.Size.Height); + texture = blockBenchModel.Textures[0]; + texture = SwapBoxBottomTexture(texture, boxes); } - - return modelInfo; + + return CreateSkinModelInfo(texture, boxes, partOffsets); } - private static SkinModelInfo CreateSkinModelInfo(IEnumerable boxes, IEnumerable partOffsets) + private static SkinModelInfo CreateSkinModelInfo(Image texture, IEnumerable boxes, IEnumerable partOffsets) { - SkinModelInfo modelInfo = new SkinModelInfo(); - modelInfo.ANIM = ( + SkinANIM skinANIM = ( SkinAnimMask.HEAD_DISABLED | SkinAnimMask.HEAD_OVERLAY_DISABLED | SkinAnimMask.BODY_DISABLED | @@ -109,11 +106,15 @@ namespace PckStudio.Internal SkinAnimMask.LEFT_LEG_DISABLED | SkinAnimMask.LEFT_LEG_OVERLAY_DISABLED); - modelInfo.PartOffsets.AddRange(partOffsets); + skinANIM = skinANIM.SetFlag(SkinAnimFlag.RESOLUTION_64x64, texture.Size.Width == texture.Size.Height); + + SkinModel skinModel = new SkinModel(); + + skinModel.PartOffsets.AddRange(partOffsets); SkinBOX ApplyOffset(SkinBOX box) { - SkinPartOffset offset = modelInfo.PartOffsets.FirstOrDefault(offset => offset.Type == (box.IsOverlayPart() ? box.GetBaseType() : box.Type)); + SkinPartOffset offset = skinModel.PartOffsets.FirstOrDefault(offset => offset.Type == (box.IsOverlayPart() ? box.GetBaseType() : box.Type)); return string.IsNullOrEmpty(offset.Type) ? box : new SkinBOX(box.Type, box.Pos - (Vector3.UnitY * offset.Value), box.Size, box.UV, box.HideWithArmor, box.Mirror, box.Scale); } @@ -121,7 +122,7 @@ namespace PckStudio.Internal IEnumerable customBoxes = convertedBoxes.Where(box => !SkinBOX.KnownHashes.ContainsKey(box.GetHashCode())); - modelInfo.AdditionalBoxes.AddRange(customBoxes); + skinModel.AdditionalBoxes.AddRange(customBoxes); // check for know boxes and filter them out SkinAnimMask mask = (SkinAnimMask)convertedBoxes @@ -132,9 +133,9 @@ namespace PckStudio.Internal .Aggregate((a, b) => a | b); if (mask != SkinAnimMask.NONE) - modelInfo.ANIM &= ~mask; + skinANIM &= ~mask; - return modelInfo; + return new SkinModelInfo(texture, skinANIM, skinModel); } private static IEnumerable ReadOutliner(string parentName, JArray oulineChildren, IReadOnlyCollection elements) @@ -177,7 +178,7 @@ namespace PckStudio.Internal BlockBenchModel blockBenchModel = BlockBenchModel.Create(BlockBenchFormatInfos.BedrockEntity, Path.GetFileNameWithoutExtension(filepath), new Size(64, exportTexture.Width == exportTexture.Height ? 64 : 32), [exportTexture]); Dictionary outliners = new Dictionary(5); - List elements = new List(modelInfo.AdditionalBoxes.Count); + List elements = new List(modelInfo.Model.AdditionalBoxes.Count); Dictionary offsetLookUp = new Dictionary(5); @@ -185,7 +186,7 @@ namespace PckStudio.Internal { string offsetType = box.IsOverlayPart() ? box.GetBaseType() : box.Type; - Vector3 offset = GetOffsetForPart(offsetType, ref offsetLookUp, modelInfo.PartOffsets); + Vector3 offset = GetOffsetForPart(offsetType, ref offsetLookUp, modelInfo.Model.PartOffsets); if (!outliners.ContainsKey(offsetType)) { outliners.Add(offsetType, new Outline(offsetType) @@ -203,9 +204,9 @@ namespace PckStudio.Internal outliners[offsetType].Children.Add(element.Uuid); } - ANIM2BOX(modelInfo.ANIM, AddElement); + ANIM2BOX(modelInfo.Anim, AddElement); - foreach (SkinBOX box in modelInfo.AdditionalBoxes) + foreach (SkinBOX box in modelInfo.Model.AdditionalBoxes) { AddElement(box); } @@ -272,19 +273,15 @@ namespace PckStudio.Internal (IEnumerable boxes, IEnumerable partOffsets) = LoadGeometry(geometry); - SkinModelInfo modelInfo = CreateSkinModelInfo(boxes, partOffsets); - + Image texture = null; string texturePath = Path.Combine(Path.GetDirectoryName(filepath), Path.GetFileNameWithoutExtension(filepath)) + ".png"; if (File.Exists(texturePath)) { - modelInfo.Texture = Image.FromFile(texturePath).ReleaseFromFile(); - modelInfo.Texture = SwapBoxBottomTexture(modelInfo); + texture = Image.FromFile(texturePath).ReleaseFromFile(); + texture = SwapBoxBottomTexture(texture, boxes); } - if (geometry.Description?.TextureSize.Width == geometry.Description?.TextureSize.Height) - modelInfo.ANIM = modelInfo.ANIM.SetFlag(SkinAnimFlag.RESOLUTION_64x64, true); - - return modelInfo; + return CreateSkinModelInfo(texture, boxes, partOffsets); } private static (IEnumerable boxes, IEnumerable partOffsets) LoadGeometry(Geometry geometry) @@ -327,7 +324,7 @@ namespace PckStudio.Internal { string offsetType = box.IsOverlayPart() ? box.GetBaseType() : box.Type; - Vector3 offset = GetOffsetForPart(offsetType, ref offsetLookUp, modelInfo.PartOffsets); + Vector3 offset = GetOffsetForPart(offsetType, ref offsetLookUp, modelInfo.Model.PartOffsets); if (!bones.ContainsKey(offsetType)) { @@ -351,9 +348,9 @@ namespace PckStudio.Internal }); } - ANIM2BOX(modelInfo.ANIM, AddBone); + ANIM2BOX(modelInfo.Anim, AddBone); - foreach (SkinBOX box in modelInfo.AdditionalBoxes) + foreach (SkinBOX box in modelInfo.Model.AdditionalBoxes) { AddBone(box); } @@ -497,7 +494,12 @@ namespace PckStudio.Internal private static Image SwapBoxBottomTexture(SkinModelInfo modelInfo) { - return SwapTextureAreas(modelInfo.Texture, modelInfo.AdditionalBoxes.Where(box => !(box.Size == Vector3.One || box.Size == Vector3.Zero)).Select(box => + return SwapBoxBottomTexture(modelInfo.Texture, modelInfo.Model.AdditionalBoxes); + } + + private static Image SwapBoxBottomTexture(Image texture, IEnumerable boxes) + { + return SwapTextureAreas(texture, boxes.Where(box => !(box.Size == Vector3.One || box.Size == Vector3.Zero)).Select(box => { var imgPos = Point.Truncate(new PointF(box.UV.X + box.Size.X + box.Size.Z, box.UV.Y)); var area = new RectangleF(imgPos, Size.Truncate(new SizeF(box.Size.X, box.Size.Z))); diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj index 0aa6d7b7..d50b3ebd 100644 --- a/PCK-Studio/PckStudio.csproj +++ b/PCK-Studio/PckStudio.csproj @@ -659,7 +659,7 @@ - +