summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2025-01-17 17:58:13 +0100
committerHampusM <hampus@hampusmat.com>2025-01-17 19:02:33 +0100
commit6fc7c0b2bf5547159b1d45c2ef9016df1f565dd8 (patch)
tree673c75bee5499a7887d583d2be3af356958090cc /engine
parent99dfc7b3c9f5721dae6a016a1171b451e97a4d7c (diff)
feat(engine): replace mesh::cube::create vertex cb with face cb
Diffstat (limited to 'engine')
-rw-r--r--engine/src/data_types/vector.rs4
-rw-r--r--engine/src/math.rs2
-rw-r--r--engine/src/mesh/cube.rs989
-rw-r--r--engine/src/vertex.rs2
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