From e8c6c096b2068f4ea71b021bf02f56d266ed671c Mon Sep 17 00:00:00 2001 From: HampusM Date: Sun, 18 Feb 2024 19:18:18 +0100 Subject: refactor(engine): move data types to a data types module --- engine/src/color.rs | 25 ---- engine/src/data_types.rs | 4 + engine/src/data_types/color.rs | 25 ++++ engine/src/data_types/matrix.rs | 109 ++++++++++++++ engine/src/data_types/vector.rs | 324 ++++++++++++++++++++++++++++++++++++++++ engine/src/lib.rs | 7 +- engine/src/matrix.rs | 109 -------------- engine/src/vector.rs | 324 ---------------------------------------- 8 files changed, 466 insertions(+), 461 deletions(-) delete mode 100644 engine/src/color.rs create mode 100644 engine/src/data_types.rs create mode 100644 engine/src/data_types/color.rs create mode 100644 engine/src/data_types/matrix.rs create mode 100644 engine/src/data_types/vector.rs delete mode 100644 engine/src/matrix.rs delete mode 100644 engine/src/vector.rs diff --git a/engine/src/color.rs b/engine/src/color.rs deleted file mode 100644 index 697ea8b..0000000 --- a/engine/src/color.rs +++ /dev/null @@ -1,25 +0,0 @@ -#[derive(Debug, Clone, Default)] -#[repr(C)] -pub struct Color -{ - pub red: Value, - pub green: Value, - pub blue: Value, -} - -impl Color -{ - pub const WHITE_F32: Self = Self { red: 1.0, green: 1.0, blue: 1.0 }; -} - -impl From for Color -{ - fn from(value: Value) -> Self - { - Self { - red: value.clone(), - green: value.clone(), - blue: value, - } - } -} diff --git a/engine/src/data_types.rs b/engine/src/data_types.rs new file mode 100644 index 0000000..01d0a1e --- /dev/null +++ b/engine/src/data_types.rs @@ -0,0 +1,4 @@ +pub mod color; +pub mod vector; + +pub(crate) mod matrix; 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 +{ + pub red: Value, + pub green: Value, + pub blue: Value, +} + +impl Color +{ + pub const WHITE_F32: Self = Self { red: 1.0, green: 1.0, blue: 1.0 }; +} + +impl From for Color +{ + 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 +{ + /// Items must be layed out this way for it to work with OpenGL shaders. + items: [[Value; ROWS]; COLUMNS], +} + +impl Matrix +{ + 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 Matrix +{ + /// 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 +{ + pub fn translate(&mut self, translation: &Vec3) + { + 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) + { + 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, target: &Vec3, up: &Vec3) + { + 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 +{ + pub x: Value, + pub y: Value, +} + +impl Vec2 +{ + pub const ZERO: Self = Self { x: 0, y: 0 }; +} + +impl Add for Vec2 +where + Value: Add + Clone, +{ + type Output = Self; + + fn add(self, rhs: Value) -> Self::Output + { + Self { + x: self.x + rhs.clone(), + y: self.y + rhs, + } + } +} + +impl Sub for Vec2 +where + Value: Sub + Clone, +{ + type Output = Self; + + fn sub(self, rhs: Value) -> Self::Output + { + Self { + x: self.x - rhs.clone(), + y: self.y - rhs, + } + } +} + +impl Mul for Vec2 +where + Value: Mul + Clone, +{ + type Output = Self; + + fn mul(self, rhs: Value) -> Self::Output + { + Self { + x: self.x * rhs.clone(), + y: self.y * rhs, + } + } +} + +impl Div for Vec2 +where + Value: Div + 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 +{ + pub x: Value, + pub y: Value, + pub z: Value, +} + +impl Vec3 +{ + 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 Vec3 +{ + pub fn as_ptr(&self) -> *const Value + { + &self.x + } +} + +impl Sub for Vec3 +where + Value: Sub, +{ + 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 Sub for &Vec3 +where + for<'a, 'b> &'a Value: Sub<&'b Value, Output = Value>, +{ + type Output = Vec3; + + 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 Add for Vec3 +where + Value: Add, +{ + 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 Add for &Vec3 +where + for<'a, 'b> &'a Value: Add<&'b Value, Output = Value>, +{ + type Output = Vec3; + + 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 Neg for Vec3 +where + Value: Neg, +{ + type Output = Self; + + fn neg(mut self) -> Self::Output + { + self.x = -self.x; + self.y = -self.y; + self.z = -self.z; + + self + } +} + +impl Add for Vec3 +where + Value: Add + 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 Sub for Vec3 +where + Value: Sub + 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 Mul for Vec3 +where + Value: Mul + 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 AddAssign for Vec3 +where + Value: AddAssign, +{ + fn add_assign(&mut self, rhs: Self) + { + self.x += rhs.x; + self.y += rhs.y; + self.z += rhs.z; + } +} + +impl SubAssign for Vec3 +where + Value: SubAssign, +{ + fn sub_assign(&mut self, rhs: Self) + { + self.x -= rhs.x; + self.y -= rhs.y; + self.z -= rhs.z; + } +} + +impl From for Vec3 +where + Value: Clone, +{ + fn from(value: Value) -> Self + { + Self { + x: value.clone(), + y: value.clone(), + z: value, + } + } +} + +impl From> for Vec3 +{ + fn from(color: Color) -> Self + { + Self { + x: color.red, + y: color.green, + z: color.blue, + } + } +} diff --git a/engine/src/lib.rs b/engine/src/lib.rs index fdd79a4..fada83f 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -12,7 +12,6 @@ use crate::object::{Id as ObjectId, Object}; use crate::renderer::Renderer; use crate::vector::Vec2; -mod matrix; mod opengl; mod projection; mod renderer; @@ -20,19 +19,21 @@ mod shader_preprocessor; mod transform; pub mod camera; -pub mod color; +pub mod data_types; pub mod lighting; pub mod material; pub mod math; pub mod mesh; pub mod object; pub mod texture; -pub mod vector; pub mod vertex; pub use glfw::window::Key; pub use glfw::WindowSize; +pub(crate) use crate::data_types::matrix; +pub use crate::data_types::{color, vector}; + #[derive(Debug)] pub struct Engine { diff --git a/engine/src/matrix.rs b/engine/src/matrix.rs deleted file mode 100644 index 85a3721..0000000 --- a/engine/src/matrix.rs +++ /dev/null @@ -1,109 +0,0 @@ -use crate::vector::Vec3; - -#[derive(Debug, Clone)] -#[repr(C)] -pub struct Matrix -{ - /// Items must be layed out this way for it to work with OpenGL shaders. - items: [[Value; ROWS]; COLUMNS], -} - -impl Matrix -{ - 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 Matrix -{ - /// 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 -{ - pub fn translate(&mut self, translation: &Vec3) - { - 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) - { - 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, target: &Vec3, up: &Vec3) - { - 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/vector.rs b/engine/src/vector.rs deleted file mode 100644 index 5b7779c..0000000 --- a/engine/src/vector.rs +++ /dev/null @@ -1,324 +0,0 @@ -use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign}; - -use crate::color::Color; - -#[derive(Debug, Default, Clone)] -pub struct Vec2 -{ - pub x: Value, - pub y: Value, -} - -impl Vec2 -{ - pub const ZERO: Self = Self { x: 0, y: 0 }; -} - -impl Add for Vec2 -where - Value: Add + Clone, -{ - type Output = Self; - - fn add(self, rhs: Value) -> Self::Output - { - Self { - x: self.x + rhs.clone(), - y: self.y + rhs, - } - } -} - -impl Sub for Vec2 -where - Value: Sub + Clone, -{ - type Output = Self; - - fn sub(self, rhs: Value) -> Self::Output - { - Self { - x: self.x - rhs.clone(), - y: self.y - rhs, - } - } -} - -impl Mul for Vec2 -where - Value: Mul + Clone, -{ - type Output = Self; - - fn mul(self, rhs: Value) -> Self::Output - { - Self { - x: self.x * rhs.clone(), - y: self.y * rhs, - } - } -} - -impl Div for Vec2 -where - Value: Div + 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 -{ - pub x: Value, - pub y: Value, - pub z: Value, -} - -impl Vec3 -{ - 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 Vec3 -{ - pub fn as_ptr(&self) -> *const Value - { - &self.x - } -} - -impl Sub for Vec3 -where - Value: Sub, -{ - 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 Sub for &Vec3 -where - for<'a, 'b> &'a Value: Sub<&'b Value, Output = Value>, -{ - type Output = Vec3; - - 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 Add for Vec3 -where - Value: Add, -{ - 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 Add for &Vec3 -where - for<'a, 'b> &'a Value: Add<&'b Value, Output = Value>, -{ - type Output = Vec3; - - 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 Neg for Vec3 -where - Value: Neg, -{ - type Output = Self; - - fn neg(mut self) -> Self::Output - { - self.x = -self.x; - self.y = -self.y; - self.z = -self.z; - - self - } -} - -impl Add for Vec3 -where - Value: Add + 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 Sub for Vec3 -where - Value: Sub + 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 Mul for Vec3 -where - Value: Mul + 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 AddAssign for Vec3 -where - Value: AddAssign, -{ - fn add_assign(&mut self, rhs: Self) - { - self.x += rhs.x; - self.y += rhs.y; - self.z += rhs.z; - } -} - -impl SubAssign for Vec3 -where - Value: SubAssign, -{ - fn sub_assign(&mut self, rhs: Self) - { - self.x -= rhs.x; - self.y -= rhs.y; - self.z -= rhs.z; - } -} - -impl From for Vec3 -where - Value: Clone, -{ - fn from(value: Value) -> Self - { - Self { - x: value.clone(), - y: value.clone(), - z: value, - } - } -} - -impl From> for Vec3 -{ - fn from(color: Color) -> Self - { - Self { - x: color.red, - y: color.green, - z: color.blue, - } - } -} -- cgit v1.2.3-18-g5258