summaryrefslogtreecommitdiff
path: root/engine/src/data_types
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-02-18 19:18:18 +0100
committerHampusM <hampus@hampusmat.com>2024-02-18 19:18:18 +0100
commite8c6c096b2068f4ea71b021bf02f56d266ed671c (patch)
tree0cc54c1c82bf7af9881da00fa4d1a882a8263fd1 /engine/src/data_types
parent12e0f5ffffcaa36cce3cd4fecc007b9a2955ff23 (diff)
refactor(engine): move data types to a data types module
Diffstat (limited to 'engine/src/data_types')
-rw-r--r--engine/src/data_types/color.rs25
-rw-r--r--engine/src/data_types/matrix.rs109
-rw-r--r--engine/src/data_types/vector.rs324
3 files changed, 458 insertions, 0 deletions
diff --git a/engine/src/data_types/color.rs b/engine/src/data_types/color.rs
new file mode 100644
index 0000000..697ea8b
--- /dev/null
+++ b/engine/src/data_types/color.rs
@@ -0,0 +1,25 @@
+#[derive(Debug, Clone, Default)]
+#[repr(C)]
+pub struct Color<Value>
+{
+ pub red: Value,
+ pub green: Value,
+ pub blue: Value,
+}
+
+impl Color<f32>
+{
+ pub const WHITE_F32: Self = Self { red: 1.0, green: 1.0, blue: 1.0 };
+}
+
+impl<Value: Clone> From<Value> for Color<Value>
+{
+ fn from(value: Value) -> Self
+ {
+ Self {
+ red: value.clone(),
+ green: value.clone(),
+ blue: value,
+ }
+ }
+}
diff --git a/engine/src/data_types/matrix.rs b/engine/src/data_types/matrix.rs
new file mode 100644
index 0000000..85a3721
--- /dev/null
+++ b/engine/src/data_types/matrix.rs
@@ -0,0 +1,109 @@
+use crate::vector::Vec3;
+
+#[derive(Debug, Clone)]
+#[repr(C)]
+pub struct Matrix<Value, const ROWS: usize, const COLUMNS: usize>
+{
+ /// Items must be layed out this way for it to work with OpenGL shaders.
+ items: [[Value; ROWS]; COLUMNS],
+}
+
+impl<Value, const ROWS: usize, const COLUMNS: usize> Matrix<Value, ROWS, COLUMNS>
+{
+ pub fn new() -> Self
+ where
+ Value: Default + Copy,
+ {
+ Self {
+ items: [[Value::default(); ROWS]; COLUMNS],
+ }
+ }
+
+ /// Sets the value at the specified cell.
+ pub fn set_cell(&mut self, row: usize, column: usize, value: Value)
+ {
+ self.items[column][row] = value;
+ }
+
+ #[must_use]
+ pub fn as_ptr(&self) -> *const Value
+ {
+ self.items[0].as_ptr()
+ }
+}
+
+impl<const ROWS_COLS: usize> Matrix<f32, ROWS_COLS, ROWS_COLS>
+{
+ /// Creates a new identity matrix.
+ #[must_use]
+ pub fn new_identity() -> Self
+ {
+ let mut index = 0;
+
+ let items = [(); ROWS_COLS].map(|()| {
+ let mut columns = [0.0; ROWS_COLS];
+
+ columns[index] = 1.0;
+
+ index += 1;
+
+ columns
+ });
+
+ Self { items }
+ }
+}
+
+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);
+ }
+
+ 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);
+ }
+
+ pub fn look_at(&mut self, eye: &Vec3<f32>, target: &Vec3<f32>, up: &Vec3<f32>)
+ {
+ let rev_target_direction = (eye - target).normalize();
+
+ let camera_right = up.cross(&rev_target_direction).normalize();
+
+ 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.set_cell(1, 0, camera_up.x);
+ self.set_cell(1, 1, camera_up.y);
+ self.set_cell(1, 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);
+
+ // The vector is negated since we want the world to be translated in the opposite
+ // direction of where we want the camera to move.
+ let camera_pos = -Vec3 {
+ x: camera_right.dot(eye),
+ y: camera_up.dot(eye),
+ 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.set_cell(3, 3, 1.0);
+ }
+}
diff --git a/engine/src/data_types/vector.rs b/engine/src/data_types/vector.rs
new file mode 100644
index 0000000..5b7779c
--- /dev/null
+++ b/engine/src/data_types/vector.rs
@@ -0,0 +1,324 @@
+use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign};
+
+use crate::color::Color;
+
+#[derive(Debug, Default, Clone)]
+pub struct Vec2<Value>
+{
+ pub x: Value,
+ pub y: Value,
+}
+
+impl Vec2<u32>
+{
+ pub const ZERO: Self = Self { x: 0, y: 0 };
+}
+
+impl<Value> Add<Value> for Vec2<Value>
+where
+ Value: Add<Output = Value> + Clone,
+{
+ type Output = Self;
+
+ fn add(self, rhs: Value) -> Self::Output
+ {
+ Self {
+ x: self.x + rhs.clone(),
+ y: self.y + rhs,
+ }
+ }
+}
+
+impl<Value> Sub<Value> for Vec2<Value>
+where
+ Value: Sub<Output = Value> + Clone,
+{
+ type Output = Self;
+
+ fn sub(self, rhs: Value) -> Self::Output
+ {
+ Self {
+ x: self.x - rhs.clone(),
+ y: self.y - rhs,
+ }
+ }
+}
+
+impl<Value> Mul<Value> for Vec2<Value>
+where
+ Value: Mul<Output = Value> + Clone,
+{
+ type Output = Self;
+
+ fn mul(self, rhs: Value) -> Self::Output
+ {
+ Self {
+ x: self.x * rhs.clone(),
+ y: self.y * rhs,
+ }
+ }
+}
+
+impl<Value> Div<Value> for Vec2<Value>
+where
+ Value: Div<Output = Value> + Clone,
+{
+ type Output = Self;
+
+ fn div(self, rhs: Value) -> Self::Output
+ {
+ Self {
+ x: self.x / rhs.clone(),
+ y: self.y / rhs,
+ }
+ }
+}
+
+#[derive(Debug, Default, Clone)]
+#[repr(C)]
+pub struct Vec3<Value>
+{
+ pub x: Value,
+ pub y: Value,
+ pub z: Value,
+}
+
+impl Vec3<f32>
+{
+ pub const UP: Self = Self { x: 0.0, y: 1.0, z: 0.0 };
+
+ /// Returns the length of the vector.
+ #[must_use]
+ pub fn length(&self) -> f32
+ {
+ (self.x.powi(2) + self.y.powi(2) + self.z.powi(2)).sqrt()
+ }
+
+ /// Normalizes the vector, returning a unit vector.
+ #[must_use]
+ pub fn normalize(&self) -> Self
+ {
+ let length = self.length();
+
+ Self {
+ x: self.x / length,
+ y: self.y / length,
+ z: self.z / length,
+ }
+ }
+
+ /// Returns the cross product of this and another vector.
+ #[must_use]
+ pub fn cross(&self, rhs: &Self) -> Self
+ {
+ Self {
+ x: (self.y * rhs.z) - (self.z * rhs.y),
+ y: (self.z * rhs.x) - (self.x * rhs.z),
+ z: (self.x * rhs.y) - (self.y * rhs.x),
+ }
+ }
+
+ /// Returns the dot product of this and another vector.
+ #[must_use]
+ pub fn dot(&self, rhs: &Self) -> f32
+ {
+ (self.x * rhs.x) + (self.y * rhs.y) + (self.z * rhs.z)
+ }
+
+ /// Returns a direction vector from the specified angle (in degrees).
+ #[must_use]
+ pub fn direction_from_angle(pitch_degs: f32, yaw_degs: f32) -> Self
+ {
+ Self {
+ x: yaw_degs.to_radians().cos() * pitch_degs.to_radians().cos(),
+ y: pitch_degs.to_radians().sin(),
+ z: yaw_degs.to_radians().sin() * pitch_degs.to_radians().cos(),
+ }
+ }
+}
+
+impl<Value> Vec3<Value>
+{
+ pub fn as_ptr(&self) -> *const Value
+ {
+ &self.x
+ }
+}
+
+impl<Value> Sub for Vec3<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,
+ }
+ }
+}
+
+impl<Value> Sub for &Vec3<Value>
+where
+ for<'a, 'b> &'a Value: Sub<&'b Value, Output = Value>,
+{
+ type Output = Vec3<Value>;
+
+ fn sub(self, rhs: Self) -> Self::Output
+ {
+ Self::Output {
+ x: &self.x - &rhs.x,
+ y: &self.y - &rhs.y,
+ z: &self.z - &rhs.z,
+ }
+ }
+}
+
+impl<Value> Add for Vec3<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,
+ }
+ }
+}
+
+impl<Value> Add for &Vec3<Value>
+where
+ for<'a, 'b> &'a Value: Add<&'b Value, Output = Value>,
+{
+ type Output = Vec3<Value>;
+
+ fn add(self, rhs: Self) -> Self::Output
+ {
+ Self::Output {
+ x: &self.x + &rhs.x,
+ y: &self.y + &rhs.y,
+ z: &self.z + &rhs.z,
+ }
+ }
+}
+
+impl<Value> Neg for Vec3<Value>
+where
+ Value: Neg<Output = Value>,
+{
+ type Output = Self;
+
+ fn neg(mut self) -> Self::Output
+ {
+ self.x = -self.x;
+ self.y = -self.y;
+ self.z = -self.z;
+
+ self
+ }
+}
+
+impl<Value> Add<Value> for Vec3<Value>
+where
+ Value: Add<Value, Output = Value> + Clone,
+{
+ type Output = Self;
+
+ fn add(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
+ }
+}
+
+impl<Value> Sub<Value> for Vec3<Value>
+where
+ Value: Sub<Value, Output = Value> + Clone,
+{
+ type Output = Self;
+
+ fn sub(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
+ }
+}
+
+impl<Value> Mul<Value> for Vec3<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
+ }
+}
+
+impl<Value> AddAssign for Vec3<Value>
+where
+ Value: AddAssign<Value>,
+{
+ fn add_assign(&mut self, rhs: Self)
+ {
+ self.x += rhs.x;
+ self.y += rhs.y;
+ self.z += rhs.z;
+ }
+}
+
+impl<Value> SubAssign for Vec3<Value>
+where
+ Value: SubAssign<Value>,
+{
+ fn sub_assign(&mut self, rhs: Self)
+ {
+ self.x -= rhs.x;
+ self.y -= rhs.y;
+ self.z -= rhs.z;
+ }
+}
+
+impl<Value> From<Value> for Vec3<Value>
+where
+ Value: Clone,
+{
+ fn from(value: Value) -> Self
+ {
+ Self {
+ x: value.clone(),
+ y: value.clone(),
+ z: value,
+ }
+ }
+}
+
+impl<Value> From<Color<Value>> for Vec3<Value>
+{
+ fn from(color: Color<Value>) -> Self
+ {
+ Self {
+ x: color.red,
+ y: color.green,
+ z: color.blue,
+ }
+ }
+}