summaryrefslogtreecommitdiff
path: root/engine/src/data_types
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/data_types')
-rw-r--r--engine/src/data_types/matrix.rs243
1 files changed, 136 insertions, 107 deletions
diff --git a/engine/src/data_types/matrix.rs b/engine/src/data_types/matrix.rs
index cc43e7b..48796bf 100644
--- a/engine/src/data_types/matrix.rs
+++ b/engine/src/data_types/matrix.rs
@@ -1,12 +1,11 @@
-use std::ops::Mul;
+use std::ops::{Index, IndexMut, Mul};
use crate::vector::{Vec3, Vec4};
#[derive(Debug, Clone)]
pub struct Matrix<Value, const ROWS: usize, const COLUMNS: usize>
{
- /// Items must be layed out this way for it to work with OpenGL shaders.
- pub items: [[Value; ROWS]; COLUMNS],
+ items: [[Value; COLUMNS]; ROWS],
}
impl<Value, const ROWS: usize, const COLUMNS: usize> Matrix<Value, ROWS, COLUMNS>
@@ -25,21 +24,32 @@ impl<Value, const ROWS: usize, const COLUMNS: usize> Matrix<Value, ROWS, COLUMNS
pub fn from_columns<Column>(columns: [Column; COLUMNS]) -> Self
where
Column: Into<[Value; ROWS]>,
+ Value: Default,
{
- Self {
- items: columns.map(|column| column.into()),
+ let mut items =
+ std::array::from_fn(|_| std::array::from_fn(|_| Value::default()));
+
+ for (column_index, column) in columns.into_iter().enumerate() {
+ for (row_index, item) in column.into().into_iter().enumerate() {
+ items[row_index][column_index] = item;
+ }
}
+
+ Self { items }
}
- /// Sets the value at the specified cell.
- pub fn set_cell(&mut self, row: usize, column: usize, value: Value)
+ pub fn get_column_copied(&self, column_index: usize) -> [Value; ROWS]
+ where
+ Value: Default + Copy,
{
- self.items[column][row] = value;
+ std::array::from_fn::<Value, ROWS, _>(|row_index| {
+ self[CellPos { row: row_index, col: column_index }]
+ })
}
- pub fn items(&self) -> &[[Value; ROWS]; COLUMNS]
+ pub fn items(&self) -> &[Value]
{
- &self.items
+ &self.items.as_flattened()
}
}
@@ -60,19 +70,13 @@ impl<const ROWS_COLS: usize> Matrix<f32, ROWS_COLS, ROWS_COLS>
#[must_use]
pub fn new_identity() -> Self
{
- let mut index = 0;
-
- let items = [(); ROWS_COLS].map(|()| {
- let mut columns = [0.0; ROWS_COLS];
+ let mut identity = Self::new();
- columns[index] = 1.0;
-
- index += 1;
-
- columns
- });
+ for index in 0..ROWS_COLS {
+ identity[CellPos { row: index, col: index }] = 1.0;
+ }
- Self { items }
+ identity
}
}
@@ -80,18 +84,18 @@ impl Matrix<f32, 4, 4>
{
pub fn translate(&mut self, translation: &Vec3<f32>)
{
- self.set_cell(0, 3, translation.x);
- self.set_cell(1, 3, translation.y);
- self.set_cell(2, 3, translation.z);
- self.set_cell(3, 3, 1.0);
+ self[CellPos { row: 0, col: 3 }] = translation.x;
+ self[CellPos { row: 1, col: 3 }] = translation.y;
+ self[CellPos { row: 2, col: 3 }] = translation.z;
+ self[CellPos { row: 3, col: 3 }] = 1.0;
}
pub fn scale(&mut self, scaling: &Vec3<f32>)
{
- self.set_cell(0, 0, scaling.x);
- self.set_cell(1, 1, scaling.y);
- self.set_cell(2, 2, scaling.z);
- self.set_cell(3, 3, 1.0);
+ self[CellPos { row: 0, col: 0 }] = scaling.x;
+ self[CellPos { row: 1, col: 1 }] = scaling.y;
+ self[CellPos { row: 2, col: 2 }] = scaling.z;
+ self[CellPos { row: 3, col: 3 }] = 1.0;
}
pub fn look_at(&mut self, eye: Vec3<f32>, target: Vec3<f32>, up: Vec3<f32>)
@@ -102,17 +106,17 @@ impl Matrix<f32, 4, 4>
let camera_up = rev_target_direction.cross(&camera_right);
- self.set_cell(0, 0, camera_right.x);
- self.set_cell(0, 1, camera_right.y);
- self.set_cell(0, 2, camera_right.z);
+ self[CellPos { row: 0, col: 0 }] = camera_right.x;
+ self[CellPos { row: 0, col: 1 }] = camera_right.y;
+ self[CellPos { row: 0, col: 2 }] = camera_right.z;
- self.set_cell(1, 0, camera_up.x);
- self.set_cell(1, 1, camera_up.y);
- self.set_cell(1, 2, camera_up.z);
+ self[CellPos { row: 1, col: 0 }] = camera_up.x;
+ self[CellPos { row: 1, col: 1 }] = camera_up.y;
+ self[CellPos { row: 1, col: 2 }] = camera_up.z;
- self.set_cell(2, 0, rev_target_direction.x);
- self.set_cell(2, 1, rev_target_direction.y);
- self.set_cell(2, 2, rev_target_direction.z);
+ self[CellPos { row: 2, col: 0 }] = rev_target_direction.x;
+ self[CellPos { row: 2, col: 1 }] = rev_target_direction.y;
+ self[CellPos { row: 2, col: 2 }] = rev_target_direction.z;
// The vector is negated since we want the world to be translated in the opposite
// direction of where we want the camera to move.
@@ -122,56 +126,56 @@ impl Matrix<f32, 4, 4>
z: rev_target_direction.dot(&eye),
};
- self.set_cell(0, 3, camera_pos.x);
- self.set_cell(1, 3, camera_pos.y);
- self.set_cell(2, 3, camera_pos.z);
+ self[CellPos { row: 0, col: 3 }] = camera_pos.x;
+ self[CellPos { row: 1, col: 3 }] = camera_pos.y;
+ self[CellPos { row: 2, col: 3 }] = camera_pos.z;
- self.set_cell(3, 3, 1.0);
+ self[CellPos { row: 3, col: 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 coef_00 = self[CellPos { row: 2, col: 2 }] * self[CellPos { row: 3, col: 3 }]
+ - self[CellPos { row: 2, col: 3 }] * self[CellPos { row: 3, col: 2 }];
+ let coef_02 = self[CellPos { row: 2, col: 1 }] * self[CellPos { row: 3, col: 3 }]
+ - self[CellPos { row: 2, col: 3 }] * self[CellPos { row: 3, col: 1 }];
+ let coef_03 = self[CellPos { row: 2, col: 1 }] * self[CellPos { row: 3, col: 2 }]
+ - self[CellPos { row: 2, col: 2 }] * self[CellPos { row: 3, col: 1 }];
+
+ let coef_04 = self[CellPos { row: 1, col: 2 }] * self[CellPos { row: 3, col: 3 }]
+ - self[CellPos { row: 1, col: 3 }] * self[CellPos { row: 3, col: 2 }];
+ let coef_06 = self[CellPos { row: 1, col: 1 }] * self[CellPos { row: 3, col: 3 }]
+ - self[CellPos { row: 1, col: 3 }] * self[CellPos { row: 3, col: 1 }];
+ let coef_07 = self[CellPos { row: 1, col: 1 }] * self[CellPos { row: 3, col: 2 }]
+ - self[CellPos { row: 1, col: 2 }] * self[CellPos { row: 3, col: 1 }];
+
+ let coef_08 = self[CellPos { row: 1, col: 2 }] * self[CellPos { row: 2, col: 3 }]
+ - self[CellPos { row: 1, col: 3 }] * self[CellPos { row: 2, col: 2 }];
+ let coef_10 = self[CellPos { row: 1, col: 1 }] * self[CellPos { row: 2, col: 3 }]
+ - self[CellPos { row: 1, col: 3 }] * self[CellPos { row: 2, col: 1 }];
+ let coef_11 = self[CellPos { row: 1, col: 1 }] * self[CellPos { row: 2, col: 2 }]
+ - self[CellPos { row: 1, col: 2 }] * self[CellPos { row: 2, col: 1 }];
+
+ let coef_12 = self[CellPos { row: 0, col: 2 }] * self[CellPos { row: 3, col: 3 }]
+ - self[CellPos { row: 0, col: 3 }] * self[CellPos { row: 3, col: 2 }];
+ let coef_14 = self[CellPos { row: 0, col: 1 }] * self[CellPos { row: 3, col: 3 }]
+ - self[CellPos { row: 0, col: 3 }] * self[CellPos { row: 3, col: 1 }];
+ let coef_15 = self[CellPos { row: 0, col: 1 }] * self[CellPos { row: 3, col: 2 }]
+ - self[CellPos { row: 0, col: 2 }] * self[CellPos { row: 3, col: 1 }];
+
+ let coef_16 = self[CellPos { row: 0, col: 2 }] * self[CellPos { row: 2, col: 3 }]
+ - self[CellPos { row: 0, col: 3 }] * self[CellPos { row: 2, col: 2 }];
+ let coef_18 = self[CellPos { row: 0, col: 1 }] * self[CellPos { row: 2, col: 3 }]
+ - self[CellPos { row: 0, col: 3 }] * self[CellPos { row: 2, col: 1 }];
+ let coef_19 = self[CellPos { row: 0, col: 1 }] * self[CellPos { row: 2, col: 2 }]
+ - self[CellPos { row: 0, col: 2 }] * self[CellPos { row: 2, col: 1 }];
+
+ let coef_20 = self[CellPos { row: 0, col: 2 }] * self[CellPos { row: 1, col: 3 }]
+ - self[CellPos { row: 0, col: 3 }] * self[CellPos { row: 1, col: 2 }];
+ let coef_22 = self[CellPos { row: 0, col: 1 }] * self[CellPos { row: 1, col: 3 }]
+ - self[CellPos { row: 0, col: 3 }] * self[CellPos { row: 1, col: 1 }];
+ let coef_23 = self[CellPos { row: 0, col: 1 }] * self[CellPos { row: 1, col: 2 }]
+ - self[CellPos { row: 0, col: 2 }] * self[CellPos { row: 1, col: 1 }];
let fac_0 = Vec4 {
x: coef_00,
@@ -211,28 +215,28 @@ impl Matrix<f32, 4, 4>
};
let vec_0 = Vec4 {
- x: self.items[1][0],
- y: self.items[0][0],
- z: self.items[0][0],
- w: self.items[0][0],
+ x: self[CellPos { row: 0, col: 1 }],
+ y: self[CellPos { row: 0, col: 0 }],
+ z: self[CellPos { row: 0, col: 0 }],
+ w: self[CellPos { row: 0, col: 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],
+ x: self[CellPos { row: 1, col: 1 }],
+ y: self[CellPos { row: 1, col: 0 }],
+ z: self[CellPos { row: 1, col: 0 }],
+ w: self[CellPos { row: 1, col: 0 }],
};
let vec_2 = Vec4 {
- x: self.items[1][2],
- y: self.items[0][2],
- z: self.items[0][2],
- w: self.items[0][2],
+ x: self[CellPos { row: 2, col: 1 }],
+ y: self[CellPos { row: 2, col: 0 }],
+ z: self[CellPos { row: 2, col: 0 }],
+ w: self[CellPos { row: 2, col: 0 }],
};
let vec_3 = Vec4 {
- x: self.items[1][3],
- y: self.items[0][3],
- z: self.items[0][3],
- w: self.items[0][3],
+ x: self[CellPos { row: 3, col: 1 }],
+ y: self[CellPos { row: 3, col: 0 }],
+ z: self[CellPos { row: 3, col: 0 }],
+ w: self[CellPos { row: 3, col: 0 }],
};
let inv_0 = vec_1 * fac_0 - vec_2 * fac_1 + vec_3 * fac_2;
@@ -251,13 +255,13 @@ impl Matrix<f32, 4, 4>
]);
let row_0 = Vec4 {
- x: inverse.items[0][0],
- y: inverse.items[1][0],
- z: inverse.items[2][0],
- w: inverse.items[3][0],
+ x: inverse[CellPos { row: 0, col: 0 }],
+ y: inverse[CellPos { row: 0, col: 1 }],
+ z: inverse[CellPos { row: 0, col: 2 }],
+ w: inverse[CellPos { row: 0, col: 3 }],
};
- let dot_0 = Vec4::<f32>::from(self.items[0]) * row_0;
+ let dot_0 = Vec4::<f32>::from(self.get_column_copied(0)) * row_0;
let dot_1 = (dot_0.x + dot_0.y) + (dot_0.z + dot_0.w);
@@ -274,9 +278,34 @@ impl Mul<f32> for Matrix<f32, 4, 4>
fn mul(self, scalar: f32) -> Self::Output
{
Self {
- items: self
- .items
- .map(|column| (Vec4::from(column) * scalar).into()),
+ items: self.items.map(|row| (Vec4::from(row) * scalar).into()),
}
}
}
+
+impl<Value, const ROWS: usize, const COLUMNS: usize> Index<CellPos>
+ for Matrix<Value, ROWS, COLUMNS>
+{
+ type Output = Value;
+
+ fn index(&self, cell_pos: CellPos) -> &Self::Output
+ {
+ &self.items[cell_pos.row][cell_pos.col]
+ }
+}
+
+impl<Value, const ROWS: usize, const COLUMNS: usize> IndexMut<CellPos>
+ for Matrix<Value, ROWS, COLUMNS>
+{
+ fn index_mut(&mut self, cell_pos: CellPos) -> &mut Self::Output
+ {
+ &mut self.items[cell_pos.row][cell_pos.col]
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct CellPos
+{
+ pub row: usize,
+ pub col: usize,
+}