diff options
| author | HampusM <hampus@hampusmat.com> | 2026-03-20 14:22:19 +0100 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-03-20 14:22:19 +0100 |
| commit | f285f82072b491b1f3cc92db8e08485f26779d5a (patch) | |
| tree | bf6c6c61cdfb3a12550e55966c8552957ade9e71 /engine/src/data_types | |
| parent | 0546d575c11d3668d0f95933697ae4f670fe2a55 (diff) | |
Diffstat (limited to 'engine/src/data_types')
| -rw-r--r-- | engine/src/data_types/matrix.rs | 170 | ||||
| -rw-r--r-- | engine/src/data_types/vector.rs | 141 |
2 files changed, 306 insertions, 5 deletions
diff --git a/engine/src/data_types/matrix.rs b/engine/src/data_types/matrix.rs index b754b62..39aeea0 100644 --- a/engine/src/data_types/matrix.rs +++ b/engine/src/data_types/matrix.rs @@ -1,4 +1,6 @@ -use crate::vector::Vec3; +use std::ops::Mul; + +use crate::vector::{Vec3, Vec4, VecN}; #[derive(Debug, Clone)] pub struct Matrix<Value, const ROWS: usize, const COLUMNS: usize> @@ -20,17 +22,24 @@ impl<Value, const ROWS: usize, const COLUMNS: usize> Matrix<Value, ROWS, COLUMNS } } + pub fn from_columns<ColumnVec>(columns: [ColumnVec; COLUMNS]) -> Self + where + ColumnVec: VecN<Value, ROWS>, + { + Self { + items: columns.map(|column| column.into_array()), + } + } + /// Sets the value at the specified cell. pub fn set_cell(&mut self, row: usize, column: usize, value: Value) { self.items[column][row] = value; } - /// Returns the internal 2D array as a pointer. - #[must_use] - pub fn as_ptr(&self) -> *const Value + pub fn items(&self) -> &[[Value; ROWS]; COLUMNS] { - self.items[0].as_ptr() + &self.items } } @@ -119,4 +128,155 @@ impl Matrix<f32, 4, 4> self.set_cell(3, 3, 1.0); } + + pub fn inverse(&self) -> Self + { + let coef_00 = + self.items[2][2] * self.items[3][3] - self.items[3][2] * self.items[2][3]; + let coef_02 = + self.items[1][2] * self.items[3][3] - self.items[3][2] * self.items[1][3]; + let coef_03 = + self.items[1][2] * self.items[2][3] - self.items[2][2] * self.items[1][3]; + + let coef_04 = + self.items[2][1] * self.items[3][3] - self.items[3][1] * self.items[2][3]; + let coef_06 = + self.items[1][1] * self.items[3][3] - self.items[3][1] * self.items[1][3]; + let coef_07 = + self.items[1][1] * self.items[2][3] - self.items[2][1] * self.items[1][3]; + + let coef_08 = + self.items[2][1] * self.items[3][2] - self.items[3][1] * self.items[2][2]; + let coef_10 = + self.items[1][1] * self.items[3][2] - self.items[3][1] * self.items[1][2]; + let coef_11 = + self.items[1][1] * self.items[2][2] - self.items[2][1] * self.items[1][2]; + + let coef_12 = + self.items[2][0] * self.items[3][3] - self.items[3][0] * self.items[2][3]; + let coef_14 = + self.items[1][0] * self.items[3][3] - self.items[3][0] * self.items[1][3]; + let coef_15 = + self.items[1][0] * self.items[2][3] - self.items[2][0] * self.items[1][3]; + + let coef_16 = + self.items[2][0] * self.items[3][2] - self.items[3][0] * self.items[2][2]; + let coef_18 = + self.items[1][0] * self.items[3][2] - self.items[3][0] * self.items[1][2]; + let coef_19 = + self.items[1][0] * self.items[2][2] - self.items[2][0] * self.items[1][2]; + + let coef_20 = + self.items[2][0] * self.items[3][1] - self.items[3][0] * self.items[2][1]; + let coef_22 = + self.items[1][0] * self.items[3][1] - self.items[3][0] * self.items[1][1]; + let coef_23 = + self.items[1][0] * self.items[2][1] - self.items[2][0] * self.items[1][1]; + + let fac_0 = Vec4 { + x: coef_00, + y: coef_00, + z: coef_02, + w: coef_03, + }; + let fac_1 = Vec4 { + x: coef_04, + y: coef_04, + z: coef_06, + w: coef_07, + }; + let fac_2 = Vec4 { + x: coef_08, + y: coef_08, + z: coef_10, + w: coef_11, + }; + let fac_3 = Vec4 { + x: coef_12, + y: coef_12, + z: coef_14, + w: coef_15, + }; + let fac_4 = Vec4 { + x: coef_16, + y: coef_16, + z: coef_18, + w: coef_19, + }; + let fac_5 = Vec4 { + x: coef_20, + y: coef_20, + z: coef_22, + w: coef_23, + }; + + let vec_0 = Vec4 { + x: self.items[1][0], + y: self.items[0][0], + z: self.items[0][0], + w: self.items[0][0], + }; + let vec_1 = Vec4 { + x: self.items[1][1], + y: self.items[0][1], + z: self.items[0][1], + w: self.items[0][1], + }; + let vec_2 = Vec4 { + x: self.items[1][2], + y: self.items[0][2], + z: self.items[0][2], + w: self.items[0][2], + }; + let vec_3 = Vec4 { + x: self.items[1][3], + y: self.items[0][3], + z: self.items[0][3], + w: self.items[0][3], + }; + + let inv_0 = vec_1 * fac_0 - vec_2 * fac_1 + vec_3 * fac_2; + let inv_1 = vec_0 * fac_0 - vec_2 * fac_3 + vec_3 * fac_4; + let inv_2 = vec_0 * fac_1 - vec_1 * fac_3 + vec_3 * fac_5; + let inv_3 = vec_0 * fac_2 - vec_1 * fac_4 + vec_2 * fac_5; + + let sign_a = Vec4 { x: 1.0, y: -1.0, z: 1.0, w: -1.0 }; + let sign_b = Vec4 { x: -1.0, y: 1.0, z: -1.0, w: 1.0 }; + + let inverse = Self::from_columns([ + inv_0 * sign_a, + inv_1 * sign_b, + inv_2 * sign_a, + inv_3 * sign_b, + ]); + + let row_0 = Vec4 { + x: inverse.items[0][0], + y: inverse.items[1][0], + z: inverse.items[2][0], + w: inverse.items[3][0], + }; + + let dot_0 = Vec4::<f32>::from(self.items[0]) * row_0; + + let dot_1 = (dot_0.x + dot_0.y) + (dot_0.z + dot_0.w); + + let one_over_determinant = 1.0 / dot_1; + + inverse * one_over_determinant + } +} + +impl Mul<f32> for Matrix<f32, 4, 4> +{ + type Output = Self; + + fn mul(self, scalar: f32) -> Self::Output + { + Self { + items: self + .items + .map(|column| (Vec4::from(column) * scalar).into_array()), + } + } } diff --git a/engine/src/data_types/vector.rs b/engine/src/data_types/vector.rs index dc6df30..1a4e49e 100644 --- a/engine/src/data_types/vector.rs +++ b/engine/src/data_types/vector.rs @@ -2,6 +2,12 @@ use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign}; use crate::color::Color; +/// A vector of `Value`s with `N` number of elements. +pub trait VecN<Value, const N: usize>: sealed::Sealed +{ + fn into_array(self) -> [Value; N]; +} + #[derive(Debug, Default, Clone, Copy, PartialEq)] pub struct Vec2<Value> { @@ -97,6 +103,16 @@ where } } +impl<Value> VecN<Value, 2> for Vec2<Value> +{ + fn into_array(self) -> [Value; 2] + { + [self.x, self.y] + } +} + +impl<Value> sealed::Sealed for Vec2<Value> {} + #[derive(Debug, Default, Clone, Copy, PartialEq)] pub struct Vec3<Value> { @@ -365,3 +381,128 @@ impl<Value> From<Color<Value>> for Vec3<Value> } } } + +impl<Value> VecN<Value, 3> for Vec3<Value> +{ + fn into_array(self) -> [Value; 3] + { + [self.x, self.y, self.z] + } +} + +impl<Value> sealed::Sealed for Vec3<Value> {} + +#[derive(Debug, Default, Clone, Copy, PartialEq)] +pub struct Vec4<Value> +{ + pub x: Value, + pub y: Value, + pub z: Value, + pub w: Value, +} + +impl<Value> Mul for Vec4<Value> +where + Value: Mul<Value, Output = Value>, +{ + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output + { + Self::Output { + x: self.x * rhs.x, + y: self.y * rhs.y, + z: self.z * rhs.z, + w: self.w * rhs.w, + } + } +} + +impl<Value> Add for Vec4<Value> +where + Value: Add<Value, Output = Value>, +{ + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output + { + Self::Output { + x: self.x + rhs.x, + y: self.y + rhs.y, + z: self.z + rhs.z, + w: self.w + rhs.w, + } + } +} + +impl<Value> Sub for Vec4<Value> +where + Value: Sub<Value, Output = Value>, +{ + type Output = Self; + + fn sub(self, rhs: Self) -> Self::Output + { + Self::Output { + x: self.x - rhs.x, + y: self.y - rhs.y, + z: self.z - rhs.z, + w: self.w - rhs.w, + } + } +} + +impl<Value> Mul<Value> for Vec4<Value> +where + Value: Mul<Value, Output = Value> + Clone, +{ + type Output = Self; + + fn mul(mut self, rhs: Value) -> Self::Output + { + self.x = self.x * rhs.clone(); + self.y = self.y * rhs.clone(); + self.z = self.z * rhs.clone(); + self.w = self.w * rhs.clone(); + + self + } +} + +impl<Value: Clone> From<Value> for Vec4<Value> +{ + fn from(value: Value) -> Self + { + Self { + x: value.clone(), + y: value.clone(), + z: value.clone(), + w: value, + } + } +} + +impl<Value> From<[Value; 4]> for Vec4<Value> +{ + fn from(values: [Value; 4]) -> Self + { + let [x, y, z, w] = values; + + Self { x, y, z, w } + } +} + +impl<Value> VecN<Value, 4> for Vec4<Value> +{ + fn into_array(self) -> [Value; 4] + { + [self.x, self.y, self.z, self.w] + } +} + +impl<Value> sealed::Sealed for Vec4<Value> {} + +mod sealed +{ + pub trait Sealed {} +} |
