mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Collider rendering
This commit is contained in:
@@ -231,7 +231,7 @@ namespace GlitchyEditor
|
||||
return Math.Clamp(1.5f - Vector3.Distance(_editor.CurrentCamera.Position, pos) / 50, 0, 1);
|
||||
}
|
||||
|
||||
for (var (entity, transform, camera) in _activeScene.[Friend]_ecsWorld.Enumerate<TransformComponent, CameraComponent>())
|
||||
for (var (entity, transform, camera) in _activeScene.GetEntities<TransformComponent, CameraComponent>())
|
||||
{
|
||||
if (_editor.EntityHierarchyWindow.SelectedEntities.Contains(.(entity, _activeScene)))
|
||||
{
|
||||
@@ -245,7 +245,7 @@ namespace GlitchyEditor
|
||||
//Renderer2D.DrawQuad(world, _iconCamera, .White, .(0, 0, 1, 1), entity.Index);
|
||||
}
|
||||
|
||||
for (var (entity, transform, light) in _activeScene.[Friend]_ecsWorld.Enumerate<TransformComponent, LightComponent>())
|
||||
for (var (entity, transform, light) in _activeScene.GetEntities<TransformComponent, LightComponent>())
|
||||
{
|
||||
if (_editor.EntityHierarchyWindow.SelectedEntities.Contains(.(entity, _activeScene)))
|
||||
{
|
||||
@@ -263,7 +263,16 @@ namespace GlitchyEditor
|
||||
|
||||
float alpha = CalculateAlpha(transform.WorldTransform.Translation);
|
||||
Renderer2D.DrawQuad(world, _editorIcons.DirectionalLight, ColorRGBA(light.SceneLight.Color.R * alpha, light.SceneLight.Color.G * alpha, light.SceneLight.Color.B * alpha, alpha), .(0, 0, 1, 1), entity.Index);
|
||||
//Renderer2D.DrawQuad(world, _iconDirectionalLight, ColorRGBA(light.SceneLight.Color, alpha), .(0, 0, 1, 1), entity.Index);
|
||||
}
|
||||
|
||||
for (var (entity, transform, collider) in _activeScene.GetEntities<TransformComponent, BoxCollider2DComponent>())
|
||||
{
|
||||
Renderer2D.DrawRect(transform.WorldTransform * Matrix.Translation(collider.Offset.X, collider.Offset.Y, 0) * Matrix.Scaling(collider.Size.X * 2, collider.Size.Y * 2, 0));
|
||||
}
|
||||
|
||||
for (var (entity, transform, collider) in _activeScene.GetEntities<TransformComponent, CircleCollider2DComponent>())
|
||||
{
|
||||
Renderer2D.DrawCircle(transform.WorldTransform * Matrix.Translation(collider.Offset.X, collider.Offset.Y, 0) * Matrix.Scaling(collider.Radius * 2), (Texture2D)null, ColorRGBA(0f, 1f, 0f), 0.01f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,5 +4,4 @@ namespace GlitchyEngine.Math
|
||||
{
|
||||
typealias Matrix3x3 = DirectX.Math.Matrix3x3;
|
||||
typealias Matrix4x3 = DirectX.Math.Matrix4x3;
|
||||
typealias Matrix = DirectX.Math.Matrix;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,877 @@
|
||||
using System;
|
||||
|
||||
namespace GlitchyEngine.Math;
|
||||
|
||||
/**
|
||||
* Represents a 4 by 4 column-major matrix.
|
||||
*/
|
||||
[Union]
|
||||
public struct Matrix
|
||||
{
|
||||
public struct Values
|
||||
{
|
||||
public float _11, _21, _31, _41,
|
||||
_12, _22, _32, _42,
|
||||
_13, _23, _33, _43,
|
||||
_14, _24, _34, _44;
|
||||
}
|
||||
|
||||
public const Matrix Zero = .();
|
||||
public const Matrix Identity = .(.UnitX, .UnitY, .UnitZ, .UnitW);
|
||||
|
||||
public using Values V;
|
||||
public float[4][4] Values;
|
||||
public Vector4[4] Columns;
|
||||
|
||||
/// Creates a new zero-matrix.
|
||||
public this() => this = default;
|
||||
|
||||
/**
|
||||
* Initializes a new Matrix.
|
||||
* @param value The value that will be assigned to all components.
|
||||
*/
|
||||
/// Creates a new matrix.
|
||||
public this(float value)
|
||||
{
|
||||
this = ?;
|
||||
_11 = _12 = _13 = _14 =
|
||||
_21 = _22 = _23 = _24 =
|
||||
_31 = _32 = _33 = _34 =
|
||||
_41 = _42 = _43 = _44 = value;
|
||||
}
|
||||
|
||||
/// Creates a new matrix and initializes it with the given entries.
|
||||
public this(float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, float m31, float m32, float m33)
|
||||
{
|
||||
Values[0][0] = m00; Values[0][1] = m10; Values[0][2] = m20; Values[0][3] = m30;
|
||||
Values[1][0] = m01; Values[1][1] = m11; Values[1][2] = m21; Values[1][3] = m31;
|
||||
Values[2][0] = m02; Values[2][1] = m12; Values[2][2] = m22; Values[2][3] = m32;
|
||||
Values[3][0] = m03; Values[3][1] = m13; Values[3][2] = m23; Values[3][3] = m33;
|
||||
}
|
||||
|
||||
/// Creates a new matrix and initializes it with the given column-vectors.
|
||||
public this(Vector4 c0, Vector4 c1, Vector4 c2, Vector4 c3)
|
||||
{
|
||||
Columns[0] = c0;
|
||||
Columns[1] = c1;
|
||||
Columns[2] = c2;
|
||||
Columns[3] = c3;
|
||||
}
|
||||
|
||||
public ref Vector3 Right
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
#unwarn
|
||||
return ref *(Vector3*)&Columns[0];
|
||||
}
|
||||
}
|
||||
|
||||
public ref Vector3 Up
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
#unwarn
|
||||
return ref *(Vector3*)&Columns[1];
|
||||
}
|
||||
}
|
||||
|
||||
public ref Vector3 Forward
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
#unwarn
|
||||
return ref *(Vector3*)&Columns[2];
|
||||
}
|
||||
}
|
||||
|
||||
public ref Vector3 Translation
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
#unwarn
|
||||
return ref *(Vector3*)&Columns[3];
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 Scale
|
||||
{
|
||||
[Inline]
|
||||
get => .(_11, _22, _33);
|
||||
|
||||
[Inline]
|
||||
set mut
|
||||
{
|
||||
_11 = value.X;
|
||||
_22 = value.Y;
|
||||
_33 = value.Z;
|
||||
}
|
||||
}
|
||||
|
||||
public ref float this[int row, int column]
|
||||
{
|
||||
get
|
||||
{
|
||||
#unwarn
|
||||
return ref *(float*)&Values[column][row];
|
||||
}
|
||||
|
||||
[Checked]
|
||||
get
|
||||
{
|
||||
if(column < 0 || column > 3 || row < 0 || row > 3)
|
||||
Internal.ThrowIndexOutOfRange();
|
||||
|
||||
#unwarn
|
||||
return ref *(float*)&Values[column][row];
|
||||
}
|
||||
}
|
||||
|
||||
public ref Vector4 this[int column]
|
||||
{
|
||||
get
|
||||
{
|
||||
#unwarn
|
||||
return ref *(Vector4*)&Columns[column];
|
||||
}
|
||||
|
||||
|
||||
[Checked]
|
||||
get
|
||||
{
|
||||
if(column < 0 || column > 3)
|
||||
Internal.ThrowIndexOutOfRange();
|
||||
|
||||
#unwarn
|
||||
return ref *(Vector4*)&Columns[column];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Assignment Operators
|
||||
//
|
||||
|
||||
// Addition
|
||||
|
||||
public void operator +=(Matrix value) mut
|
||||
{
|
||||
Columns[0] += value.Columns[0];
|
||||
Columns[1] += value.Columns[1];
|
||||
Columns[2] += value.Columns[2];
|
||||
Columns[3] += value.Columns[3];
|
||||
}
|
||||
|
||||
// Matrix + Scalar : Matrix + Scalar * Identity
|
||||
public void operator +=(float scalar) mut
|
||||
{
|
||||
_11 += scalar;
|
||||
_22 += scalar;
|
||||
_33 += scalar;
|
||||
_44 += scalar;
|
||||
}
|
||||
|
||||
// Subtraction
|
||||
|
||||
public void operator -=(Matrix value) mut
|
||||
{
|
||||
Columns[0] -= value.Columns[0];
|
||||
Columns[1] -= value.Columns[1];
|
||||
Columns[2] -= value.Columns[2];
|
||||
Columns[3] -= value.Columns[3];
|
||||
}
|
||||
|
||||
// Matrix - Scalar : Matrix - Scalar * Identity
|
||||
public void operator -=(float scalar) mut
|
||||
{
|
||||
_11 -= scalar;
|
||||
_22 -= scalar;
|
||||
_33 -= scalar;
|
||||
_44 -= scalar;
|
||||
}
|
||||
|
||||
// Multiplication
|
||||
|
||||
public void operator *=(float scalar) mut
|
||||
{
|
||||
Columns[0] *= scalar;
|
||||
Columns[1] *= scalar;
|
||||
Columns[2] *= scalar;
|
||||
Columns[3] *= scalar;
|
||||
}
|
||||
|
||||
public void operator *=(Matrix value) mut
|
||||
{
|
||||
this = this * value;
|
||||
}
|
||||
|
||||
// Divide
|
||||
|
||||
public void operator /=(float scalar) mut
|
||||
{
|
||||
float inv = 1.0f / scalar;
|
||||
Columns[0] *= inv;
|
||||
Columns[1] *= inv;
|
||||
Columns[2] *= inv;
|
||||
Columns[3] *= inv;
|
||||
}
|
||||
|
||||
//
|
||||
// Operators
|
||||
//
|
||||
|
||||
// Addition
|
||||
|
||||
public static Matrix operator +(Matrix left, Matrix right)
|
||||
{
|
||||
return .(left.Columns[0] + right.Columns[0],
|
||||
left.Columns[1] + right.Columns[1],
|
||||
left.Columns[2] + right.Columns[2],
|
||||
left.Columns[3] + right.Columns[3]);
|
||||
}
|
||||
|
||||
public static Matrix operator +(Matrix left, float right)
|
||||
{
|
||||
Matrix result = left;
|
||||
result._11 += right;
|
||||
result._22 += right;
|
||||
result._33 += right;
|
||||
result._44 += right;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix operator +(float left, Matrix right)
|
||||
{
|
||||
Matrix result = right;
|
||||
result._11 += left;
|
||||
result._22 += left;
|
||||
result._33 += left;
|
||||
result._44 += left;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Subtraction
|
||||
|
||||
public static Matrix operator -(Matrix left, Matrix right)
|
||||
{
|
||||
return .(left.Columns[0] - right.Columns[0],
|
||||
left.Columns[1] - right.Columns[1],
|
||||
left.Columns[2] - right.Columns[2],
|
||||
left.Columns[3] - right.Columns[3]);
|
||||
}
|
||||
|
||||
public static Matrix operator -(Matrix value, float scalar)
|
||||
{
|
||||
Matrix result = value;
|
||||
result._11 -= scalar;
|
||||
result._22 -= scalar;
|
||||
result._33 -= scalar;
|
||||
result._44 -= scalar;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix operator -(float scalar, Matrix value)
|
||||
{
|
||||
Matrix result = value;
|
||||
result._11 -= scalar;
|
||||
result._22 -= scalar;
|
||||
result._33 -= scalar;
|
||||
result._44 -= scalar;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix operator -(Matrix value)
|
||||
{
|
||||
return .(-value.Columns[0],
|
||||
-value.Columns[1],
|
||||
-value.Columns[2],
|
||||
-value.Columns[3]);
|
||||
}
|
||||
|
||||
// Multiplication
|
||||
|
||||
public static Matrix operator *(Matrix left, Matrix right)
|
||||
{
|
||||
#unwarn
|
||||
var l = &left.V;
|
||||
#unwarn
|
||||
var r = &right.V;
|
||||
|
||||
Matrix result = ?;
|
||||
|
||||
result._11 = (l._11 * r._11) + (l._12 * r._21) + (l._13 * r._31) + (l._14 * r._41);
|
||||
result._12 = (l._11 * r._12) + (l._12 * r._22) + (l._13 * r._32) + (l._14 * r._42);
|
||||
result._13 = (l._11 * r._13) + (l._12 * r._23) + (l._13 * r._33) + (l._14 * r._43);
|
||||
result._14 = (l._11 * r._14) + (l._12 * r._24) + (l._13 * r._34) + (l._14 * r._44);
|
||||
|
||||
result._21 = (l._21 * r._11) + (l._22 * r._21) + (l._23 * r._31) + (l._24 * r._41);
|
||||
result._22 = (l._21 * r._12) + (l._22 * r._22) + (l._23 * r._32) + (l._24 * r._42);
|
||||
result._23 = (l._21 * r._13) + (l._22 * r._23) + (l._23 * r._33) + (l._24 * r._43);
|
||||
result._24 = (l._21 * r._14) + (l._22 * r._24) + (l._23 * r._34) + (l._24 * r._44);
|
||||
|
||||
result._31 = (l._31 * r._11) + (l._32 * r._21) + (l._33 * r._31) + (l._34 * r._41);
|
||||
result._32 = (l._31 * r._12) + (l._32 * r._22) + (l._33 * r._32) + (l._34 * r._42);
|
||||
result._33 = (l._31 * r._13) + (l._32 * r._23) + (l._33 * r._33) + (l._34 * r._43);
|
||||
result._34 = (l._31 * r._14) + (l._32 * r._24) + (l._33 * r._34) + (l._34 * r._44);
|
||||
|
||||
result._41 = (l._41 * r._11) + (l._42 * r._21) + (l._43 * r._31) + (l._44 * r._41);
|
||||
result._42 = (l._41 * r._12) + (l._42 * r._22) + (l._43 * r._32) + (l._44 * r._42);
|
||||
result._43 = (l._41 * r._13) + (l._42 * r._23) + (l._43 * r._33) + (l._44 * r._43);
|
||||
result._44 = (l._41 * r._14) + (l._42 * r._24) + (l._43 * r._34) + (l._44 * r._44);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix operator *(Matrix value, float scalar)
|
||||
{
|
||||
return .(value.Columns[0] * scalar,
|
||||
value.Columns[1] * scalar,
|
||||
value.Columns[2] * scalar,
|
||||
value.Columns[3] * scalar);
|
||||
}
|
||||
|
||||
public static Matrix operator *(float scalar, Matrix value)
|
||||
{
|
||||
return .(value.Columns[0] * scalar,
|
||||
value.Columns[1] * scalar,
|
||||
value.Columns[2] * scalar,
|
||||
value.Columns[3] * scalar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies a matrix and a column-vector resulting in a column vector.
|
||||
*/
|
||||
public static Vector4 operator *(Matrix matrix, Vector4 columnVector)
|
||||
{
|
||||
#unwarn
|
||||
var m = &matrix.V;
|
||||
|
||||
Vector4 result = ?;
|
||||
result.X = (m._11 * columnVector.X) + (m._12 * columnVector.Y) + (m._13 * columnVector.Z) + (m._14 * columnVector.W);
|
||||
result.Y = (m._21 * columnVector.X) + (m._22 * columnVector.Y) + (m._23 * columnVector.Z) + (m._24 * columnVector.W);
|
||||
result.Z = (m._31 * columnVector.X) + (m._32 * columnVector.Y) + (m._33 * columnVector.Z) + (m._34 * columnVector.W);
|
||||
result.W = (m._41 * columnVector.X) + (m._42 * columnVector.Y) + (m._43 * columnVector.Z) + (m._44 * columnVector.W);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies a row-vector and a matrix resulting in a row vector.
|
||||
*/
|
||||
public static Vector4 operator *(Vector4 rowVector, Matrix matrix)
|
||||
{
|
||||
#unwarn
|
||||
var m = &matrix.V;
|
||||
|
||||
Vector4 result = ?;
|
||||
result.X = (rowVector.X * m._11) + (rowVector.Y * m._21) + (rowVector.Z * m._31) + (rowVector.W * m._41);
|
||||
result.Y = (rowVector.X * m._12) + (rowVector.Y * m._22) + (rowVector.Z * m._32) + (rowVector.W * m._42);
|
||||
result.Z = (rowVector.X * m._13) + (rowVector.Y * m._23) + (rowVector.Z * m._33) + (rowVector.W * m._43);
|
||||
result.W = (rowVector.X * m._14) + (rowVector.Y * m._24) + (rowVector.Z * m._34) + (rowVector.W * m._44);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Divison
|
||||
|
||||
public static Matrix operator /(Matrix m, float s)
|
||||
{
|
||||
float f = 1 / s;
|
||||
Matrix M = m;
|
||||
|
||||
return .(M.Columns[0] * f, M.Columns[1] * f, M.Columns[2] * f, M.Columns[3] * f);
|
||||
}
|
||||
|
||||
public static Matrix Scaling(float scale)
|
||||
{
|
||||
return .(scale, 0, 0, 0,
|
||||
0, scale, 0, 0,
|
||||
0, 0, scale, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
public static Matrix Scaling(float scaleX, float scaleY, float scaleZ)
|
||||
{
|
||||
return .(scaleX, 0, 0, 0,
|
||||
0, scaleY, 0, 0,
|
||||
0, 0, scaleZ, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
public static Matrix Scaling(Vector3 scale)
|
||||
{
|
||||
return .(scale.X, 0, 0, 0,
|
||||
0, scale.Y, 0, 0,
|
||||
0, 0, scale.Z, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
public static Matrix Translation(float x, float y, float z)
|
||||
{
|
||||
return .(1, 0, 0, x,
|
||||
0, 1, 0, y,
|
||||
0, 0, 1, z,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
public static Matrix Translation(Vector3 translation)
|
||||
{
|
||||
return .(1, 0, 0, translation.X,
|
||||
0, 1, 0, translation.Y,
|
||||
0, 0, 1, translation.Z,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
public static Matrix RotationX(float rot)
|
||||
{
|
||||
float sin = Math.Sin(rot);
|
||||
float cos = Math.Cos(rot);
|
||||
|
||||
return .(1, 0, 0, 0,
|
||||
0, cos, -sin, 0,
|
||||
0, sin, cos, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
public static Matrix RotationY(float rot)
|
||||
{
|
||||
float sin = Math.Sin(rot);
|
||||
float cos = Math.Cos(rot);
|
||||
|
||||
return .(cos, 0, sin, 0,
|
||||
0, 1, 0, 0,
|
||||
-sin, 0, cos, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
public static Matrix RotationZ(float rot)
|
||||
{
|
||||
float sin = Math.Sin(rot);
|
||||
float cos = Math.Cos(rot);
|
||||
|
||||
return .(cos, -sin, 0, 0,
|
||||
sin, cos, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a view Matrix that is located at specified postion and looks at the given target.
|
||||
* @param position The cameras position.
|
||||
* @param target The point the camera looks at.
|
||||
* @param up A vector defining the up direction of the camera.
|
||||
* @returns a view matrix.
|
||||
*/
|
||||
public static Matrix LookAt(Vector3 position, Vector3 target, Vector3 up)
|
||||
{
|
||||
Vector3 forward = target - position;
|
||||
forward.Normalize();
|
||||
|
||||
Vector3 right = Vector3.Cross(up, forward);
|
||||
right.Normalize();
|
||||
|
||||
Vector3 newUp = Vector3.Cross(forward, right);
|
||||
newUp.Normalize();
|
||||
|
||||
Matrix result = .Identity;
|
||||
|
||||
result.Forward = forward;
|
||||
result.Up = up;
|
||||
result.Right = right;
|
||||
result.Translation.X = -Vector3.Dot(position, right);
|
||||
result.Translation.Y = -Vector3.Dot(position, up);
|
||||
result.Translation.Z = -Vector3.Dot(position, forward);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Returns the transpose of this matrix
|
||||
[DisableChecks]
|
||||
public Matrix Transpose()
|
||||
{
|
||||
return .(_11, _21, _31, _41,
|
||||
_12, _22, _32, _42,
|
||||
_13, _23, _33, _43,
|
||||
_14, _24, _34, _44);
|
||||
}
|
||||
|
||||
/**
|
||||
Calculates the inverse of the matrix.
|
||||
*/
|
||||
[DisableChecks]
|
||||
public float Determinant() mut
|
||||
{
|
||||
// From: Lengyel, Eric. Foundations of Game Engine Development, Volume 1: Mathematics (S.61). Kindle-Version.
|
||||
|
||||
Vector3 a = *(Vector3*)&Columns[0];
|
||||
Vector3 b = *(Vector3*)&Columns[1];
|
||||
Vector3 c = *(Vector3*)&Columns[2];
|
||||
Vector3 d = *(Vector3*)&Columns[3];
|
||||
|
||||
float x = this[3, 0];
|
||||
float y = this[3, 1];
|
||||
float z = this[3, 2];
|
||||
float w = this[3, 3];
|
||||
|
||||
Vector3 s = Vector3.Cross(a, b);
|
||||
Vector3 t = Vector3.Cross(c, d);
|
||||
Vector3 u = y * a - x * b;
|
||||
Vector3 v = w * c - z * d;
|
||||
|
||||
return Vector3.Dot(s, v) + Vector3.Dot(t, u);
|
||||
}
|
||||
|
||||
/**
|
||||
Calculates the inverse of the matrix.
|
||||
*/
|
||||
public Matrix Invert()
|
||||
{
|
||||
// From: Lengyel, Eric. Foundations of Game Engine Development, Volume 1: Mathematics (S.61). Kindle-Version.
|
||||
|
||||
#unwarn
|
||||
Vector3 a = *(Vector3*)&Columns[0];
|
||||
#unwarn
|
||||
Vector3 b = *(Vector3*)&Columns[1];
|
||||
#unwarn
|
||||
Vector3 c = *(Vector3*)&Columns[2];
|
||||
#unwarn
|
||||
Vector3 d = *(Vector3*)&Columns[3];
|
||||
|
||||
float x = this[3, 0];
|
||||
float y = this[3, 1];
|
||||
float z = this[3, 2];
|
||||
float w = this[3, 3];
|
||||
|
||||
Vector3 s = Vector3.Cross(a, b);
|
||||
Vector3 t = Vector3.Cross(c, d);
|
||||
Vector3 u = y * a - x * b;
|
||||
Vector3 v = w * c - z * d;
|
||||
|
||||
float invDet = 1.0f / (Vector3.Dot(s, v) + Vector3.Dot(t, u));
|
||||
|
||||
s *= invDet;
|
||||
t *= invDet;
|
||||
u *= invDet;
|
||||
v *= invDet;
|
||||
|
||||
Vector3 r0 = Vector3.Cross(b, v) + t * y;
|
||||
Vector3 r1 = Vector3.Cross(v, a) - t * x;
|
||||
Vector3 r2 = Vector3.Cross(d, u) + s * w;
|
||||
Vector3 r3 = Vector3.Cross(u, c) - s * z;
|
||||
return .(r0.X, r0.Y, r0.Z, -Vector3.Dot(b, t),
|
||||
r1.X, r1.Y, r1.Z, Vector3.Dot(a, t),
|
||||
r2.X, r2.Y, r2.Z, -Vector3.Dot(d, s),
|
||||
r3.X, r3.Y, r3.Z, Vector3.Dot(c, s));
|
||||
}
|
||||
|
||||
/// Calculates the inverse of the matrix.
|
||||
public static Matrix Invert(in Matrix matrix)
|
||||
{
|
||||
// From: Lengyel, Eric. Foundations of Game Engine Development, Volume 1: Mathematics (S.61). Kindle-Version.
|
||||
|
||||
#unwarn
|
||||
Vector3 a = *(Vector3*)&matrix.Columns[0];
|
||||
#unwarn
|
||||
Vector3 b = *(Vector3*)&matrix.Columns[1];
|
||||
#unwarn
|
||||
Vector3 c = *(Vector3*)&matrix.Columns[2];
|
||||
#unwarn
|
||||
Vector3 d = *(Vector3*)&matrix.Columns[3];
|
||||
|
||||
float x = matrix[3, 0];
|
||||
float y = matrix[3, 1];
|
||||
float z = matrix[3, 2];
|
||||
float w = matrix[3, 3];
|
||||
|
||||
Vector3 s = Vector3.Cross(a, b);
|
||||
Vector3 t = Vector3.Cross(c, d);
|
||||
Vector3 u = y * a - x * b;
|
||||
Vector3 v = w * c - z * d;
|
||||
|
||||
float invDet = 1.0f / (Vector3.Dot(s, v) + Vector3.Dot(t, u));
|
||||
|
||||
s *= invDet;
|
||||
t *= invDet;
|
||||
u *= invDet;
|
||||
v *= invDet;
|
||||
|
||||
Vector3 r0 = Vector3.Cross(b, v) + t * y;
|
||||
Vector3 r1 = Vector3.Cross(v, a) - t * x;
|
||||
Vector3 r2 = Vector3.Cross(d, u) + s * w;
|
||||
Vector3 r3 = Vector3.Cross(u, c) - s * z;
|
||||
return .(r0.X, r0.Y, r0.Z, -Vector3.Dot(b, t),
|
||||
r1.X, r1.Y, r1.Z, Vector3.Dot(a, t),
|
||||
r2.X, r2.Y, r2.Z, -Vector3.Dot(d, s),
|
||||
r3.X, r3.Y, r3.Z, Vector3.Dot(c, s));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a perspective projection matrix.
|
||||
* @param fovY The vertical field of view.
|
||||
* @param aspectRation The aspect ratio of the viewport.
|
||||
* @param nearPlane The distance to the near plane.
|
||||
* @param farPlane The distance to the far plane.
|
||||
*/
|
||||
public static Matrix PerspectiveProjection(float fovY, float aspectRatio, float nearPlane, float farPlane)
|
||||
{
|
||||
// Lengyel, Eric. Foundations of Game Engine Development, Volume 2: Rendering (Seite82). . Kindle-Version.
|
||||
|
||||
float g = 1.0f / Math.Tan(fovY * 0.5f);
|
||||
float k = farPlane / (farPlane - nearPlane);
|
||||
|
||||
return .(g / aspectRatio, 0, 0, 0,
|
||||
0, g, 0, 0,
|
||||
0, 0, k, -nearPlane * k,
|
||||
0, 0, 1, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a perspective projection matrix with reversed near- and far plane.
|
||||
* (i.e. Points on near plane have z-value of 1 and points of far plane have z-value of 0)
|
||||
* @param fovY The vertical field of view.
|
||||
* @param aspectRation The aspect ratio of the viewport.
|
||||
* @param nearPlane The distance to the near plane.
|
||||
* @param farPlane The distance to the far plane.
|
||||
*/
|
||||
public static Matrix ReversedPerspectiveProjection(float fovY, float aspectRatio, float nearPlane, float farPlane)
|
||||
{
|
||||
// Lengyel, Eric. Foundations of Game Engine Development, Volume 2: Rendering (Seite86). . Kindle-Version.
|
||||
|
||||
float g = 1.0f / Math.Tan(fovY * 0.5f);
|
||||
float k = nearPlane / (nearPlane - farPlane);
|
||||
|
||||
return .(g / aspectRatio, 0, 0, 0,
|
||||
0, g, 0, 0,
|
||||
0, 0, k, -farPlane * k,
|
||||
0, 0, 1, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a perspective projection matrix with a far plane at infinity.
|
||||
* @param fovY The vertical field of view.
|
||||
* @param aspectRation The aspect ratio of the viewport.
|
||||
* @param nearPlane The distance to the near plane.
|
||||
* @param ε An offset to account for floating point round-off errors at infinity.
|
||||
* Note: Use a tiny value significant compared to the floating-point value of one.
|
||||
*/
|
||||
public static Matrix InfinitePerspectiveProjection(float fovY, float aspectRatio, float nearPlane, float ε = 1e-6f)
|
||||
{
|
||||
// Lengyel, Eric. Foundations of Game Engine Development, Volume 2: Rendering (Seite83). . Kindle-Version.
|
||||
|
||||
float g = 1.0f / Math.Tan(fovY * 0.5f);
|
||||
|
||||
float f = 1 - ε;
|
||||
|
||||
return .(g / aspectRatio, 0, 0, 0,
|
||||
0, g, 0, 0,
|
||||
0, 0, f, -nearPlane * f,
|
||||
0, 0, 1, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a perspective projection matrix with a far plane at infinity with reversed near- and far plane.
|
||||
* (i.e. Points on near plane have z-value of 1 and points of far plane have z-value of 0)
|
||||
* @param fovY The vertical field of view.
|
||||
* @param aspectRation The aspect ratio of the viewport.
|
||||
* @param nearPlane The distance to the near plane.
|
||||
* @param ε An offset to account for floating point round-off errors at infinity.
|
||||
* Note: Use a tiny value significant compared to the floating-point value of one.
|
||||
*/
|
||||
public static Matrix ReversedInfinitePerspectiveProjection(float fovY, float aspectRatio, float nearPlane, float ε = 1e-6f)
|
||||
{
|
||||
// Lengyel, Eric. Foundations of Game Engine Development, Volume 2: Rendering (Seite88). . Kindle-Version.
|
||||
|
||||
float g = 1.0f / Math.Tan(fovY * 0.5f);
|
||||
|
||||
return .(g / aspectRatio, 0, 0, 0,
|
||||
0, g, 0, 0,
|
||||
0, 0, ε, nearPlane * (1 - ε),
|
||||
0, 0, 1, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an orthographic projection matrix with the camera centered at the near-plane.
|
||||
* @param width The width of the view volume.
|
||||
* @param height The height of the view volume.
|
||||
* @param depth The depth of the view volume.
|
||||
*/
|
||||
public static Matrix OrthographicProjection(float width, float height, float depth)
|
||||
{
|
||||
// Lengyel, Eric. Foundations of Game Engine Development, Volume 2: Rendering (Seite91). . Kindle-Version.
|
||||
return .(2.0f / width, 0, 0, 0,
|
||||
0, 2.0f/height, 0, 0,
|
||||
0, 0, 1.0f / depth, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an orthographic projection matrix.
|
||||
* @param left The left side of the view volume.
|
||||
* @param right The right side of the view volume.
|
||||
* @param top The top side of the view volume.
|
||||
* @param bottom The bottom side of the view volume.
|
||||
* @param near The near plane of the view volume.
|
||||
* @param far The far plane of the view volume.
|
||||
*/
|
||||
public static Matrix OrthographicProjectionOffCenter(float left, float right, float top, float bottom, float near, float far)
|
||||
{
|
||||
// Lengyel, Eric. Foundations of Game Engine Development, Volume 2: Rendering (Seite91). . Kindle-Version.
|
||||
|
||||
float w_inv = 1.0f / (right - left);
|
||||
float h_inv = 1.0f / (top - bottom);
|
||||
float d_inv = 1.0f / (far - near);
|
||||
|
||||
return .(2.0f * w_inv, 0.0f, 0.0f, -(right + left) * w_inv,
|
||||
0.0f, 2.0f * h_inv, 0.0f, -(bottom + top) * h_inv,
|
||||
0.0f, 0.0f, d_inv, -near * d_inv,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
public static bool operator ==(Matrix left, Matrix right)
|
||||
{
|
||||
return Matrix.Equals(left, right);
|
||||
}
|
||||
|
||||
public static bool operator !=(Matrix left, Matrix right)
|
||||
{
|
||||
return !Matrix.Equals(left, right);
|
||||
}
|
||||
|
||||
public static bool Equals(Matrix left, Matrix right)
|
||||
{
|
||||
return left.Values == right.Values;
|
||||
}
|
||||
|
||||
public static explicit operator Matrix3x3(Matrix value)
|
||||
{
|
||||
return .(value.Right, value.Up, value.Forward);
|
||||
}
|
||||
|
||||
public static void Exponent(ref Matrix matrix, int exponent, out Matrix result)
|
||||
{
|
||||
if(exponent == 0)
|
||||
result = .Identity;
|
||||
else if(exponent == 1)
|
||||
result = matrix;
|
||||
else if(exponent > 1)
|
||||
{
|
||||
result = .Identity;
|
||||
Matrix b = matrix;
|
||||
|
||||
var exponent;
|
||||
|
||||
for(;exponent > 0;)
|
||||
{
|
||||
if(exponent & 1 > 0)
|
||||
result *= b;
|
||||
|
||||
exponent >>= 1;
|
||||
|
||||
if(exponent > 0)
|
||||
b *= b;
|
||||
}
|
||||
|
||||
}
|
||||
else // Exponent < 0
|
||||
{
|
||||
Matrix m = matrix.Invert();
|
||||
Exponent(ref m, -exponent, out result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Orthogonalizes the matrix.
|
||||
*/
|
||||
public void Orthogonalize() mut
|
||||
{
|
||||
Columns[1] -= .Project(Columns[1], Columns[0]);
|
||||
Columns[2] -= .Project(Columns[2], Columns[0]) + .Project(Columns[2], Columns[1]);
|
||||
Columns[3] -= .Project(Columns[3], Columns[0]) + .Project(Columns[3], Columns[1]) + .Project(Columns[3], Columns[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Orthonormalizes the matrix.
|
||||
*/
|
||||
public void Orthonormalize() mut
|
||||
{
|
||||
Columns[0].Normalize();
|
||||
Columns[1] = .Normalize(.Reject(Columns[1], Columns[0]));
|
||||
Columns[2] = .Normalize(.Reject(.Reject(Columns[2], Columns[0]), Columns[1]));
|
||||
Columns[3] = .Normalize(.Reject(.Reject(.Reject(Columns[2], Columns[0]), Columns[1]), Columns[2]));
|
||||
}
|
||||
public static Self RotationQuaternion(Quaternion rotation)
|
||||
{
|
||||
float xSq = 2 * rotation.X * rotation.X;
|
||||
float ySq = 2 * rotation.Y * rotation.Y;
|
||||
float zSq = 2 * rotation.Z * rotation.Z;
|
||||
|
||||
float xy = 2 * rotation.X * rotation.Y;
|
||||
float xz = 2 * rotation.X * rotation.Z;
|
||||
float xw = 2 * rotation.X * rotation.W;
|
||||
float yz = 2 * rotation.Y * rotation.Z;
|
||||
float yw = 2 * rotation.Y * rotation.W;
|
||||
float zw = 2 * rotation.Z * rotation.W;
|
||||
|
||||
Self result = ?;
|
||||
|
||||
result._11 = 1 - ySq - zSq;
|
||||
result._21 = xy + zw;
|
||||
result._31 = xz - yw;
|
||||
result._41 = 0;
|
||||
|
||||
result._12 = xy - zw;
|
||||
result._22 = 1 - xSq - zSq;
|
||||
result._32 = yz + xw;
|
||||
result._42 = 0;
|
||||
|
||||
result._13 = xz + yw;
|
||||
result._23 = yz - xw;
|
||||
result._33 = 1 - xSq - ySq;
|
||||
result._43 = 0;
|
||||
|
||||
result._14 = 0;
|
||||
result._24 = 0;
|
||||
result._34 = 0;
|
||||
result._44 = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void Decompose(Self matrix, out Vector3 position, out Quaternion rotation, out Vector3 scale)
|
||||
{
|
||||
var matrix;
|
||||
|
||||
// Translation -> get last column
|
||||
position = matrix.Translation;
|
||||
// Zero translation for next step
|
||||
matrix.Translation = .Zero;
|
||||
|
||||
// TODO: this doesn't detect mirroring
|
||||
|
||||
// Extract scaling from matrix
|
||||
scale.X = (*(Vector3*)&matrix.Columns[0]).Magnitude();
|
||||
scale.Y = (*(Vector3*)&matrix.Columns[1]).Magnitude();
|
||||
scale.Z = (*(Vector3*)&matrix.Columns[2]).Magnitude();
|
||||
|
||||
if(MathHelper.IsZero(scale.X) || MathHelper.IsZero(scale.Y) || MathHelper.IsZero(scale.Z))
|
||||
{
|
||||
rotation = .Identity;
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove scale from matrix (normalize the columns)
|
||||
matrix.Columns[0] /= scale.X;
|
||||
matrix.Columns[1] /= scale.Y;
|
||||
matrix.Columns[2] /= scale.Z;
|
||||
|
||||
rotation = Quaternion.FromMatrix(matrix);
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
using System;
|
||||
using GlitchyEngine.Math;
|
||||
using GlitchyEngine;
|
||||
|
||||
namespace DirectX.Math
|
||||
{
|
||||
extension Matrix
|
||||
{
|
||||
typealias Vec3 = GlitchyEngine.Math.Vector3;
|
||||
|
||||
public static Self RotationQuaternion(Quaternion rotation)
|
||||
{
|
||||
float xSq = 2 * rotation.X * rotation.X;
|
||||
float ySq = 2 * rotation.Y * rotation.Y;
|
||||
float zSq = 2 * rotation.Z * rotation.Z;
|
||||
|
||||
float xy = 2 * rotation.X * rotation.Y;
|
||||
float xz = 2 * rotation.X * rotation.Z;
|
||||
float xw = 2 * rotation.X * rotation.W;
|
||||
float yz = 2 * rotation.Y * rotation.Z;
|
||||
float yw = 2 * rotation.Y * rotation.W;
|
||||
float zw = 2 * rotation.Z * rotation.W;
|
||||
|
||||
Self result = ?;
|
||||
|
||||
result.V._11 = 1 - ySq - zSq;
|
||||
result.V._21 = xy + zw;
|
||||
result.V._31 = xz - yw;
|
||||
result.V._41 = 0;
|
||||
|
||||
result.V._12 = xy - zw;
|
||||
result.V._22 = 1 - xSq - zSq;
|
||||
result.V._32 = yz + xw;
|
||||
result.V._42 = 0;
|
||||
|
||||
result.V._13 = xz + yw;
|
||||
result.V._23 = yz - xw;
|
||||
result.V._33 = 1 - xSq - ySq;
|
||||
result.V._43 = 0;
|
||||
|
||||
result.V._14 = 0;
|
||||
result.V._24 = 0;
|
||||
result.V._34 = 0;
|
||||
result.V._44 = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void Decompose(Self matrix, out Vec3 position, out Quaternion rotation, out Vec3 scale)
|
||||
{
|
||||
var matrix;
|
||||
|
||||
// Translation -> get last column
|
||||
position = matrix.Translation;
|
||||
// Zero translation for next step
|
||||
matrix.Translation = .Zero;
|
||||
|
||||
// TODO: this doesn't detect mirroring
|
||||
|
||||
// Extract scaling from matrix
|
||||
scale.X = (*(Vec3*)&matrix.Columns[0]).Magnitude();
|
||||
scale.Y = (*(Vec3*)&matrix.Columns[1]).Magnitude();
|
||||
scale.Z = (*(Vec3*)&matrix.Columns[2]).Magnitude();
|
||||
|
||||
if(MathHelper.IsZero(scale.X) || MathHelper.IsZero(scale.Y) || MathHelper.IsZero(scale.Z))
|
||||
{
|
||||
rotation = .Identity;
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove scale from matrix (normalize the columns)
|
||||
matrix.Columns[0] /= scale.X;
|
||||
matrix.Columns[1] /= scale.Y;
|
||||
matrix.Columns[2] /= scale.Z;
|
||||
|
||||
rotation = Quaternion.FromMatrix(matrix);
|
||||
}
|
||||
|
||||
/*[Test]
|
||||
static void TestQuaternionToMatrix()
|
||||
{
|
||||
// Rotation around Z-Axis by 90°
|
||||
Quaternion quat = .(0, 0, 0.707107f, 0.707107f);
|
||||
quat.Normalize();
|
||||
|
||||
|
||||
}*/
|
||||
}
|
||||
}
|
||||
@@ -144,7 +144,7 @@ namespace GlitchyEngine.Math
|
||||
{
|
||||
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
|
||||
|
||||
var m = matrix.V;
|
||||
var m = matrix;
|
||||
|
||||
Quaternion result = ?;
|
||||
|
||||
|
||||
@@ -111,15 +111,15 @@ namespace GlitchyEngine.Renderer
|
||||
|
||||
Vector4[8] corners;
|
||||
// Perspective
|
||||
if(projection.V._43 != 0.0f)
|
||||
if(projection._43 != 0.0f)
|
||||
{
|
||||
// near plane for perspective projection, far plane if reversed
|
||||
float d1 = -projection.V._34 / projection.V._33;
|
||||
float d1 = -projection._34 / projection._33;
|
||||
|
||||
float d2 = projection.V._34 / (1.0f - projection.V._33);
|
||||
float d2 = projection._34 / (1.0f - projection._33);
|
||||
|
||||
float gOverS = projection.V._11;
|
||||
float g = projection.V._22;
|
||||
float gOverS = projection._11;
|
||||
float g = projection._22;
|
||||
|
||||
//var corners = //(Vector4*)&_vbFrustum.Data;
|
||||
|
||||
@@ -158,14 +158,14 @@ namespace GlitchyEngine.Renderer
|
||||
}
|
||||
else
|
||||
{
|
||||
float l = -(projection.V._14 + 1.0f) / projection.V._11;
|
||||
float r = (1.0f - projection.V._14) / projection.V._11;
|
||||
float l = -(projection._14 + 1.0f) / projection._11;
|
||||
float r = (1.0f - projection._14) / projection._11;
|
||||
|
||||
float t = -(projection.V._24 + 1.0f) / projection.V._22;
|
||||
float b = (1.0f - projection.V._24) / projection.V._22;
|
||||
float t = -(projection._24 + 1.0f) / projection._22;
|
||||
float b = (1.0f - projection._24) / projection._22;
|
||||
|
||||
float n = -projection.V._34 / projection.V._33;
|
||||
float f = (1 - projection.V._34) / projection.V._33;
|
||||
float n = -projection._34 / projection._33;
|
||||
float f = (1 - projection._34) / projection._33;
|
||||
|
||||
//var corners = (Vector4*)&_vbFrustum.Data;
|
||||
corners[0] = .(r, t, n, 1.0f);
|
||||
|
||||
@@ -491,5 +491,25 @@ namespace GlitchyEngine.World
|
||||
handler(entity, componentType, component);
|
||||
}
|
||||
}
|
||||
|
||||
public WorldEnumerator<TComponent> GetEntities<TComponent>() where TComponent : struct
|
||||
{
|
||||
return _ecsWorld.Enumerate<TComponent>();
|
||||
}
|
||||
|
||||
public WorldEnumerator<TComponent1, TComponent2> GetEntities<TComponent1, TComponent2>()
|
||||
where TComponent1 : struct
|
||||
where TComponent2 : struct
|
||||
{
|
||||
return _ecsWorld.Enumerate<TComponent1, TComponent2>();
|
||||
}
|
||||
|
||||
public WorldEnumerator<TComponent1, TComponent2, TComponent3> GetEntities<TComponent1, TComponent2, TComponent3>()
|
||||
where TComponent1 : struct
|
||||
where TComponent2 : struct
|
||||
where TComponent3 : struct
|
||||
{
|
||||
return _ecsWorld.Enumerate<TComponent1, TComponent2, TComponent3>();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user