From 6376d709c082e8abf289545d5e2aac32e993209a Mon Sep 17 00:00:00 2001
From: miku-666 <74728189+NessieHax@users.noreply.github.com>
Date: Sun, 29 Oct 2023 12:15:10 +0100
Subject: [PATCH] Improved SkinRenderer.cs - Fixed mouse getting stuck when
lossing focus of the window
---
PCK-Studio/Extensions/CursorExtensions.cs | 51 ++
PCK-Studio/PckStudio.csproj | 1 +
PCK-Studio/Rendering/SkinRenderer.Designer.cs | 10 +-
PCK-Studio/Rendering/SkinRenderer.cs | 445 ++++++++++++------
4 files changed, 350 insertions(+), 157 deletions(-)
create mode 100644 PCK-Studio/Extensions/CursorExtensions.cs
diff --git a/PCK-Studio/Extensions/CursorExtensions.cs b/PCK-Studio/Extensions/CursorExtensions.cs
new file mode 100644
index 00000000..2739674c
--- /dev/null
+++ b/PCK-Studio/Extensions/CursorExtensions.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace PckStudio.Extensions
+{
+ internal static class CursorExtensions
+ {
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct PointStruct
+ {
+ public Int32 x;
+ public Int32 y;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct CursorInfoStruct
+ {
+ /// The structure size in bytes that must be set via calling Marshal.SizeOf(typeof(CursorInfoStruct)).
+ public Int32 cbSize;
+ /// The cursor state: 0 == hidden, 1 == showing, 2 == suppressed (is supposed to be when finger touch is used, but in practice finger touch results in 0, not 2)
+ public Int32 flags;
+ /// A handle to the cursor.
+ public IntPtr hCursor;
+ /// The cursor screen coordinates.
+ public PointStruct pt;
+ }
+
+ /// Must initialize cbSize
+ [DllImport("user32.dll")]
+ static extern bool GetCursorInfo(ref CursorInfoStruct pci);
+
+ public static bool IsVisible(this Cursor _)
+ {
+ CursorInfoStruct pci = new CursorInfoStruct();
+ pci.cbSize = Marshal.SizeOf(typeof(CursorInfoStruct));
+ GetCursorInfo(ref pci);
+ // const Int32 hidden = 0x00;
+ const Int32 showing = 0x01;
+ // const Int32 suppressed = 0x02;
+ bool isVisible = ((pci.flags & showing) != 0);
+ return isVisible;
+ }
+
+ }
+}
diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj
index 20d3ecc4..f181fb8a 100644
--- a/PCK-Studio/PckStudio.csproj
+++ b/PCK-Studio/PckStudio.csproj
@@ -135,6 +135,7 @@
+
diff --git a/PCK-Studio/Rendering/SkinRenderer.Designer.cs b/PCK-Studio/Rendering/SkinRenderer.Designer.cs
index a930ab2f..07aaebae 100644
--- a/PCK-Studio/Rendering/SkinRenderer.Designer.cs
+++ b/PCK-Studio/Rendering/SkinRenderer.Designer.cs
@@ -36,17 +36,25 @@ namespace PckStudio.Rendering
{
components = new System.ComponentModel.Container();
moveTimer = new System.Windows.Forms.Timer(components);
- moveTimer.Tick += new EventHandler(Move_Tick);
+ animationTimer = new System.Windows.Forms.Timer(components);
+ moveTimer.Tick += new EventHandler(moveTimer_Tick);
+ animationTimer.Tick += new EventHandler(animationTimer_Tick);
SuspendLayout();
//
// moveTimer
//
moveTimer.Enabled = true;
moveTimer.Interval = 10;
+ //
+ // animationTimer
+ //
+ animationTimer.Enabled = false;
+ animationTimer.Interval = 50;
Name = "Renderer3D";
ResumeLayout(false);
}
private System.Windows.Forms.Timer moveTimer;
+ private System.Windows.Forms.Timer animationTimer;
}
}
diff --git a/PCK-Studio/Rendering/SkinRenderer.cs b/PCK-Studio/Rendering/SkinRenderer.cs
index 00990b1b..0931a486 100644
--- a/PCK-Studio/Rendering/SkinRenderer.cs
+++ b/PCK-Studio/Rendering/SkinRenderer.cs
@@ -6,8 +6,6 @@ using System.Text;
using System.Threading.Tasks;
using OpenTK;
using PckStudio.Internal;
-using static System.Windows.Forms.VisualStyles.VisualStyleElement.Tab;
-using System.Windows.Media.Media3D;
using PckStudio.Extensions;
using OpenTK.Graphics.OpenGL;
using System.Windows.Forms;
@@ -15,6 +13,7 @@ using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using PckStudio.Properties;
+using PckStudio.Forms.Editor;
namespace PckStudio.Rendering
{
@@ -31,32 +30,44 @@ namespace PckStudio.Rendering
get => _texture;
set
{
- if (skinShader is not null)
+ if (value is null)
+ return;
+
+ if (HasValidContext && skinShader is not null)
{
var texture = new Texture2D(value);
texture.Bind(0);
skinShader.SetUniform1("u_Texture", 0);
Refresh();
}
- TextureScaleValue = new Vector2(1f / value.Width, 1f / value.Height);
_texture = value;
}
}
- private Vector2 _lookAngle = Vector2.Zero;
+ [Description("Anim flags for special effects applied to the skin")]
+ [Category("Appearance")]
+ public SkinANIM ANIM
+ {
+ get => _anim;
+ set
+ {
+ _anim = value;
+ OnANIMUpdate();
+ }
+ }
+
+ [Description("Additional model data")]
+ [Category("Appearance")]
+ public List ModelData { get; } = new List();
+
[Description("The offset from the orignal point (for zoom)")]
[Category("Appearance")]
public Vector2 LookAngle
{
- get => _lookAngle;
- set
- {
- _lookAngle = value;
- camera.LookAt(value);
- }
+ get => camera.Position;
+ set => camera.LookAt(value);
}
- private Vector2 TextureScaleValue = new Vector2(1f / 64);
private void GLDebugMessage(DebugSource source, DebugType type, int id, DebugSeverity severity, int length, IntPtr message, IntPtr userParam)
{
@@ -68,31 +79,108 @@ namespace PckStudio.Rendering
Debug.WriteLine(msg);
}
- private Vector2 _modelRotation;
- private Vector2 modelRotation
+ private Vector2 _globalModelRotation;
+ private Vector2 GlobalModelRotation
{
- get => _modelRotation;
+ get => _globalModelRotation;
set
{
- _modelRotation.X = MathHelper.Clamp(value.X, -5f, 5f);
- _modelRotation.Y = MathHelper.Clamp(value.Y, -180f, 180f);
+ _globalModelRotation.X = MathHelper.Clamp(value.X, -90f, 90f);
+ _globalModelRotation.Y = MathHelper.Clamp(value.Y, -180f, 180f);
}
}
- private bool IsMouseDown;
+ private Bitmap _texture;
+ private Vector2 TextureScaleValue = new Vector2(1f / 64);
+ private const float OverlayScale = 0.1f;
+
+ private bool IsLeftMouseDown;
private bool IsRightMouseDown;
- private bool IsMouseHidden;
+ private bool IsMouseHidden
+ {
+ get => !Cursor.IsVisible();
+ set
+ {
+ if (value)
+ {
+ Cursor.Hide();
+ return;
+ }
+ Cursor.Show();
+ }
+ }
private Point PreviousMouseLocation;
private Point MouseLoc;
+
private Shader skinShader;
+ private SkinANIM _anim;
- private Dictionary renderGroups;
+ private Dictionary defaultRenderGroups;
+ private Dictionary additionalModelRenderGroups;
- private Bitmap _texture;
+
+ private float animationRot;
+ private float animationRotStep = 1f;
public SkinRenderer()
{
InitializeComponent();
+ InitializeCamera();
+ _anim = new SkinANIM(); // use backing field to not raise OnANIMUpdate
+ defaultRenderGroups = new Dictionary(6)
+ {
+ { "HEAD", new RenderGroup("HEAD") },
+ { "BODY", new RenderGroup("BODY") },
+ { "ARM0", new RenderGroup("ARM0") },
+ { "ARM1", new RenderGroup("ARM1") },
+ { "LEG0", new RenderGroup("LEG0") },
+ { "LEG1", new RenderGroup("LEG1") },
+
+ { "HEADWEAR", new RenderGroup("HEADWEAR") },
+ { "JACKET", new RenderGroup("JACKET")},
+ { "SLEEVE0", new RenderGroup("SLEEVE0")},
+ { "SLEEVE1", new RenderGroup("SLEEVE1")},
+ { "LEGGING0", new RenderGroup("LEGGING0")},
+ { "LEGGING1", new RenderGroup("LEGGING1")},
+
+ //{ "PANTS0", new RenderGroup("PANTS0")},
+ //{ "PANTS1", new RenderGroup("PANTS1")},
+ //{ "WAIST", new RenderGroup("WAIST")},
+ //{ "SOCK0", new RenderGroup("SOCK0")},
+ //{ "SOCK1", new RenderGroup("SOCK1")},
+ //{ "BOOT0", new RenderGroup("BOOT0")},
+ //{ "BOOT1", new RenderGroup("BOOT1")},
+ //{ "ARMARMOR1", new RenderGroup("ARMARMOR1")},
+ //{ "ARMARMOR0", new RenderGroup("ARMARMOR0")},
+ //{ "BODYARMOR", new RenderGroup("BODYARMOR")},
+ //{ "BELT", new RenderGroup("BELT")},
+ };
+ additionalModelRenderGroups = new Dictionary(6)
+ {
+ { "HEAD", new RenderGroup("HEAD") },
+ { "BODY", new RenderGroup("BODY") },
+ { "ARM0", new RenderGroup("ARM0") },
+ { "ARM1", new RenderGroup("ARM1") },
+ { "LEG0", new RenderGroup("LEG0") },
+ { "LEG1", new RenderGroup("LEG1") },
+
+ { "HEADWEAR", new RenderGroup("HEADWEAR") },
+ { "JACKET", new RenderGroup("JACKET")},
+ { "SLEEVE0", new RenderGroup("SLEEVE0")},
+ { "SLEEVE1", new RenderGroup("SLEEVE1")},
+ { "LEGGING0", new RenderGroup("LEGGING0")},
+ { "LEGGING1", new RenderGroup("LEGGING1")},
+ };
+ }
+
+ private void InitializeCamera()
+ {
+ const float distance = 36f;
+ camera = new PerspectiveCamera(new Vector2(0f, 5f), distance, Vector2.Zero, 60f)
+ {
+ MinimumFov = 30f,
+ MaximumFov = 90f,
+ };
}
protected override void OnLoad(EventArgs e)
@@ -102,55 +190,70 @@ namespace PckStudio.Rendering
return;
MakeCurrent();
- camera = new Camera(new Vector2(0f, 1f), 36f, Vector2.Zero, 60f);
-
- camera.MinimumFov = 30f;
- camera.MaximumFov = 90f;
-
- camera.LookAt(new Vector2(0f, 5f));
+ Trace.TraceInformation(GL.GetString(StringName.Version));
GL.DebugMessageCallback(GLDebugMessage, IntPtr.Zero);
- Trace.TraceInformation(GL.GetString(StringName.Version));
-
skinShader = Shader.Create(Resources.skinVertexShader, Resources.skinFragment);
skinShader.Bind();
- Texture = Resources.slim_template;
-
- renderGroups = new Dictionary(6)
+ if (_texture is null)
{
- { "HEAD", new RenderGroup("HEAD") },
- { "BODY", new RenderGroup("BODY") },
- { "ARM0", new RenderGroup("ARM0") },
- { "ARM1", new RenderGroup("ARM1") },
- { "LEG0", new RenderGroup("LEG0") },
- { "LEG1", new RenderGroup("LEG1") }
- };
+ Texture = Resources.classic_template;
+ if (Texture.Size == new Size(64, 64))
+ {
+ ANIM.SetFlag(SkinAnimFlag.RESOLUTION_64x64, true);
+ }
+ }
- var headbox = new SkinBOX("HEAD", new(-4, -8, -4), new(8, 8, 8), new( 0, 0));
- var bodybox = new SkinBOX("BODY", new(-4, 0, -2), new(8, 12, 4), new(16, 16));
- var arm0box = new SkinBOX("ARM0", new(-3, -2, -2), new(4, 12, 4), new(40, 16));
- var arm1box = new SkinBOX("ARM1", new(-1, -2, -2), new(4, 12, 4), new(32, 48));
- var leg0box = new SkinBOX("LEG0", new(-2, 0, -2), new(4, 12, 4), new( 0, 16));
- var leg1box = new SkinBOX("LEG1", new(-2, 0, -2), new(4, 12, 4), new(16, 48));
+ var headbox = new SkinBOX("HEAD", new(-4, -8, -4), new(8, 8, 8), new( 0, 0));
+ var headoverlaybox = new SkinBOX("HEADWEAR", new(-4, -8, -4), new(8, 8, 8), new(32, 0), scale: OverlayScale);
+ var bodybox = new SkinBOX("BODY", new(-4, 0, -2), new(8, 12, 4), new(16, 16));
+ var bodyoverlaybox = new SkinBOX("JACKET", new(-4, 0, -2), new(8, 12, 4), new(16, 32), scale: OverlayScale);
+ var arm0box = new SkinBOX("ARM0", new(-3, -2, -2), new(4, 12, 4), new(40, 16));
+ var arm1box = new SkinBOX("ARM1", new(-1, -2, -2), new(4, 12, 4), new(32, 48));
+ var arm0overlaybox = new SkinBOX("SLEEVE0", new(-3, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale);
+ var arm1overlaybox = new SkinBOX("SLEEVE1", new(-1, -2, -2), new(4, 12, 4), new(48, 48), scale: OverlayScale);
+ var leg0box = new SkinBOX("LEG0", new(-2, 0, -2), new(4, 12, 4), new( 0, 16));
+ var leg0overlaybox = new SkinBOX("LEGGING0", new(-2, 0, -2), new(4, 12, 4), new( 0, 32), scale: OverlayScale);
+ var leg1box = new SkinBOX("LEG1", new(-2, 0, -2), new(4, 12, 4), new(16, 48));
+ var leg1overlaybox = new SkinBOX("LEGGING1", new(-2, 0, -2), new(4, 12, 4), new( 0, 48), scale: OverlayScale);
- AddGroup(headbox, TextureScaleValue);
- AddGroup(bodybox, TextureScaleValue);
- AddGroup(arm0box, TextureScaleValue);
- AddGroup(arm1box, TextureScaleValue);
- AddGroup(leg0box, TextureScaleValue);
- AddGroup(leg1box, TextureScaleValue);
+ AddToGroup(headbox);
+ AddToGroup(headoverlaybox);
+ AddToGroup(bodybox);
+ AddToGroup(bodyoverlaybox);
+ AddToGroup(arm0box);
+ AddToGroup(arm0overlaybox);
+ AddToGroup(arm1box);
+ AddToGroup(arm1overlaybox);
+ AddToGroup(leg0box);
+ AddToGroup(leg0overlaybox);
+ AddToGroup(leg1box);
+ AddToGroup(leg1overlaybox);
+
+ foreach (var item in ModelData)
+ {
+ AddCustomModelPart(item);
+ }
GLErrorCheck();
}
- private void AddGroup(SkinBOX skinBox, Vector2 textureScaleValue)
+ private void AddCustomModelPart(SkinBOX skinBox)
{
- if (!renderGroups.ContainsKey(skinBox.Type))
+ if (!additionalModelRenderGroups.ContainsKey(skinBox.Type))
throw new KeyNotFoundException(skinBox.Type);
- renderGroups[skinBox.Type].AddBox(skinBox, textureScaleValue);
+ additionalModelRenderGroups[skinBox.Type].AddBox(skinBox);
+ }
+
+ private void AddToGroup(SkinBOX skinBox)
+ {
+ if (!defaultRenderGroups.ContainsKey(skinBox.Type))
+ throw new KeyNotFoundException(skinBox.Type);
+
+ defaultRenderGroups[skinBox.Type].AddBox(skinBox);
}
[Conditional("DEBUG")]
@@ -160,69 +263,19 @@ namespace PckStudio.Rendering
Debug.Assert(error == ErrorCode.NoError, error.ToString());
}
- private RenderBuffer GetBox3D(SkinBOX skinBOX)
- {
- return GetBox3D(skinBOX.Pos.ToOpenTKVector(), skinBOX.Size.ToOpenTKVector(), skinBOX.UV.ToOpenTKVector());
- }
-
- private RenderBuffer GetBox3D(Vector3 position, Vector3 size, Vector2 uv)
- {
- var vertexData = new TextureVertex[]
- {
- new TextureVertex(new Vector3(position.X , size.Y + position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z, uv.Y + size.Z) * TextureScaleValue),
- new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z) * TextureScaleValue),
- new TextureVertex(new Vector3(size.X + position.X, position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z + size.Y) * TextureScaleValue),
- new TextureVertex(new Vector3(position.X , position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z, uv.Y + size.Z + size.Y) * TextureScaleValue),
-
- new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z * 2 + size.X * 2, uv.Y + size.Z) * TextureScaleValue),
- new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z * 2 + size.X, uv.Y + size.Z) * TextureScaleValue),
- new TextureVertex(new Vector3(size.X + position.X, position.Y, position.Z), new Vector2(uv.X + size.Z * 2 + size.X, uv.Y + size.Z + size.Y) * TextureScaleValue),
- new TextureVertex(new Vector3(position.X , position.Y, position.Z), new Vector2(uv.X + size.Z * 2 + size.X * 2, uv.Y + size.Z + size.Y) * TextureScaleValue),
-
- new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z), new Vector2(uv.X, uv.Y + size.Z) * TextureScaleValue),
- new TextureVertex(new Vector3(position.X , position.Y, position.Z), new Vector2(uv.X, uv.Y + size.Z + size.Y) * TextureScaleValue),
- new TextureVertex(new Vector3(size.X + position.X, size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z + size.X, uv.Y) * TextureScaleValue),
- new TextureVertex(new Vector3(position.X , size.Y + position.Y, position.Z), new Vector2(uv.X + size.Z, uv.Y) * TextureScaleValue),
-
- new TextureVertex(new Vector3(position.X , position.Y, position.Z), new Vector2(uv.X + size.Z + size.X, uv.Y) * TextureScaleValue),
- new TextureVertex(new Vector3(size.X + position.X, position.Y, position.Z), new Vector2(uv.X + size.Z + size.X * 2, uv.Y) * TextureScaleValue),
- new TextureVertex(new Vector3(size.X + position.X, position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X * 2, uv.Y + size.Z) * TextureScaleValue),
- new TextureVertex(new Vector3(position.X , position.Y, size.Z + position.Z), new Vector2(uv.X + size.Z + size.X, uv.Y + size.Z) * TextureScaleValue),
- };
-
- var indexBuffer = new IndexBuffer(
- 0, 1, 2, 3, // Face 1 (Front)
- 4, 5, 6, 7, // Face 2 (Back)
- 0, 8, 9, 3, // Face 3 (Left)
- 1, 5, 6, 2, // Face 4 (Right)
- 0, 1, 10, 11, // Face 5(Top)
- 12, 13, 14, 15 // Face 6 (Bottom)
- );
-
- var buffer = new VertexBuffer(vertexData, vertexData.Length * TextureVertex.SizeInBytes);
- var layout = new VertexBufferLayout();
- layout.Add(3);
- layout.Add(4);
- layout.Add(2);
-
- var vertexArray = new VertexArray();
-
- vertexArray.AddBuffer(buffer, layout);
-
- return new RenderBuffer(vertexArray, indexBuffer, PrimitiveType.Quads);
- }
-
- private Matrix4 GetModelFromSkinBOX(SkinBOX skinBox)
- {
- return Matrix4.CreateTranslation(skinBox.Pos.ToOpenTKVector()) * Matrix4.CreateScale(skinBox.Scale);
- }
-
protected override bool ProcessDialogKey(Keys keyData)
{
switch (keyData)
{
+ case Keys.Escape:
+ if (IsMouseHidden || IsLeftMouseDown || IsRightMouseDown)
+ {
+ IsMouseHidden = IsRightMouseDown = IsLeftMouseDown = false;
+ Cursor.Position = PreviousMouseLocation;
+ }
+ break;
case Keys.R:
- modelRotation = Vector2.Zero;
+ GlobalModelRotation = Vector2.Zero;
LookAngle = Vector2.Zero;
Refresh();
return true;
@@ -236,10 +289,48 @@ namespace PckStudio.Rendering
Texture = Image.FromFile(fileDialog.FileName) as Bitmap;
}
return true;
+ case Keys.F3:
+
+ return true;
+ case Keys.A:
+ {
+ using var animeditor = new ANIMEditor(ANIM);
+ if (animeditor.ShowDialog() == DialogResult.OK)
+ {
+ ANIM = animeditor.ResultAnim;
+ Refresh();
+ }
+ }
+ return true;
}
return base.ProcessDialogKey(keyData);
}
+ private void OnANIMUpdate()
+ {
+ bool slim = ANIM.GetFlag(SkinAnimFlag.SLIM_MODEL);
+ if (slim || ANIM.GetFlag(SkinAnimFlag.RESOLUTION_64x64))
+ {
+ int slimValue = slim ? 3 : 4;
+ TextureScaleValue = new Vector2(1f / 64);
+ defaultRenderGroups["ARM0"].ReplaceBox(0, new(-3, -2, -2), new(slimValue, 12, 4), new(40, 16));
+ defaultRenderGroups["ARM1"].ReplaceBox(0, new(-1, -2, -2), new(slimValue, 12, 4), new(32, 48));
+ defaultRenderGroups["SLEEVE0"].ReplaceBox(0, new(-3, -2, -2), new(slimValue, 12, 4), new(40, 32), scale: OverlayScale);
+ defaultRenderGroups["SLEEVE1"].ReplaceBox(0, new(-1, -2, -2), new(slimValue, 12, 4), new(48, 48), scale: OverlayScale);
+
+ defaultRenderGroups["LEG0"].ReplaceBox(0, new(-2, 0, -2), new(4, 12, 4), new(0, 16));
+ defaultRenderGroups["LEG1"].ReplaceBox(0, new(-2, 0, -2), new(4, 12, 4), new(16, 48));
+ return;
+ }
+ TextureScaleValue = new Vector2(1f / 64, 1f / 32);
+ defaultRenderGroups["ARM0"].ReplaceBox(0, new(-3, -2, -2), new(4, 12, 4), new(40, 16));
+ defaultRenderGroups["ARM1"].ReplaceBox(0, new(-1, -2, -2), new(4, 12, 4), new(40, 16));
+ defaultRenderGroups["LEG0"].ReplaceBox(0, new(-2, 0, -2), new(4, 12, 4), new(0, 16));
+ defaultRenderGroups["LEG1"].ReplaceBox(0, new(-2, 0, -2), new(4, 12, 4), new(0, 16));
+ defaultRenderGroups["SLEEVE0"].ReplaceBox(0, new(-3, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale);
+ defaultRenderGroups["SLEEVE1"].ReplaceBox(0, new(-1, -2, -2), new(4, 12, 4), new(40, 32), scale: OverlayScale);
+ }
+
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
@@ -248,12 +339,13 @@ namespace PckStudio.Rendering
return;
}
- MakeCurrent();
+ MakeCurrent();
camera.Update(Size.Width / (float)Size.Height);
var viewProjection = camera.GetViewProjection();
skinShader.SetUniformMat4("u_ViewProjection", ref viewProjection);
+ skinShader.SetUniform2("u_TexScale", TextureScaleValue);
GL.Viewport(Size);
@@ -272,48 +364,74 @@ namespace PckStudio.Rendering
GL.Enable(EnableCap.AlphaTest); // Enable transparent
GL.AlphaFunc(AlphaFunction.Greater, 0.4f);
- Matrix4 transform = Matrix4.CreateTranslation(new Vector3(0f, 16f, 0f));
- Matrix4 rotation = Matrix4.CreateFromAxisAngle(new Vector3(-1f, 0f, 0f), MathHelper.DegreesToRadians(modelRotation.X))
- * Matrix4.CreateFromAxisAngle(new Vector3(0f, 1f, 0f), MathHelper.DegreesToRadians(modelRotation.Y));
+ Matrix4 modelRotationMatrix = Matrix4.CreateFromAxisAngle(new Vector3(-1f, 0f, 0f), MathHelper.DegreesToRadians(GlobalModelRotation.X))
+ * Matrix4.CreateFromAxisAngle(new Vector3(0f, 1f, 0f), MathHelper.DegreesToRadians(GlobalModelRotation.Y));
+
+
+ RenderSkinPartIf("HEAD" , !ANIM.GetFlag(SkinAnimFlag.HEAD_DISABLED), new Vector3(0f, 16f, 0f), modelRotationMatrix);
+ RenderSkinPartIf("HEADWEAR", !ANIM.GetFlag(SkinAnimFlag.HEAD_OVERLAY_DISABLED), new Vector3(0f, 16f + OverlayScale, 0f), modelRotationMatrix);
- var model = transform * rotation;
+ RenderSkinPartIf("BODY" , !ANIM.GetFlag(SkinAnimFlag.BODY_DISABLED), new Vector3(0f, -4f, 0f), modelRotationMatrix);
+ RenderSkinPartIf("JACKET", !ANIM.GetFlag(SkinAnimFlag.BODY_OVERLAY_DISABLED), new Vector3(0f, -4f + OverlayScale, 0f), modelRotationMatrix);
- skinShader.SetUniformMat4("u_Model", ref model);
- Renderer.Draw(skinShader, renderGroups["HEAD"].GetRenderBuffer());
+ var extraRightRotation = Matrix4.CreateFromAxisAngle(Vector3.UnitY, MathHelper.DegreesToRadians(animationRot));
+ var extraLeftRotation = Matrix4.CreateFromAxisAngle(Vector3.UnitY, MathHelper.DegreesToRadians(-animationRot));
+ var translationRight = new Vector3(ANIM.GetFlag(SkinAnimFlag.SLIM_MODEL) ? -4f : -5f, -2f, 0f);
+ var translationLeft = new Vector3(5f, -2f, 0f);
+ if (ANIM.GetFlag(SkinAnimFlag.ZOMBIE_ARMS))
+ {
+ extraRightRotation *= Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(-90f));
+ extraLeftRotation *= Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(-90f));
+ translationRight.Yz = translationLeft.Yz = new Vector2(-8f, 6f);
+ }
- transform = Matrix4.CreateTranslation(new Vector3(0f, -4f, 0f));
- model = transform * rotation;
+ RenderSkinPartIf("ARM0" , !ANIM.GetFlag(SkinAnimFlag.RIGHT_ARM_DISABLED) , translationRight, extraRightRotation * modelRotationMatrix);
+ RenderSkinPartIf("SLEEVE0", !ANIM.GetFlag(SkinAnimFlag.RIGHT_ARM_OVERLAY_DISABLED), translationRight, extraRightRotation * modelRotationMatrix);
- skinShader.SetUniformMat4("u_Model", ref model);
- Renderer.Draw(skinShader, renderGroups["BODY"].GetRenderBuffer());
+ RenderSkinPartIf("ARM1" , !ANIM.GetFlag(SkinAnimFlag.LEFT_ARM_DISABLED) , translationLeft , extraLeftRotation * modelRotationMatrix);
+ RenderSkinPartIf("SLEEVE1", !ANIM.GetFlag(SkinAnimFlag.LEFT_ARM_OVERLAY_DISABLED) , translationLeft , extraLeftRotation * modelRotationMatrix);
+
+ RenderSkinPartIf("LEG0" , !ANIM.GetFlag(SkinAnimFlag.RIGHT_LEG_DISABLED) , new Vector3(-2f, -16f, 0f), modelRotationMatrix);
+ RenderSkinPartIf("LEGGING0", !ANIM.GetFlag(SkinAnimFlag.RIGHT_LEG_OVERLAY_DISABLED), new Vector3(-2f, -16f, 0f), modelRotationMatrix);
- transform = Matrix4.CreateTranslation(new Vector3(-5f, -2f, 0f));
- model = transform * rotation;
-
- skinShader.SetUniformMat4("u_Model", ref model);
- Renderer.Draw(skinShader, renderGroups["ARM0"].GetRenderBuffer());
-
- transform = Matrix4.CreateTranslation(new Vector3(5f, -2f, 0f));
- model = transform * rotation;
-
- skinShader.SetUniformMat4("u_Model", ref model);
- Renderer.Draw(skinShader, renderGroups["ARM1"].GetRenderBuffer());
-
- transform = Matrix4.CreateTranslation(new Vector3(-2f, -16f, 0f));
- model = transform * rotation;
-
- skinShader.SetUniformMat4("u_Model", ref model);
- Renderer.Draw(skinShader, renderGroups["LEG0"].GetRenderBuffer());
-
- transform = Matrix4.CreateTranslation(new Vector3(2f, -16f, 0f));
- model = transform * rotation;
-
- skinShader.SetUniformMat4("u_Model", ref model);
- Renderer.Draw(skinShader, renderGroups["LEG1"].GetRenderBuffer());
+ RenderSkinPartIf("LEG1" , !ANIM.GetFlag(SkinAnimFlag.LEFT_LEG_DISABLED) , new Vector3( 2f, -16f, 0f), modelRotationMatrix);
+ RenderSkinPartIf("LEGGING1", !ANIM.GetFlag(SkinAnimFlag.LEFT_LEG_OVERLAY_DISABLED) , new Vector3( 2f, -16f, 0f), modelRotationMatrix);
+#if flase
+ RenderAdditionalModelData("HEAD", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
+ RenderAdditionalModelData("BODY", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
+ RenderAdditionalModelData("ARM0", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
+ RenderAdditionalModelData("ARM1", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
+ RenderAdditionalModelData("LEG0", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
+ RenderAdditionalModelData("LEG1", new Vector3(0f, 28f, 0f), /*Matrix4.CreateFromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(180f)) **/ modelRotationMatrix);
+#endif
SwapBuffers();
}
+ private void RenderSkinPartIf(string name, bool condition, Vector3 translation, Matrix4 rotation)
+ {
+ if (condition)
+ {
+ RenderSkinPart(name, translation, rotation);
+ }
+ }
+
+ private void RenderSkinPart(string name, Vector3 translation, Matrix4 rotation)
+ {
+ var transform = Matrix4.CreateTranslation(translation);
+ var model = transform * rotation;
+ skinShader.SetUniformMat4("u_Model", ref model);
+ Renderer.Draw(skinShader, defaultRenderGroups[name].GetRenderBuffer());
+ }
+
+ private void RenderAdditionalModelData(string name, Vector3 translation, Matrix4 rotation)
+ {
+ var transform = Matrix4.CreateTranslation(translation);
+ var model = transform * rotation;
+ skinShader.SetUniformMat4("u_Model", ref model);
+ Renderer.Draw(skinShader, additionalModelRenderGroups[name].GetRenderBuffer());
+ }
+
protected override void OnMouseWheel(MouseEventArgs e)
{
camera.Fov -= e.Delta / System.Windows.Input.Mouse.MouseWheelDeltaForOneLine;
@@ -322,24 +440,22 @@ namespace PckStudio.Rendering
protected override void OnMouseDown(MouseEventArgs e)
{
- if (!IsMouseDown && e.Button == MouseButtons.Left)
+ if (!IsLeftMouseDown && e.Button == MouseButtons.Left)
{
// If the ray didn't hit the model then rotate the model
PreviousMouseLocation = Cursor.Position; // Store the old mouse position to reset it when the action is over
if (!IsMouseHidden) // Hide the mouse
{
- Cursor.Hide();
IsMouseHidden = true;
}
MouseLoc = Cursor.Position; // Store the current mouse position to use it for the rotate action
- IsMouseDown = true;
+ IsLeftMouseDown = true;
}
else if (!IsRightMouseDown && e.Button == MouseButtons.Right)
{
PreviousMouseLocation = Cursor.Position; // Store the old mouse position to reset it when the action is over
if (!IsMouseHidden) // Hide the mouse
{
- Cursor.Hide();
IsMouseHidden = true;
}
MouseLoc = Cursor.Position; // Store the current mouse position to use it for the move action
@@ -352,19 +468,36 @@ namespace PckStudio.Rendering
if (IsMouseHidden)
{
Cursor.Position = PreviousMouseLocation;
- IsMouseDown = IsMouseHidden = IsRightMouseDown = false;
- Cursor.Show();
+ IsMouseHidden = IsLeftMouseDown = IsRightMouseDown = false;
}
}
- private void Move_Tick(object sender, EventArgs e)
+ private void animationTimer_Tick(object sender, EventArgs e)
{
+ if (!Focused)
+ return;
+
+ const float angle = 2f;
+
+ animationRot += animationRotStep;
+ if (animationRot > angle || animationRot < -angle)
+ animationRotStep = -animationRotStep;
+ Refresh();
+ }
+
+ private void moveTimer_Tick(object sender, EventArgs e)
+ {
+ if (!Focused)
+ {
+ return;
+ }
+
// Rotate the model
- if (IsMouseDown)
+ if (IsLeftMouseDown)
{
float rotationYDelta = (float)Math.Round((Cursor.Position.X - MouseLoc.X) * 0.5f);
float rotationXDelta = (float)Math.Round(-(Cursor.Position.Y - MouseLoc.Y) * 0.5f);
- modelRotation += new Vector2(rotationXDelta, rotationYDelta);
+ GlobalModelRotation += new Vector2(rotationXDelta, rotationYDelta);
Refresh();
Cursor.Position = new Point((int)Math.Round(Screen.PrimaryScreen.Bounds.Width / 2d), (int)Math.Round(Screen.PrimaryScreen.Bounds.Height / 2d));
MouseLoc = Cursor.Position;
@@ -382,4 +515,4 @@ namespace PckStudio.Rendering
}
}
}
-}
+}
\ No newline at end of file