mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-06-04 03:45:47 +00:00
Improved SkinRenderer.cs
- Fixed mouse getting stuck when lossing focus of the window
This commit is contained in:
51
PCK-Studio/Extensions/CursorExtensions.cs
Normal file
51
PCK-Studio/Extensions/CursorExtensions.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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" />
|
||||
|
||||
10
PCK-Studio/Rendering/SkinRenderer.Designer.cs
generated
10
PCK-Studio/Rendering/SkinRenderer.Designer.cs
generated
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user