summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engine')
-rw-r--r--engine/src/mesh.rs76
-rw-r--r--engine/src/mesh/cube.rs443
-rw-r--r--engine/src/mesh/vertex_buffer.rs20
3 files changed, 94 insertions, 445 deletions
diff --git a/engine/src/mesh.rs b/engine/src/mesh.rs
index 82e2877..c0120a2 100644
--- a/engine/src/mesh.rs
+++ b/engine/src/mesh.rs
@@ -1,9 +1,11 @@
use std::alloc::Layout;
-use crate::mesh::vertex_buffer::VertexLabel;
+use zerocopy::IntoBytes;
+
+use crate::data_types::dimens::Dimens3;
+use crate::mesh::vertex_buffer::{VertexAttrProperties, VertexLabel};
use crate::vector::Vec3;
-pub mod cube;
pub mod vertex_buffer;
#[derive(Debug, Clone)]
@@ -15,6 +17,76 @@ pub struct Mesh
impl Mesh
{
+ pub fn cube(size: Dimens3<f32>) -> Self
+ {
+ let half_w = size.width / 2.0;
+ let half_h = size.height / 2.0;
+ let half_d = size.depth / 2.0;
+
+ let vertices = [
+ // pos.x, pos.y, pos.z, texture_coords.x, texture_coords.y, normal.x,
+ // normal.y, normal.z
+ [half_w, half_h, half_d, 1.00, 1.00, 0.0, 1.00, 0.0],
+ [-half_w, half_h, half_d, 0.0, 1.00, 0.0, 1.00, 0.0],
+ [half_w, half_h, -half_d, 1.00, 0.0, 0.0, 1.00, 0.0],
+ [-half_w, half_h, -half_d, 0.0, 0.0, 0.0, 1.00, 0.0],
+ [half_w, -half_h, half_d, 1.00, 1.00, 0.0, -1.00, 0.0],
+ [-half_w, -half_h, half_d, 0.0, 1.00, 0.0, -1.00, 0.0],
+ [half_w, -half_h, -half_d, 1.00, 0.0, 0.0, -1.00, 0.0],
+ [-half_w, -half_h, -half_d, 0.0, 0.0, 0.0, -1.00, 0.0],
+ [-half_w, half_h, half_d, 1.00, 1.00, -1.00, 0.0, 0.0],
+ [-half_w, half_h, -half_d, 0.0, 1.00, -1.00, 0.0, 0.0],
+ [-half_w, -half_h, half_d, 1.00, 0.0, -1.00, 0.0, 0.0],
+ [-half_w, -half_h, -half_d, 0.0, 0.0, -1.00, 0.0, 0.0],
+ [half_w, half_h, half_d, 1.00, 1.00, 1.00, 0.0, 0.0],
+ [half_w, half_h, -half_d, 0.0, 1.00, 1.00, 0.0, 0.0],
+ [half_w, -half_h, half_d, 1.00, 0.0, 1.00, 0.0, 0.0],
+ [half_w, -half_h, -half_d, 0.0, 0.0, 1.00, 0.0, 0.0],
+ [half_w, half_h, -half_d, 1.00, 1.00, 0.0, 0.0, -1.00],
+ [-half_w, half_h, -half_d, 0.0, 1.00, 0.0, 0.0, -1.00],
+ [half_w, -half_h, -half_d, 1.00, 0.0, 0.0, 0.0, -1.00],
+ [-half_w, -half_h, -half_d, 0.0, 0.0, 0.0, 0.0, -1.00],
+ [half_w, half_h, half_d, 1.00, 1.00, 0.0, 0.0, 1.00],
+ [-half_w, half_h, half_d, 0.0, 1.00, 0.0, 0.0, 1.00],
+ [half_w, -half_h, half_d, 1.00, 0.0, 0.0, 0.0, 1.00],
+ [-half_w, -half_h, half_d, 0.0, 0.0, 0.0, 0.0, 1.00],
+ ];
+
+ let elements = [
+ 0, 1, 2, 1, 3, 2, 4, 5, 6, 5, 7, 6, 8, 9, 10, 9, 11, 10, 12, 13, 14, 13, 15,
+ 14, 16, 17, 18, 17, 19, 18, 20, 21, 22, 21, 23, 22,
+ ];
+
+ Mesh::builder()
+ .vertices(unsafe {
+ vertex_buffer::VertexBuffer::from_raw(
+ &[
+ VertexAttrProperties {
+ label: VertexLabel::Position,
+ ty: VertexAttrType::Float32Array { length: 3 },
+ layout: Layout::new::<[f32; 3]>(),
+ byte_offset: 0,
+ },
+ VertexAttrProperties {
+ label: VertexLabel::Uv,
+ ty: VertexAttrType::Float32Array { length: 2 },
+ layout: Layout::new::<[f32; 2]>(),
+ byte_offset: size_of::<[f32; 3]>(),
+ },
+ VertexAttrProperties {
+ label: VertexLabel::Normal,
+ ty: VertexAttrType::Float32Array { length: 3 },
+ layout: Layout::new::<[f32; 3]>(),
+ byte_offset: size_of::<[f32; 3]>() + size_of::<[f32; 2]>(),
+ },
+ ],
+ vertices.as_bytes().to_vec(),
+ )
+ })
+ .indices(elements)
+ .build()
+ }
+
pub fn builder() -> Builder
{
Builder::default()
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,
- },
- ],
- });
-}
diff --git a/engine/src/mesh/vertex_buffer.rs b/engine/src/mesh/vertex_buffer.rs
index 4df3ffc..90e5752 100644
--- a/engine/src/mesh/vertex_buffer.rs
+++ b/engine/src/mesh/vertex_buffer.rs
@@ -73,6 +73,26 @@ pub struct VertexBuffer
impl VertexBuffer
{
+ pub unsafe fn from_raw(
+ vertex_attr_props: &[VertexAttrProperties],
+ buffer: Vec<u8>,
+ ) -> Self
+ {
+ let last_vertex_attr_props = vertex_attr_props
+ .iter()
+ .max_by_key(|props| props.byte_offset)
+ .expect("No vertex attribute properties are given");
+
+ let vertex_size =
+ last_vertex_attr_props.byte_offset + last_vertex_attr_props.layout.size();
+
+ Self {
+ buf: buffer,
+ vertex_size,
+ vertex_attr_props: vertex_attr_props.to_vec(),
+ }
+ }
+
pub fn with_capacity(vertex_attrs: &[VertexAttrInfo], capacity: usize) -> Self
{
let mut vertex_attr_props = vertex_attrs