Improved SkinRenderer.cs

- Fixed mouse getting stuck when lossing focus of the window
This commit is contained in:
miku-666
2023-10-29 12:15:10 +01:00
parent 883e0051fd
commit 6376d709c0
4 changed files with 350 additions and 157 deletions

View File

@@ -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
{
/// <summary> The structure size in bytes that must be set via calling Marshal.SizeOf(typeof(CursorInfoStruct)).</summary>
public Int32 cbSize;
/// <summary> 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)</summary>
public Int32 flags;
/// <summary> A handle to the cursor. </summary>
public IntPtr hCursor;
/// <summary> The cursor screen coordinates.</summary>
public PointStruct pt;
}
/// <summary> Must initialize cbSize</summary>
[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;
}
}
}

View File

@@ -135,6 +135,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Classes\Utils\Ray.cs" />
<Compile Include="Extensions\CursorExtensions.cs" />
<Compile Include="Extensions\PckFileDataExtensions.cs" />
<Compile Include="Extensions\System.Numerics.cs" />
<Compile Include="Extensions\TreeNodeExtensions.cs" />

View File

@@ -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;
}
}

View File

@@ -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<SkinBOX> ModelData { get; } = new List<SkinBOX>();
[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<string, RenderGroup> renderGroups;
private Dictionary<string, RenderGroup> defaultRenderGroups;
private Dictionary<string, RenderGroup> 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<string, RenderGroup>(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<string, RenderGroup>(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<string, RenderGroup>(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<TextureVertex>(vertexData, vertexData.Length * TextureVertex.SizeInBytes);
var layout = new VertexBufferLayout();
layout.Add<float>(3);
layout.Add<float>(4);
layout.Add<float>(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
}
}
}
}
}