From 735f943dfd18cd3bad505bb0258182f0860af830 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 11 Jul 2024 09:05:12 +1000 Subject: [PATCH 01/19] Started camera projection implemetation --- .idea/.idea.Hypercube/.idea/indexLayout.xml | 4 +- Hypercube.Client/Dependencies.cs | 4 + .../Graphics/Rendering/Renderer.Render.cs | 8 +- .../Graphics/Rendering/Renderer.cs | 5 +- Hypercube.Client/Graphics/Shading/IShader.cs | 7 +- Hypercube.Client/Graphics/Shading/Shader.cs | 26 ++- .../Graphics/Viewports/Camera2D.cs | 37 +++- .../Graphics/Viewports/CameraManager.cs | 50 ++++- .../Graphics/Viewports/ICamera.cs | 9 +- .../Graphics/Viewports/ICameraManager.cs | 10 +- .../Input/Handler/IInputHandler.cs | 1 + .../Input/Handler/InputHandler.cs | 14 +- Hypercube.Shared.Math/Matrix/Matrix3X3.cs | 42 ++--- .../Matrix/Matrix4X4.Compability.cs | 12 ++ Hypercube.Shared.Math/Matrix/Matrix4X4.cs | 173 ++++++++++++------ .../Vector/Vector2.Compability.cs | 6 + .../Vector/Vector3.Compability.cs | 12 ++ Hypercube.Shared.Math/Vector/Vector3.cs | 28 ++- .../Vector/Vector4.Compability.cs | 30 +++ Hypercube.Shared.Math/Vector/Vector4.cs | 4 +- Resources/Shaders/base.frag | 4 +- Resources/Shaders/base.vert | 9 +- 22 files changed, 378 insertions(+), 117 deletions(-) create mode 100644 Hypercube.Shared.Math/Matrix/Matrix4X4.Compability.cs create mode 100644 Hypercube.Shared.Math/Vector/Vector3.Compability.cs create mode 100644 Hypercube.Shared.Math/Vector/Vector4.Compability.cs diff --git a/.idea/.idea.Hypercube/.idea/indexLayout.xml b/.idea/.idea.Hypercube/.idea/indexLayout.xml index 7b08163..2a75c2c 100644 --- a/.idea/.idea.Hypercube/.idea/indexLayout.xml +++ b/.idea/.idea.Hypercube/.idea/indexLayout.xml @@ -1,7 +1,9 @@ - + + Resources + diff --git a/Hypercube.Client/Dependencies.cs b/Hypercube.Client/Dependencies.cs index 6985f28..66f0dac 100644 --- a/Hypercube.Client/Dependencies.cs +++ b/Hypercube.Client/Dependencies.cs @@ -1,6 +1,7 @@ using Hypercube.Client.Graphics; using Hypercube.Client.Graphics.Rendering; using Hypercube.Client.Graphics.Texturing; +using Hypercube.Client.Graphics.Viewports; using Hypercube.Client.Input.Handler; using Hypercube.Client.Input.Manager; using Hypercube.Client.Runtimes; @@ -34,6 +35,9 @@ public static void Register(DependenciesContainer rootContainer) // Texturing rootContainer.Register(); + // Camera + rootContainer.Register(); + // Rendering rootContainer.Register(); diff --git a/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs b/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs index bbfb1fd..8c5ab2c 100644 --- a/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs +++ b/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs @@ -1,9 +1,9 @@ using Hypercube.Client.Graphics.Shading; using Hypercube.Client.Graphics.Texturing; using Hypercube.Client.Graphics.Viewports; -using Hypercube.Client.Graphics.Windows; using Hypercube.Shared.Math; using Hypercube.Shared.Math.Box; +using Hypercube.Shared.Math.Matrix; using Hypercube.Shared.Runtimes.Loop.Event; using OpenToolkit.Graphics.OpenGL4; @@ -35,6 +35,8 @@ private void OnLoad() _baseTexture = _textureManager.CreateHandler("Resources/Textures/opengl_logo.png"); _baseTexture.Bind(); + //_cameraManager.SetMainCamera(_cameraManager.CreateCamera2D(MainWindow.Size)); + _vbo = new BufferObject(BufferTarget.ArrayBuffer); _ebo = new BufferObject(BufferTarget.ElementArrayBuffer); _vao = new ArrayObject(); @@ -59,7 +61,7 @@ private void OnLoad() private void OnFrameUpdate(UpdateFrameEvent args) { #if DEBUG - _windowManager.WindowSetTitle(MainWindow, $"FPS: {_timing.Fps} | RealTime: {_timing.RealTime}"); + _windowManager.WindowSetTitle(MainWindow, $"FPS: {_timing.Fps} | RealTime: {_timing.RealTime} | cPos: {_cameraManager.MainCamera?.Position ?? null}"); #endif _windowManager.PollEvents(); } @@ -86,6 +88,8 @@ private void OnFrameRender(RenderFrameEvent args) BatchUpdate(); _baseShader.Use(); + _baseShader.SetUniform(_baseShader.GetUniformLocation("model"), Matrix4X4.Identity); + _baseShader.SetUniform(_baseShader.GetUniformLocation("projection"), _cameraManager.Projection); _vao.Bind(); GL.DrawElements(BeginMode.Triangles, (int) _batchIndexIndex, DrawElementsType.UnsignedInt, 0); diff --git a/Hypercube.Client/Graphics/Rendering/Renderer.cs b/Hypercube.Client/Graphics/Rendering/Renderer.cs index 057a1e5..ad81e4e 100644 --- a/Hypercube.Client/Graphics/Rendering/Renderer.cs +++ b/Hypercube.Client/Graphics/Rendering/Renderer.cs @@ -1,7 +1,7 @@ using System.Collections.Frozen; -using Hypercube.Client.Graphics.Event; using Hypercube.Client.Graphics.OpenGL; using Hypercube.Client.Graphics.Texturing; +using Hypercube.Client.Graphics.Viewports; using Hypercube.Client.Graphics.Windows; using Hypercube.Client.Graphics.Windows.Manager; using Hypercube.Shared.Dependency; @@ -21,7 +21,8 @@ public sealed partial class Renderer : IRenderer, IPostInject [Dependency] private readonly IEventBus _eventBus = default!; [Dependency] private readonly ITextureManager _textureManager = default!; [Dependency] private readonly ITiming _timing = default!; - + [Dependency] private readonly ICameraManager _cameraManager = default!; + private readonly ILogger _logger = LoggingManager.GetLogger("renderer"); private readonly ILogger _loggerOpenGL = LoggingManager.GetLogger("open_gl")!; diff --git a/Hypercube.Client/Graphics/Shading/IShader.cs b/Hypercube.Client/Graphics/Shading/IShader.cs index 4838e90..8881364 100644 --- a/Hypercube.Client/Graphics/Shading/IShader.cs +++ b/Hypercube.Client/Graphics/Shading/IShader.cs @@ -1,7 +1,12 @@ -namespace Hypercube.Client.Graphics.Shading; +using Hypercube.Shared.Math.Matrix; + +namespace Hypercube.Client.Graphics.Shading; public interface IShader { void Use(); + int GetUniformLocation(string name); void SetUniform(string name, int value); + void SetUniform(string name, Matrix4X4 value, bool transpose = false); + void SetUniform(int index, Matrix4X4 value, bool transpose = false); } \ No newline at end of file diff --git a/Hypercube.Client/Graphics/Shading/Shader.cs b/Hypercube.Client/Graphics/Shading/Shader.cs index 347dd03..6870968 100644 --- a/Hypercube.Client/Graphics/Shading/Shader.cs +++ b/Hypercube.Client/Graphics/Shading/Shader.cs @@ -1,6 +1,6 @@ -using Hypercube.Shared.Math.Vector; +using Hypercube.Shared.Math.Matrix; +using Hypercube.Shared.Math.Vector; using OpenToolkit.Graphics.OpenGL4; -using Vector2 = Hypercube.Shared.Math.Vector.Vector2; namespace Hypercube.Client.Graphics.Shading; @@ -51,12 +51,17 @@ public void Use() GL.UseProgram(_handle); } + public int GetUniformLocation(string name) + { + return GL.GetUniformLocation(_handle, name); + } + public void SetUniform(string name, int value) { GL.UseProgram(_handle); GL.Uniform1(_uniformLocations[name], value); } - + public void SetUniform(string name, Vector2Int value) { GL.UseProgram(_handle); @@ -74,6 +79,21 @@ public void SetUniform(string name, Vector2 value) GL.UseProgram(_handle); GL.Uniform2(_uniformLocations[name], value.X, value.Y); } + + public void SetUniform(string name, Matrix4X4 value, bool transpose = false) + { + SetUniform(GL.GetUniformLocation(_handle, name), value, transpose); + } + + public void SetUniform(int index, Matrix4X4 value, bool transpose = false) + { + unsafe + { + var matrix = transpose ? Matrix4X4.Transpose(value) : new Matrix4X4(value); + GL.UseProgram(_handle); + GL.UniformMatrix4(index, 1, false, (float*) &matrix); + } + } private int CreateShader(string path, ShaderType type) { diff --git a/Hypercube.Client/Graphics/Viewports/Camera2D.cs b/Hypercube.Client/Graphics/Viewports/Camera2D.cs index 11689cc..f4f8a26 100644 --- a/Hypercube.Client/Graphics/Viewports/Camera2D.cs +++ b/Hypercube.Client/Graphics/Viewports/Camera2D.cs @@ -6,14 +6,33 @@ namespace Hypercube.Client.Graphics.Viewports; public class Camera2D : ICamera { - public float ZFar { get; private set; } - public float ZNear { get; private set; } - public Vector2 Position { get; private set; } - public float Zoom { get; private set; } + public Vector3 Position { get; private set; } + + private readonly float _zFar; + private readonly float _zNear; + private Vector2Int Size { get; set; } + private float Zoom { get; set; } = 1f; + + private Vector2 HalfSize => Size / 2f; + public Matrix4X4 Projection { get; private set; } - public Matrix4X4 Projection; + public Camera2D(Vector2Int size, Vector2 position, float zNear, float zFar) + { + Size = size; + Position = new Vector3(position); + _zNear = zNear; + _zFar = zFar; + + UpdateProjection(); + } - public void SetPosition(Vector2 position) + public void SetSize(Vector2Int size) + { + Size = size; + UpdateProjection(); + } + + public void SetPosition(Vector3 position) { Position = position; UpdateProjection(); @@ -27,9 +46,9 @@ public void SetZoom(float zoom) private void UpdateProjection() { - var size = new Box2(); - - var projection = Matrix4X4.CreateOrthographic(size, ZNear, ZFar); + var position = (Vector2)Position; + var box2 = new Box2(position - HalfSize, position + HalfSize); + var projection = Matrix4X4.CreateOrthographic(box2, _zNear, _zFar); var scale = Matrix4X4.CreateScale(Zoom); Projection = projection * scale; diff --git a/Hypercube.Client/Graphics/Viewports/CameraManager.cs b/Hypercube.Client/Graphics/Viewports/CameraManager.cs index 0213d02..ae6273f 100644 --- a/Hypercube.Client/Graphics/Viewports/CameraManager.cs +++ b/Hypercube.Client/Graphics/Viewports/CameraManager.cs @@ -1,5 +1,9 @@ -using Hypercube.Shared.Dependency; +using Hypercube.Client.Input; +using Hypercube.Client.Input.Handler; +using Hypercube.Shared.Dependency; using Hypercube.Shared.EventBus; +using Hypercube.Shared.Math.Matrix; +using Hypercube.Shared.Math.Vector; using Hypercube.Shared.Runtimes.Loop.Event; namespace Hypercube.Client.Graphics.Viewports; @@ -7,6 +11,11 @@ namespace Hypercube.Client.Graphics.Viewports; public class CameraManager : ICameraManager, IPostInject { [Dependency] private readonly IEventBus _eventBus = default!; + [Dependency] private readonly IInputHandler _inputHandler = default!; + + public ICamera? MainCamera { get; private set; } + + public Matrix4X4 Projection => MainCamera?.Projection ?? Matrix4X4.Identity; public void PostInject() { @@ -15,6 +24,45 @@ public void PostInject() private void OnUpdate(UpdateFrameEvent args) { + if (MainCamera is null) + return; + + // Debug camera controls + var position = MainCamera.Position; + + if (_inputHandler.IsKeyDown(Key.W)) + position += Vector3.Forward; + + if (_inputHandler.IsKeyDown(Key.S)) + position -= Vector3.Back; + + if (_inputHandler.IsKeyDown(Key.A)) + position -= Vector3.Forward.Cross(Vector3.Up).Normalized; + + if (_inputHandler.IsKeyDown(Key.D)) + position += Vector3.Forward.Cross(Vector3.Up).Normalized; + + if (_inputHandler.IsKeyDown(Key.Space)) + position += Vector3.Up; + + if (_inputHandler.IsKeyDown(Key.LeftShift)) + position -= Vector3.Up; + MainCamera.SetPosition(position); + } + + public void SetMainCamera(ICamera camera) + { + MainCamera = camera; + } + + public ICamera CreateCamera2D(Vector2Int size) + { + return CreateCamera2D(size, Vector2.Zero); + } + + public ICamera CreateCamera2D(Vector2Int size, Vector2 position, float zNear = 0.01f, float zFar = 100f) + { + return new Camera2D(size, position, zNear, zFar); } } \ No newline at end of file diff --git a/Hypercube.Client/Graphics/Viewports/ICamera.cs b/Hypercube.Client/Graphics/Viewports/ICamera.cs index 0c26f15..491757b 100644 --- a/Hypercube.Client/Graphics/Viewports/ICamera.cs +++ b/Hypercube.Client/Graphics/Viewports/ICamera.cs @@ -1,6 +1,11 @@ -namespace Hypercube.Client.Graphics.Viewports; +using Hypercube.Shared.Math.Matrix; +using Hypercube.Shared.Math.Vector; + +namespace Hypercube.Client.Graphics.Viewports; public interface ICamera { - + Matrix4X4 Projection { get; } + Vector3 Position { get; } + void SetPosition(Vector3 position); } \ No newline at end of file diff --git a/Hypercube.Client/Graphics/Viewports/ICameraManager.cs b/Hypercube.Client/Graphics/Viewports/ICameraManager.cs index 88db334..1a35c26 100644 --- a/Hypercube.Client/Graphics/Viewports/ICameraManager.cs +++ b/Hypercube.Client/Graphics/Viewports/ICameraManager.cs @@ -1,6 +1,12 @@ -namespace Hypercube.Client.Graphics.Viewports; +using Hypercube.Shared.Math.Matrix; +using Hypercube.Shared.Math.Vector; + +namespace Hypercube.Client.Graphics.Viewports; public interface ICameraManager { - + ICamera? MainCamera { get; } + Matrix4X4 Projection { get; } + void SetMainCamera(ICamera camera); + ICamera CreateCamera2D(Vector2Int size); } \ No newline at end of file diff --git a/Hypercube.Client/Input/Handler/IInputHandler.cs b/Hypercube.Client/Input/Handler/IInputHandler.cs index 635e552..f0ff620 100644 --- a/Hypercube.Client/Input/Handler/IInputHandler.cs +++ b/Hypercube.Client/Input/Handler/IInputHandler.cs @@ -13,4 +13,5 @@ public interface IInputHandler // TODO: Create Analyzer to allow access only for IWindowManager implementation void SendKeyState(KeyStateChangedArgs changedArgs); + bool IsKeyDown(Key key); } \ No newline at end of file diff --git a/Hypercube.Client/Input/Handler/InputHandler.cs b/Hypercube.Client/Input/Handler/InputHandler.cs index f2666fc..a11d733 100644 --- a/Hypercube.Client/Input/Handler/InputHandler.cs +++ b/Hypercube.Client/Input/Handler/InputHandler.cs @@ -6,7 +6,8 @@ public sealed class InputHandler : IInputHandler { public event Action? KeyUp; public event Action? KeyDown; - + + private readonly HashSet _keysDown = new(); private readonly ILogger _logger = LoggingManager.GetLogger("input_handler"); public void SendKeyState(KeyStateChangedArgs changedArgs) @@ -23,10 +24,17 @@ public void SendKeyState(KeyStateChangedArgs changedArgs) if (changedArgs.Pressed) { - KeyUp?.Invoke(changedArgs); + KeyDown?.Invoke(changedArgs); + _keysDown.Add(changedArgs.Key); return; } - KeyDown?.Invoke(changedArgs); + _keysDown.Remove(changedArgs.Key); + KeyUp?.Invoke(changedArgs); + } + + public bool IsKeyDown(Key key) + { + return _keysDown.Contains(key); } } \ No newline at end of file diff --git a/Hypercube.Shared.Math/Matrix/Matrix3X3.cs b/Hypercube.Shared.Math/Matrix/Matrix3X3.cs index f5b1394..d2a7c36 100644 --- a/Hypercube.Shared.Math/Matrix/Matrix3X3.cs +++ b/Hypercube.Shared.Math/Matrix/Matrix3X3.cs @@ -9,9 +9,9 @@ public struct Matrix3X3(Vector3 x, Vector3 y, Vector3 z) private const int IndexRaw1 = 1; private const int IndexRaw2 = 2; - private const int IndexColum0 = 0; - private const int IndexColum1 = 1; - private const int IndexColum2 = 2; + private const int IndexColumn0 = 0; + private const int IndexColumn1 = 1; + private const int IndexColumn2 = 2; public static Matrix3X3 Zero => new(Vector3.Zero); public static Matrix3X3 One => new(Vector3.One); @@ -126,23 +126,23 @@ public float M22 { IndexRaw0 => colum switch { - IndexColum0 => M00, - IndexColum1 => M01, - IndexColum2 => M02, + IndexColumn0 => M00, + IndexColumn1 => M01, + IndexColumn2 => M02, _ => throw new ArgumentOutOfRangeException(nameof(colum), colum, null) }, IndexRaw1 => colum switch { - IndexColum0 => M10, - IndexColum1 => M11, - IndexColum2 => M12, + IndexColumn0 => M10, + IndexColumn1 => M11, + IndexColumn2 => M12, _ => throw new ArgumentOutOfRangeException(nameof(colum), colum, null) }, IndexRaw2 => colum switch { - IndexColum0 => M20, - IndexColum1 => M21, - IndexColum2 => M22, + IndexColumn0 => M20, + IndexColumn1 => M21, + IndexColumn2 => M22, _ => throw new ArgumentOutOfRangeException(nameof(colum), colum, null) }, _ => throw new ArgumentOutOfRangeException(nameof(raw), raw, null) @@ -154,15 +154,15 @@ public float M22 case IndexRaw0: switch (colum) { - case IndexColum0: + case IndexColumn0: M00 = value; break; - case IndexColum1: + case IndexColumn1: M01 = value; break; - case IndexColum2: + case IndexColumn2: M02 = value; break; @@ -174,15 +174,15 @@ public float M22 case IndexRaw1: switch (colum) { - case IndexColum0: + case IndexColumn0: M10 = value; break; - case IndexColum1: + case IndexColumn1: M11 = value; break; - case IndexColum2: + case IndexColumn2: M12 = value; break; @@ -194,15 +194,15 @@ public float M22 case IndexRaw2: switch (colum) { - case IndexColum0: + case IndexColumn0: M20 = value; break; - case IndexColum1: + case IndexColumn1: M21 = value; break; - case IndexColum2: + case IndexColumn2: M22 = value; break; diff --git a/Hypercube.Shared.Math/Matrix/Matrix4X4.Compability.cs b/Hypercube.Shared.Math/Matrix/Matrix4X4.Compability.cs new file mode 100644 index 0000000..2febb57 --- /dev/null +++ b/Hypercube.Shared.Math/Matrix/Matrix4X4.Compability.cs @@ -0,0 +1,12 @@ +using System.Runtime.CompilerServices; + +namespace Hypercube.Shared.Math.Matrix; + +public partial struct Matrix4X4 +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator OpenTK.Mathematics.Matrix4(Matrix4X4 matrix4X4) + { + return new OpenTK.Mathematics.Matrix4(matrix4X4.Raw0, matrix4X4.Raw1, matrix4X4.Raw2, matrix4X4.Raw3); + } +} \ No newline at end of file diff --git a/Hypercube.Shared.Math/Matrix/Matrix4X4.cs b/Hypercube.Shared.Math/Matrix/Matrix4X4.cs index b2d466b..aa924d7 100644 --- a/Hypercube.Shared.Math/Matrix/Matrix4X4.cs +++ b/Hypercube.Shared.Math/Matrix/Matrix4X4.cs @@ -4,26 +4,27 @@ namespace Hypercube.Shared.Math.Matrix; -public struct Matrix4X4(Vector4 x, Vector4 y, Vector4 z, Vector4 w) : IEquatable +public partial struct Matrix4X4(Vector4 x, Vector4 y, Vector4 z, Vector4 w) : IEquatable { public static Matrix4X4 Zero => new(Vector4.Zero); public static Matrix4X4 One => new(Vector4.One); + public static Matrix4X4 Identity => new( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - + public Vector4 Raw0 = x; public Vector4 Raw1 = y; public Vector4 Raw2 = z; public Vector4 Raw3 = w; - public Vector4 Colum0 => new(M00, M10, M20, M30); - public Vector4 Colum1 => new(M01, M11, M21, M31); - public Vector4 Colum2 => new(M02, M12, M22, M32); - public Vector4 Colum3 => new(M03, M13, M23, M33); - + public Vector4 Column0 => new(M00, M10, M20, M30); + public Vector4 Column1 => new(M01, M11, M21, M31); + public Vector4 Column2 => new(M02, M12, M22, M32); + public Vector4 Column3 => new(M03, M13, M23, M33); + /// /// Matrix x: 0, y: 0 element. /// @@ -34,7 +35,7 @@ public float M00 [MethodImpl(MethodImplOptions.AggressiveInlining)] set => Raw0 = Raw0.WithX(value); } - + /// /// Matrix x: 1, y: 0 element. /// @@ -67,7 +68,7 @@ public float M03 [MethodImpl(MethodImplOptions.AggressiveInlining)] set => Raw0 = Raw0.WithW(value); } - + /// /// Matrix x: 0, y: 1 element. /// @@ -78,7 +79,7 @@ public float M10 [MethodImpl(MethodImplOptions.AggressiveInlining)] set => Raw1 = Raw1.WithX(value); } - + /// /// Matrix x: 1, y: 1 element. /// @@ -89,7 +90,7 @@ public float M11 [MethodImpl(MethodImplOptions.AggressiveInlining)] set => Raw1 = Raw1.WithY(value); } - + /// /// Matrix x: 2, y: 1 element. /// @@ -100,7 +101,7 @@ public float M12 [MethodImpl(MethodImplOptions.AggressiveInlining)] set => Raw1 = Raw1.WithZ(value); } - + /// /// Matrix x: 3, y: 1 element. /// @@ -111,7 +112,7 @@ public float M13 [MethodImpl(MethodImplOptions.AggressiveInlining)] set => Raw1 = Raw1.WithW(value); } - + /// /// Matrix x: 0, y: 2 element. /// @@ -122,7 +123,7 @@ public float M20 [MethodImpl(MethodImplOptions.AggressiveInlining)] set => Raw2 = Raw2.WithX(value); } - + /// /// Matrix x: 1, y: 2 element. /// @@ -133,7 +134,7 @@ public float M21 [MethodImpl(MethodImplOptions.AggressiveInlining)] set => Raw2 = Raw2.WithY(value); } - + /// /// Matrix x: 2, y: 2 element. /// @@ -144,7 +145,7 @@ public float M22 [MethodImpl(MethodImplOptions.AggressiveInlining)] set => Raw2 = Raw2.WithZ(value); } - + /// /// Matrix x: 3, y: 2 element. /// @@ -155,7 +156,7 @@ public float M23 [MethodImpl(MethodImplOptions.AggressiveInlining)] set => Raw2 = Raw2.WithW(value); } - + /// /// Matrix x: 0, y: 3 element. /// @@ -166,7 +167,7 @@ public float M30 [MethodImpl(MethodImplOptions.AggressiveInlining)] set => Raw3 = Raw3.WithX(value); } - + /// /// Matrix x: 1, y: 3 element. /// @@ -177,18 +178,18 @@ public float M31 [MethodImpl(MethodImplOptions.AggressiveInlining)] set => Raw3 = Raw3.WithY(value); } - + /// /// Matrix x: 2, y: 3 element. /// - public float M32 + public float M32 { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => Raw3.Z; [MethodImpl(MethodImplOptions.AggressiveInlining)] set => Raw3 = Raw3.WithZ(value); } - + /// /// Matrix x: 3, y: 3 element. /// @@ -199,11 +200,11 @@ public float M33 [MethodImpl(MethodImplOptions.AggressiveInlining)] set => Raw3 = Raw3.WithW(value); } - + public Matrix4X4(Vector4 value) : this(value, value, value, value) { } - + /// /// Creating matrix /// @@ -226,7 +227,7 @@ public Matrix4X4(float m00, float m01, float m02, float m03, public Matrix4X4(Matrix4X4 matrix4X4) : this(matrix4X4.Raw0, matrix4X4.Raw1, matrix4X4.Raw2, matrix4X4.Raw3) { } - + public bool Equals(Matrix4X4 other) { return Raw0.Equals(other.Raw0) && @@ -244,7 +245,7 @@ public override int GetHashCode() { return HashCode.Combine(Raw0, Raw1, Raw2, Raw3); } - + public override string ToString() { return $"{Raw0}\n{Raw1}\n{Raw2}\n{Raw3}"; @@ -254,29 +255,29 @@ public override string ToString() { var result = Zero; - result.M00 = (a.Raw0 * b.Colum0).Sum(); - result.M01 = (a.Raw0 * b.Colum1).Sum(); - result.M02 = (a.Raw0 * b.Colum2).Sum(); - result.M03 = (a.Raw0 * b.Colum3).Sum(); - - result.M10 = (a.Raw1 * b.Colum0).Sum(); - result.M11 = (a.Raw1 * b.Colum1).Sum(); - result.M12 = (a.Raw1 * b.Colum2).Sum(); - result.M13 = (a.Raw1 * b.Colum3).Sum(); - - result.M20 = (a.Raw2 * b.Colum0).Sum(); - result.M21 = (a.Raw2 * b.Colum1).Sum(); - result.M22 = (a.Raw2 * b.Colum2).Sum(); - result.M23 = (a.Raw2 * b.Colum3).Sum(); - - result.M30 = (a.Raw3 * b.Colum0).Sum(); - result.M31 = (a.Raw3 * b.Colum1).Sum(); - result.M32 = (a.Raw3 * b.Colum2).Sum(); - result.M33 = (a.Raw3 * b.Colum3).Sum(); - + result.M00 = (a.Raw0 * b.Column0).Sum(); + result.M01 = (a.Raw0 * b.Column1).Sum(); + result.M02 = (a.Raw0 * b.Column2).Sum(); + result.M03 = (a.Raw0 * b.Column3).Sum(); + + result.M10 = (a.Raw1 * b.Column0).Sum(); + result.M11 = (a.Raw1 * b.Column1).Sum(); + result.M12 = (a.Raw1 * b.Column2).Sum(); + result.M13 = (a.Raw1 * b.Column3).Sum(); + + result.M20 = (a.Raw2 * b.Column0).Sum(); + result.M21 = (a.Raw2 * b.Column1).Sum(); + result.M22 = (a.Raw2 * b.Column2).Sum(); + result.M23 = (a.Raw2 * b.Column3).Sum(); + + result.M30 = (a.Raw3 * b.Column0).Sum(); + result.M31 = (a.Raw3 * b.Column1).Sum(); + result.M32 = (a.Raw3 * b.Column2).Sum(); + result.M33 = (a.Raw3 * b.Column3).Sum(); + return result; } - + public static Vector4 operator *(Matrix4X4 a, Vector4 b) { return new Vector4( @@ -296,20 +297,26 @@ public override string ToString() return !a.Equals(b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix4X4 Transpose(Matrix4X4 matrix4X4) + { + return new Matrix4X4(matrix4X4.Column0, matrix4X4.Column1, matrix4X4.Column2, matrix4X4.Column3); + } + /// /// Creating scale matrix /// /// v | 0 | 0 | 0 /// 0 | v | 0 | 0 /// 0 | 0 | v | 0 - /// 0 | 0 | 0 | v + /// 0 | 0 | 0 | 1 /// /// public static Matrix4X4 CreateScale(float value) { - return CreateScale(value, value, value, value); + return CreateScale(value, value, value); } - + /// /// Creating scale matrix /// @@ -321,9 +328,9 @@ public static Matrix4X4 CreateScale(float value) /// public static Matrix4X4 CreateScale(Vector2 scale) { - return CreateScale(scale.X, scale.Y, 1f, 1f); + return CreateScale(scale.X, scale.Y, 1f); } - + /// /// Creating scale matrix /// @@ -335,9 +342,9 @@ public static Matrix4X4 CreateScale(Vector2 scale) /// public static Matrix4X4 CreateScale(Vector3 scale) { - return CreateScale(scale.X, scale.Y, scale.Z, 1f); + return CreateScale(scale.X, scale.Y, scale.Z); } - + /// /// Creating scale matrix /// @@ -347,18 +354,64 @@ public static Matrix4X4 CreateScale(Vector3 scale) /// 0 | 0 | 0 | 1 /// /// - public static Matrix4X4 CreateScale(float x, float y, float z, float w) + public static Matrix4X4 CreateScale(float x, float y, float z) { var result = Identity; result.M00 = x; result.M11 = y; result.M22 = z; - result.M33 = w; return result; } + /// + /// Creating translate matrix + /// + /// 1 | 0 | 0 | x + /// 0 | 1 | 0 | y + /// 0 | 0 | 1 | 0 + /// 0 | 0 | 0 | 1 + /// + /// + public static Matrix4X4 CreateTranslate(Vector2 vector2) + { + return CreateTranslate(vector2.X, vector2.Y, 0f); + } + + /// + /// Creating translate matrix + /// + /// 1 | 0 | 0 | x + /// 0 | 1 | 0 | y + /// 0 | 0 | 1 | z + /// 0 | 0 | 0 | 1 + /// + /// + public static Matrix4X4 CreateTranslate(Vector3 vector3) + { + return CreateTranslate(vector3.X, vector3.Y, vector3.Z); + } + + /// + /// Creating translate matrix + /// + /// 1 | 0 | 0 | x + /// 0 | 1 | 0 | y + /// 0 | 0 | 1 | z + /// 0 | 0 | 0 | 1 + /// + /// + public static Matrix4X4 CreateTranslate(float x, float y, float z) + { + var result = Identity; + + result.M03 = x; + result.M13 = y; + result.M23 = z; + + return result; + } /// /// Creating orthographic matrix /// @@ -379,10 +432,10 @@ public static Matrix4X4 CreateOrthographic(Box2 box2, float zNear, float zFar) result.M03 = -(box2.Right + box2.Left) / (box2.Right - box2.Left); result.M13 = -(box2.Top + box2.Bottom) / (box2.Top - box2.Bottom); result.M23 = -(zFar + zNear) / (zFar - zNear); - + return result; } - + /// /// Creating perspective matrix /// @@ -407,13 +460,13 @@ public static Matrix4X4 CreatePerspective(float fov, float aspect, float zNear, var halfFov = fov / 2; var tanHalfFov = (float)System.Math.Tan(halfFov); var zDelta = zFar - zNear; - + result.M00 = 1 / (aspect * tanHalfFov); result.M11 = 1 / tanHalfFov; result.M22 = zFar / zDelta; result.M23 = 1; result.M32 = zFar * zNear / zDelta; - + return result; } -} \ No newline at end of file +} diff --git a/Hypercube.Shared.Math/Vector/Vector2.Compability.cs b/Hypercube.Shared.Math/Vector/Vector2.Compability.cs index 5462fa9..0f012c5 100644 --- a/Hypercube.Shared.Math/Vector/Vector2.Compability.cs +++ b/Hypercube.Shared.Math/Vector/Vector2.Compability.cs @@ -4,6 +4,12 @@ namespace Hypercube.Shared.Math.Vector; public readonly partial struct Vector2 { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector3(Vector2 vector) + { + return new Vector3(vector.X, vector.Y, 0f); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Vector2(System.Numerics.Vector2 vector) { diff --git a/Hypercube.Shared.Math/Vector/Vector3.Compability.cs b/Hypercube.Shared.Math/Vector/Vector3.Compability.cs new file mode 100644 index 0000000..2045295 --- /dev/null +++ b/Hypercube.Shared.Math/Vector/Vector3.Compability.cs @@ -0,0 +1,12 @@ +using System.Runtime.CompilerServices; + +namespace Hypercube.Shared.Math.Vector; + +public readonly partial struct Vector3 +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector2(Vector3 vector) + { + return new Vector2(vector.X, vector.Y); + } +} \ No newline at end of file diff --git a/Hypercube.Shared.Math/Vector/Vector3.cs b/Hypercube.Shared.Math/Vector/Vector3.cs index 6bc7cd8..07a5342 100644 --- a/Hypercube.Shared.Math/Vector/Vector3.cs +++ b/Hypercube.Shared.Math/Vector/Vector3.cs @@ -2,7 +2,7 @@ namespace Hypercube.Shared.Math.Vector; -public readonly struct Vector3(float x, float y, float z) +public readonly partial struct Vector3(float x, float y, float z) { public static readonly Vector3 Zero = new(0, 0, 0); public static readonly Vector3 One = new(1, 1, 1); @@ -20,10 +20,17 @@ public readonly struct Vector3(float x, float y, float z) public readonly float Y = y; public readonly float Z = z; + public float Length => (float)System.Math.Sqrt(X * X + Y * Y + Z * Z); + public Vector3 Normalized => this / Length; + public Vector3(float value) : this(value, value, value) { } + public Vector3(Vector2 vector2) : this(vector2.X, vector2.Y, 0) + { + } + public Vector3(Vector2 vector2, float z) : this(vector2.X, vector2.Y, z) { } @@ -56,6 +63,18 @@ public Vector3 WithZ(float value) return new Vector3(X, Y, value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 Cross(Vector3 other) + { + return Vector3.Cross(this, other); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override string ToString() + { + return $"{x}, {y}, {z}"; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 operator +(Vector3 a, Vector3 b) { @@ -135,8 +154,11 @@ public Vector3 WithZ(float value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override string ToString() + public static Vector3 Cross(Vector3 left, Vector3 right) { - return $"{x}, {y}, {z}"; + return new Vector3( + left.Y * right.Z - left.Z * right.Y, + left.Z * right.X - left.X * right.Z, + left.X * right.Y - left.Y * right.X); } } \ No newline at end of file diff --git a/Hypercube.Shared.Math/Vector/Vector4.Compability.cs b/Hypercube.Shared.Math/Vector/Vector4.Compability.cs new file mode 100644 index 0000000..9d42586 --- /dev/null +++ b/Hypercube.Shared.Math/Vector/Vector4.Compability.cs @@ -0,0 +1,30 @@ +using System.Runtime.CompilerServices; + +namespace Hypercube.Shared.Math.Vector; + +public readonly partial struct Vector4 +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector4(System.Numerics.Vector4 vector4) + { + return new Vector4(vector4.X, vector4.Y, vector4.Z, vector4.W); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator System.Numerics.Vector4(Vector4 vector4) + { + return new System.Numerics.Vector4(vector4.X, vector4.Y, vector4.Z, vector4.W); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector4(OpenTK.Mathematics.Vector4 vector4) + { + return new Vector4(vector4.X, vector4.Y, vector4.Z, vector4.W); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator OpenTK.Mathematics.Vector4(Vector4 vector4) + { + return new OpenTK.Mathematics.Vector4(vector4.X, vector4.Y, vector4.Z, vector4.W); + } +} \ No newline at end of file diff --git a/Hypercube.Shared.Math/Vector/Vector4.cs b/Hypercube.Shared.Math/Vector/Vector4.cs index d1e9486..00f154f 100644 --- a/Hypercube.Shared.Math/Vector/Vector4.cs +++ b/Hypercube.Shared.Math/Vector/Vector4.cs @@ -3,7 +3,7 @@ namespace Hypercube.Shared.Math.Vector; -public readonly struct Vector4(float x, float y, float z, float w) : IEquatable +public readonly partial struct Vector4(float x, float y, float z, float w) : IEquatable { public static readonly Vector4 Zero = new(0, 0, 0, 0); public static readonly Vector4 One = new(1, 1, 1, 1); @@ -25,7 +25,7 @@ public Vector4(Vector2 vector2, float z, float w) : this(vector2.X, vector2.Y, z { } - public Vector4(Vector4 Vector4, float w) : this(Vector4.X, Vector4.Y, Vector4.Z, w) + public Vector4(Vector4 vector4, float w) : this(vector4.X, vector4.Y, vector4.Z, w) { } diff --git a/Resources/Shaders/base.frag b/Resources/Shaders/base.frag index e58fb8f..88f9e22 100644 --- a/Resources/Shaders/base.frag +++ b/Resources/Shaders/base.frag @@ -8,6 +8,6 @@ in vec2 TexCoord; uniform sampler2D texture0; void main() -{ - FragColor = texture(texture0, TexCoord) * Color; +{ + FragColor = texture(texture0, TexCoord) * Color; } \ No newline at end of file diff --git a/Resources/Shaders/base.vert b/Resources/Shaders/base.vert index 9a5affb..08cc46d 100644 --- a/Resources/Shaders/base.vert +++ b/Resources/Shaders/base.vert @@ -7,10 +7,13 @@ layout (location = 2) in vec2 aTexCoord; out vec4 Color; out vec2 TexCoord; +uniform mat4 projection; +uniform mat4 model; + void main() { - gl_Position = vec4(aPos, 1.0); + gl_Position = vec4(aPos, 1.0); - Color = aColor; - TexCoord = aTexCoord; + Color = aColor; + TexCoord = aTexCoord; } \ No newline at end of file From 815f41427f7faed6161157f212d8a211065ef041 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 11 Jul 2024 09:38:16 +1000 Subject: [PATCH 02/19] Added StructLayout to evrything --- Hypercube.Client/Graphics/Vertex.cs | 2 +- Hypercube.Shared.Math/Color.cs | 2 ++ Hypercube.Shared.Math/Matrix/Matrix3X3.cs | 2 ++ Hypercube.Shared.Math/Matrix/Matrix4X4.cs | 2 ++ Hypercube.Shared.Math/Vector/Vector2.cs | 2 ++ Hypercube.Shared.Math/Vector/Vector2Int.cs | 8 ++++++-- Hypercube.Shared.Math/Vector/Vector3.cs | 17 ++++++++++++++--- Hypercube.Shared.Math/Vector/Vector4.cs | 2 ++ 8 files changed, 31 insertions(+), 6 deletions(-) diff --git a/Hypercube.Client/Graphics/Vertex.cs b/Hypercube.Client/Graphics/Vertex.cs index 62523b4..9ba010f 100644 --- a/Hypercube.Client/Graphics/Vertex.cs +++ b/Hypercube.Client/Graphics/Vertex.cs @@ -12,8 +12,8 @@ public readonly struct Vertex private static readonly Color DefaultColor = Color.White; public readonly Vector3 Position; - public readonly Vector2 UVCoords; public readonly Color Color; + public readonly Vector2 UVCoords; public Vertex(Vector3 position, Vector2 uvCoords, Color color) { diff --git a/Hypercube.Shared.Math/Color.cs b/Hypercube.Shared.Math/Color.cs index a926016..6ecd9ee 100644 --- a/Hypercube.Shared.Math/Color.cs +++ b/Hypercube.Shared.Math/Color.cs @@ -1,8 +1,10 @@ using System.Globalization; +using System.Runtime.InteropServices; using Hypercube.Shared.Math.Vector; namespace Hypercube.Shared.Math; +[StructLayout(LayoutKind.Sequential)] public readonly struct Color { public static readonly Color White = new(1f, 1f, 1f); diff --git a/Hypercube.Shared.Math/Matrix/Matrix3X3.cs b/Hypercube.Shared.Math/Matrix/Matrix3X3.cs index d2a7c36..4c6cbb1 100644 --- a/Hypercube.Shared.Math/Matrix/Matrix3X3.cs +++ b/Hypercube.Shared.Math/Matrix/Matrix3X3.cs @@ -1,8 +1,10 @@ using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using Hypercube.Shared.Math.Vector; namespace Hypercube.Shared.Math.Matrix; +[StructLayout(LayoutKind.Sequential)] public struct Matrix3X3(Vector3 x, Vector3 y, Vector3 z) { private const int IndexRaw0 = 0; diff --git a/Hypercube.Shared.Math/Matrix/Matrix4X4.cs b/Hypercube.Shared.Math/Matrix/Matrix4X4.cs index aa924d7..95ca417 100644 --- a/Hypercube.Shared.Math/Matrix/Matrix4X4.cs +++ b/Hypercube.Shared.Math/Matrix/Matrix4X4.cs @@ -1,9 +1,11 @@ using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using Hypercube.Shared.Math.Box; using Hypercube.Shared.Math.Vector; namespace Hypercube.Shared.Math.Matrix; +[StructLayout(LayoutKind.Sequential)] public partial struct Matrix4X4(Vector4 x, Vector4 y, Vector4 z, Vector4 w) : IEquatable { public static Matrix4X4 Zero => new(Vector4.Zero); diff --git a/Hypercube.Shared.Math/Vector/Vector2.cs b/Hypercube.Shared.Math/Vector/Vector2.cs index 61b3cf9..8ce7e98 100644 --- a/Hypercube.Shared.Math/Vector/Vector2.cs +++ b/Hypercube.Shared.Math/Vector/Vector2.cs @@ -1,7 +1,9 @@ using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace Hypercube.Shared.Math.Vector; +[StructLayout(LayoutKind.Sequential)] public readonly partial struct Vector2(float x, float y) : IEquatable { public static readonly Vector2 Zero = new(0, 0); diff --git a/Hypercube.Shared.Math/Vector/Vector2Int.cs b/Hypercube.Shared.Math/Vector/Vector2Int.cs index 63aaf8e..c61fba7 100644 --- a/Hypercube.Shared.Math/Vector/Vector2Int.cs +++ b/Hypercube.Shared.Math/Vector/Vector2Int.cs @@ -1,5 +1,8 @@ -namespace Hypercube.Shared.Math.Vector; +using System.Runtime.InteropServices; +namespace Hypercube.Shared.Math.Vector; + +[StructLayout(LayoutKind.Sequential)] public readonly partial struct Vector2Int(int x, int y) { public static readonly Vector2Int Zero = new(0, 0); @@ -11,7 +14,8 @@ public readonly partial struct Vector2Int(int x, int y) public readonly int X = x; public readonly int Y = y; - public readonly float Ratio = x / (float)y; + + public float Ratio => x / (float)y; public static Vector2Int operator +(Vector2Int a, Vector2Int b) { diff --git a/Hypercube.Shared.Math/Vector/Vector3.cs b/Hypercube.Shared.Math/Vector/Vector3.cs index 07a5342..b6912a5 100644 --- a/Hypercube.Shared.Math/Vector/Vector3.cs +++ b/Hypercube.Shared.Math/Vector/Vector3.cs @@ -1,7 +1,9 @@ using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace Hypercube.Shared.Math.Vector; +[StructLayout(LayoutKind.Sequential)] public readonly partial struct Vector3(float x, float y, float z) { public static readonly Vector3 Zero = new(0, 0, 0); @@ -20,9 +22,18 @@ public readonly partial struct Vector3(float x, float y, float z) public readonly float Y = y; public readonly float Z = z; - public float Length => (float)System.Math.Sqrt(X * X + Y * Y + Z * Z); - public Vector3 Normalized => this / Length; - + public float Length + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => MathF.Sqrt(X * X + Y * Y + Z * Z); + } + + public Vector3 Normalized + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => this / Length; + } + public Vector3(float value) : this(value, value, value) { } diff --git a/Hypercube.Shared.Math/Vector/Vector4.cs b/Hypercube.Shared.Math/Vector/Vector4.cs index 00f154f..2f1b43b 100644 --- a/Hypercube.Shared.Math/Vector/Vector4.cs +++ b/Hypercube.Shared.Math/Vector/Vector4.cs @@ -1,8 +1,10 @@ using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using Hypercube.Shared.Math.Extensions; namespace Hypercube.Shared.Math.Vector; +[StructLayout(LayoutKind.Sequential)] public readonly partial struct Vector4(float x, float y, float z, float w) : IEquatable { public static readonly Vector4 Zero = new(0, 0, 0, 0); From ab71dda1a1c414488a2f3b71895a0e4305affab2 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:31:21 +1000 Subject: [PATCH 03/19] Crated strange camera working --- .../Graphics/Rendering/Renderer.Render.cs | 18 +- Hypercube.Client/Graphics/Shading/Shader.cs | 9 +- .../Graphics/Viewports/Camera2D.cs | 13 +- .../Graphics/Viewports/CameraManager.cs | 29 ++- .../Graphics/Viewports/ICameraManager.cs | 1 + .../Matrix/Matrix4X4.Compability.cs | 2 +- Hypercube.Shared.Math/Matrix/Matrix4X4.cs | 185 ++++++++++-------- Hypercube.Shared.Math/Vector/Vector4.cs | 22 ++- Resources/Shaders/base.vert | 2 +- 9 files changed, 152 insertions(+), 129 deletions(-) diff --git a/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs b/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs index 8c5ab2c..edc2dc1 100644 --- a/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs +++ b/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs @@ -1,4 +1,5 @@ -using Hypercube.Client.Graphics.Shading; +using System.Numerics; +using Hypercube.Client.Graphics.Shading; using Hypercube.Client.Graphics.Texturing; using Hypercube.Client.Graphics.Viewports; using Hypercube.Shared.Math; @@ -35,7 +36,7 @@ private void OnLoad() _baseTexture = _textureManager.CreateHandler("Resources/Textures/opengl_logo.png"); _baseTexture.Bind(); - //_cameraManager.SetMainCamera(_cameraManager.CreateCamera2D(MainWindow.Size)); + _cameraManager.SetMainCamera(_cameraManager.CreateCamera2D(MainWindow.Size)); _vbo = new BufferObject(BufferTarget.ArrayBuffer); _ebo = new BufferObject(BufferTarget.ElementArrayBuffer); @@ -64,6 +65,7 @@ private void OnFrameUpdate(UpdateFrameEvent args) _windowManager.WindowSetTitle(MainWindow, $"FPS: {_timing.Fps} | RealTime: {_timing.RealTime} | cPos: {_cameraManager.MainCamera?.Position ?? null}"); #endif _windowManager.PollEvents(); + _cameraManager.UpdateInput(_cameraManager.MainCamera, args.DeltaSeconds); } private void OnFrameRender(RenderFrameEvent args) @@ -80,16 +82,16 @@ private void OnFrameRender(RenderFrameEvent args) var colorG = new Color(0f, sin, 0f); var colorB = new Color(0f, 0f, sin); - DrawTexture(_baseTexture, new Box2(-1.0f, 1.0f, 0.0f, 0.0f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), Color.White); - DrawTexture(_baseTexture, new Box2(0.0f, 1.0f, 1.0f, 0.0f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorR); - DrawTexture(_baseTexture, new Box2(-1.0f, 0.0f, 0.0f, -1.0f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorG); - DrawTexture(_baseTexture, new Box2(0.0f, 0.0f, 1.0f, -1.0f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorB); + DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(Vector2.Zero), new Box2(0.0f, 1.0f, 1.0f, 0.0f), Color.White); + //DrawTexture(_baseTexture, new Box2(0.0f, 1.0f, 1.0f, 0.0f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorR); + //DrawTexture(_baseTexture, new Box2(-1.0f, 0.0f, 0.0f, -1.0f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorG); + // DrawTexture(_baseTexture, new Box2(0.0f, 0.0f, 1.0f, -1.0f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorB); BatchUpdate(); _baseShader.Use(); - _baseShader.SetUniform(_baseShader.GetUniformLocation("model"), Matrix4X4.Identity); - _baseShader.SetUniform(_baseShader.GetUniformLocation("projection"), _cameraManager.Projection); + _baseShader.SetUniform("model", Matrix4X4.CreateScale(0.1f)); + _baseShader.SetUniform("projection", _cameraManager.Projection); _vao.Bind(); GL.DrawElements(BeginMode.Triangles, (int) _batchIndexIndex, DrawElementsType.UnsignedInt, 0); diff --git a/Hypercube.Client/Graphics/Shading/Shader.cs b/Hypercube.Client/Graphics/Shading/Shader.cs index 6870968..3aed54a 100644 --- a/Hypercube.Client/Graphics/Shading/Shader.cs +++ b/Hypercube.Client/Graphics/Shading/Shader.cs @@ -87,12 +87,9 @@ public void SetUniform(string name, Matrix4X4 value, bool transpose = false) public void SetUniform(int index, Matrix4X4 value, bool transpose = false) { - unsafe - { - var matrix = transpose ? Matrix4X4.Transpose(value) : new Matrix4X4(value); - GL.UseProgram(_handle); - GL.UniformMatrix4(index, 1, false, (float*) &matrix); - } + var matrix = transpose ? Matrix4X4.Transpose(value) : new Matrix4X4(value); + GL.UseProgram(_handle); + GL.UniformMatrix4(index, 1, false, matrix.ToArray()); } private int CreateShader(string path, ShaderType type) diff --git a/Hypercube.Client/Graphics/Viewports/Camera2D.cs b/Hypercube.Client/Graphics/Viewports/Camera2D.cs index f4f8a26..d46b3cf 100644 --- a/Hypercube.Client/Graphics/Viewports/Camera2D.cs +++ b/Hypercube.Client/Graphics/Viewports/Camera2D.cs @@ -11,7 +11,7 @@ public class Camera2D : ICamera private readonly float _zFar; private readonly float _zNear; private Vector2Int Size { get; set; } - private float Zoom { get; set; } = 1f; + private float Zoom { get; set; } = 10f; private Vector2 HalfSize => Size / 2f; public Matrix4X4 Projection { get; private set; } @@ -46,11 +46,10 @@ public void SetZoom(float zoom) private void UpdateProjection() { - var position = (Vector2)Position; - var box2 = new Box2(position - HalfSize, position + HalfSize); - var projection = Matrix4X4.CreateOrthographic(box2, _zNear, _zFar); - var scale = Matrix4X4.CreateScale(Zoom); - - Projection = projection * scale; + var projection = Matrix4X4.CreateOrthographic(HalfSize, _zNear, _zFar); + var scale = Matrix4X4.CreateScale(Zoom); + var translate = Matrix4X4.CreateTranslate(Position); + + Projection = projection * scale * translate; } } \ No newline at end of file diff --git a/Hypercube.Client/Graphics/Viewports/CameraManager.cs b/Hypercube.Client/Graphics/Viewports/CameraManager.cs index ae6273f..d9ed9bf 100644 --- a/Hypercube.Client/Graphics/Viewports/CameraManager.cs +++ b/Hypercube.Client/Graphics/Viewports/CameraManager.cs @@ -8,47 +8,40 @@ namespace Hypercube.Client.Graphics.Viewports; -public class CameraManager : ICameraManager, IPostInject +public class CameraManager : ICameraManager { - [Dependency] private readonly IEventBus _eventBus = default!; [Dependency] private readonly IInputHandler _inputHandler = default!; public ICamera? MainCamera { get; private set; } - public Matrix4X4 Projection => MainCamera?.Projection ?? Matrix4X4.Identity; - public void PostInject() - { - _eventBus.Subscribe(OnUpdate); - } - - private void OnUpdate(UpdateFrameEvent args) + public void UpdateInput(ICamera? camera, float delta) { - if (MainCamera is null) + if (camera is null) return; // Debug camera controls - var position = MainCamera.Position; + var position = camera.Position; if (_inputHandler.IsKeyDown(Key.W)) - position += Vector3.Forward; + position += Vector3.Forward * delta; if (_inputHandler.IsKeyDown(Key.S)) - position -= Vector3.Back; + position -= Vector3.Forward * delta; if (_inputHandler.IsKeyDown(Key.A)) - position -= Vector3.Forward.Cross(Vector3.Up).Normalized; + position -= Vector3.Right * delta; if (_inputHandler.IsKeyDown(Key.D)) - position += Vector3.Forward.Cross(Vector3.Up).Normalized; + position += Vector3.Right * delta; if (_inputHandler.IsKeyDown(Key.Space)) - position += Vector3.Up; + position += Vector3.Up * delta; if (_inputHandler.IsKeyDown(Key.LeftShift)) - position -= Vector3.Up; + position -= Vector3.Up * delta; - MainCamera.SetPosition(position); + camera.SetPosition(position); } public void SetMainCamera(ICamera camera) diff --git a/Hypercube.Client/Graphics/Viewports/ICameraManager.cs b/Hypercube.Client/Graphics/Viewports/ICameraManager.cs index 1a35c26..035fc39 100644 --- a/Hypercube.Client/Graphics/Viewports/ICameraManager.cs +++ b/Hypercube.Client/Graphics/Viewports/ICameraManager.cs @@ -9,4 +9,5 @@ public interface ICameraManager Matrix4X4 Projection { get; } void SetMainCamera(ICamera camera); ICamera CreateCamera2D(Vector2Int size); + void UpdateInput(ICamera? camera, float delta); } \ No newline at end of file diff --git a/Hypercube.Shared.Math/Matrix/Matrix4X4.Compability.cs b/Hypercube.Shared.Math/Matrix/Matrix4X4.Compability.cs index 2febb57..f930d1c 100644 --- a/Hypercube.Shared.Math/Matrix/Matrix4X4.Compability.cs +++ b/Hypercube.Shared.Math/Matrix/Matrix4X4.Compability.cs @@ -7,6 +7,6 @@ public partial struct Matrix4X4 [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OpenTK.Mathematics.Matrix4(Matrix4X4 matrix4X4) { - return new OpenTK.Mathematics.Matrix4(matrix4X4.Raw0, matrix4X4.Raw1, matrix4X4.Raw2, matrix4X4.Raw3); + return new OpenTK.Mathematics.Matrix4(matrix4X4.Row0, matrix4X4.Row1, matrix4X4.Row2, matrix4X4.Row3); } } \ No newline at end of file diff --git a/Hypercube.Shared.Math/Matrix/Matrix4X4.cs b/Hypercube.Shared.Math/Matrix/Matrix4X4.cs index 95ca417..155da8a 100644 --- a/Hypercube.Shared.Math/Matrix/Matrix4X4.cs +++ b/Hypercube.Shared.Math/Matrix/Matrix4X4.cs @@ -6,8 +6,10 @@ namespace Hypercube.Shared.Math.Matrix; [StructLayout(LayoutKind.Sequential)] -public partial struct Matrix4X4(Vector4 x, Vector4 y, Vector4 z, Vector4 w) : IEquatable +public partial struct Matrix4X4 : IEquatable { + public const int Size = 4 * Vector4.Size; + public static Matrix4X4 Zero => new(Vector4.Zero); public static Matrix4X4 One => new(Vector4.One); @@ -17,10 +19,10 @@ public partial struct Matrix4X4(Vector4 x, Vector4 y, Vector4 z, Vector4 w) : IE 0, 0, 1, 0, 0, 0, 0, 1); - public Vector4 Raw0 = x; - public Vector4 Raw1 = y; - public Vector4 Raw2 = z; - public Vector4 Raw3 = w; + public Vector4 Row0; + public Vector4 Row1; + public Vector4 Row2; + public Vector4 Row3; public Vector4 Column0 => new(M00, M10, M20, M30); public Vector4 Column1 => new(M01, M11, M21, M31); @@ -33,9 +35,9 @@ public partial struct Matrix4X4(Vector4 x, Vector4 y, Vector4 z, Vector4 w) : IE public float M00 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw0.X; + get => Row0.X; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw0 = Raw0.WithX(value); + set => Row0 = Row0.WithX(value); } /// @@ -44,9 +46,9 @@ public float M00 public float M01 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw0.Y; + get => Row0.Y; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw0 = Raw0.WithY(value); + set => Row0 = Row0.WithY(value); } /// @@ -55,9 +57,9 @@ public float M01 public float M02 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw0.Z; + get => Row0.Z; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw0 = Raw0.WithZ(value); + set => Row0 = Row0.WithZ(value); } /// @@ -66,9 +68,9 @@ public float M02 public float M03 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw0.W; + get => Row0.W; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw0 = Raw0.WithW(value); + set => Row0 = Row0.WithW(value); } /// @@ -77,9 +79,9 @@ public float M03 public float M10 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw1.X; + get => Row1.X; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw1 = Raw1.WithX(value); + set => Row1 = Row1.WithX(value); } /// @@ -88,9 +90,9 @@ public float M10 public float M11 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw1.Y; + get => Row1.Y; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw1 = Raw1.WithY(value); + set => Row1 = Row1.WithY(value); } /// @@ -99,9 +101,9 @@ public float M11 public float M12 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw1.Z; + get => Row1.Z; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw1 = Raw1.WithZ(value); + set => Row1 = Row1.WithZ(value); } /// @@ -110,9 +112,9 @@ public float M12 public float M13 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw1.W; + get => Row1.W; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw1 = Raw1.WithW(value); + set => Row1 = Row1.WithW(value); } /// @@ -121,9 +123,9 @@ public float M13 public float M20 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw2.X; + get => Row2.X; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw2 = Raw2.WithX(value); + set => Row2 = Row2.WithX(value); } /// @@ -132,9 +134,9 @@ public float M20 public float M21 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw2.Y; + get => Row2.Y; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw2 = Raw2.WithY(value); + set => Row2 = Row2.WithY(value); } /// @@ -143,9 +145,9 @@ public float M21 public float M22 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw2.Z; + get => Row2.Z; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw2 = Raw2.WithZ(value); + set => Row2 = Row2.WithZ(value); } /// @@ -154,9 +156,9 @@ public float M22 public float M23 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw2.W; + get => Row2.W; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw2 = Raw2.WithW(value); + set => Row2 = Row2.WithW(value); } /// @@ -165,9 +167,9 @@ public float M23 public float M30 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw3.X; + get => Row3.X; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw3 = Raw3.WithX(value); + set => Row3 = Row3.WithX(value); } /// @@ -176,9 +178,9 @@ public float M30 public float M31 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw3.Y; + get => Row3.Y; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw3 = Raw3.WithY(value); + set => Row3 = Row3.WithY(value); } /// @@ -187,9 +189,9 @@ public float M31 public float M32 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw3.Z; + get => Row3.Z; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw3 = Raw3.WithZ(value); + set => Row3 = Row3.WithZ(value); } /// @@ -198,11 +200,19 @@ public float M32 public float M33 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw3.W; + get => Row3.W; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw3 = Raw3.WithW(value); + set => Row3 = Row3.WithW(value); } + public Matrix4X4(Vector4 x, Vector4 y, Vector4 z, Vector4 w) + { + Row0 = x; + Row1 = y; + Row2 = z; + Row3 = w; + } + public Matrix4X4(Vector4 value) : this(value, value, value, value) { } @@ -226,16 +236,27 @@ public Matrix4X4(float m00, float m01, float m02, float m03, { } - public Matrix4X4(Matrix4X4 matrix4X4) : this(matrix4X4.Raw0, matrix4X4.Raw1, matrix4X4.Raw2, matrix4X4.Raw3) + public Matrix4X4(Matrix4X4 matrix4X4) : this(matrix4X4.Row0, matrix4X4.Row1, matrix4X4.Row2, matrix4X4.Row3) { } public bool Equals(Matrix4X4 other) { - return Raw0.Equals(other.Raw0) && - Raw1.Equals(other.Raw1) && - Raw2.Equals(other.Raw2) && - Raw3.Equals(other.Raw3); + return Row0.Equals(other.Row0) && + Row1.Equals(other.Row1) && + Row2.Equals(other.Row2) && + Row3.Equals(other.Row3); + } + + public float[] ToArray() + { + return new float[] + { + M00, M01, M02, M03, + M10, M11, M12, M13, + M20, M21, M22, M23, + M30, M31, M32, M33 + }; } public override bool Equals(object? obj) @@ -245,37 +266,37 @@ public override bool Equals(object? obj) public override int GetHashCode() { - return HashCode.Combine(Raw0, Raw1, Raw2, Raw3); + return HashCode.Combine(Row0, Row1, Row2, Row3); } public override string ToString() { - return $"{Raw0}\n{Raw1}\n{Raw2}\n{Raw3}"; + return $"{Row0}\n{Row1}\n{Row2}\n{Row3}"; } public static Matrix4X4 operator *(Matrix4X4 a, Matrix4X4 b) { var result = Zero; - result.M00 = (a.Raw0 * b.Column0).Sum(); - result.M01 = (a.Raw0 * b.Column1).Sum(); - result.M02 = (a.Raw0 * b.Column2).Sum(); - result.M03 = (a.Raw0 * b.Column3).Sum(); + result.M00 = (a.Row0 * b.Column0).Sum(); + result.M01 = (a.Row0 * b.Column1).Sum(); + result.M02 = (a.Row0 * b.Column2).Sum(); + result.M03 = (a.Row0 * b.Column3).Sum(); - result.M10 = (a.Raw1 * b.Column0).Sum(); - result.M11 = (a.Raw1 * b.Column1).Sum(); - result.M12 = (a.Raw1 * b.Column2).Sum(); - result.M13 = (a.Raw1 * b.Column3).Sum(); + result.M10 = (a.Row1 * b.Column0).Sum(); + result.M11 = (a.Row1 * b.Column1).Sum(); + result.M12 = (a.Row1 * b.Column2).Sum(); + result.M13 = (a.Row1 * b.Column3).Sum(); - result.M20 = (a.Raw2 * b.Column0).Sum(); - result.M21 = (a.Raw2 * b.Column1).Sum(); - result.M22 = (a.Raw2 * b.Column2).Sum(); - result.M23 = (a.Raw2 * b.Column3).Sum(); + result.M20 = (a.Row2 * b.Column0).Sum(); + result.M21 = (a.Row2 * b.Column1).Sum(); + result.M22 = (a.Row2 * b.Column2).Sum(); + result.M23 = (a.Row2 * b.Column3).Sum(); - result.M30 = (a.Raw3 * b.Column0).Sum(); - result.M31 = (a.Raw3 * b.Column1).Sum(); - result.M32 = (a.Raw3 * b.Column2).Sum(); - result.M33 = (a.Raw3 * b.Column3).Sum(); + result.M30 = (a.Row3 * b.Column0).Sum(); + result.M31 = (a.Row3 * b.Column1).Sum(); + result.M32 = (a.Row3 * b.Column2).Sum(); + result.M33 = (a.Row3 * b.Column3).Sum(); return result; } @@ -283,10 +304,10 @@ public override string ToString() public static Vector4 operator *(Matrix4X4 a, Vector4 b) { return new Vector4( - (a.Raw0 * b).Sum(), - (a.Raw1 * b).Sum(), - (a.Raw2 * b).Sum(), - (a.Raw3 * b).Sum()); + (a.Row0 * b).Sum(), + (a.Row1 * b).Sum(), + (a.Row2 * b).Sum(), + (a.Row3 * b).Sum()); } public static bool operator ==(Matrix4X4 a, Matrix4X4 b) @@ -414,27 +435,27 @@ public static Matrix4X4 CreateTranslate(float x, float y, float z) return result; } - /// - /// Creating orthographic matrix - /// - /// 2 / (r - l) | 0 | 0 | -(r + l) / (r - l) - /// 0 | 2 / (t - b) | 0 | -(t + b) / (t - b) - /// 0 | 0 | -2 / (zF - zN) | -(zF + zN) / (zF - zN) - /// 0 | 0 | 0 | 1 - /// - /// + public static Matrix4X4 CreateOrthographic(Box2 box2, float zNear, float zFar) + { + return CreateOrthographic(box2.Width, box2.Height, zNear, zFar); + } + + public static Matrix4X4 CreateOrthographic(Vector2 size, float zNear, float zFar) + { + return CreateOrthographic(size.X, size.Y, zNear, zFar); + } + + public static Matrix4X4 CreateOrthographic(float width, float height, float zNear, float zFar) { var result = Identity; - - result.M00 = 2 / (box2.Right - box2.Left); - result.M11 = 2 / (box2.Top - box2.Bottom); - result.M22 = -2 / (zFar - zNear); - - result.M03 = -(box2.Right + box2.Left) / (box2.Right - box2.Left); - result.M13 = -(box2.Top + box2.Bottom) / (box2.Top - box2.Bottom); - result.M23 = -(zFar + zNear) / (zFar - zNear); - + var range = 1.0f / (zNear - zFar); + + result.Row0 = new Vector4(2.0f / width, 0, 0, 0); + result.Row1 = new Vector4(0, 2.0f / height, 0, 0); + result.Row2 = new Vector4(0, 0, range, 0); + result.Row3 = new Vector4(0, 0, range * zNear, 1); + return result; } diff --git a/Hypercube.Shared.Math/Vector/Vector4.cs b/Hypercube.Shared.Math/Vector/Vector4.cs index 2f1b43b..95bc583 100644 --- a/Hypercube.Shared.Math/Vector/Vector4.cs +++ b/Hypercube.Shared.Math/Vector/Vector4.cs @@ -5,8 +5,10 @@ namespace Hypercube.Shared.Math.Vector; [StructLayout(LayoutKind.Sequential)] -public readonly partial struct Vector4(float x, float y, float z, float w) : IEquatable +public readonly partial struct Vector4 : IEquatable { + public const int Size = 4 * sizeof(float); + public static readonly Vector4 Zero = new(0, 0, 0, 0); public static readonly Vector4 One = new(1, 1, 1, 1); public static readonly Vector4 UnitX = new(1, 0, 0, 0); @@ -14,11 +16,19 @@ public readonly partial struct Vector4(float x, float y, float z, float w) : IEq public static readonly Vector4 UnitZ = new(0, 0, 1, 0); public static readonly Vector4 UnitW = new(0, 0, 0, 1); - public readonly float X = x; - public readonly float Y = y; - public readonly float Z = z; - public readonly float W = w; + public readonly float X; + public readonly float Y; + public readonly float Z; + public readonly float W; + public Vector4(float x, float y, float z, float w) + { + X = x; + Y = y; + Z = z; + W = w; + } + public Vector4(float value) : this(value, value, value, value) { } @@ -81,7 +91,7 @@ public override bool Equals(object? obj) [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { - return $"{x}, {y}, {z}, {w}"; + return $"{X}, {Y}, {Z}, {W}"; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Resources/Shaders/base.vert b/Resources/Shaders/base.vert index 08cc46d..4f59d2f 100644 --- a/Resources/Shaders/base.vert +++ b/Resources/Shaders/base.vert @@ -12,7 +12,7 @@ uniform mat4 model; void main() { - gl_Position = vec4(aPos, 1.0); + gl_Position = model * projection * vec4(aPos, 1.0); Color = aColor; TexCoord = aTexCoord; From 23f996405ffe2f948ebb0a8ece88b42cb49bfd18 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:39:47 +1000 Subject: [PATCH 04/19] Less zoom value --- Hypercube.Client/Graphics/Viewports/Camera2D.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hypercube.Client/Graphics/Viewports/Camera2D.cs b/Hypercube.Client/Graphics/Viewports/Camera2D.cs index d46b3cf..0a99a70 100644 --- a/Hypercube.Client/Graphics/Viewports/Camera2D.cs +++ b/Hypercube.Client/Graphics/Viewports/Camera2D.cs @@ -11,7 +11,7 @@ public class Camera2D : ICamera private readonly float _zFar; private readonly float _zNear; private Vector2Int Size { get; set; } - private float Zoom { get; set; } = 10f; + private float Zoom { get; set; } = 1f; private Vector2 HalfSize => Size / 2f; public Matrix4X4 Projection { get; private set; } From c3eff984c6a08db944a4cf0ecc991bd75619fe85 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:44:54 +1000 Subject: [PATCH 05/19] Updated rendering --- Hypercube.Client/Graphics/Rendering/Renderer.Render.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs b/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs index 1dda4c0..901aae8 100644 --- a/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs +++ b/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs @@ -82,15 +82,15 @@ private void OnFrameRender(RenderFrameEvent args) var colorG = new Color(0f, sin, 0f); var colorB = new Color(0f, 0f, sin); - DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(Vector2.Zero), new Box2(0.0f, 1.0f, 1.0f, 0.0f), Color.White); - //DrawTexture(_baseTexture, new Box2(0.0f, 1.0f, 1.0f, 0.0f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorR); - //DrawTexture(_baseTexture, new Box2(-1.0f, 0.0f, 0.0f, -1.0f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorG); - // DrawTexture(_baseTexture, new Box2(0.0f, 0.0f, 1.0f, -1.0f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorB); + DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(-Vector2.UnitY * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), Color.White); + DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(Vector2.UnitX * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorR); + DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(-Vector2.UnitX * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorG); + DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(Vector2.UnitY * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorB); BatchUpdate(); _baseShader.Use(); - _baseShader.SetUniform("model", Matrix4X4.CreateScale(0.1f)); + _baseShader.SetUniform("model", Matrix4X4.CreateScale(1f)); _baseShader.SetUniform("projection", _cameraManager.Projection); _vao.Bind(); From caf46457b43e3784366732fef8a32a742d7c913a Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:55:41 +1000 Subject: [PATCH 06/19] Updated camera & math --- .../Graphics/Rendering/Renderer.Render.cs | 11 +++++--- .../Graphics/Viewports/Camera2D.cs | 2 +- .../Graphics/Viewports/CameraManager.cs | 2 +- Hypercube.Shared.Math/Matrix/Matrix4X4.cs | 27 +++++++++---------- Resources/Shaders/base.vert | 3 ++- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs b/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs index 901aae8..af92825 100644 --- a/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs +++ b/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs @@ -82,15 +82,18 @@ private void OnFrameRender(RenderFrameEvent args) var colorG = new Color(0f, sin, 0f); var colorB = new Color(0f, 0f, sin); - DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(-Vector2.UnitY * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), Color.White); - DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(Vector2.UnitX * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorR); - DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(-Vector2.UnitX * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorG); - DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(Vector2.UnitY * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorB); + DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(-Vector2.UnitY), new Box2(0.0f, 1.0f, 1.0f, 0.0f), Color.White); + DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(Vector2.UnitX), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorR); + DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(-Vector2.UnitX), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorG); + DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(Vector2.UnitY), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorB); BatchUpdate(); + var view = Matrix4X4.CreateTranslation(0.0f, 0.0f, -3.0f); + _baseShader.Use(); _baseShader.SetUniform("model", Matrix4X4.CreateScale(1f)); + _baseShader.SetUniform("view", view); _baseShader.SetUniform("projection", _cameraManager.Projection); _vao.Bind(); diff --git a/Hypercube.Client/Graphics/Viewports/Camera2D.cs b/Hypercube.Client/Graphics/Viewports/Camera2D.cs index 0a99a70..9c1dce1 100644 --- a/Hypercube.Client/Graphics/Viewports/Camera2D.cs +++ b/Hypercube.Client/Graphics/Viewports/Camera2D.cs @@ -48,7 +48,7 @@ private void UpdateProjection() { var projection = Matrix4X4.CreateOrthographic(HalfSize, _zNear, _zFar); var scale = Matrix4X4.CreateScale(Zoom); - var translate = Matrix4X4.CreateTranslate(Position); + var translate = Matrix4X4.CreateTranslation(Position); Projection = projection * scale * translate; } diff --git a/Hypercube.Client/Graphics/Viewports/CameraManager.cs b/Hypercube.Client/Graphics/Viewports/CameraManager.cs index d9ed9bf..6903520 100644 --- a/Hypercube.Client/Graphics/Viewports/CameraManager.cs +++ b/Hypercube.Client/Graphics/Viewports/CameraManager.cs @@ -54,7 +54,7 @@ public ICamera CreateCamera2D(Vector2Int size) return CreateCamera2D(size, Vector2.Zero); } - public ICamera CreateCamera2D(Vector2Int size, Vector2 position, float zNear = 0.01f, float zFar = 100f) + public ICamera CreateCamera2D(Vector2Int size, Vector2 position, float zNear = 0.1f, float zFar = 100f) { return new Camera2D(size, position, zNear, zFar); } diff --git a/Hypercube.Shared.Math/Matrix/Matrix4X4.cs b/Hypercube.Shared.Math/Matrix/Matrix4X4.cs index 155da8a..b903159 100644 --- a/Hypercube.Shared.Math/Matrix/Matrix4X4.cs +++ b/Hypercube.Shared.Math/Matrix/Matrix4X4.cs @@ -397,9 +397,9 @@ public static Matrix4X4 CreateScale(float x, float y, float z) /// 0 | 0 | 0 | 1 /// /// - public static Matrix4X4 CreateTranslate(Vector2 vector2) + public static Matrix4X4 CreateTranslation(Vector2 vector2) { - return CreateTranslate(vector2.X, vector2.Y, 0f); + return CreateTranslation(vector2.X, vector2.Y, 0f); } /// @@ -411,9 +411,9 @@ public static Matrix4X4 CreateTranslate(Vector2 vector2) /// 0 | 0 | 0 | 1 /// /// - public static Matrix4X4 CreateTranslate(Vector3 vector3) + public static Matrix4X4 CreateTranslation(Vector3 vector3) { - return CreateTranslate(vector3.X, vector3.Y, vector3.Z); + return CreateTranslation(vector3.X, vector3.Y, vector3.Z); } /// @@ -425,7 +425,7 @@ public static Matrix4X4 CreateTranslate(Vector3 vector3) /// 0 | 0 | 0 | 1 /// /// - public static Matrix4X4 CreateTranslate(float x, float y, float z) + public static Matrix4X4 CreateTranslation(float x, float y, float z) { var result = Identity; @@ -480,15 +480,14 @@ public static Matrix4X4 CreatePerspective(float fov, float aspect, float zNear, { var result = Zero; - var halfFov = fov / 2; - var tanHalfFov = (float)System.Math.Tan(halfFov); - var zDelta = zFar - zNear; - - result.M00 = 1 / (aspect * tanHalfFov); - result.M11 = 1 / tanHalfFov; - result.M22 = zFar / zDelta; - result.M23 = 1; - result.M32 = zFar * zNear / zDelta; + var height = 1.0f / MathF.Tan(fov * 0.5f); + var width = height / aspect; + var range = float.IsPositiveInfinity(zFar) ? -1.0f : zFar / (zNear - zFar); + + result.Row0 = new Vector4(width, 0, 0, 0); + result.Row1 = new Vector4(0, height, 0, 0); + result.Row2 = new Vector4(0, 0, range, -1.0f); + result.Row3 = new Vector4(0, 0, range * zNear, 0); return result; } diff --git a/Resources/Shaders/base.vert b/Resources/Shaders/base.vert index 4f59d2f..bd8ed34 100644 --- a/Resources/Shaders/base.vert +++ b/Resources/Shaders/base.vert @@ -9,10 +9,11 @@ out vec2 TexCoord; uniform mat4 projection; uniform mat4 model; +uniform mat4 view; void main() { - gl_Position = model * projection * vec4(aPos, 1.0); + gl_Position = view * model * projection * vec4(aPos, 1.0); Color = aColor; TexCoord = aTexCoord; From e3b5517ac9b372207912d29be6720c2e4589785f Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 11 Jul 2024 14:21:47 +1000 Subject: [PATCH 07/19] Code clean up --- Hypercube.Client/Graphics/Viewports/Camera2D.cs | 9 +++++++-- Hypercube.Client/Graphics/Viewports/CameraManager.cs | 2 -- Hypercube.Client/Graphics/Viewports/ICamera.cs | 3 +++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Hypercube.Client/Graphics/Viewports/Camera2D.cs b/Hypercube.Client/Graphics/Viewports/Camera2D.cs index 9c1dce1..59492f8 100644 --- a/Hypercube.Client/Graphics/Viewports/Camera2D.cs +++ b/Hypercube.Client/Graphics/Viewports/Camera2D.cs @@ -1,5 +1,4 @@ -using Hypercube.Shared.Math.Box; -using Hypercube.Shared.Math.Matrix; +using Hypercube.Shared.Math.Matrix; using Hypercube.Shared.Math.Vector; namespace Hypercube.Client.Graphics.Viewports; @@ -31,6 +30,12 @@ public void SetSize(Vector2Int size) Size = size; UpdateProjection(); } + + public void SetPosition(Vector2 position) + { + Position = position; + UpdateProjection(); + } public void SetPosition(Vector3 position) { diff --git a/Hypercube.Client/Graphics/Viewports/CameraManager.cs b/Hypercube.Client/Graphics/Viewports/CameraManager.cs index 6903520..3bb6279 100644 --- a/Hypercube.Client/Graphics/Viewports/CameraManager.cs +++ b/Hypercube.Client/Graphics/Viewports/CameraManager.cs @@ -1,10 +1,8 @@ using Hypercube.Client.Input; using Hypercube.Client.Input.Handler; using Hypercube.Shared.Dependency; -using Hypercube.Shared.EventBus; using Hypercube.Shared.Math.Matrix; using Hypercube.Shared.Math.Vector; -using Hypercube.Shared.Runtimes.Loop.Event; namespace Hypercube.Client.Graphics.Viewports; diff --git a/Hypercube.Client/Graphics/Viewports/ICamera.cs b/Hypercube.Client/Graphics/Viewports/ICamera.cs index 491757b..6e92297 100644 --- a/Hypercube.Client/Graphics/Viewports/ICamera.cs +++ b/Hypercube.Client/Graphics/Viewports/ICamera.cs @@ -6,6 +6,9 @@ namespace Hypercube.Client.Graphics.Viewports; public interface ICamera { Matrix4X4 Projection { get; } + Vector3 Position { get; } + + void SetPosition(Vector2 position); void SetPosition(Vector3 position); } \ No newline at end of file From 5e742416a6886ec6182e04366032903ce28f412a Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 11 Jul 2024 15:17:54 +1000 Subject: [PATCH 08/19] Updated matrix usage in rendering --- .../Graphics/Rendering/Renderer.Render.cs | 19 +-- .../Graphics/Viewports/Camera2D.cs | 15 ++- .../Graphics/Viewports/CameraManager.cs | 20 ++-- .../Graphics/Viewports/ICamera.cs | 2 + Hypercube.Shared.Math/Angle.cs | 10 +- Hypercube.Shared.Math/Matrix/Matrix4X4.cs | 112 ++++++++++++++++++ 6 files changed, 156 insertions(+), 22 deletions(-) diff --git a/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs b/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs index af92825..21da60f 100644 --- a/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs +++ b/Hypercube.Client/Graphics/Rendering/Renderer.Render.cs @@ -1,10 +1,10 @@ -using System.Numerics; -using Hypercube.Client.Graphics.Shading; +using Hypercube.Client.Graphics.Shading; using Hypercube.Client.Graphics.Texturing; using Hypercube.Client.Graphics.Viewports; using Hypercube.Shared.Math; using Hypercube.Shared.Math.Box; using Hypercube.Shared.Math.Matrix; +using Hypercube.Shared.Math.Vector; using Hypercube.Shared.Runtimes.Loop.Event; using OpenToolkit.Graphics.OpenGL4; @@ -62,7 +62,7 @@ private void OnLoad() private void OnFrameUpdate(UpdateFrameEvent args) { #if DEBUG - _windowManager.WindowSetTitle(MainWindow, $"FPS: {_timing.Fps} | RealTime: {_timing.RealTime} | cPos: {_cameraManager.MainCamera?.Position ?? null}"); + _windowManager.WindowSetTitle(MainWindow, $"FPS: {_timing.Fps} | RealTime: {_timing.RealTime} | cPos: {_cameraManager.MainCamera?.Position ?? null} | cRot: {_cameraManager.MainCamera?.Rotation ?? null}"); #endif _windowManager.PollEvents(); _cameraManager.UpdateInput(_cameraManager.MainCamera, args.DeltaSeconds); @@ -82,17 +82,18 @@ private void OnFrameRender(RenderFrameEvent args) var colorG = new Color(0f, sin, 0f); var colorB = new Color(0f, 0f, sin); - DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(-Vector2.UnitY), new Box2(0.0f, 1.0f, 1.0f, 0.0f), Color.White); - DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(Vector2.UnitX), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorR); - DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(-Vector2.UnitX), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorG); - DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(Vector2.UnitY), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorB); + DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(-Vector2.UnitY * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), Color.White); + DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(Vector2.UnitX * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorR); + DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(-Vector2.UnitX * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorG); + DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(Vector2.UnitY * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorB); BatchUpdate(); - + + var model = Matrix4X4.CreateTranslation(Vector2.Zero) * Matrix4X4.CreateRotationZ(0) * Matrix4X4.CreateScale(Vector2.One); var view = Matrix4X4.CreateTranslation(0.0f, 0.0f, -3.0f); _baseShader.Use(); - _baseShader.SetUniform("model", Matrix4X4.CreateScale(1f)); + _baseShader.SetUniform("model", model); _baseShader.SetUniform("view", view); _baseShader.SetUniform("projection", _cameraManager.Projection); diff --git a/Hypercube.Client/Graphics/Viewports/Camera2D.cs b/Hypercube.Client/Graphics/Viewports/Camera2D.cs index 59492f8..3a5d21c 100644 --- a/Hypercube.Client/Graphics/Viewports/Camera2D.cs +++ b/Hypercube.Client/Graphics/Viewports/Camera2D.cs @@ -6,6 +6,7 @@ namespace Hypercube.Client.Graphics.Viewports; public class Camera2D : ICamera { public Vector3 Position { get; private set; } + public Vector3 Rotation { get; private set; } private readonly float _zFar; private readonly float _zNear; @@ -43,6 +44,12 @@ public void SetPosition(Vector3 position) UpdateProjection(); } + public void SetRotation(Vector3 rotation) + { + Rotation = Rotation.WithZ(rotation.Z); + UpdateProjection(); + } + public void SetZoom(float zoom) { Zoom = zoom; @@ -51,10 +58,12 @@ public void SetZoom(float zoom) private void UpdateProjection() { - var projection = Matrix4X4.CreateOrthographic(HalfSize, _zNear, _zFar); - var scale = Matrix4X4.CreateScale(Zoom); + var projection = Matrix4X4.CreateOrthographic(Size, _zNear, _zFar); + var translate = Matrix4X4.CreateTranslation(Position); + var rotation = Matrix4X4.CreateRotationZ(Rotation.Z); + var scale = Matrix4X4.CreateScale(Zoom); - Projection = projection * scale * translate; + Projection = projection * translate * rotation * scale; } } \ No newline at end of file diff --git a/Hypercube.Client/Graphics/Viewports/CameraManager.cs b/Hypercube.Client/Graphics/Viewports/CameraManager.cs index 3bb6279..4e2c6d7 100644 --- a/Hypercube.Client/Graphics/Viewports/CameraManager.cs +++ b/Hypercube.Client/Graphics/Viewports/CameraManager.cs @@ -20,26 +20,28 @@ public void UpdateInput(ICamera? camera, float delta) // Debug camera controls var position = camera.Position; + var rotation = camera.Rotation; if (_inputHandler.IsKeyDown(Key.W)) - position += Vector3.Forward * delta; + position -= Vector3.UnitY * delta; if (_inputHandler.IsKeyDown(Key.S)) - position -= Vector3.Forward * delta; + position += Vector3.UnitY * delta; if (_inputHandler.IsKeyDown(Key.A)) - position -= Vector3.Right * delta; + position -= Vector3.UnitX * delta; if (_inputHandler.IsKeyDown(Key.D)) - position += Vector3.Right * delta; - - if (_inputHandler.IsKeyDown(Key.Space)) - position += Vector3.Up * delta; + position += Vector3.UnitX * delta; + + if (_inputHandler.IsKeyDown(Key.Q)) + rotation -= Vector3.UnitZ * delta; - if (_inputHandler.IsKeyDown(Key.LeftShift)) - position -= Vector3.Up * delta; + if (_inputHandler.IsKeyDown(Key.E)) + rotation += Vector3.UnitZ * delta; camera.SetPosition(position); + camera.SetRotation(rotation); } public void SetMainCamera(ICamera camera) diff --git a/Hypercube.Client/Graphics/Viewports/ICamera.cs b/Hypercube.Client/Graphics/Viewports/ICamera.cs index 6e92297..a0a55cd 100644 --- a/Hypercube.Client/Graphics/Viewports/ICamera.cs +++ b/Hypercube.Client/Graphics/Viewports/ICamera.cs @@ -8,7 +8,9 @@ public interface ICamera Matrix4X4 Projection { get; } Vector3 Position { get; } + Vector3 Rotation { get; } void SetPosition(Vector2 position); void SetPosition(Vector3 position); + void SetRotation(Vector3 rotation); } \ No newline at end of file diff --git a/Hypercube.Shared.Math/Angle.cs b/Hypercube.Shared.Math/Angle.cs index 47f6552..e52a056 100644 --- a/Hypercube.Shared.Math/Angle.cs +++ b/Hypercube.Shared.Math/Angle.cs @@ -1,8 +1,16 @@ -namespace Hypercube.Shared.Math; +using System.Runtime.CompilerServices; + +namespace Hypercube.Shared.Math; public readonly struct Angle(double theta) { public static readonly Angle Zero = new(0); public readonly double Theta = theta; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator float(Angle angle) + { + return (float)angle.Theta; + } } \ No newline at end of file diff --git a/Hypercube.Shared.Math/Matrix/Matrix4X4.cs b/Hypercube.Shared.Math/Matrix/Matrix4X4.cs index b903159..486b94d 100644 --- a/Hypercube.Shared.Math/Matrix/Matrix4X4.cs +++ b/Hypercube.Shared.Math/Matrix/Matrix4X4.cs @@ -388,6 +388,118 @@ public static Matrix4X4 CreateScale(float x, float y, float z) return result; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix4X4 CreateRotation(Vector3 direction, float angle) + { + var cos = MathF.Cos(-angle); + var sin = MathF.Sin(-angle); + var t = 1.0f - cos; + + direction = direction.Normalized; + + return new Matrix4X4( + t * direction.X * direction.X + cos, + t * direction.X * direction.Y - sin * direction.Z, + t * direction.X * direction.Z + sin * direction.Y, + 0, + t * direction.X * direction.Y + sin * direction.Z, + t * direction.Y * direction.Y + cos, + t * direction.Y * direction.Z - sin * direction.X, + 0, + t * direction.X * direction.Z - sin * direction.Y, + t * direction.Y * direction.Z + sin * direction.X, + t * direction.Z * direction.Z + cos, + 0, + 0, + 0, + 0, + 1 + ); + } + + /// + /// Creating rotation axis X matrix + /// + /// 1 | 0 | 0 | 0 + /// 0 | cos | sin | 0 + /// 0 | -sin | cos | 0 + /// 0 | 0 | 0 | 1 + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix4X4 CreateRotationX(float angle) + { + var cos = MathF.Cos(angle); + var sin = MathF.Sin(angle); + + return new Matrix4X4( + Vector4.UnitX, + new Vector4(0, cos, sin, 0), + new Vector4(0, -sin, cos, 0), + Vector4.UnitW + ); + } + + /// + /// Creating rotation axis Y matrix + /// + /// cos | 0 | -sin | 0 + /// 0 | 1 | 0 | 0 + /// sin | 0 | cos | 0 + /// 0 | 0 | 0 | 1 + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix4X4 CreateRotationY(float angle) + { + var cos = MathF.Cos(angle); + var sin = MathF.Sin(angle); + + return new Matrix4X4( + new Vector4(cos, 0, -sin, 0), + Vector4.UnitY, + new Vector4(sin, 0, cos, 0), + Vector4.UnitW + ); + } + + /// + /// Creating rotation axis Z matrix + /// + /// cos | sin | 0 | 0 + /// -sin | cos | 0 | 0 + /// 0 | 0 | 1 | 0 + /// 0 | 0 | 0 | 1 + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix4X4 CreateRotationZ(float angle) + { + var cos = MathF.Cos(angle); + var sin = MathF.Sin(angle); + + return new Matrix4X4( + new Vector4(cos, sin, 0, 0), + new Vector4(-sin, cos, 0, 0), + Vector4.UnitZ, + Vector4.UnitW + ); + } + + /// + /// Creating translate matrix + /// + /// 1 | 0 | 0 | v + /// 0 | 1 | 0 | v + /// 0 | 0 | 1 | v + /// 0 | 0 | 0 | 1 + /// + /// + public static Matrix4X4 CreateTranslation(float value) + { + return CreateTranslation(value, value, value); + } + /// /// Creating translate matrix /// From 50ae84d54bb73fb7fe3ea947d1b6594e9cd2b49a Mon Sep 17 00:00:00 2001 From: JerryImMouse Date: Fri, 12 Jul 2024 01:57:39 +0500 Subject: [PATCH 09/19] remove unused method --- Hypercube.Client/Graphics/Viewports/Camera2D.cs | 6 ------ Hypercube.Client/Graphics/Viewports/ICamera.cs | 1 - 2 files changed, 7 deletions(-) diff --git a/Hypercube.Client/Graphics/Viewports/Camera2D.cs b/Hypercube.Client/Graphics/Viewports/Camera2D.cs index 3a5d21c..b83331e 100644 --- a/Hypercube.Client/Graphics/Viewports/Camera2D.cs +++ b/Hypercube.Client/Graphics/Viewports/Camera2D.cs @@ -31,12 +31,6 @@ public void SetSize(Vector2Int size) Size = size; UpdateProjection(); } - - public void SetPosition(Vector2 position) - { - Position = position; - UpdateProjection(); - } public void SetPosition(Vector3 position) { diff --git a/Hypercube.Client/Graphics/Viewports/ICamera.cs b/Hypercube.Client/Graphics/Viewports/ICamera.cs index a0a55cd..c12f0b9 100644 --- a/Hypercube.Client/Graphics/Viewports/ICamera.cs +++ b/Hypercube.Client/Graphics/Viewports/ICamera.cs @@ -10,7 +10,6 @@ public interface ICamera Vector3 Position { get; } Vector3 Rotation { get; } - void SetPosition(Vector2 position); void SetPosition(Vector3 position); void SetRotation(Vector3 rotation); } \ No newline at end of file From c24691fd15c4cee6e60e3abf8734dc1be3035904 Mon Sep 17 00:00:00 2001 From: JerryImMouse Date: Fri, 12 Jul 2024 01:57:49 +0500 Subject: [PATCH 10/19] fix matrices multiplying --- Resources/Shaders/base.vert | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Shaders/base.vert b/Resources/Shaders/base.vert index bd8ed34..b663ed1 100644 --- a/Resources/Shaders/base.vert +++ b/Resources/Shaders/base.vert @@ -13,7 +13,7 @@ uniform mat4 view; void main() { - gl_Position = view * model * projection * vec4(aPos, 1.0); + gl_Position = vec4(aPos, 1.0) * model * view * projection; Color = aColor; TexCoord = aTexCoord; From 19f5e235cad3ffdf6bd2f1e39ee57806d8e502a5 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Fri, 12 Jul 2024 07:09:15 +1000 Subject: [PATCH 11/19] Added scale to camera --- .../Graphics/Viewports/Camera2D.cs | 9 +++++---- .../Graphics/Viewports/CameraManager.cs | 18 ++++++++++++++---- Hypercube.Client/Graphics/Viewports/ICamera.cs | 4 +++- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Hypercube.Client/Graphics/Viewports/Camera2D.cs b/Hypercube.Client/Graphics/Viewports/Camera2D.cs index b83331e..fde8ce8 100644 --- a/Hypercube.Client/Graphics/Viewports/Camera2D.cs +++ b/Hypercube.Client/Graphics/Viewports/Camera2D.cs @@ -7,11 +7,12 @@ public class Camera2D : ICamera { public Vector3 Position { get; private set; } public Vector3 Rotation { get; private set; } + public Vector3 Scale { get; private set; } = Vector3.One; private readonly float _zFar; private readonly float _zNear; private Vector2Int Size { get; set; } - private float Zoom { get; set; } = 1f; + private Vector2 HalfSize => Size / 2f; public Matrix4X4 Projection { get; private set; } @@ -44,9 +45,9 @@ public void SetRotation(Vector3 rotation) UpdateProjection(); } - public void SetZoom(float zoom) + public void SetScale(Vector3 scale) { - Zoom = zoom; + Scale = scale; UpdateProjection(); } @@ -56,7 +57,7 @@ private void UpdateProjection() var translate = Matrix4X4.CreateTranslation(Position); var rotation = Matrix4X4.CreateRotationZ(Rotation.Z); - var scale = Matrix4X4.CreateScale(Zoom); + var scale = Matrix4X4.CreateScale(Scale); Projection = projection * translate * rotation * scale; } diff --git a/Hypercube.Client/Graphics/Viewports/CameraManager.cs b/Hypercube.Client/Graphics/Viewports/CameraManager.cs index 4e2c6d7..6b8cdba 100644 --- a/Hypercube.Client/Graphics/Viewports/CameraManager.cs +++ b/Hypercube.Client/Graphics/Viewports/CameraManager.cs @@ -21,18 +21,21 @@ public void UpdateInput(ICamera? camera, float delta) // Debug camera controls var position = camera.Position; var rotation = camera.Rotation; + var scale = camera.Scale; + + var speed = 20f; if (_inputHandler.IsKeyDown(Key.W)) - position -= Vector3.UnitY * delta; + position -= Vector3.UnitY * speed * delta; if (_inputHandler.IsKeyDown(Key.S)) - position += Vector3.UnitY * delta; + position += Vector3.UnitY * speed * delta; if (_inputHandler.IsKeyDown(Key.A)) - position -= Vector3.UnitX * delta; + position += Vector3.UnitX * speed * delta; if (_inputHandler.IsKeyDown(Key.D)) - position += Vector3.UnitX * delta; + position -= Vector3.UnitX * speed * delta; if (_inputHandler.IsKeyDown(Key.Q)) rotation -= Vector3.UnitZ * delta; @@ -40,8 +43,15 @@ public void UpdateInput(ICamera? camera, float delta) if (_inputHandler.IsKeyDown(Key.E)) rotation += Vector3.UnitZ * delta; + if (_inputHandler.IsKeyDown(Key.T)) + scale -= Vector3.One * delta; + + if (_inputHandler.IsKeyDown(Key.Y)) + scale += Vector3.One * delta; + camera.SetPosition(position); camera.SetRotation(rotation); + camera.SetScale(scale); } public void SetMainCamera(ICamera camera) diff --git a/Hypercube.Client/Graphics/Viewports/ICamera.cs b/Hypercube.Client/Graphics/Viewports/ICamera.cs index c12f0b9..fd8d030 100644 --- a/Hypercube.Client/Graphics/Viewports/ICamera.cs +++ b/Hypercube.Client/Graphics/Viewports/ICamera.cs @@ -9,7 +9,9 @@ public interface ICamera Vector3 Position { get; } Vector3 Rotation { get; } - + Vector3 Scale { get; } + void SetPosition(Vector3 position); void SetRotation(Vector3 rotation); + void SetScale(Vector3 scale); } \ No newline at end of file From e996c77dd5522de0578a727590abbbe6db452512 Mon Sep 17 00:00:00 2001 From: JerryImMouse Date: Fri, 12 Jul 2024 02:11:54 +0500 Subject: [PATCH 12/19] install opentoolkit to shared math --- Hypercube.Shared.Math/Hypercube.Shared.Math.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Hypercube.Shared.Math/Hypercube.Shared.Math.csproj b/Hypercube.Shared.Math/Hypercube.Shared.Math.csproj index 8f59722..b60e9ec 100644 --- a/Hypercube.Shared.Math/Hypercube.Shared.Math.csproj +++ b/Hypercube.Shared.Math/Hypercube.Shared.Math.csproj @@ -9,6 +9,7 @@ + From 7dfb92397471ee5fae21fe1c972334b0ccf69c6f Mon Sep 17 00:00:00 2001 From: JerryImMouse Date: Fri, 12 Jul 2024 02:12:07 +0500 Subject: [PATCH 13/19] add constructor comments --- Hypercube.Shared.Math/Matrix/Matrix4X4.cs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Hypercube.Shared.Math/Matrix/Matrix4X4.cs b/Hypercube.Shared.Math/Matrix/Matrix4X4.cs index 486b94d..b48c718 100644 --- a/Hypercube.Shared.Math/Matrix/Matrix4X4.cs +++ b/Hypercube.Shared.Math/Matrix/Matrix4X4.cs @@ -204,7 +204,19 @@ public float M33 [MethodImpl(MethodImplOptions.AggressiveInlining)] set => Row3 = Row3.WithW(value); } - + /// + /// Creates new matrix 4x4 + /// + /// Row0.X | Row0.Y | Row0.Z | Row0.W + /// Row1.X | Row1.Y | Row1.Z | Row1.W + /// Row2.X | Row2.Y | Row2.Z | Row2.W + /// Row2.X | Row2.Y | Row2.Z | Row2.W + /// + /// + /// Row 0 + /// Row 1 + /// Row 2 + /// Row 3 public Matrix4X4(Vector4 x, Vector4 y, Vector4 z, Vector4 w) { Row0 = x; @@ -212,7 +224,10 @@ public Matrix4X4(Vector4 x, Vector4 y, Vector4 z, Vector4 w) Row2 = z; Row3 = w; } - + /// + /// Creates new matrix with all rows is "" + /// + /// Vector4 to make rows out of public Matrix4X4(Vector4 value) : this(value, value, value, value) { } From 1f4145ef802d6f5132203c60b9db034e98b4ce90 Mon Sep 17 00:00:00 2001 From: JerryImMouse Date: Fri, 12 Jul 2024 02:28:38 +0500 Subject: [PATCH 14/19] add compatibility operators --- .../Matrix/Matrix4X4.Compability.cs | 26 ++++++++++ .../Vector/Vector2.Compability.cs | 28 ++++++++++ .../Vector/Vector3.Compability.cs | 52 +++++++++++++++++++ .../Vector/Vector4.Compability.cs | 24 +++++++++ 4 files changed, 130 insertions(+) diff --git a/Hypercube.Shared.Math/Matrix/Matrix4X4.Compability.cs b/Hypercube.Shared.Math/Matrix/Matrix4X4.Compability.cs index f930d1c..d626311 100644 --- a/Hypercube.Shared.Math/Matrix/Matrix4X4.Compability.cs +++ b/Hypercube.Shared.Math/Matrix/Matrix4X4.Compability.cs @@ -1,12 +1,38 @@ using System.Runtime.CompilerServices; +using OpenTK.Mathematics; namespace Hypercube.Shared.Math.Matrix; public partial struct Matrix4X4 { + /* + * OpenTK Compatibility + */ + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator OpenTK.Mathematics.Matrix4(Matrix4X4 matrix4X4) { return new OpenTK.Mathematics.Matrix4(matrix4X4.Row0, matrix4X4.Row1, matrix4X4.Row2, matrix4X4.Row3); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Matrix4X4(Matrix4 matrix4) + { + return new Matrix4X4(matrix4.Row0, matrix4.Row1, matrix4.Row2, matrix4.Row3); + } + + /* + * Open Toolkit Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator OpenToolkit.Mathematics.Matrix4(Matrix4X4 matrix4X4) + { + return new OpenToolkit.Mathematics.Matrix4(matrix4X4.Row0, matrix4X4.Row1, matrix4X4.Row2, matrix4X4.Row3); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Matrix4X4(OpenToolkit.Mathematics.Matrix4 matrix4) + { + return new Matrix4X4(matrix4.Row0, matrix4.Row1, matrix4.Row2, matrix4.Row3); + } } \ No newline at end of file diff --git a/Hypercube.Shared.Math/Vector/Vector2.Compability.cs b/Hypercube.Shared.Math/Vector/Vector2.Compability.cs index 0f012c5..942ee23 100644 --- a/Hypercube.Shared.Math/Vector/Vector2.Compability.cs +++ b/Hypercube.Shared.Math/Vector/Vector2.Compability.cs @@ -4,12 +4,20 @@ namespace Hypercube.Shared.Math.Vector; public readonly partial struct Vector2 { + /* + * Self Compatibility + */ + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Vector3(Vector2 vector) { return new Vector3(vector.X, vector.Y, 0f); } + /* + * System.Numerics Compatibility + */ + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Vector2(System.Numerics.Vector2 vector) { @@ -22,6 +30,10 @@ public static implicit operator System.Numerics.Vector2(Vector2 vector) return new System.Numerics.Vector2(vector.X, vector.Y); } + /* + * OpenTK Compatibility + */ + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Vector2(OpenTK.Mathematics.Vector2 vector) { @@ -33,4 +45,20 @@ public static implicit operator OpenTK.Mathematics.Vector2(Vector2 vector) { return new OpenTK.Mathematics.Vector2(vector.X, vector.Y); } + + /* + * OpenToolkit Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector2(OpenToolkit.Mathematics.Vector2 vector) + { + return new Vector2(vector.X, vector.Y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator OpenToolkit.Mathematics.Vector2(Vector2 vector) + { + return new OpenToolkit.Mathematics.Vector2(vector.X, vector.Y); + } } \ No newline at end of file diff --git a/Hypercube.Shared.Math/Vector/Vector3.Compability.cs b/Hypercube.Shared.Math/Vector/Vector3.Compability.cs index 2045295..82be42e 100644 --- a/Hypercube.Shared.Math/Vector/Vector3.Compability.cs +++ b/Hypercube.Shared.Math/Vector/Vector3.Compability.cs @@ -4,9 +4,61 @@ namespace Hypercube.Shared.Math.Vector; public readonly partial struct Vector3 { + /* + * Vector2 Compatibility + */ + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Vector2(Vector3 vector) { return new Vector2(vector.X, vector.Y); } + + /* + * System.Numerics Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator System.Numerics.Vector3(Vector3 vector3) + { + return new System.Numerics.Vector3(vector3.X, vector3.Y, vector3.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector3(System.Numerics.Vector3 vector3) + { + return new Vector3(vector3.X, vector3.Y, vector3.Z); + } + + /* + * OpenTK Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator OpenTK.Mathematics.Vector3(Vector3 vector) + { + return new OpenTK.Mathematics.Vector3(vector.X, vector.Y, vector.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector3(OpenTK.Mathematics.Vector3 vector) + { + return new Vector3(vector.X, vector.Y, vector.Z); + } + + /* + * OpenToolkit Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator OpenToolkit.Mathematics.Vector3(Vector3 vector) + { + return new OpenToolkit.Mathematics.Vector3(vector.X, vector.Y, vector.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector3(OpenToolkit.Mathematics.Vector3 vector) + { + return new Vector3(vector.X, vector.Y, vector.Z); + } } \ No newline at end of file diff --git a/Hypercube.Shared.Math/Vector/Vector4.Compability.cs b/Hypercube.Shared.Math/Vector/Vector4.Compability.cs index 9d42586..61adf86 100644 --- a/Hypercube.Shared.Math/Vector/Vector4.Compability.cs +++ b/Hypercube.Shared.Math/Vector/Vector4.Compability.cs @@ -4,6 +4,10 @@ namespace Hypercube.Shared.Math.Vector; public readonly partial struct Vector4 { + /* + * System.Numerics Compatibility + */ + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Vector4(System.Numerics.Vector4 vector4) { @@ -16,6 +20,10 @@ public static implicit operator System.Numerics.Vector4(Vector4 vector4) return new System.Numerics.Vector4(vector4.X, vector4.Y, vector4.Z, vector4.W); } + /* + * OpenTK Compatibility + */ + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Vector4(OpenTK.Mathematics.Vector4 vector4) { @@ -27,4 +35,20 @@ public static implicit operator OpenTK.Mathematics.Vector4(Vector4 vector4) { return new OpenTK.Mathematics.Vector4(vector4.X, vector4.Y, vector4.Z, vector4.W); } + + /* + * OpenToolkit Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator OpenToolkit.Mathematics.Vector4(Vector4 vector4) + { + return new OpenToolkit.Mathematics.Vector4(vector4.X, vector4.Y, vector4.Z, vector4.W); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector4(OpenToolkit.Mathematics.Vector4 vector4) + { + return new Vector4(vector4.X, vector4.Y, vector4.Z, vector4.W); + } } \ No newline at end of file From 27c9d95675e157792932828e45d8681e075118c9 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Fri, 12 Jul 2024 07:38:18 +1000 Subject: [PATCH 15/19] Closes #6; Fixed callbacks destruction --- .../Manager/GlfwWindowManager.Callbacks.cs | 43 ++++++++++++++++--- .../Windows/Manager/GlfwWindowManager.Init.cs | 7 +-- .../Manager/GlfwWindowManager.Window.cs | 8 ++-- .../Windows/Manager/GlfwWindowManager.cs | 3 ++ 4 files changed, 44 insertions(+), 17 deletions(-) diff --git a/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Callbacks.cs b/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Callbacks.cs index 3eb4225..22e20f1 100644 --- a/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Callbacks.cs +++ b/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Callbacks.cs @@ -1,22 +1,43 @@ -using Hypercube.Client.Graphics.Event; -using Hypercube.Client.Input; +using Hypercube.Client.Input; using Hypercube.Client.Utilities; using OpenTK.Windowing.GraphicsLibraryFramework; using GlfwKeyModifiers = OpenTK.Windowing.GraphicsLibraryFramework.KeyModifiers; using KeyModifiers = Hypercube.Client.Input.KeyModifiers; +using static OpenTK.Windowing.GraphicsLibraryFramework.GLFWCallbacks; namespace Hypercube.Client.Graphics.Windows.Manager; public sealed unsafe partial class GlfwWindowManager { - private void OnWindowClosed(Window* window) + private ErrorCallback? _errorCallback; + + private KeyCallback? _keyCallback; + + private WindowCloseCallback? _windowCloseCallback; + private WindowSizeCallback? _windowSizeCallback; + private WindowFocusCallback? _windowFocusCallback; + + /// + /// GC doesn't think our callbacks are stored anywhere, + /// so it cleans them up, + /// we need to indicate that there is a link to them so they don't get lost. + /// + private void HandleCallbacks() { - if (!TryGetWindow(window, out var registration)) - return; + _errorCallback = OnErrorHandled; + + _keyCallback = OnWindowKeyHandled; - _renderer.CloseWindow(registration); + _windowCloseCallback = OnWindowClosed; + _windowSizeCallback = OnWindowResized; + _windowFocusCallback = OnWindowFocusChanged; } - + + private void OnErrorHandled(ErrorCode error, string description) + { + _logger.Error(GLFWHelper.FormatError(error, description)); + } + private void OnWindowKeyHandled(Window* window, Keys glfwKey, int scanCode, InputAction action, GlfwKeyModifiers mods) { var key = (Key)glfwKey; @@ -49,6 +70,14 @@ private void OnWindowKeyHandled(Window* window, Keys glfwKey, int scanCode, Inpu (KeyModifiers)mods, scanCode)); } + + private void OnWindowClosed(Window* window) + { + if (!TryGetWindow(window, out var registration)) + return; + + _renderer.CloseWindow(registration); + } private void OnWindowResized(Window* window, int width, int height) { diff --git a/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Init.cs b/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Init.cs index 6509d6c..46c21fc 100644 --- a/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Init.cs +++ b/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Init.cs @@ -14,7 +14,7 @@ private bool GlfwInit() } // Set callback to handle errors - GLFW.SetErrorCallback(OnErrorHandled); + GLFW.SetErrorCallback(_errorCallback); _initialized = true; @@ -22,9 +22,4 @@ private bool GlfwInit() _logger.EngineInfo($"Initialize, version: {version}"); return true; } - - private void OnErrorHandled(ErrorCode error, string description) - { - _logger.Error(GLFWHelper.FormatError(error, description)); - } } \ No newline at end of file diff --git a/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Window.cs b/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Window.cs index 4a92ee6..ae1e6c1 100644 --- a/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Window.cs +++ b/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Window.cs @@ -130,10 +130,10 @@ private GlfwWindowRegistration WindowSetup(Window* window, WindowCreateSettings SetWindowIcons(registration, settings.WindowImages.ToList()); // Setting callbacks - GLFW.SetKeyCallback(window, OnWindowKeyHandled); - GLFW.SetWindowCloseCallback(window, OnWindowClosed); - GLFW.SetWindowSizeCallback(window, OnWindowResized); - GLFW.SetWindowFocusCallback(window, OnWindowFocusChanged); + GLFW.SetKeyCallback(window, _keyCallback); + GLFW.SetWindowCloseCallback(window, _windowCloseCallback); + GLFW.SetWindowSizeCallback(window, _windowSizeCallback); + GLFW.SetWindowFocusCallback(window, _windowFocusCallback); return registration; } diff --git a/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.cs b/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.cs index 8f38686..65d3a4e 100644 --- a/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.cs +++ b/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.cs @@ -26,6 +26,9 @@ public bool Init() { DependencyManager.Inject(this); + // We don't let GC take our callbacks + HandleCallbacks(); + if (!GlfwInit()) return false; From e37dffc1eba78482f9453b92ce61e6aabdb2894a Mon Sep 17 00:00:00 2001 From: JerryImMouse Date: Fri, 12 Jul 2024 02:40:43 +0500 Subject: [PATCH 16/19] renaming --- .../{Matrix4X4.Compability.cs => Matrix4X4.Compatibility.cs} | 0 .../Vector/{Vector2.Compability.cs => Vector2.Compatibility.cs} | 0 .../{Vector2Int.Compability.cs => Vector2Int.Compatibility.cs} | 0 .../Vector/{Vector3.Compability.cs => Vector3.Compatibility.cs} | 0 .../Vector/{Vector4.Compability.cs => Vector4.Compatibility.cs} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename Hypercube.Shared.Math/Matrix/{Matrix4X4.Compability.cs => Matrix4X4.Compatibility.cs} (100%) rename Hypercube.Shared.Math/Vector/{Vector2.Compability.cs => Vector2.Compatibility.cs} (100%) rename Hypercube.Shared.Math/Vector/{Vector2Int.Compability.cs => Vector2Int.Compatibility.cs} (100%) rename Hypercube.Shared.Math/Vector/{Vector3.Compability.cs => Vector3.Compatibility.cs} (100%) rename Hypercube.Shared.Math/Vector/{Vector4.Compability.cs => Vector4.Compatibility.cs} (100%) diff --git a/Hypercube.Shared.Math/Matrix/Matrix4X4.Compability.cs b/Hypercube.Shared.Math/Matrix/Matrix4X4.Compatibility.cs similarity index 100% rename from Hypercube.Shared.Math/Matrix/Matrix4X4.Compability.cs rename to Hypercube.Shared.Math/Matrix/Matrix4X4.Compatibility.cs diff --git a/Hypercube.Shared.Math/Vector/Vector2.Compability.cs b/Hypercube.Shared.Math/Vector/Vector2.Compatibility.cs similarity index 100% rename from Hypercube.Shared.Math/Vector/Vector2.Compability.cs rename to Hypercube.Shared.Math/Vector/Vector2.Compatibility.cs diff --git a/Hypercube.Shared.Math/Vector/Vector2Int.Compability.cs b/Hypercube.Shared.Math/Vector/Vector2Int.Compatibility.cs similarity index 100% rename from Hypercube.Shared.Math/Vector/Vector2Int.Compability.cs rename to Hypercube.Shared.Math/Vector/Vector2Int.Compatibility.cs diff --git a/Hypercube.Shared.Math/Vector/Vector3.Compability.cs b/Hypercube.Shared.Math/Vector/Vector3.Compatibility.cs similarity index 100% rename from Hypercube.Shared.Math/Vector/Vector3.Compability.cs rename to Hypercube.Shared.Math/Vector/Vector3.Compatibility.cs diff --git a/Hypercube.Shared.Math/Vector/Vector4.Compability.cs b/Hypercube.Shared.Math/Vector/Vector4.Compatibility.cs similarity index 100% rename from Hypercube.Shared.Math/Vector/Vector4.Compability.cs rename to Hypercube.Shared.Math/Vector/Vector4.Compatibility.cs From 13d5dfc579e4ca4a3044e6460e7d3bb4e56526e7 Mon Sep 17 00:00:00 2001 From: JerryImMouse Date: Fri, 12 Jul 2024 02:40:50 +0500 Subject: [PATCH 17/19] matrix 3x3 changes --- Hypercube.Shared.Math/Matrix/Matrix3X3.cs | 68 +++++++++++++++-------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/Hypercube.Shared.Math/Matrix/Matrix3X3.cs b/Hypercube.Shared.Math/Matrix/Matrix3X3.cs index 4c6cbb1..822dca4 100644 --- a/Hypercube.Shared.Math/Matrix/Matrix3X3.cs +++ b/Hypercube.Shared.Math/Matrix/Matrix3X3.cs @@ -5,7 +5,7 @@ namespace Hypercube.Shared.Math.Matrix; [StructLayout(LayoutKind.Sequential)] -public struct Matrix3X3(Vector3 x, Vector3 y, Vector3 z) +public partial struct Matrix3X3 { private const int IndexRaw0 = 0; private const int IndexRaw1 = 1; @@ -19,9 +19,9 @@ public struct Matrix3X3(Vector3 x, Vector3 y, Vector3 z) public static Matrix3X3 One => new(Vector3.One); public static Matrix3X3 Identity => new(Vector3.Right, Vector3.Up, Vector3.Forward); - public Vector3 Raw0 = x; - public Vector3 Raw1 = y; - public Vector3 Raw2 = z; + public Vector3 Row0; + public Vector3 Row1; + public Vector3 Row2; /// /// Matrix x: 0, y: 0 element. @@ -29,9 +29,9 @@ public struct Matrix3X3(Vector3 x, Vector3 y, Vector3 z) public float M00 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw0.X; + get => Row0.X; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw0 = Raw0.WithX(value); + set => Row0 = Row0.WithX(value); } /// @@ -40,9 +40,9 @@ public float M00 public float M01 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw0.Y; + get => Row0.Y; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw0 = Raw0.WithY(value); + set => Row0 = Row0.WithY(value); } /// @@ -51,9 +51,9 @@ public float M01 public float M02 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw0.Z; + get => Row0.Z; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw0 = Raw0.WithZ(value); + set => Row0 = Row0.WithZ(value); } /// @@ -62,9 +62,9 @@ public float M02 public float M10 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw1.X; + get => Row1.X; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw1 = Raw1.WithX(value); + set => Row1 = Row1.WithX(value); } /// @@ -73,9 +73,9 @@ public float M10 public float M11 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw1.Y; + get => Row1.Y; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw1 = Raw1.WithY(value); + set => Row1 = Row1.WithY(value); } /// @@ -84,9 +84,9 @@ public float M11 public float M12 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw1.Z; + get => Row1.Z; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw1 = Raw1.WithZ(value); + set => Row1 = Row1.WithZ(value); } /// @@ -95,9 +95,9 @@ public float M12 public float M20 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw2.X; + get => Row2.X; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw2 = Raw2.WithX(value); + set => Row2 = Row2.WithX(value); } /// @@ -106,9 +106,9 @@ public float M20 public float M21 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw2.Y; + get => Row2.Y; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw2 = Raw2.WithY(value); + set => Row2 = Row2.WithY(value); } /// @@ -117,9 +117,9 @@ public float M21 public float M22 { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Raw2.Z; + get => Row2.Z; [MethodImpl(MethodImplOptions.AggressiveInlining)] - set => Raw2 = Raw2.WithZ(value); + set => Row2 = Row2.WithZ(value); } public float this[int raw, int colum] @@ -218,11 +218,33 @@ public float M22 } } } + /// + /// Creates 3x3 matrix + /// + /// x.X | x.Y | x.Z + /// y.X | y.Y | y.Z + /// z.X | z.Y | z.Z + /// + /// + public Matrix3X3(Vector3 x, Vector3 y, Vector3 z) + { + Row0 = x; + Row1 = y; + Row2 = z; + } public Matrix3X3(Vector3 value) : this(value, value, value) { } + /// + /// Creates 3x3 matrix + /// + /// m00 | m01 | m02 + /// m10 | m11 | m12 + /// m20 | m21 | m22 + /// + /// public Matrix3X3(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22) : this(new Vector3(m00, m01, m02), @@ -379,6 +401,6 @@ public static Matrix3X3 CreateTransform(Vector2 position, Angle angle, Vector2 s public static Vector3 operator *(Matrix3X3 a, Vector3 b) { - return a.Raw0 * b.X + a.Raw1 * b.Y + a.Raw2 * b.Z; + return a.Row0 * b.X + a.Row1 * b.Y + a.Row2 * b.Z; } } \ No newline at end of file From 3b4e0dec96d942f60dffadf675fffeb5d86135a4 Mon Sep 17 00:00:00 2001 From: JerryImMouse Date: Fri, 12 Jul 2024 02:41:01 +0500 Subject: [PATCH 18/19] matrix 3x3 compatibility --- .../Matrix/Matrix3X3.Compatibility.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Hypercube.Shared.Math/Matrix/Matrix3X3.Compatibility.cs diff --git a/Hypercube.Shared.Math/Matrix/Matrix3X3.Compatibility.cs b/Hypercube.Shared.Math/Matrix/Matrix3X3.Compatibility.cs new file mode 100644 index 0000000..1d6affa --- /dev/null +++ b/Hypercube.Shared.Math/Matrix/Matrix3X3.Compatibility.cs @@ -0,0 +1,39 @@ +using System.Runtime.CompilerServices; +using OpenTK.Mathematics; + +namespace Hypercube.Shared.Math.Matrix; + +public partial struct Matrix3X3 +{ + /* + * OpenTK Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Matrix3(Matrix3X3 matrix3) + { + return new Matrix3(matrix3.Row0, matrix3.Row1, matrix3.Row2); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Matrix3X3(Matrix3 matrix3) + { + return new Matrix3X3(matrix3.Row0, matrix3.Row1, matrix3.Row2); + } + + /* + * OpenToolkit Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator OpenToolkit.Mathematics.Matrix3(Matrix3X3 matrix3) + { + return new OpenToolkit.Mathematics.Matrix3(matrix3.Row0, matrix3.Row1, matrix3.Row2); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Matrix3X3(OpenToolkit.Mathematics.Matrix3 matrix3) + { + return new Matrix3X3(matrix3.Row0, matrix3.Row1, matrix3.Row2); + } +} \ No newline at end of file From 5f1c041e339a48a1bca909aa17e7e4e4c7aca009 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Fri, 12 Jul 2024 08:06:11 +1000 Subject: [PATCH 19/19] Clean up more math structs --- .../Manager/GlfwWindowManager.Window.cs | 2 +- Hypercube.Shared.Math/Matrix/Matrix3X3.cs | 21 +-- Hypercube.Shared.Math/Matrix/Matrix4X4.cs | 9 +- .../Vector/Vector2.Compatibility.cs | 22 +++ Hypercube.Shared.Math/Vector/Vector2.cs | 27 ++-- .../Vector/Vector2Int.Compatibility.cs | 68 +++++++++ Hypercube.Shared.Math/Vector/Vector2Int.cs | 132 ++++++++++++------ .../Vector/Vector3.Compatibility.cs | 24 +++- Hypercube.Shared.Math/Vector/Vector3.cs | 44 ++++-- Hypercube.Shared.Math/Vector/Vector4.cs | 3 +- 10 files changed, 269 insertions(+), 83 deletions(-) diff --git a/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Window.cs b/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Window.cs index 4a92ee6..816e174 100644 --- a/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Window.cs +++ b/Hypercube.Client/Graphics/Windows/Manager/GlfwWindowManager.Window.cs @@ -118,7 +118,7 @@ private GlfwWindowRegistration WindowSetup(Window* window, WindowCreateSettings Pointer = window, Id = new WindowId(_nextWindowId++), - Ratio = framebufferSize.Ratio, + Ratio = framebufferSize.AspectRatio, Size = size, FramebufferSize = framebufferSize }; diff --git a/Hypercube.Shared.Math/Matrix/Matrix3X3.cs b/Hypercube.Shared.Math/Matrix/Matrix3X3.cs index 822dca4..ddf205f 100644 --- a/Hypercube.Shared.Math/Matrix/Matrix3X3.cs +++ b/Hypercube.Shared.Math/Matrix/Matrix3X3.cs @@ -4,12 +4,13 @@ namespace Hypercube.Shared.Math.Matrix; +// TODO: May be it's can be immutable, and also layout broken [StructLayout(LayoutKind.Sequential)] public partial struct Matrix3X3 { - private const int IndexRaw0 = 0; - private const int IndexRaw1 = 1; - private const int IndexRaw2 = 2; + private const int IndexRow0 = 0; + private const int IndexRow1 = 1; + private const int IndexRow2 = 2; private const int IndexColumn0 = 0; private const int IndexColumn1 = 1; @@ -17,7 +18,7 @@ public partial struct Matrix3X3 public static Matrix3X3 Zero => new(Vector3.Zero); public static Matrix3X3 One => new(Vector3.One); - public static Matrix3X3 Identity => new(Vector3.Right, Vector3.Up, Vector3.Forward); + public static Matrix3X3 Identity => new(Vector3.UnitX, Vector3.UnitY, Vector3.UnitZ); public Vector3 Row0; public Vector3 Row1; @@ -126,21 +127,21 @@ public float M22 { get => raw switch { - IndexRaw0 => colum switch + IndexRow0 => colum switch { IndexColumn0 => M00, IndexColumn1 => M01, IndexColumn2 => M02, _ => throw new ArgumentOutOfRangeException(nameof(colum), colum, null) }, - IndexRaw1 => colum switch + IndexRow1 => colum switch { IndexColumn0 => M10, IndexColumn1 => M11, IndexColumn2 => M12, _ => throw new ArgumentOutOfRangeException(nameof(colum), colum, null) }, - IndexRaw2 => colum switch + IndexRow2 => colum switch { IndexColumn0 => M20, IndexColumn1 => M21, @@ -153,7 +154,7 @@ public float M22 { switch (raw) { - case IndexRaw0: + case IndexRow0: switch (colum) { case IndexColumn0: @@ -173,7 +174,7 @@ public float M22 } break; - case IndexRaw1: + case IndexRow1: switch (colum) { case IndexColumn0: @@ -193,7 +194,7 @@ public float M22 } break; - case IndexRaw2: + case IndexRow2: switch (colum) { case IndexColumn0: diff --git a/Hypercube.Shared.Math/Matrix/Matrix4X4.cs b/Hypercube.Shared.Math/Matrix/Matrix4X4.cs index b48c718..17cef3d 100644 --- a/Hypercube.Shared.Math/Matrix/Matrix4X4.cs +++ b/Hypercube.Shared.Math/Matrix/Matrix4X4.cs @@ -8,16 +8,9 @@ namespace Hypercube.Shared.Math.Matrix; [StructLayout(LayoutKind.Sequential)] public partial struct Matrix4X4 : IEquatable { - public const int Size = 4 * Vector4.Size; - public static Matrix4X4 Zero => new(Vector4.Zero); public static Matrix4X4 One => new(Vector4.One); - - public static Matrix4X4 Identity => new( - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1); + public static Matrix4X4 Identity => new(Vector4.UnitX, Vector4.UnitY, Vector4.UnitZ, Vector4.UnitW); public Vector4 Row0; public Vector4 Row1; diff --git a/Hypercube.Shared.Math/Vector/Vector2.Compatibility.cs b/Hypercube.Shared.Math/Vector/Vector2.Compatibility.cs index 942ee23..b79f9eb 100644 --- a/Hypercube.Shared.Math/Vector/Vector2.Compatibility.cs +++ b/Hypercube.Shared.Math/Vector/Vector2.Compatibility.cs @@ -8,12 +8,34 @@ public readonly partial struct Vector2 * Self Compatibility */ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector2Int(Vector2 vector) + { + return new Vector2Int((int)vector.X, (int)vector.Y); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Vector3(Vector2 vector) { return new Vector3(vector.X, vector.Y, 0f); } + /* + * Tuple Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector2((float x, float y) a) + { + return new Vector2(a.x, a.y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator (float x, float y)(Vector2 a) + { + return (a.X, a.Y); + } + /* * System.Numerics Compatibility */ diff --git a/Hypercube.Shared.Math/Vector/Vector2.cs b/Hypercube.Shared.Math/Vector/Vector2.cs index 8ce7e98..4742380 100644 --- a/Hypercube.Shared.Math/Vector/Vector2.cs +++ b/Hypercube.Shared.Math/Vector/Vector2.cs @@ -4,24 +4,33 @@ namespace Hypercube.Shared.Math.Vector; [StructLayout(LayoutKind.Sequential)] -public readonly partial struct Vector2(float x, float y) : IEquatable +public readonly partial struct Vector2 : IEquatable { public static readonly Vector2 Zero = new(0, 0); public static readonly Vector2 One = new(1, 1); - public static readonly Vector2 Up = new(0, 1); - public static readonly Vector2 Down = new(0, -1); - public static readonly Vector2 Right = new(1, 0); - public static readonly Vector2 Left = new(-1, 0); + public static readonly Vector2 UnitX = new(1, 0); public static readonly Vector2 UnitY = new(0, 1); - public readonly float X = x; - public readonly float Y = y; + public readonly float X; + public readonly float Y; + public float AspectRatio + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => X / Y; + } + public float Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => MathF.Sqrt(x * x + y * y); + get => MathF.Sqrt(X * X + Y * Y); + } + + public Vector2(float x, float y) + { + X = x; + Y = y; } public Vector2(float value) : this(value, value) @@ -65,7 +74,7 @@ public override int GetHashCode() [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { - return $"{x}, {y}"; + return $"{X}, {Y}"; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Hypercube.Shared.Math/Vector/Vector2Int.Compatibility.cs b/Hypercube.Shared.Math/Vector/Vector2Int.Compatibility.cs index f1df15b..fc6d717 100644 --- a/Hypercube.Shared.Math/Vector/Vector2Int.Compatibility.cs +++ b/Hypercube.Shared.Math/Vector/Vector2Int.Compatibility.cs @@ -4,6 +4,42 @@ namespace Hypercube.Shared.Math.Vector; public readonly partial struct Vector2Int { + /* + * Self Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector2(Vector2Int vector) + { + return new Vector2(vector.X, vector.Y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector3(Vector2Int vector) + { + return new Vector3(vector.X, vector.Y, 0f); + } + + /* + * Tuple Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector2Int((int x, int y) a) + { + return new Vector2Int(a.x, a.y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator (int x, int y)(Vector2Int a) + { + return (a.X, a.Y); + } + + /* + * System.Drawing Compatibility + */ + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Vector2Int(System.Drawing.Size size) { @@ -15,4 +51,36 @@ public static implicit operator System.Drawing.Size(Vector2Int vector2) { return new System.Drawing.Size(vector2.X, vector2.Y); } + + /* + * OpenTK Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector2Int(OpenTK.Mathematics.Vector2i vector) + { + return new Vector2Int(vector.X, vector.Y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator OpenTK.Mathematics.Vector2i(Vector2Int vector) + { + return new OpenTK.Mathematics.Vector2i(vector.X, vector.Y); + } + + /* + * OpenToolkit Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector2Int(OpenToolkit.Mathematics.Vector2i vector) + { + return new Vector2Int(vector.X, vector.Y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator OpenToolkit.Mathematics.Vector2i(Vector2Int vector) + { + return new OpenToolkit.Mathematics.Vector2i(vector.X, vector.Y); + } } \ No newline at end of file diff --git a/Hypercube.Shared.Math/Vector/Vector2Int.cs b/Hypercube.Shared.Math/Vector/Vector2Int.cs index c61fba7..554e67f 100644 --- a/Hypercube.Shared.Math/Vector/Vector2Int.cs +++ b/Hypercube.Shared.Math/Vector/Vector2Int.cs @@ -1,114 +1,158 @@ -using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace Hypercube.Shared.Math.Vector; [StructLayout(LayoutKind.Sequential)] -public readonly partial struct Vector2Int(int x, int y) +public readonly partial struct Vector2Int : IEquatable { public static readonly Vector2Int Zero = new(0, 0); public static readonly Vector2Int One = new(1, 1); - public static readonly Vector2Int Up = new(0, 1); - public static readonly Vector2Int Down = new(0, -1); - public static readonly Vector2Int Right = new(1, 0); - public static readonly Vector2Int Left = new(-1, 0); + + public static readonly Vector2Int UnitX = new(1, 0); + public static readonly Vector2Int UnitY = new(0, 1); + + public readonly int X; + public readonly int Y; + + public float AspectRatio + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => X / (float)Y; + } + + public float Length + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => MathF.Sqrt(X * X + Y * Y); + } + + public Vector2Int(int x, int y) + { + X = x; + Y = y; + } + + public Vector2Int(int value) : this(value, value) + { + } + + public Vector2Int(Vector2Int vector2Int) : this(vector2Int.X, vector2Int.Y) + { + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2Int WithX(int value) + { + return new Vector2Int(value, Y); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2Int WithY(int value) + { + return new Vector2Int(X, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(Vector2Int other) + { + return X == other.X && + Y == other.Y; + } - public readonly int X = x; - public readonly int Y = y; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override bool Equals(object? obj) + { + return obj is Vector2Int vector && Equals(vector); + } - public float Ratio => x / (float)y; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override int GetHashCode() + { + return HashCode.Combine(X, Y); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override string ToString() + { + return $"{X}, {Y}"; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2Int operator +(Vector2Int a, Vector2Int b) { return new Vector2Int(a.X + b.X, a.Y + b.Y); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2Int operator +(Vector2Int a, int b) { return new Vector2Int(a.X + b, a.Y + b); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2Int operator -(Vector2Int a) + { + return new Vector2Int(-a.X, -a.Y); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2Int operator -(Vector2Int a, Vector2Int b) { return new Vector2Int(a.X - b.X, a.Y - b.Y); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2Int operator -(Vector2Int a, int b) { return new Vector2Int(a.X - b, a.Y - b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2Int operator *(Vector2Int a, Vector2Int b) { return new Vector2Int(a.X * b.X, a.Y * b.Y); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2Int operator *(Vector2Int a, int b) { return new Vector2Int(a.X * b, a.Y * b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 operator *(Vector2Int a, float b) { return new Vector2(a.X * b, a.Y * b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2Int operator /(Vector2Int a, Vector2Int b) { return new Vector2Int(a.X / b.X, a.Y / b.Y); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2Int operator /(Vector2Int a, int b) { return new Vector2Int(a.X / b, a.Y / b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 operator /(Vector2Int a, float b) { return new Vector2(a.X / b, a.Y / b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Vector2Int a, Vector2Int b) { return a.Equals(b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(Vector2Int a, Vector2Int b) { return !a.Equals(b); } - - public static implicit operator Vector2(Vector2Int a) - { - return new Vector2(a.X, a.Y); - } - - public static implicit operator Vector2Int(Vector2 a) - { - return new Vector2Int((int)a.X, (int)a.Y); - } - - public static implicit operator Vector2Int((int x, int y) a) - { - return new Vector2Int(a.x, a.y); - } - - public readonly bool Equals(Vector2Int other) - { - return X == other.X && Y == other.Y; - } - - public readonly override bool Equals(object? obj) - { - return obj is Vector2Int vector && Equals(vector); - } - - public override int GetHashCode() - { - return x + y; - } - - public override string ToString() - { - return $"{x}, {y}"; - } } \ No newline at end of file diff --git a/Hypercube.Shared.Math/Vector/Vector3.Compatibility.cs b/Hypercube.Shared.Math/Vector/Vector3.Compatibility.cs index 82be42e..5236e58 100644 --- a/Hypercube.Shared.Math/Vector/Vector3.Compatibility.cs +++ b/Hypercube.Shared.Math/Vector/Vector3.Compatibility.cs @@ -5,7 +5,7 @@ namespace Hypercube.Shared.Math.Vector; public readonly partial struct Vector3 { /* - * Vector2 Compatibility + * Self Compatibility */ [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -14,6 +14,28 @@ public static implicit operator Vector2(Vector3 vector) return new Vector2(vector.X, vector.Y); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector2Int(Vector3 vector) + { + return new Vector2Int((int)vector.X, (int)vector.Y); + } + + /* + * Tuple Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector3((float x, float y, float z) a) + { + return new Vector3(a.x, a.y, a.z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator (float x, float y, float z)(Vector3 a) + { + return (a.X, a.Y, a.Z); + } + /* * System.Numerics Compatibility */ diff --git a/Hypercube.Shared.Math/Vector/Vector3.cs b/Hypercube.Shared.Math/Vector/Vector3.cs index b6912a5..e9f8463 100644 --- a/Hypercube.Shared.Math/Vector/Vector3.cs +++ b/Hypercube.Shared.Math/Vector/Vector3.cs @@ -1,19 +1,15 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using Hypercube.Shared.Math.Extensions; namespace Hypercube.Shared.Math.Vector; [StructLayout(LayoutKind.Sequential)] -public readonly partial struct Vector3(float x, float y, float z) +public readonly partial struct Vector3(float x, float y, float z) : IEquatable { public static readonly Vector3 Zero = new(0, 0, 0); public static readonly Vector3 One = new(1, 1, 1); - public static readonly Vector3 Forward = new(0, 0, 1); - public static readonly Vector3 Back = new(0, 0, -1); - public static readonly Vector3 Up = new(0, 1, 0); - public static readonly Vector3 Down = new(0, -1, 0); - public static readonly Vector3 Right = new(1, 0, 0); - public static readonly Vector3 Left = new(-1, 0, 0); + public static readonly Vector3 UnitX = new(1, 0, 0); public static readonly Vector3 UnitY = new(0, 1, 0); public static readonly Vector3 UnitZ = new(0, 0, 1); @@ -79,7 +75,27 @@ public Vector3 Cross(Vector3 other) { return Vector3.Cross(this, other); } - + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(Vector3 other) + { + return X.AboutEquals(other.X) && + Y.AboutEquals(other.Y) && + Z.AboutEquals(other.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override bool Equals(object? obj) + { + return obj is Vector3 other && Equals(other); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override int GetHashCode() + { + return HashCode.Combine(X, Y, Z); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { @@ -164,6 +180,18 @@ public override string ToString() return new Vector3(a.X / b, a.Y / b, a.Z / b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator ==(Vector3 a, Vector3 b) + { + return a.Equals(b); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator !=(Vector3 a, Vector3 b) + { + return !a.Equals(b); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Cross(Vector3 left, Vector3 right) { diff --git a/Hypercube.Shared.Math/Vector/Vector4.cs b/Hypercube.Shared.Math/Vector/Vector4.cs index 95bc583..224dcb1 100644 --- a/Hypercube.Shared.Math/Vector/Vector4.cs +++ b/Hypercube.Shared.Math/Vector/Vector4.cs @@ -7,10 +7,9 @@ namespace Hypercube.Shared.Math.Vector; [StructLayout(LayoutKind.Sequential)] public readonly partial struct Vector4 : IEquatable { - public const int Size = 4 * sizeof(float); - public static readonly Vector4 Zero = new(0, 0, 0, 0); public static readonly Vector4 One = new(1, 1, 1, 1); + public static readonly Vector4 UnitX = new(1, 0, 0, 0); public static readonly Vector4 UnitY = new(0, 1, 0, 0); public static readonly Vector4 UnitZ = new(0, 0, 1, 0);