Added IcoSphere for testing. Replaced Vector3D<T> with Vector3 since it is more performant
All checks were successful
Gitea Actions Demo / Scan the project (push) Successful in 21s

This commit is contained in:
2024-02-04 22:53:58 +01:00
parent 0b0d2360d6
commit 3912f2bd9a
7 changed files with 271 additions and 50 deletions

View File

@ -1,20 +1,20 @@
using Silk.NET.Maths;
using System.Numerics;
using Silk.NET.OpenGL;
namespace Nebulix.Rendering
{
public sealed class Mesh
{
public Vector3D<float>[] Vertices { get => vertices;
set { vertices = value; regenerate = true; normals = new Vector3D<float>[vertices.Length];} }
public Vector3[] Vertices { get => vertices;
set { vertices = value; regenerate = true; normals = new Vector3[vertices.Length];} }
public uint[] Indices { get => indices; set { indices = value; regenerate = true; } }
private uint vao = 0, vbo = 0, ebo = 0;
private uint vao, vbo, ebo;
private bool regenerate = true;
private Vector3D<float>[] vertices = [];
private Vector3[] vertices = [];
private uint[] indices = [];
private Vector3D<float>[] normals = [];
private Vector3[] normals = [];
public void Clear()
{
@ -29,13 +29,13 @@ namespace Nebulix.Rendering
uint i0 = indices[i];
uint i1 = indices[i+1];
uint i2 = indices[i+2];
Vector3D<float> v0 = vertices[i0];
Vector3D<float> v1 = vertices[i1];
Vector3D<float> v2 = vertices[i2];
Vector3 v0 = vertices[i0];
Vector3 v1 = vertices[i1];
Vector3 v2 = vertices[i2];
Vector3D<float> normal = Vector3D.Cross(v1-v0, v2-v0);
Vector3 normal = Vector3.Cross(v1-v0, v2-v0);
// Commenting this out, will result in the normals being weighted based on the triangle area
normal = Vector3D.Normalize(normal);
normal = Vector3.Normalize(normal);
normals[i0] += normal;
normals[i1] += normal;
normals[i2] += normal;
@ -43,7 +43,7 @@ namespace Nebulix.Rendering
for (int i = 0; i < normals.Length; i++)
{
normals[i] = Vector3D.Normalize(normals[i]); // smoothing for shared vertices
normals[i] = Vector3.Normalize(normals[i]); // smoothing for shared vertices
}
}

View File

@ -1,6 +1,6 @@
using Silk.NET.Maths;
using Silk.NET.OpenGL;
using Silk.NET.OpenGL;
using System.Numerics;
using Silk.NET.Maths;
namespace Nebulix.Rendering;
@ -35,6 +35,10 @@ public class Shader
_glContext.Uniform1(_glContext.GetUniformLocation(_shaderProgramId, name), value);
}
public void SetVector(string name, Vector3 value)
{
_glContext.Uniform3(_glContext.GetUniformLocation(_shaderProgramId, name), value.X, value.Y, value.Z);
}
public void SetVector(string name, Vector3D<float> value)
{
_glContext.Uniform3(_glContext.GetUniformLocation(_shaderProgramId, name), value.X, value.Y, value.Z);

35
Nebulix/Vector.cs Normal file
View File

@ -0,0 +1,35 @@
using System.Numerics;
namespace Nebulix;
public static class VectorExtensions
{
public static Vector3 Up(this Vector3 _) => Vector3.UnitY;
public static Vector3 Down(this Vector3 _) => -Vector3.UnitY;
public static Vector3 Left(this Vector3 _) => Vector3.UnitX;
public static Vector3 Right(this Vector3 _) => -Vector3.UnitX;
public static Vector3 Front(this Vector3 _) => -Vector3.UnitZ;
public static Vector3 Back(this Vector3 _) => -Vector3.UnitZ;
// Thanks to: https://stackoverflow.com/a/67920029
public static Vector3 Slerp(this Vector3 start, Vector3 end, float percent)
{
// the cosine of the angle between 2 vectors.
float dot = Vector3.Dot(start, end);
// Clamp it to be in the range of Acos()
// This may be unnecessary, but floating point precision can be a fickle mistress.
Math.Clamp(dot, -1.0f, 1.0f);
// Acos(dot) returns the angle between start and end,
// And multiplying that by percent returns the angle between start and the final result.
float theta = (float)Math.Acos(dot) * percent;
Vector3 relativeVec = end - start * dot;
relativeVec = Vector3.Normalize(relativeVec);
// Orthonormal basis
// The final result.
return ((start * (float)Math.Cos(theta)) + (relativeVec * (float)Math.Sin(theta)));
}
}