summaryrefslogtreecommitdiff
path: root/engine/src/mesh/cube.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/mesh/cube.rs')
-rw-r--r--engine/src/mesh/cube.rs209
1 files changed, 79 insertions, 130 deletions
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::<Vertex>::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::<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 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<f32>,
down_right: Vec3<f32>,
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,
});
}