Skip to content

Commit 4445f62

Browse files
committed
Add maths helpers, is this progress I don't even know anymore
1 parent 6fadfee commit 4445f62

File tree

7 files changed

+86
-76
lines changed

7 files changed

+86
-76
lines changed

examples/CSharp/OpenGL Demos/OpenGL VR Demo/Camera.cs

Lines changed: 5 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,61 +6,16 @@ namespace OpenGL_VR_Demo
66
{
77
public class Camera
88
{
9-
private Quaternion _quat;
9+
private Renderer _renderer;
1010

1111
public Vector3 Position { get; set; }
12-
public Vector3 Front { get; set; }
13-
14-
public Vector3 Up { get; private set; }
15-
public float AspectRatio { get; set; }
16-
17-
public float Yaw { get; set; } = -90f;
18-
public float Pitch { get; set; }
19-
20-
private float Zoom = 45f;
21-
22-
public Camera(Vector3 position, Vector3 front, Vector3 up, float aspectRatio)
12+
public Camera(Vector3 position, Renderer renderer)
2313
{
2414
Position = position;
25-
AspectRatio = aspectRatio;
26-
Front = front;
27-
Up = up;
28-
}
29-
30-
public void ModifyZoom(float zoomAmount)
31-
{
32-
//We don't want to be able to zoom in too close or too far away so clamp to these values
33-
Zoom = Math.Clamp(Zoom - zoomAmount, 1.0f, 45f);
34-
}
35-
36-
//public void ModifyDirection(float xOffset, float yOffset)
37-
public void ModifyDirection(Quaternion orientation)
38-
{
39-
// Yaw += xOffset;
40-
// Pitch -= yOffset;
41-
42-
////We don't want to be able to look behind us by going over our head or under our feet so make sure it stays within these bounds
43-
//Pitch = Math.Clamp(Pitch, -89f, 89f);
44-
45-
//var cameraDirection = Vector3.Zero;
46-
var cameraDirection = Vector3.Zero;
47-
cameraDirection.X = MathF.Cos(MathHelper.DegreesToRadians(Yaw)) * MathF.Cos(MathHelper.DegreesToRadians(Pitch));
48-
cameraDirection.Y = MathF.Sin(MathHelper.DegreesToRadians(Pitch));
49-
cameraDirection.Z = MathF.Sin(MathHelper.DegreesToRadians(Yaw)) * MathF.Cos(MathHelper.DegreesToRadians(Pitch));
50-
cameraDirection = Vector3.Transform(cameraDirection, orientation);
51-
Front = Vector3.Normalize(cameraDirection);
52-
53-
_quat = orientation;
15+
_renderer = renderer;
5416
}
5517

56-
public Matrix4x4 GetViewMatrix()
57-
{
58-
return Matrix4x4.CreateLookAt(Position, Position + Front, Up);
59-
}
60-
61-
public Matrix4x4 GetProjectionMatrix()
62-
{
63-
return Matrix4x4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(Zoom), AspectRatio, 0.1f, 100.0f);
64-
}
18+
public Matrix4x4 GetViewMatrix(int eye) => _renderer.GetViewMatrix(eye, Position);
19+
public Matrix4x4 GetProjectionMatrix(int eye) => _renderer.GetProjectionMatrix(eye);
6520
}
6621
}

examples/CSharp/OpenGL Demos/OpenGL VR Demo/Game.cs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Numerics;
55
using System.Runtime.CompilerServices;
66
using OpenGL_VR_Demo.OpenXR;
7+
using Silk.NET.Maths;
78
using Silk.NET.OpenGL;
89
using Silk.NET.OpenXR;
910
using Shader = Silk.NET.OpenGL.Shader;
@@ -19,6 +20,7 @@ public class Game : OpenGLXRGame
1920
private static VertexArrayObject<float, uint> VaoCube;
2021
private static Shader LightingShader;
2122
private static Shader LampShader;
23+
private static Vector3 CubePosition = new(0.2f, 0.0f, 1.0f);
2224
private static Vector3 LampPosition = new(1.2f, 1.0f, 2.0f);
2325

2426
private static Camera Camera;
@@ -84,7 +86,7 @@ public Game(bool forceNoDebug = false, bool useMinimumVersion = false)
8486

8587
protected override void Load()
8688
{
87-
Gl = Renderer.Gl;
89+
Gl = Renderer!.Gl;
8890

8991
Ebo = new(Gl, Indices, BufferTargetARB.ElementArrayBuffer);
9092
Vbo = new(Gl, Vertices, BufferTargetARB.ArrayBuffer);
@@ -99,7 +101,7 @@ protected override void Load()
99101
LampShader = new(Gl, "shader.vert", "shader.frag");
100102

101103
//Start a camera at position 3 on the Z axis, looking at position -1 on the Z axis
102-
Camera = new(Vector3.UnitZ * 6, Vector3.UnitZ * -1, Vector3.UnitY, (float)EyeWidth / EyeHeight);
104+
Camera = new(Vector3.UnitZ * 6 * 6, Renderer);
103105
}
104106

105107
protected override void Update(double delta)
@@ -110,26 +112,29 @@ protected override void Update(double delta)
110112

111113
protected override void Render(int eye, double delta)
112114
{
113-
var position = Unsafe.As<Vector3f, Vector3>(ref Renderer.ViewStates[0].Pose.Position);
114-
var orientation = Unsafe.As<Quaternionf, Quaternion>(ref Renderer.ViewStates[0].Pose.Orientation);
115-
Camera.ModifyDirection(orientation);
116-
117115
Gl.Enable(EnableCap.DepthTest);
118116
Gl.Clear((uint) (ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit));
119117

120118
VaoCube.Bind();
121119
LightingShader.Use();
120+
121+
// Define the matrix for our cube
122+
var cubeMatrix = Matrix4x4.Identity;
123+
cubeMatrix *= Matrix4x4.CreateTranslation(CubePosition);
122124

123-
//Slightly rotate the cube to give it an angled face to look at
124-
LightingShader.SetUniform("uModel", Matrix4x4.CreateRotationY(MathHelper.DegreesToRadians(25f)));
125-
LightingShader.SetUniform("uView", Renderer.Views[eye]);
126-
LightingShader.SetUniform("uProjection", Renderer.Projections[eye]);
125+
// Slightly rotate the cube to give it an angled face to look at
126+
cubeMatrix *= Matrix4x4.CreateRotationY(Scalar.DegreesToRadians(25f));
127+
128+
//LightingShader.SetUniform("uModel", Matrix4x4.CreateRotationY(MathHelper.DegreesToRadians(25f)));
129+
LightingShader.SetUniform("uModel", cubeMatrix);
130+
LightingShader.SetUniform("uView", Camera.GetViewMatrix(eye));
131+
LightingShader.SetUniform("uProjection", Camera.GetProjectionMatrix(eye));
127132
LightingShader.SetUniform("objectColor", new Vector3(1.0f, 0.5f, 0.31f));
128133
LightingShader.SetUniform("lightColor", Vector3.One);
129134
LightingShader.SetUniform("lightPos", LampPosition);
130135
LightingShader.SetUniform("viewPos", Camera.Position);
131136

132-
//We're drawing with just vertices and no indicies, and it takes 36 verticies to have a six-sided textured cube
137+
// We're drawing with just vertices and no indicies, and it takes 36 verticies to have a six-sided textured cube
133138
Gl.DrawArrays(PrimitiveType.Triangles, 0, 36);
134139

135140
LampShader.Use();
@@ -140,8 +145,8 @@ protected override void Render(int eye, double delta)
140145
lampMatrix *= Matrix4x4.CreateTranslation(LampPosition);
141146

142147
LampShader.SetUniform("uModel", lampMatrix);
143-
LampShader.SetUniform("uView", Renderer.Views[eye]);
144-
LampShader.SetUniform("uProjection", Renderer.Projections[eye]);
148+
LampShader.SetUniform("uView", Camera.GetViewMatrix(eye));
149+
LampShader.SetUniform("uProjection", Camera.GetProjectionMatrix(eye));
145150

146151
Gl.DrawArrays(PrimitiveType.Triangles, 0, 36);
147152
}

examples/CSharp/OpenGL Demos/OpenGL VR Demo/OpenXR/Renderer.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,20 @@ public class Renderer : IDisposable
3535
public uint[] SwapchainImages;
3636

3737
// Eye Info - for use in games!
38+
private Posef[] RawViews { get; set; } = new Posef[2];
39+
private Matrix4x4[] Projections { get; set; } = new Matrix4x4[2];
3840
public View[] ViewStates { get; private set; } = new View[2];
39-
public Matrix4x4[] Views { get; private set; } = new Matrix4x4[2];
40-
public Matrix4x4[] Projections { get; private set; } = new Matrix4x4[2];
41+
public Matrix4x4 GetViewMatrix(int eye, Vector3 offset = default)
42+
{
43+
if (!Matrix4x4.Invert(RawViews[eye].ToView(), out var inverse))
44+
{
45+
throw new("Couldn't create inverse pose view matrix.");
46+
}
47+
48+
return inverse;
49+
}
50+
51+
public Matrix4x4 GetProjectionMatrix(int eye) => Projections[eye];
4152

4253
// Misc
4354
private IView _view;
@@ -489,12 +500,7 @@ private unsafe void UpdateViews(in FrameState frameState)
489500
{
490501
var view = ViewStates[eye];
491502
Projections[eye] = view.Fov.ToProjection();
492-
if (!Matrix4x4.Invert(view.Pose.ToView(), out var inverse))
493-
{
494-
throw new("Couldn't create inverse pose view matrix.");
495-
}
496-
497-
Views[eye] = inverse;
503+
RawViews[eye] = view.Pose;
498504
}
499505
}
500506

examples/CSharp/OpenGL Demos/OpenGL VR Demo/OpenXR/Utilities.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ public static class Utilities
1414
public const float DefaultFarZ = 100.0f;
1515
public const float DefaultOffset = 0f;
1616

17-
public static Matrix4x4 ToView(this Posef pose)
18-
=> Matrix4x4.Identity
19-
* Matrix4x4.CreateTranslation(Unsafe.As<Vector3f, Vector3>(ref pose.Position))
20-
* Matrix4x4.CreateFromQuaternion(Unsafe.As<Quaternionf, Quaternion>(ref pose.Orientation));
17+
public static Matrix4x4 ToView(this Posef pose, Vector3 offset = default)
18+
=> Matrix4x4.Transpose(Matrix4x4.Identity
19+
* Matrix4x4.CreateTranslation(Unsafe.As<Vector3f, Vector3>(ref pose.Position) + offset)
20+
* Matrix4x4.CreateFromQuaternion(Unsafe.As<Quaternionf, Quaternion>(ref pose.Orientation)));
2121

2222
public static Matrix4x4
2323
ToProjection

src/Maths/Silk.NET.Maths/PublicAPI.Unshipped.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,8 @@ Silk.NET.Maths.Vector4D<T>.As<TOther>() -> Silk.NET.Maths.Vector4D<TOther>
2424
Silk.NET.Maths.Box2D<T>.GetScaled<TScale>(Silk.NET.Maths.Vector2D<TScale> scale, Silk.NET.Maths.Vector2D<T> anchor) -> Silk.NET.Maths.Box2D<T>
2525
Silk.NET.Maths.Box3D<T>.GetScaled<TScale>(Silk.NET.Maths.Vector3D<TScale> scale, Silk.NET.Maths.Vector3D<T> anchor) -> Silk.NET.Maths.Box3D<T>
2626
Silk.NET.Maths.Rectangle<T>.GetScaled<TScale>(Silk.NET.Maths.Vector2D<TScale> scale, Silk.NET.Maths.Vector2D<T> anchor) -> Silk.NET.Maths.Rectangle<T>
27-
Silk.NET.Maths.Cube<T>.GetScaled<TScale>(Silk.NET.Maths.Vector3D<TScale> scale, Silk.NET.Maths.Vector3D<T> anchor) -> Silk.NET.Maths.Cube<T>
27+
Silk.NET.Maths.Cube<T>.GetScaled<TScale>(Silk.NET.Maths.Vector3D<TScale> scale, Silk.NET.Maths.Vector3D<T> anchor) -> Silk.NET.Maths.Cube<T>
28+
static Silk.NET.Maths.Scalar.DegreesToRadians<T>(T degrees) -> T
29+
static Silk.NET.Maths.Scalar.RadiansToDegrees<T>(T radians) -> T
30+
static readonly Silk.NET.Maths.Scalar<T>.RadiansPerDegree -> T
31+
static readonly Silk.NET.Maths.Scalar<T>.DegreesPerRadian -> T

src/Maths/Silk.NET.Maths/Scalar.Constants.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,22 @@ public static partial class Scalar<T> where T : unmanaged
8787
/// </summary>
8888
public static readonly T Tau;
8989

90+
/// <summary>
91+
/// Represents the number of degrees in a single radian.
92+
/// </summary>
93+
/// <remarks>
94+
/// This is equivalent to <c>180 / MathF.Pi</c>
95+
/// </remarks>
96+
public static readonly T DegreesPerRadian;
97+
98+
/// <summary>
99+
/// Represents the number of radians in a single degree.
100+
/// </summary>
101+
/// <remarks>
102+
/// This is equivalent to <c>MathF.Pi / 180</c>.
103+
/// </remarks>
104+
public static readonly T RadiansPerDegree;
105+
90106
internal static readonly bool IntrinsicsApplicable = typeof(T) == typeof(byte)
91107
|| typeof(T) == typeof(sbyte)
92108
|| typeof(T) == typeof(ushort)
@@ -315,6 +331,8 @@ static Scalar()
315331
}
316332

317333
PiOver2 = Scalar.Divide(Pi, Two);
334+
DegreesPerRadian = Scalar.Divide(Scalar.As<float, T>(180), Pi);
335+
RadiansPerDegree = Scalar.Divide(Pi, Scalar.As<float, T>(180));
318336
}
319337
}
320338
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
namespace Silk.NET.Maths
5+
{
6+
public partial class Scalar
7+
{
8+
/// <summary>
9+
/// Convert degrees to radians.
10+
/// </summary>
11+
/// <param name="degrees">An angle in degrees.</param>
12+
/// <returns>The angle expressed in radians.</returns>
13+
public static T DegreesToRadians<T>(T degrees) where T : unmanaged => Multiply(degrees, Scalar<T>.RadiansPerDegree);
14+
15+
/// <summary>
16+
/// Convert radians to degrees.
17+
/// </summary>
18+
/// <param name="radians">An angle in radians.</param>
19+
/// <returns>The angle expressed in degrees.</returns>
20+
public static T RadiansToDegrees<T>(T radians) where T : unmanaged => Multiply(radians, Scalar<T>.DegreesPerRadian);
21+
}
22+
}

0 commit comments

Comments
 (0)