diff options
-rw-r--r-- | engine/src/data_types/vector.rs | 4 | ||||
-rw-r--r-- | engine/src/math.rs | 2 | ||||
-rw-r--r-- | engine/src/mesh/cube.rs | 989 | ||||
-rw-r--r-- | engine/src/vertex.rs | 2 |
4 files changed, 388 insertions, 609 deletions
diff --git a/engine/src/data_types/vector.rs b/engine/src/data_types/vector.rs index 8073cdf..802a4a7 100644 --- a/engine/src/data_types/vector.rs +++ b/engine/src/data_types/vector.rs @@ -2,7 +2,7 @@ use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign}; use crate::color::Color; -#[derive(Debug, Default, Clone, Copy)] +#[derive(Debug, Default, Clone, Copy, PartialEq)] pub struct Vec2<Value> { pub x: Value, @@ -74,7 +74,7 @@ where } } -#[derive(Debug, Default, Clone, Copy)] +#[derive(Debug, Default, Clone, Copy, PartialEq)] #[repr(C)] pub struct Vec3<Value> { diff --git a/engine/src/math.rs b/engine/src/math.rs index b86e760..0340de8 100644 --- a/engine/src/math.rs +++ b/engine/src/math.rs @@ -13,5 +13,5 @@ pub fn calc_triangle_surface_normal( let v1 = edge_b - egde_a; let v2 = edge_c - egde_a; - v1.cross(&v2) + v1.cross(&v2).normalize() } diff --git a/engine/src/mesh/cube.rs b/engine/src/mesh/cube.rs index 7cdf885..c29ce0b 100644 --- a/engine/src/mesh/cube.rs +++ b/engine/src/mesh/cube.rs @@ -1,7 +1,7 @@ use crate::math::calc_triangle_surface_normal; use crate::mesh::Mesh; use crate::util::builder; -use crate::vector::Vec3; +use crate::vector::{Vec2, Vec3}; use crate::vertex::{Builder as VertexBuilder, Vertex}; builder! { @@ -27,676 +27,455 @@ impl CreationSpec } } -#[derive(Debug)] +/// Describes a single side of a cube (obviously). +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum Side { + /// +Z Front, + + /// -Z Back, + + /// -X Left, + + /// +X Right, + + /// +Y Top, + + /// -Y Bottom, } -#[derive(Debug)] -pub enum Corner +/// Describes what location on a side of a cube a face is. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum FaceLocation { - TopRight, - TopLeft, - BottomRight, - BottomLeft, + /// 🮝 + RightUp, + + /// 🮟 + LeftDown, } /// Creates a cube mesh. +/// +/// By default, the texture coordinates are arranged so that the full texture is visible +/// on every side. This can be changed inside of the `face_cb` function. pub fn create( creation_spec: CreationSpec, - vertex_builder_cb: impl Fn(VertexBuilder, Side, Corner) -> VertexBuilder, + face_cb: impl FnMut(FaceVertices, Side, FaceLocation) -> FaceVertices, ) -> Mesh { - let mut vertices = [const { None }; VertexIndex::VARIANT_CNT]; - - create_front(&creation_spec, &mut vertices, &vertex_builder_cb); - create_back(&creation_spec, &mut vertices, &vertex_builder_cb); - create_right(&creation_spec, &mut vertices, &vertex_builder_cb); - create_left(&creation_spec, &mut vertices, &vertex_builder_cb); - create_top(&creation_spec, &mut vertices, &vertex_builder_cb); - create_bottom(&creation_spec, &mut vertices, &vertex_builder_cb); - - Mesh::new( - vertices.map(Option::unwrap).to_vec(), - Some( - VERTEX_INDICES - .into_iter() - .flatten() - .map(|index| index as u32) - .collect(), - ), - ) -} + let mut data = Data::default(); -macro_rules! one { - ($tt: tt) => { - 1 - }; -} + create_side(&SidePositions::new_top(&creation_spec), &mut data); + create_side(&SidePositions::new_bottom(&creation_spec), &mut data); + create_side(&SidePositions::new_left(&creation_spec), &mut data); + create_side(&SidePositions::new_right(&creation_spec), &mut data); + create_side(&SidePositions::new_back(&creation_spec), &mut data); + create_side(&SidePositions::new_front(&creation_spec), &mut data); -macro_rules! enum_with_variant_cnt { - ( - $(#[$attr: meta])* - enum $name: ident { - $($variant: ident,)* - } - ) => { - $(#[$attr])* - enum $name { - $($variant,)* - } - - impl $name { - const VARIANT_CNT: usize = 0 $(+ one!($variant))*; - } - }; + data.into_mesh(face_cb) } -enum_with_variant_cnt! { -#[repr(u32)] -enum VertexIndex +#[derive(Debug, Default)] +struct Data { - FrontTopRight, - FrontBottomRight, - FrontBottomLeft, - FrontTopLeft, - - BackTopRight, - BackBottomRight, - BackBottomLeft, - BackTopLeft, - - RightBackTop, - RightBackBottom, - RightFrontTop, - RightFrontBottom, - - LeftBackTop, - LeftBackBottom, - LeftFrontTop, - LeftFrontBottom, - - TopBackRight, - TopBackLeft, - TopFrontRight, - TopFrontLeft, - - BottomBackRight, - BottomBackLeft, - BottomFrontRight, - BottomFrontLeft, -} + faces: Vec<Face>, + vertex_data: VertexData, } -fn create_front( - creation_spec: &CreationSpec, - vertices: &mut [Option<Vertex>], - vertex_builder_cb: &impl Fn(VertexBuilder, Side, Corner) -> VertexBuilder, -) +#[derive(Debug, Default)] +struct VertexData { - let front_top_right_pos = Vec3 { - x: creation_spec.width / 2.0, - y: creation_spec.height / 2.0, - z: -(creation_spec.depth / 2.0), - }; - - let front_bottom_right_pos = Vec3 { - x: creation_spec.width / 2.0, - y: -(creation_spec.height / 2.0), - z: -(creation_spec.depth / 2.0), - }; + vertex_positions: Vec<Vec3<f32>>, + vertex_normals: Vec<Vec3<f32>>, +} - let front_bottom_left_pos = Vec3 { - x: -(creation_spec.width / 2.0), - y: -(creation_spec.height / 2.0), - z: -(creation_spec.depth / 2.0), - }; +impl Data +{ + fn into_mesh( + self, + mut face_cb: impl FnMut(FaceVertices, Side, FaceLocation) -> FaceVertices, + ) -> Mesh + { + let mut vertices = Vec::<Vertex>::with_capacity(self.faces.len() * 3); + let mut indices = Vec::<u32>::with_capacity(self.faces.len() * 3); - let front_top_left_pos = Vec3 { - x: -(creation_spec.width / 2.0), - y: creation_spec.height / 2.0, - z: -(creation_spec.depth / 2.0), - }; + let mut face_location = FaceLocation::RightUp; - let front_normal = calc_triangle_surface_normal( - &front_top_right_pos, - &front_bottom_right_pos, - &front_top_left_pos, - ); - - vertices[VertexIndex::FrontTopRight as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(front_top_right_pos) - .normal(front_normal), - Side::Front, - Corner::TopRight, - ) - .build(), - ); - - vertices[VertexIndex::FrontBottomRight as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(front_bottom_right_pos) - .normal(front_normal), - Side::Front, - Corner::BottomRight, - ) - .build(), - ); - - vertices[VertexIndex::FrontBottomLeft as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(front_bottom_left_pos) - .normal(front_normal), - Side::Front, - Corner::BottomLeft, - ) - .build(), - ); - - vertices[VertexIndex::FrontTopLeft as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(front_top_left_pos) - .normal(front_normal), - Side::Front, - Corner::TopLeft, - ) - .build(), - ); -} + let Self { faces, vertex_data } = self; -fn create_back( - creation_spec: &CreationSpec, - vertices: &mut [Option<Vertex>], - vertex_builder_cb: &impl Fn(VertexBuilder, Side, Corner) -> VertexBuilder, -) -{ - let back_top_right_pos = Vec3 { - x: creation_spec.width / 2.0, - y: creation_spec.height / 2.0, - z: creation_spec.depth / 2.0, - }; + for face in faces { + let side = face.side; - let back_bottom_right_pos = Vec3 { - x: creation_spec.width / 2.0, - y: -(creation_spec.height / 2.0), - z: creation_spec.depth / 2.0, - }; + let face_vertices = face_cb( + FaceVertices::new(face, &vertex_data) + .with_full_per_side_tex_coords(face_location), + side, + face_location, + ); - let back_bottom_left_pos = Vec3 { - x: -(creation_spec.width / 2.0), - y: -(creation_spec.height / 2.0), - z: creation_spec.depth / 2.0, - }; + for vertex in face_vertices.vertices { + if let Some((prev_vertex_index, _)) = vertices + .iter() + .enumerate() + .find(|(_, prev_vertex)| *prev_vertex == &vertex) + { + indices + .push(u32::try_from(prev_vertex_index).expect( + "Vertex index does not fit into 32-bit unsigned int", + )); - let back_top_left_pos = Vec3 { - x: -(creation_spec.width / 2.0), - y: creation_spec.height / 2.0, - z: creation_spec.depth / 2.0, - }; + continue; + } - let back_normal = -calc_triangle_surface_normal( - &back_top_right_pos, - &back_bottom_right_pos, - &back_top_left_pos, - ); - - vertices[VertexIndex::BackTopRight as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(back_top_right_pos) - .normal(back_normal), - Side::Back, - Corner::TopRight, - ) - .build(), - ); - - vertices[VertexIndex::BackBottomRight as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(back_bottom_right_pos) - .normal(back_normal), - Side::Back, - Corner::BottomRight, - ) - .build(), - ); - - vertices[VertexIndex::BackBottomLeft as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(back_bottom_left_pos) - .normal(back_normal), - Side::Back, - Corner::BottomLeft, - ) - .build(), - ); - - vertices[VertexIndex::BackTopLeft as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(back_top_left_pos) - .normal(back_normal), - Side::Back, - Corner::TopLeft, - ) - .build(), - ); -} + vertices.push(vertex); -fn create_right( - creation_spec: &CreationSpec, - vertices: &mut [Option<Vertex>], - vertex_builder_cb: &impl Fn(VertexBuilder, Side, Corner) -> VertexBuilder, -) -{ - let right_back_top_pos = Vec3 { - x: creation_spec.width / 2.0, - y: creation_spec.height / 2.0, - z: creation_spec.depth / 2.0, - }; + let vertex_index = u32::try_from(vertices.len() - 1) + .expect("Vertex index does not fit into 32-bit unsigned int"); - let right_back_bottom_pos = Vec3 { - x: creation_spec.width / 2.0, - y: -(creation_spec.height / 2.0), - z: creation_spec.depth / 2.0, - }; + indices.push(vertex_index); + } - let right_front_top_pos = Vec3 { - x: creation_spec.width / 2.0, - y: creation_spec.height / 2.0, - z: -(creation_spec.depth / 2.0), - }; + match face_location { + FaceLocation::RightUp => face_location = FaceLocation::LeftDown, + FaceLocation::LeftDown => face_location = FaceLocation::RightUp, + } + } - let right_front_bottom_pos = Vec3 { - x: creation_spec.width / 2.0, - y: -(creation_spec.height / 2.0), - z: -(creation_spec.depth / 2.0), - }; + Mesh::new(vertices, Some(indices)) + } +} - let right_normal = calc_triangle_surface_normal( - &right_back_top_pos, - &right_back_bottom_pos, - &right_front_top_pos, - ); - - vertices[VertexIndex::RightBackTop as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(right_back_top_pos) - .normal(right_normal), - Side::Right, - Corner::TopLeft, - ) - .build(), - ); - - vertices[VertexIndex::RightBackBottom as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(right_back_bottom_pos) - .normal(right_normal), - Side::Right, - Corner::BottomLeft, - ) - .build(), - ); - - vertices[VertexIndex::RightFrontTop as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(right_front_top_pos) - .normal(right_normal), - Side::Right, - Corner::TopRight, - ) - .build(), - ); - - vertices[VertexIndex::RightFrontBottom as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(right_front_bottom_pos) - .normal(right_normal), - Side::Right, - Corner::BottomRight, - ) - .build(), - ); +/// The vertices of a single face of a cube. +#[derive(Debug, Default, Clone)] +pub struct FaceVertices +{ + /// The three vertices of a face in counter-clockwise order. + /// + /// Order when [`FaceLocation::RightUp`]: + /// ```text + /// ₂ ₁ + /// 🮝 + /// ³ + /// ``` + /// + /// Order when [`FaceLocation::LeftDown`]: + /// ```text + /// ₁ + /// 🮟 + /// ² ³ + /// ``` + pub vertices: [Vertex; 3], } -fn create_left( - creation_spec: &CreationSpec, - vertices: &mut [Option<Vertex>], - vertex_builder_cb: &impl Fn(VertexBuilder, Side, Corner) -> VertexBuilder, -) +impl FaceVertices { - let left_back_top_pos = Vec3 { - x: -(creation_spec.width / 2.0), - y: creation_spec.height / 2.0, - z: creation_spec.depth / 2.0, - }; + fn new(face: Face, vertex_data: &VertexData) -> Self + { + Self { + vertices: face.vertices.map(|face_vertex| { + let vertex_pos = vertex_data + .vertex_positions + .get(face_vertex.pos_index as usize) + .expect("Vertex position index is out of bounds") + .clone(); + + let vertex_normal = vertex_data + .vertex_normals + .get(face_vertex.normal_index as usize) + .expect("Vertex normal index is out of bounds") + .clone(); + + VertexBuilder::default() + .pos(vertex_pos) + .normal(vertex_normal) + .build() + }), + } + } - let left_back_bottom_pos = Vec3 { - x: -(creation_spec.width / 2.0), - y: -(creation_spec.height / 2.0), - z: creation_spec.depth / 2.0, - }; + fn with_full_per_side_tex_coords(mut self, face_location: FaceLocation) -> Self + { + match face_location { + FaceLocation::RightUp => { + self.vertices[0].texture_coords = Vec2 { x: 1.0, y: 1.0 }; + self.vertices[1].texture_coords = Vec2 { x: 0.0, y: 1.0 }; + self.vertices[2].texture_coords = Vec2 { x: 1.0, y: 0.0 }; + } + FaceLocation::LeftDown => { + self.vertices[0].texture_coords = Vec2 { x: 0.0, y: 1.0 }; + self.vertices[1].texture_coords = Vec2 { x: 0.0, y: 0.0 }; + self.vertices[2].texture_coords = Vec2 { x: 1.0, y: 0.0 }; + } + }; + + self + } +} - let left_front_top_pos = Vec3 { - x: -(creation_spec.width / 2.0), - y: creation_spec.height / 2.0, - z: -(creation_spec.depth / 2.0), - }; +#[derive(Debug)] +struct Face +{ + vertices: [FaceVertex; 3], + side: Side, +} - let left_front_bottom_pos = Vec3 { - x: -(creation_spec.width / 2.0), - y: -(creation_spec.height / 2.0), - z: -(creation_spec.depth / 2.0), - }; +#[derive(Debug, PartialEq, Eq, Hash, Clone)] +struct FaceVertex +{ + pos_index: u32, + normal_index: u32, +} - let left_normal = -calc_triangle_surface_normal( - &left_back_top_pos, - &left_back_bottom_pos, - &left_front_top_pos, - ); - - vertices[VertexIndex::LeftBackTop as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(left_back_top_pos) - .normal(left_normal), - Side::Left, - Corner::TopRight, - ) - .build(), - ); - - vertices[VertexIndex::LeftBackBottom as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(left_back_bottom_pos) - .normal(left_normal), - Side::Left, - Corner::BottomRight, - ) - .build(), - ); - - vertices[VertexIndex::LeftFrontTop as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(left_front_top_pos) - .normal(left_normal), - Side::Left, - Corner::TopLeft, - ) - .build(), - ); - - vertices[VertexIndex::LeftFrontBottom as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(left_front_bottom_pos) - .normal(left_normal), - Side::Left, - Corner::BottomLeft, - ) - .build(), - ); +#[derive(Debug)] +struct SidePositions +{ + up_left: Vec3<f32>, + up_right: Vec3<f32>, + down_left: Vec3<f32>, + down_right: Vec3<f32>, + normal_calc_order: NormalCalcOrder, + side: Side, } -fn create_top( - creation_spec: &CreationSpec, - vertices: &mut [Option<Vertex>], - vertex_builder_cb: &impl Fn(VertexBuilder, Side, Corner) -> VertexBuilder, -) +impl SidePositions { - let top_back_right_pos = Vec3 { - x: creation_spec.width / 2.0, - y: creation_spec.height / 2.0, - z: creation_spec.depth / 2.0, - }; + fn new_top(creation_spec: &CreationSpec) -> Self + { + let up_left = Vec3 { + x: -(creation_spec.width / 2.0), + y: creation_spec.height / 2.0, + z: creation_spec.depth / 2.0, + }; + + let down_right = Vec3 { + x: creation_spec.width / 2.0, + y: creation_spec.height / 2.0, + z: -(creation_spec.depth / 2.0), + }; + + Self { + up_left, + up_right: Vec3 { x: down_right.x, ..up_left.clone() }, + down_left: Vec3 { x: up_left.x, ..down_right.clone() }, + down_right, + normal_calc_order: NormalCalcOrder::Clockwise, + side: Side::Top, + } + } - let top_back_left_pos = Vec3 { - x: -(creation_spec.width / 2.0), - y: creation_spec.height / 2.0, - z: creation_spec.depth / 2.0, - }; + fn new_bottom(creation_spec: &CreationSpec) -> Self + { + let up_left = Vec3 { + x: -(creation_spec.width / 2.0), + y: -creation_spec.height / 2.0, + z: creation_spec.depth / 2.0, + }; + + let down_right = Vec3 { + x: creation_spec.width / 2.0, + y: -creation_spec.height / 2.0, + z: -(creation_spec.depth / 2.0), + }; + + Self { + up_left, + up_right: Vec3 { x: down_right.x, ..up_left.clone() }, + down_left: Vec3 { x: up_left.x, ..down_right.clone() }, + down_right, + normal_calc_order: NormalCalcOrder::CounterClockwise, + side: Side::Bottom, + } + } - let top_front_left_pos = Vec3 { - x: -(creation_spec.width / 2.0), - y: creation_spec.height / 2.0, - z: -(creation_spec.depth / 2.0), - }; + fn new_left(creation_spec: &CreationSpec) -> Self + { + let up_left = Vec3 { + x: -(creation_spec.width / 2.0), + y: creation_spec.height / 2.0, + z: -(creation_spec.depth / 2.0), + }; + + let down_right = Vec3 { + x: -(creation_spec.width / 2.0), + y: -(creation_spec.height / 2.0), + z: creation_spec.depth / 2.0, + }; + + Self { + up_left, + up_right: Vec3 { z: down_right.z, ..up_left.clone() }, + down_left: Vec3 { z: up_left.z, ..down_right.clone() }, + down_right, + normal_calc_order: NormalCalcOrder::CounterClockwise, + side: Side::Left, + } + } - let top_front_right_pos = Vec3 { - x: creation_spec.width / 2.0, - y: creation_spec.height / 2.0, - z: -(creation_spec.depth / 2.0), - }; + fn new_right(creation_spec: &CreationSpec) -> Self + { + let up_left = Vec3 { + x: (creation_spec.width / 2.0), + y: creation_spec.height / 2.0, + z: -(creation_spec.depth / 2.0), + }; + + let down_right = Vec3 { + x: (creation_spec.width / 2.0), + y: -(creation_spec.height / 2.0), + z: creation_spec.depth / 2.0, + }; + + Self { + up_left, + up_right: Vec3 { z: down_right.z, ..up_left.clone() }, + down_left: Vec3 { z: up_left.z, ..down_right.clone() }, + down_right, + normal_calc_order: NormalCalcOrder::Clockwise, + side: Side::Right, + } + } + + fn new_back(creation_spec: &CreationSpec) -> Self + { + let up_left = Vec3 { + x: -(creation_spec.width / 2.0), + y: creation_spec.height / 2.0, + z: -creation_spec.depth / 2.0, + }; + + let down_right = Vec3 { + x: creation_spec.width / 2.0, + y: -(creation_spec.height / 2.0), + z: -creation_spec.depth / 2.0, + }; + + Self { + up_left, + up_right: Vec3 { x: down_right.x, ..up_left.clone() }, + down_left: Vec3 { x: up_left.x, ..down_right.clone() }, + down_right, + normal_calc_order: NormalCalcOrder::Clockwise, + side: Side::Back, + } + } - let top_normal = -calc_triangle_surface_normal( - &top_back_right_pos, - &top_back_left_pos, - &top_front_right_pos, - ); - - vertices[VertexIndex::TopBackRight as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(top_back_right_pos) - .normal(top_normal), - Side::Top, - Corner::TopRight, - ) - .build(), - ); - - vertices[VertexIndex::TopBackLeft as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(top_back_left_pos) - .normal(top_normal), - Side::Top, - Corner::TopLeft, - ) - .build(), - ); - - vertices[VertexIndex::TopFrontLeft as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(top_front_left_pos) - .normal(top_normal), - Side::Top, - Corner::BottomLeft, - ) - .build(), - ); - - vertices[VertexIndex::TopFrontRight as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(top_front_right_pos) - .normal(top_normal), - Side::Top, - Corner::BottomRight, - ) - .build(), - ); + fn new_front(creation_spec: &CreationSpec) -> Self + { + let up_left = Vec3 { + x: -(creation_spec.width / 2.0), + y: creation_spec.height / 2.0, + z: creation_spec.depth / 2.0, + }; + + let down_right = Vec3 { + x: creation_spec.width / 2.0, + y: -(creation_spec.height / 2.0), + z: creation_spec.depth / 2.0, + }; + + Self { + up_left, + up_right: Vec3 { x: down_right.x, ..up_left.clone() }, + down_left: Vec3 { x: up_left.x, ..down_right.clone() }, + down_right, + normal_calc_order: NormalCalcOrder::CounterClockwise, + side: Side::Front, + } + } } -fn create_bottom( - creation_spec: &CreationSpec, - vertices: &mut [Option<Vertex>], - vertex_builder_cb: &impl Fn(VertexBuilder, Side, Corner) -> VertexBuilder, -) +#[derive(Debug)] +enum NormalCalcOrder { - let bottom_back_right_pos = Vec3 { - x: creation_spec.width / 2.0, - y: -(creation_spec.height / 2.0), - z: (creation_spec.depth / 2.0), - }; + Clockwise, + CounterClockwise, +} - let bottom_back_left_pos = Vec3 { - x: -(creation_spec.width / 2.0), - y: -(creation_spec.height / 2.0), - z: creation_spec.depth / 2.0, +fn create_side(side_positions: &SidePositions, data: &mut Data) +{ + let normal = match side_positions.normal_calc_order { + NormalCalcOrder::Clockwise => calc_triangle_surface_normal( + &side_positions.up_left, + &side_positions.up_right, + &side_positions.down_left, + ), + NormalCalcOrder::CounterClockwise => calc_triangle_surface_normal( + &side_positions.up_left, + &side_positions.down_left, + &side_positions.up_right, + ), }; - let bottom_front_right_pos = Vec3 { - x: creation_spec.width / 2.0, - y: -(creation_spec.height / 2.0), - z: -(creation_spec.depth / 2.0), - }; + data.vertex_data.vertex_normals.push(normal); - let bottom_front_left_pos = Vec3 { - x: -(creation_spec.width / 2.0), - y: -(creation_spec.height / 2.0), - z: -(creation_spec.depth / 2.0), - }; + let top_normal_index = data.vertex_data.vertex_normals.len() - 1; - let bottom_normal = calc_triangle_surface_normal( - &bottom_back_right_pos, - &bottom_back_left_pos, - &bottom_front_right_pos, - ); - - vertices[VertexIndex::BottomBackRight as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(bottom_back_right_pos) - .normal(bottom_normal), - Side::Bottom, - Corner::BottomRight, - ) - .build(), - ); - - vertices[VertexIndex::BottomBackLeft as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(bottom_back_left_pos) - .normal(bottom_normal), - Side::Bottom, - Corner::BottomLeft, - ) - .build(), - ); - - vertices[VertexIndex::BottomFrontRight as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(bottom_front_right_pos) - .normal(bottom_normal), - Side::Bottom, - Corner::TopRight, - ) - .build(), - ); - - vertices[VertexIndex::BottomFrontLeft as usize] = Some( - vertex_builder_cb( - VertexBuilder::default() - .pos(bottom_front_left_pos) - .normal(bottom_normal), - Side::Bottom, - Corner::TopLeft, - ) - .build(), - ); -} + data.vertex_data + .vertex_positions + .push(side_positions.up_right); -const VERTEX_INDICES_FRONT: [VertexIndex; 6] = [ - // 🮝 - VertexIndex::FrontTopRight, - VertexIndex::FrontBottomRight, - VertexIndex::FrontTopLeft, - // - // 🮟 - VertexIndex::FrontBottomRight, - VertexIndex::FrontBottomLeft, - VertexIndex::FrontTopLeft, -]; + let up_right_pos_index = data.vertex_data.vertex_positions.len() - 1; -const VERTEX_INDICES_BACK: [VertexIndex; 6] = [ - // 🮝 - VertexIndex::BackTopRight, - VertexIndex::BackBottomRight, - VertexIndex::BackTopLeft, - // - // 🮟 - VertexIndex::BackBottomRight, - VertexIndex::BackBottomLeft, - VertexIndex::BackTopLeft, -]; + data.vertex_data + .vertex_positions + .push(side_positions.up_left); -const VERTEX_INDICES_RIGHT: [VertexIndex; 6] = [ - // 🮝 - VertexIndex::RightBackTop, - VertexIndex::RightBackBottom, - VertexIndex::RightFrontTop, - // - // 🮟 - VertexIndex::RightBackBottom, - VertexIndex::RightFrontBottom, - VertexIndex::RightFrontTop, -]; + let up_left_pos_index = data.vertex_data.vertex_positions.len() - 1; -const VERTEX_INDICES_LEFT: [VertexIndex; 6] = [ - // 🮝 - VertexIndex::LeftBackTop, - VertexIndex::LeftBackBottom, - VertexIndex::LeftFrontTop, - // - // 🮟 - VertexIndex::LeftBackBottom, - VertexIndex::LeftFrontBottom, - VertexIndex::LeftFrontTop, -]; + data.vertex_data + .vertex_positions + .push(side_positions.down_left); -const VERTEX_INDICES_TOP: [VertexIndex; 6] = [ - // 🮝 - VertexIndex::TopBackRight, - VertexIndex::TopBackLeft, - VertexIndex::TopFrontRight, - // - // 🮟 - VertexIndex::TopBackLeft, - VertexIndex::TopFrontLeft, - VertexIndex::TopFrontRight, -]; + let down_left_pos_index = data.vertex_data.vertex_positions.len() - 1; + + data.vertex_data + .vertex_positions + .push(side_positions.down_right); + + let down_right_pos_index = data.vertex_data.vertex_positions.len() - 1; -const VERTEX_INDICES_BOTTOM: [VertexIndex; 6] = [ // 🮝 - VertexIndex::BottomBackRight, - VertexIndex::BottomBackLeft, - VertexIndex::BottomFrontRight, - // + data.faces.push(Face { + vertices: [ + FaceVertex { + pos_index: up_right_pos_index as u32, + normal_index: top_normal_index as u32, + }, + FaceVertex { + pos_index: up_left_pos_index as u32, + normal_index: top_normal_index as u32, + }, + FaceVertex { + pos_index: down_right_pos_index as u32, + normal_index: top_normal_index as u32, + }, + ], + side: side_positions.side, + }); + // 🮟 - VertexIndex::BottomBackLeft, - VertexIndex::BottomFrontLeft, - VertexIndex::BottomFrontRight, -]; - -const VERTEX_INDICES: [[VertexIndex; 6]; 6] = [ - VERTEX_INDICES_FRONT, - VERTEX_INDICES_BACK, - VERTEX_INDICES_RIGHT, - VERTEX_INDICES_LEFT, - VERTEX_INDICES_TOP, - VERTEX_INDICES_BOTTOM, -]; + data.faces.push(Face { + vertices: [ + FaceVertex { + pos_index: up_left_pos_index as u32, + normal_index: top_normal_index as u32, + }, + FaceVertex { + pos_index: down_left_pos_index as u32, + normal_index: top_normal_index as u32, + }, + FaceVertex { + pos_index: down_right_pos_index as u32, + normal_index: top_normal_index as u32, + }, + ], + side: side_positions.side, + }); +} diff --git a/engine/src/vertex.rs b/engine/src/vertex.rs index 5739323..30640c4 100644 --- a/engine/src/vertex.rs +++ b/engine/src/vertex.rs @@ -5,7 +5,7 @@ use crate::vector::{Vec2, Vec3}; builder! { #[builder(name = Builder, derives = (Debug, Default))] -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone, Default, PartialEq)] #[repr(C)] #[non_exhaustive] pub struct Vertex |