From 8955828520b49b3361135e7bff2a4f01df2f5949 Mon Sep 17 00:00:00 2001
From: miku-666 <74728189+NessieHax@users.noreply.github.com>
Date: Fri, 1 Mar 2024 15:19:33 +0100
Subject: [PATCH] SkinRenderer - Add simple single selected box outline
rendering
---
.../Forms/Editor/CustomSkinEditor.Designer.cs | 25 ++--
PCK-Studio/Forms/Editor/CustomSkinEditor.cs | 6 +
PCK-Studio/Forms/Editor/CustomSkinEditor.resx | 132 +++++++++++-------
PCK-Studio/PckStudio.csproj | 1 +
PCK-Studio/Rendering/BoundingBox.cs | 21 +++
PCK-Studio/Rendering/ColorVertex.cs | 5 +
PCK-Studio/Rendering/SceneViewport.cs | 73 ++++++++++
PCK-Studio/Rendering/SkinRenderer.cs | 48 +++++++
8 files changed, 252 insertions(+), 59 deletions(-)
create mode 100644 PCK-Studio/Rendering/BoundingBox.cs
diff --git a/PCK-Studio/Forms/Editor/CustomSkinEditor.Designer.cs b/PCK-Studio/Forms/Editor/CustomSkinEditor.Designer.cs
index 22bdf208..55f32a05 100644
--- a/PCK-Studio/Forms/Editor/CustomSkinEditor.Designer.cs
+++ b/PCK-Studio/Forms/Editor/CustomSkinEditor.Designer.cs
@@ -47,7 +47,7 @@
this.outlineColorButton = new MetroFramework.Controls.MetroButton();
this.generateTextureCheckBox = new MetroFramework.Controls.MetroCheckBox();
this.checkGuide = new MetroFramework.Controls.MetroCheckBox();
- this.checkBoxArmor = new MetroFramework.Controls.MetroCheckBox();
+ this.showArmorCheckbox = new MetroFramework.Controls.MetroCheckBox();
this.SizeXUpDown = new System.Windows.Forms.NumericUpDown();
this.SizeYUpDown = new System.Windows.Forms.NumericUpDown();
this.SizeZUpDown = new System.Windows.Forms.NumericUpDown();
@@ -214,12 +214,13 @@
this.checkGuide.UseSelectable = true;
this.checkGuide.CheckedChanged += new System.EventHandler(this.checkGuide_CheckedChanged);
//
- // checkBoxArmor
+ // showArmorCheckbox
//
- resources.ApplyResources(this.checkBoxArmor, "checkBoxArmor");
- this.checkBoxArmor.Name = "checkBoxArmor";
- this.checkBoxArmor.Theme = MetroFramework.MetroThemeStyle.Dark;
- this.checkBoxArmor.UseSelectable = true;
+ resources.ApplyResources(this.showArmorCheckbox, "showArmorCheckbox");
+ this.showArmorCheckbox.Name = "showArmorCheckbox";
+ this.showArmorCheckbox.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.showArmorCheckbox.UseSelectable = true;
+ this.showArmorCheckbox.CheckedChanged += new System.EventHandler(this.showArmorCheckbox_CheckedChanged);
//
// SizeXUpDown
//
@@ -351,9 +352,9 @@
//
// metroTabControl1
//
- resources.ApplyResources(this.metroTabControl1, "metroTabControl1");
this.metroTabControl1.Controls.Add(this.skinPartsTabPage);
this.metroTabControl1.Controls.Add(this.skinOffsetsTabPage);
+ resources.ApplyResources(this.metroTabControl1, "metroTabControl1");
this.metroTabControl1.Name = "metroTabControl1";
this.metroTabControl1.SelectedIndex = 0;
this.metroTabControl1.Style = MetroFramework.MetroColorStyle.Pink;
@@ -362,8 +363,8 @@
//
// skinPartsTabPage
//
- resources.ApplyResources(this.skinPartsTabPage, "skinPartsTabPage");
this.skinPartsTabPage.Controls.Add(this.skinPartListBox);
+ resources.ApplyResources(this.skinPartsTabPage, "skinPartsTabPage");
this.skinPartsTabPage.Name = "skinPartsTabPage";
//
// skinOffsetsTabPage
@@ -380,12 +381,14 @@
//
// renderer3D1
//
+ resources.ApplyResources(this.renderer3D1, "renderer3D1");
this.renderer3D1.BackColor = System.Drawing.Color.DimGray;
this.renderer3D1.ClampModel = false;
- resources.ApplyResources(this.renderer3D1, "renderer3D1");
+ this.renderer3D1.MouseSensetivity = 0.01F;
this.renderer3D1.Name = "renderer3D1";
this.renderer3D1.OutlineColor = System.Drawing.Color.Empty;
this.renderer3D1.RefreshRate = 50;
+ this.renderer3D1.ShowArmor = false;
this.renderer3D1.ShowGuideLines = false;
this.renderer3D1.Texture = null;
this.renderer3D1.VSync = true;
@@ -417,7 +420,7 @@
this.Controls.Add(this.SizeZUpDown);
this.Controls.Add(this.SizeYUpDown);
this.Controls.Add(this.SizeXUpDown);
- this.Controls.Add(this.checkBoxArmor);
+ this.Controls.Add(this.showArmorCheckbox);
this.Controls.Add(this.checkGuide);
this.Controls.Add(this.generateTextureCheckBox);
this.Controls.Add(this.outlineColorButton);
@@ -468,7 +471,7 @@
private MetroFramework.Controls.MetroButton buttonEXPORT;
private MetroFramework.Controls.MetroCheckBox generateTextureCheckBox;
private MetroFramework.Controls.MetroCheckBox checkGuide;
- private MetroFramework.Controls.MetroCheckBox checkBoxArmor;
+ private MetroFramework.Controls.MetroCheckBox showArmorCheckbox;
private System.Windows.Forms.NumericUpDown SizeXUpDown;
private System.Windows.Forms.NumericUpDown SizeYUpDown;
private System.Windows.Forms.NumericUpDown SizeZUpDown;
diff --git a/PCK-Studio/Forms/Editor/CustomSkinEditor.cs b/PCK-Studio/Forms/Editor/CustomSkinEditor.cs
index 3f759cd3..51cbfc34 100644
--- a/PCK-Studio/Forms/Editor/CustomSkinEditor.cs
+++ b/PCK-Studio/Forms/Editor/CustomSkinEditor.cs
@@ -285,6 +285,7 @@ namespace PckStudio.Forms.Editor
int scale = 4;
if (skinPartListBox.SelectedItem is SkinBOX box)
{
+ renderer3D1.SelectedIndex = skinPartListBox.SelectedIndex;
uvPictureBox.Image = new Bitmap(uvPictureBox.BackgroundImage.Width * scale, uvPictureBox.BackgroundImage.Height * scale);
using (Graphics g = Graphics.FromImage(uvPictureBox.Image))
{
@@ -322,6 +323,11 @@ namespace PckStudio.Forms.Editor
{
outlineColorButton.Visible = renderer3D1.ShowGuideLines = checkGuide.Checked;
}
+
+ private void showArmorCheckbox_CheckedChanged(object sender, EventArgs e)
+ {
+ renderer3D1.ShowArmor = showArmorCheckbox.Checked;
+ }
}
class CSMJObject
diff --git a/PCK-Studio/Forms/Editor/CustomSkinEditor.resx b/PCK-Studio/Forms/Editor/CustomSkinEditor.resx
index 327c7aaa..abd45aa3 100644
--- a/PCK-Studio/Forms/Editor/CustomSkinEditor.resx
+++ b/PCK-Studio/Forms/Editor/CustomSkinEditor.resx
@@ -267,6 +267,15 @@
17, 17
+
+ 152, 108
+
+
+ contextMenuStrip1
+
+
+ System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
@@ -339,15 +348,6 @@
Change Color
-
- 152, 108
-
-
- contextMenuStrip1
-
-
- System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
Bottom, Right
@@ -579,34 +579,34 @@
16
-
+
Bottom, Right
-
+
True
-
+
627, 503
-
- 129, 15
+
+ 89, 15
-
+
149
-
- Show Armor Offsets
+
+ Show Armor
-
- checkBoxArmor
+
+ showArmorCheckbox
-
+
MetroFramework.Controls.MetroCheckBox, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
-
+
$this
-
+
15
@@ -960,6 +960,51 @@
2
+
+ skinPartsTabPage
+
+
+ System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ metroTabControl1
+
+
+ 0
+
+
+ skinOffsetsTabPage
+
+
+ System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ metroTabControl1
+
+
+ 1
+
+
+ 23, 59
+
+
+ 161, 488
+
+
+ 1
+
+
+ metroTabControl1
+
+
+ MetroFramework.Controls.MetroTabControl, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
+
+
+ $this
+
+
+ 1
+
4, 38
@@ -984,18 +1029,6 @@
0
-
- Fill
-
-
- 0, 0
-
-
- 153, 446
-
-
- 0
-
offsetListBox
@@ -1032,26 +1065,29 @@
1
-
- 23, 59
+
+ Fill
-
- 161, 488
+
+ 0, 0
-
- 1
+
+ 153, 446
-
- metroTabControl1
+
+ 0
-
- MetroFramework.Controls.MetroTabControl, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
+
+ offsetListBox
-
- $this
+
+ System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- 1
+
+ skinOffsetsTabPage
+
+
+ 0
Top, Bottom, Left, Right
diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj
index 35e5d6a6..c10757d5 100644
--- a/PCK-Studio/PckStudio.csproj
+++ b/PCK-Studio/PckStudio.csproj
@@ -150,6 +150,7 @@
True
Resources.resx
+
diff --git a/PCK-Studio/Rendering/BoundingBox.cs b/PCK-Studio/Rendering/BoundingBox.cs
new file mode 100644
index 00000000..eb1b1590
--- /dev/null
+++ b/PCK-Studio/Rendering/BoundingBox.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using OpenTK;
+
+namespace PckStudio.Rendering
+{
+ internal struct BoundingBox
+ {
+ public readonly Vector3 Start;
+ public readonly Vector3 End;
+
+ public BoundingBox(Vector3 start, Vector3 end)
+ {
+ Start = start;
+ End = end;
+ }
+ }
+}
diff --git a/PCK-Studio/Rendering/ColorVertex.cs b/PCK-Studio/Rendering/ColorVertex.cs
index d465e846..7ad41069 100644
--- a/PCK-Studio/Rendering/ColorVertex.cs
+++ b/PCK-Studio/Rendering/ColorVertex.cs
@@ -17,6 +17,11 @@ namespace PckStudio.Rendering
Position = position;
Color = color;
}
+
+ public ColorVertex(Vector3 position)
+ : this(position, System.Drawing.Color.White)
+ {
+ }
public Vector3 Position { get; set; }
public Color4 Color { get; set; }
diff --git a/PCK-Studio/Rendering/SceneViewport.cs b/PCK-Studio/Rendering/SceneViewport.cs
index 6c65fe28..927f8092 100644
--- a/PCK-Studio/Rendering/SceneViewport.cs
+++ b/PCK-Studio/Rendering/SceneViewport.cs
@@ -26,9 +26,13 @@ https://github.com/KareemMAX/Minecraft-Skiner/blob/master/src/Minecraft%20skiner
*/
using System;
+using System.Drawing;
using System.Windows.Forms;
using OpenTK;
+using OpenTK.Graphics.OpenGL;
+using PckStudio.Properties;
using PckStudio.Rendering.Camera;
+using PckStudio.Rendering.Shader;
namespace PckStudio.Rendering
{
@@ -53,6 +57,37 @@ namespace PckStudio.Rendering
private int refreshRate = 60;
private Timer timer;
+ private VertexArray VAO;
+ private VertexBuffer VBO;
+ private IndexBuffer IBO;
+ private ShaderProgram colorShader;
+
+ protected void Init()
+ {
+ colorShader = ShaderProgram.Create(Resources.plainColorVertexShader, Resources.plainColorFragmentShader);
+ VAO = new VertexArray();
+ VBO = new VertexBuffer();
+ IBO = IndexBuffer.Create(
+ 0, 1,
+ 1, 2,
+ 2, 3,
+ 3, 0,
+
+ 4, 5,
+ 5, 6,
+ 6, 7,
+ 7, 4,
+
+ 0, 4,
+ 1, 5,
+ 2, 6,
+ 3, 7);
+ VertexBufferLayout layout = new VertexBufferLayout();
+ layout.Add(ShaderDataType.Float3);
+ layout.Add(ShaderDataType.Float4);
+ VAO.AddBuffer(VBO, layout);
+ }
+
public SceneViewport() : base()
{
timer = new Timer();
@@ -64,6 +99,44 @@ namespace PckStudio.Rendering
VSync = true;
}
+
+ protected void DrawBoundingBox(Matrix4 transform, BoundingBox boundingBox, Color color)
+ {
+ colorShader.Bind();
+ Matrix4 viewProjection = Camera.GetViewProjection();
+ colorShader.SetUniformMat4("ViewProjection", ref viewProjection);
+ colorShader.SetUniformMat4("Transform", ref transform);
+ colorShader.SetUniform4("baseColor", color);
+ colorShader.SetUniform1("intensity", 0.6f);
+
+ GL.Enable(EnableCap.LineSmooth);
+
+ GL.DepthFunc(DepthFunction.Always);
+
+ Renderer.SetLineWidth(2f);
+
+ Vector3 s = boundingBox.Start;
+ Vector3 e = boundingBox.End;
+
+ ColorVertex[] vertices = [
+ new ColorVertex(new Vector3(s.X, e.Y, e.Z)),
+ new ColorVertex(new Vector3(e.X, e.Y, e.Z)),
+ new ColorVertex(new Vector3(e.X, s.Y, e.Z)),
+ new ColorVertex(new Vector3(s.X, s.Y, e.Z)),
+ new ColorVertex(new Vector3(s.X, e.Y, s.Z)),
+ new ColorVertex(new Vector3(e.X, e.Y, s.Z)),
+ new ColorVertex(new Vector3(e.X, s.Y, s.Z)),
+ new ColorVertex(new Vector3(s.X, s.Y, s.Z)),
+ ];
+
+ VAO.Bind();
+ VBO.SetData(vertices);
+ IBO.Bind();
+ GL.DrawElements(PrimitiveType.Lines, IBO.GetCount(), DrawElementsType.UnsignedInt, 0);
+ GL.DepthFunc(DepthFunction.Less);
+ Renderer.SetLineWidth(1f);
+ }
+
private void TimerTick(object sender, EventArgs e)
{
OnTimerTick?.Invoke(sender, e);
diff --git a/PCK-Studio/Rendering/SkinRenderer.cs b/PCK-Studio/Rendering/SkinRenderer.cs
index ddfe9342..9bf656f8 100644
--- a/PCK-Studio/Rendering/SkinRenderer.cs
+++ b/PCK-Studio/Rendering/SkinRenderer.cs
@@ -77,6 +77,7 @@ namespace PckStudio.Rendering
}
public float MouseSensetivity { get; set; } = 0.01f;
+ public int SelectedIndex { get; set; } = -1;
public bool ClampModel { get; set; } = false;
public bool ShowArmor { get; set; } = false;
@@ -288,6 +289,8 @@ namespace PckStudio.Rendering
cubeMesh.UploadData();
}
GLErrorCheck();
+ base.Init();
+ GLErrorCheck();
initialized = true;
}
@@ -1029,10 +1032,55 @@ namespace PckStudio.Rendering
GL.BlendFunc(BlendingFactor.DstAlpha, BlendingFactor.OneMinusSrcAlpha);
GL.DepthFunc(DepthFunction.Less);
}
+
+ if (ModelData.IndexInRange(SelectedIndex))
+ {
+ SkinBOX box = ModelData[SelectedIndex];
+ var cubeBoundingBox = Cube.FromSkinBox(box).GetBoundingBox();
+
+ if (meshStorage.ContainsKey(box.Type))
+ {
+ var cubeMesh = meshStorage[box.Type];
+
+ Matrix4 GetGroupTransform(string type)
+ {
+ switch (type)
+ {
+ case "ARM0":
+ case "SLEEVE0":
+ return RightArmMatrix * armRightMatrix;
+ case "ARM1":
+ case "SLEEVE1":
+ return LeftArmMatrix * armLeftMatrix;
+ case "LEG0":
+ case "PANTS0":
+ return legRightMatrix;
+ case "LEG1":
+ case "PANTS1":
+ return legLeftMatrix;
+ default:
+ return Matrix4.Identity;
+ }
+ }
+
+ transform *= GetGroupTransform(box.Type);
+ Vector3 translation = cubeMesh.Translation - cubeMesh.Offset;
+ Vector3 pivot = cubeMesh.Pivot + cubeMesh.Offset;
+ transform = Pivot(translation, pivot, transform);
+ }
+
+ GL.BlendFunc(BlendingFactor.DstAlpha, BlendingFactor.OneMinusSrcAlpha);
+ base.DrawBoundingBox(transform, cubeBoundingBox, Color.Red);
+ GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
+ }
}
+
// Ground plane
{
+ GL.Enable(EnableCap.DepthTest);
+ GL.Enable(EnableCap.AlphaTest); // Enable transparent
+ GL.AlphaFunc(AlphaFunction.Always, 0.0f);
GL.BlendFunc(BlendingFactor.DstAlpha, BlendingFactor.OneMinusSrcAlpha);
lineShader.Bind();
lineShader.SetUniformMat4("ViewProjection", ref viewProjection);