summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engine/src/mesh.rs263
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>,