From 484e2295a2fae589c7b5c9ae05aba57867ae681a Mon Sep 17 00:00:00 2001 From: HampusM Date: Tue, 14 Apr 2026 16:22:44 +0200 Subject: refactor(engine): make mesh vertices dynamic --- engine/src/mesh/cube.rs | 209 ++++++++++++++++++------------------------------ 1 file changed, 79 insertions(+), 130 deletions(-) (limited to 'engine/src/mesh/cube.rs') diff --git a/engine/src/mesh/cube.rs b/engine/src/mesh/cube.rs index fe45a4a..dba6473 100644 --- a/engine/src/mesh/cube.rs +++ b/engine/src/mesh/cube.rs @@ -1,7 +1,14 @@ +use std::collections::HashMap; + use crate::builder; use crate::data_types::dimens::Dimens3; use crate::math::calc_triangle_surface_normal; -use crate::mesh::{Mesh, Vertex}; +use crate::mesh::vertex_buffer::{ + NamedVertexAttr, + VertexAttrInfo, + VertexBuffer as MeshVertexBuffer, +}; +use crate::mesh::{Mesh, POSITION_VERTEX_ATTRIB_NAME, VertexAttrType}; use crate::vector::{Vec2, Vec3}; builder! { @@ -39,29 +46,6 @@ impl CreationSpecBuilder } } -/// 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, -} - /// Describes what location on a side of a cube a face is. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum FaceLocation @@ -77,11 +61,10 @@ pub enum FaceLocation /// /// 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, - face_cb: impl FnMut(FaceVertices, Side, FaceLocation) -> FaceVertices, -) -> Mesh +pub fn create(creation_spec: CreationSpec) -> Mesh { + // TODO: Reimplement this mess + let mut data = Data::default(); create_side(&SidePositions::new_top(&creation_spec), &mut data); @@ -91,7 +74,7 @@ pub fn create( create_side(&SidePositions::new_back(&creation_spec), &mut data); create_side(&SidePositions::new_front(&creation_spec), &mut data); - data.into_mesh(face_cb) + data.into_mesh() } #[derive(Debug, Default)] @@ -110,88 +93,55 @@ struct VertexData impl Data { - fn into_mesh( - self, - mut face_cb: impl FnMut(FaceVertices, Side, FaceLocation) -> FaceVertices, - ) -> Mesh + fn into_mesh(self) -> Mesh { - let mut vertices = Vec::::with_capacity(self.faces.len() * 3); + let mut vertex_buf = MeshVertexBuffer::with_capacity( + &[ + VertexAttrInfo { + name: POSITION_VERTEX_ATTRIB_NAME.into(), + ty: VertexAttrType::Float32Array { length: 3 }, + }, + VertexAttrInfo { + name: "texture_coords".into(), + ty: VertexAttrType::Float32Array { length: 2 }, + }, + VertexAttrInfo { + name: "normal".into(), + ty: VertexAttrType::Float32Array { length: 3 }, + }, + ], + self.faces.len() * 3, + ); + let mut indices = Vec::::with_capacity(self.faces.len() * 3); + let mut added_face_vertices = HashMap::::new(); + let mut face_location = FaceLocation::RightUp; let Self { faces, vertex_data } = self; for face in faces { - let side = face.side; - - let face_vertices = face_cb( - FaceVertices::new(face, &vertex_data) - .with_full_per_side_tex_coords(face_location), - side, - face_location, - ); - - 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 face_texture_coords = match face_location { + FaceLocation::RightUp => [ + Vec2 { x: 1.0, y: 1.0 }, + Vec2 { x: 0.0, y: 1.0 }, + Vec2 { x: 1.0, y: 0.0 }, + ], + FaceLocation::LeftDown => [ + Vec2 { x: 0.0, y: 1.0 }, + Vec2 { x: 0.0, y: 0.0 }, + Vec2 { x: 1.0, y: 0.0 }, + ], + }; + + for (face_vertex, vertex_uv) in face.vertices.iter().zip(face_texture_coords) + { + if let Some(vertex_index) = added_face_vertices.get(face_vertex) { + indices.push(*vertex_index); continue; } - vertices.push(vertex); - - let vertex_index = u32::try_from(vertices.len() - 1) - .expect("Vertex index does not fit into 32-bit unsigned int"); - - indices.push(vertex_index); - } - - match face_location { - FaceLocation::RightUp => face_location = FaceLocation::LeftDown, - FaceLocation::LeftDown => face_location = FaceLocation::RightUp, - } - } - - Mesh::new(vertices, Some(indices)) - } -} - -/// 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], -} - -impl FaceVertices -{ - 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) @@ -204,30 +154,39 @@ impl FaceVertices .expect("Vertex normal index is out of bounds") .clone(); - Vertex::builder() - .pos(vertex_pos) - .normal(vertex_normal) - .build() - }), - } - } + vertex_buf.push(( + NamedVertexAttr { + name: POSITION_VERTEX_ATTRIB_NAME, + value: vertex_pos.into_array(), + }, + NamedVertexAttr { + name: "texture_coords", + value: vertex_uv.into_array(), + }, + NamedVertexAttr { + name: "normal", + value: vertex_normal.into_array(), + }, + )); + + let vertex_index = u32::try_from(vertex_buf.len() - 1) + .expect("Vertex index does not fit into 32-bit unsigned int"); - 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 }.into(); - self.vertices[1].texture_coords = Vec2 { x: 0.0, y: 1.0 }.into(); - self.vertices[2].texture_coords = Vec2 { x: 1.0, y: 0.0 }.into(); + indices.push(vertex_index); + + added_face_vertices.insert(face_vertex.clone(), vertex_index); } - FaceLocation::LeftDown => { - self.vertices[0].texture_coords = Vec2 { x: 0.0, y: 1.0 }.into(); - self.vertices[1].texture_coords = Vec2 { x: 0.0, y: 0.0 }.into(); - self.vertices[2].texture_coords = Vec2 { x: 1.0, y: 0.0 }.into(); + + match face_location { + FaceLocation::RightUp => face_location = FaceLocation::LeftDown, + FaceLocation::LeftDown => face_location = FaceLocation::RightUp, } - }; + } - self + Mesh::builder() + .vertices(vertex_buf) + .indices(indices) + .build() } } @@ -235,7 +194,6 @@ impl FaceVertices struct Face { vertices: [FaceVertex; 3], - side: Side, } #[derive(Debug, PartialEq, Eq, Hash, Clone)] @@ -253,7 +211,6 @@ struct SidePositions down_left: Vec3, down_right: Vec3, normal_calc_order: NormalCalcOrder, - side: Side, } impl SidePositions @@ -278,7 +235,6 @@ impl SidePositions down_left: Vec3 { x: up_left.x, ..down_right.clone() }, down_right, normal_calc_order: NormalCalcOrder::Clockwise, - side: Side::Top, } } @@ -302,7 +258,6 @@ impl SidePositions down_left: Vec3 { x: up_left.x, ..down_right.clone() }, down_right, normal_calc_order: NormalCalcOrder::CounterClockwise, - side: Side::Bottom, } } @@ -326,7 +281,6 @@ impl SidePositions down_left: Vec3 { z: up_left.z, ..down_right.clone() }, down_right, normal_calc_order: NormalCalcOrder::CounterClockwise, - side: Side::Left, } } @@ -350,7 +304,6 @@ impl SidePositions down_left: Vec3 { z: up_left.z, ..down_right.clone() }, down_right, normal_calc_order: NormalCalcOrder::Clockwise, - side: Side::Right, } } @@ -374,7 +327,6 @@ impl SidePositions down_left: Vec3 { x: up_left.x, ..down_right.clone() }, down_right, normal_calc_order: NormalCalcOrder::Clockwise, - side: Side::Back, } } @@ -398,7 +350,6 @@ impl SidePositions down_left: Vec3 { x: up_left.x, ..down_right.clone() }, down_right, normal_calc_order: NormalCalcOrder::CounterClockwise, - side: Side::Front, } } } @@ -469,7 +420,6 @@ fn create_side(side_positions: &SidePositions, data: &mut Data) normal_index: top_normal_index as u32, }, ], - side: side_positions.side, }); // 🮟 @@ -488,6 +438,5 @@ fn create_side(side_positions: &SidePositions, data: &mut Data) normal_index: top_normal_index as u32, }, ], - side: side_positions.side, }); } -- cgit v1.2.3-18-g5258