diff options
| author | HampusM <hampus@hampusmat.com> | 2026-09-12 12:15:08 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-09-12 12:15:08 +0200 |
| commit | de530482a01828c065801bf1bc18617108b7ae40 (patch) | |
| tree | fe2d7f97cd68f7e856075acc1df5193570e3f175 /engine/src/mesh.rs | |
| parent | 6eefb4d3a03d8ba4f3e7f5494831d6417b8dcc12 (diff) | |
feat(engine): make cube mesh UVs specifiable
Diffstat (limited to 'engine/src/mesh.rs')
| -rw-r--r-- | engine/src/mesh.rs | 263 |
1 files changed, 227 insertions, 36 deletions
diff --git a/engine/src/mesh.rs b/engine/src/mesh.rs index c0120a2..fff5804 100644 --- a/engine/src/mesh.rs +++ b/engine/src/mesh.rs @@ -4,7 +4,7 @@ use zerocopy::IntoBytes; use crate::data_types::dimens::Dimens3; use crate::mesh::vertex_buffer::{VertexAttrProperties, VertexLabel}; -use crate::vector::Vec3; +use crate::vector::{Vec2, Vec3}; pub mod vertex_buffer; @@ -19,43 +19,107 @@ impl Mesh { pub fn cube(size: Dimens3<f32>) -> Self { + Self::cube_with_options(CubeOptions::default().size(size)) + } + + pub fn cube_with_options(options: CubeOptions) -> Self + { + let CubeOptions { + size, + top_face: + CubeFaceOptions { + uv_max: top_uv_max, + uv_min: top_uv_min, + }, + bottom_face: + CubeFaceOptions { + uv_max: bot_uv_max, + uv_min: bot_uv_min, + }, + left_face: + CubeFaceOptions { + uv_max: left_uv_max, + uv_min: left_uv_min, + }, + right_face: + CubeFaceOptions { + uv_max: right_uv_max, + uv_min: right_uv_min, + }, + back_face: + CubeFaceOptions { + uv_max: back_uv_max, + uv_min: back_uv_min, + }, + front_face: + CubeFaceOptions { + uv_max: front_uv_max, + uv_min: front_uv_min, + }, + } = options; + 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, - ]; + #[inline(always)] + fn vertex(pos: [f32; 3], uv: [f32; 2], normal: Vec3<f32>) -> [f32; 8] + { + let [pos_x, pos_y, pos_z] = pos; + let [uv_x, uv_y] = uv; + + [ + pos_x, pos_y, pos_z, uv_x, uv_y, normal.x, normal.y, normal.z, + ] + } + + let top_vertices = [ + ([half_w, half_h, half_d], [top_uv_max.x, top_uv_max.y]), + ([-half_w, half_h, half_d], [top_uv_min.x, top_uv_max.y]), + ([half_w, half_h, -half_d], [top_uv_max.x, top_uv_min.y]), + ([-half_w, half_h, -half_d], [top_uv_min.x, top_uv_min.y]), + ] + .map(|(pos, uv)| vertex(pos, uv, Vec3::UP)); + + let bottom_vertices = [ + ([half_w, -half_h, half_d], [bot_uv_max.x, bot_uv_max.y]), + ([-half_w, -half_h, half_d], [bot_uv_min.x, bot_uv_max.y]), + ([half_w, -half_h, -half_d], [bot_uv_max.x, bot_uv_min.y]), + ([-half_w, -half_h, -half_d], [bot_uv_min.x, bot_uv_min.y]), + ] + .map(|(pos, uv)| vertex(pos, uv, Vec3::DOWN)); + + let left_vertices = [ + ([-half_w, half_h, half_d], [left_uv_max.x, left_uv_max.y]), + ([-half_w, half_h, -half_d], [left_uv_min.x, left_uv_max.y]), + ([-half_w, -half_h, half_d], [left_uv_max.x, left_uv_min.y]), + ([-half_w, -half_h, -half_d], [left_uv_min.x, left_uv_min.y]), + ] + .map(|(pos, uv)| vertex(pos, uv, Vec3::LEFT)); + + let right_vertices = [ + ([half_w, half_h, half_d], [right_uv_max.x, right_uv_max.y]), + ([half_w, half_h, -half_d], [right_uv_min.x, right_uv_max.y]), + ([half_w, -half_h, half_d], [right_uv_max.x, right_uv_min.y]), + ([half_w, -half_h, -half_d], [right_uv_min.x, right_uv_min.y]), + ] + .map(|(pos, uv)| vertex(pos, uv, Vec3::RIGHT)); + + let back_vertices = [ + ([half_w, half_h, -half_d], [back_uv_max.x, back_uv_max.y]), + ([-half_w, half_h, -half_d], [back_uv_min.x, back_uv_max.y]), + ([half_w, -half_h, -half_d], [back_uv_max.x, back_uv_min.y]), + ([-half_w, -half_h, -half_d], [back_uv_min.x, back_uv_min.y]), + ] + .map(|(pos, uv)| vertex(pos, uv, Vec3::BACK)); + + let front_vertices = [ + ([half_w, half_h, half_d], [front_uv_max.x, front_uv_max.y]), + ([-half_w, half_h, half_d], [front_uv_min.x, front_uv_max.y]), + ([half_w, -half_h, half_d], [front_uv_max.x, front_uv_min.y]), + ([-half_w, -half_h, half_d], [front_uv_min.x, front_uv_min.y]), + ] + .map(|(pos, uv)| vertex(pos, uv, Vec3::FRONT)); Mesh::builder() .vertices(unsafe { @@ -80,10 +144,22 @@ impl Mesh byte_offset: size_of::<[f32; 3]>() + size_of::<[f32; 2]>(), }, ], - vertices.as_bytes().to_vec(), + [ + top_vertices, + bottom_vertices, + left_vertices, + right_vertices, + back_vertices, + front_vertices, + ] + .as_bytes() + .to_vec(), ) }) - .indices(elements) + .indices([ + 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, + ]) .build() } @@ -218,6 +294,121 @@ impl VertexAttrType } #[derive(Debug, Clone)] +#[non_exhaustive] +pub struct CubeOptions +{ + pub size: Dimens3<f32>, + pub top_face: CubeFaceOptions, + pub bottom_face: CubeFaceOptions, + pub front_face: CubeFaceOptions, + pub back_face: CubeFaceOptions, + pub left_face: CubeFaceOptions, + pub right_face: CubeFaceOptions, +} + +impl CubeOptions +{ + #[must_use] + pub fn size(mut self, size: Dimens3<f32>) -> Self + { + self.size = size; + self + } + + #[must_use] + pub fn top_face(mut self, top_face: CubeFaceOptions) -> Self + { + self.top_face = top_face; + self + } + + #[must_use] + pub fn bottom_face(mut self, bottom_face: CubeFaceOptions) -> Self + { + self.bottom_face = bottom_face; + self + } + + #[must_use] + pub fn front_face(mut self, front_face: CubeFaceOptions) -> Self + { + self.front_face = front_face; + self + } + + #[must_use] + pub fn back_face(mut self, back_face: CubeFaceOptions) -> Self + { + self.back_face = back_face; + self + } + + #[must_use] + pub fn left_face(mut self, left_face: CubeFaceOptions) -> Self + { + self.left_face = left_face; + self + } + + #[must_use] + pub fn right_face(mut self, right_face: CubeFaceOptions) -> Self + { + self.right_face = right_face; + self + } +} + +impl Default for CubeOptions +{ + fn default() -> Self + { + Self { + size: Dimens3 { width: 1.0, height: 1.0, depth: 1.0 }, + top_face: CubeFaceOptions::default(), + bottom_face: CubeFaceOptions::default(), + front_face: CubeFaceOptions::default(), + back_face: CubeFaceOptions::default(), + left_face: CubeFaceOptions::default(), + right_face: CubeFaceOptions::default(), + } + } +} + +#[derive(Debug, Clone)] +#[non_exhaustive] +pub struct CubeFaceOptions +{ + pub uv_max: Vec2<f32>, + pub uv_min: Vec2<f32>, +} + +impl CubeFaceOptions +{ + pub fn uv_max(mut self, uv_max: Vec2<f32>) -> Self + { + self.uv_max = uv_max; + self + } + + pub fn uv_min(mut self, uv_min: Vec2<f32>) -> Self + { + self.uv_min = uv_min; + self + } +} + +impl Default for CubeFaceOptions +{ + fn default() -> Self + { + Self { + uv_max: Vec2 { x: 1.0, y: 1.0 }, + uv_min: Vec2 { x: 0.0, y: 0.0 }, + } + } +} + +#[derive(Debug, Clone)] pub struct DirectionPositions { pub up: Vec3<f32>, |
