diff options
Diffstat (limited to 'engine/src/mesh/cube.rs')
| -rw-r--r-- | engine/src/mesh/cube.rs | 443 |
1 files changed, 0 insertions, 443 deletions
diff --git a/engine/src/mesh/cube.rs b/engine/src/mesh/cube.rs deleted file mode 100644 index a89466a..0000000 --- a/engine/src/mesh/cube.rs +++ /dev/null @@ -1,443 +0,0 @@ -use std::collections::HashMap; - -use crate::builder; -use crate::data_types::dimens::Dimens3; -use crate::math::calc_triangle_surface_normal; -use crate::mesh::vertex_buffer::{ - NamedVertexAttr, - VertexAttrInfo, - VertexBuffer as MeshVertexBuffer, - VertexLabel, -}; -use crate::mesh::{Mesh, VertexAttrType}; -use crate::vector::{Vec2, Vec3}; - -builder! { -/// Cube mesh creation specification. -#[builder(name = CreationSpecBuilder, derives = (Debug, Default))] -#[derive(Debug, Default)] -#[non_exhaustive] -pub struct CreationSpec -{ - pub width: f32, - pub height: f32, - pub depth: f32, -} -} - -impl CreationSpec -{ - /// Returns a new `CreationSpec` builder. - #[must_use] - pub fn builder() -> CreationSpecBuilder - { - CreationSpecBuilder::default() - } -} - -impl CreationSpecBuilder -{ - pub fn dimens(mut self, dimens: Dimens3<f32>) -> Self - { - self.width = dimens.width; - self.height = dimens.height; - self.depth = dimens.depth; - - self - } -} - -/// Describes what location on a side of a cube a face is. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub enum FaceLocation -{ - /// 🮝 - 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) -> Mesh -{ - // TODO: Reimplement this mess - - let mut data = Data::default(); - - 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); - - data.into_mesh() -} - -#[derive(Debug, Default)] -struct Data -{ - faces: Vec<Face>, - vertex_data: VertexData, -} - -#[derive(Debug, Default)] -struct VertexData -{ - vertex_positions: Vec<Vec3<f32>>, - vertex_normals: Vec<Vec3<f32>>, -} - -impl Data -{ - fn into_mesh(self) -> Mesh - { - let mut vertex_buf = MeshVertexBuffer::with_capacity( - &[ - VertexAttrInfo { - label: VertexLabel::Position, - ty: VertexAttrType::Float32Array { length: 3 }, - }, - VertexAttrInfo { - label: VertexLabel::Uv, - ty: VertexAttrType::Float32Array { length: 2 }, - }, - VertexAttrInfo { - label: VertexLabel::Normal, - ty: VertexAttrType::Float32Array { length: 3 }, - }, - ], - self.faces.len() * 3, - ); - - let mut indices = Vec::<u32>::with_capacity(self.faces.len() * 3); - - let mut added_face_vertices = HashMap::<FaceVertex, u32>::new(); - - let mut face_location = FaceLocation::RightUp; - - let Self { faces, vertex_data } = self; - - for face in faces { - 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; - } - - 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(); - - vertex_buf.push(( - NamedVertexAttr { - label: VertexLabel::Position, - value: vertex_pos.into_array(), - }, - NamedVertexAttr { - label: VertexLabel::Uv, - value: vertex_uv.into_array(), - }, - NamedVertexAttr { - label: VertexLabel::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"); - - indices.push(vertex_index); - - added_face_vertices.insert(face_vertex.clone(), vertex_index); - } - - match face_location { - FaceLocation::RightUp => face_location = FaceLocation::LeftDown, - FaceLocation::LeftDown => face_location = FaceLocation::RightUp, - } - } - - Mesh::builder() - .vertices(vertex_buf) - .indices(indices) - .build() - } -} - -#[derive(Debug)] -struct Face -{ - vertices: [FaceVertex; 3], -} - -#[derive(Debug, PartialEq, Eq, Hash, Clone)] -struct FaceVertex -{ - pos_index: u32, - normal_index: u32, -} - -#[derive(Debug)] -struct SidePositions -{ - up_left: Vec3<f32>, - up_right: Vec3<f32>, - down_left: Vec3<f32>, - down_right: Vec3<f32>, - normal_calc_order: NormalCalcOrder, -} - -impl SidePositions -{ - 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, - } - } - - 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, - } - } - - 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, - } - } - - 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, - } - } - - 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, - } - } - - 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, - } - } -} - -#[derive(Debug)] -enum NormalCalcOrder -{ - Clockwise, - CounterClockwise, -} - -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, - ), - }; - - data.vertex_data.vertex_normals.push(normal); - - let top_normal_index = data.vertex_data.vertex_normals.len() - 1; - - data.vertex_data - .vertex_positions - .push(side_positions.up_right); - - let up_right_pos_index = data.vertex_data.vertex_positions.len() - 1; - - data.vertex_data - .vertex_positions - .push(side_positions.up_left); - - let up_left_pos_index = data.vertex_data.vertex_positions.len() - 1; - - data.vertex_data - .vertex_positions - .push(side_positions.down_left); - - 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; - - // 🮝 - 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, - }, - ], - }); - - // 🮟 - 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, - }, - ], - }); -} |
