diff options
Diffstat (limited to 'src/cube.rs')
-rw-r--r-- | src/cube.rs | 522 |
1 files changed, 522 insertions, 0 deletions
diff --git a/src/cube.rs b/src/cube.rs new file mode 100644 index 0000000..d81eb76 --- /dev/null +++ b/src/cube.rs @@ -0,0 +1,522 @@ +use engine::math::calc_triangle_surface_normal; +use engine::object::Builder as ObjectBuilder; +use engine::vector::Vec3; +use engine::vertex::{Builder as VertexBuilder, Vertex}; + +pub enum Side +{ + Front, + Back, + Left, + Right, + Top, + Bottom, +} + +pub enum Corner +{ + TopRight, + TopLeft, + BottomRight, + BottomLeft, +} + +pub fn create_cube( + vertex_builder_cb: impl Fn(VertexBuilder, Side, Corner) -> VertexBuilder, +) -> ObjectBuilder +{ + let mut vertices: [Option<Vertex>; VertexIndex::VARIANT_CNT] = + [(); VertexIndex::VARIANT_CNT].map(|()| None); + + let front_top_right_pos = Vec3 { x: 0.5, y: 0.5, z: -0.5 }; + let front_bottom_right_pos = Vec3 { x: 0.5, y: -0.5, z: -0.5 }; + let front_bottom_left_pos = Vec3 { x: -0.5, y: -0.5, z: -0.5 }; + let front_top_left_pos = Vec3 { x: -0.5, y: 0.5, z: -0.5 }; + + let front_normal = calc_triangle_surface_normal( + &front_top_right_pos, + &front_bottom_right_pos, + &front_top_left_pos, + ); + + vertices[VertexIndex::FrontTopRight as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(front_top_right_pos) + .normal(front_normal.clone()), + Side::Front, + Corner::TopRight, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::FrontBottomRight as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(front_bottom_right_pos) + .normal(front_normal.clone()), + Side::Front, + Corner::BottomRight, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::FrontBottomLeft as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(front_bottom_left_pos) + .normal(front_normal.clone()), + Side::Front, + Corner::BottomLeft, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::FrontTopLeft as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(front_top_left_pos) + .normal(front_normal.clone()), + Side::Front, + Corner::TopLeft, + ) + .build() + .unwrap(), + ); + + let back_top_right_pos = Vec3 { x: 0.5, y: 0.5, z: 0.5 }; + let back_bottom_right_pos = Vec3 { x: 0.5, y: -0.5, z: 0.5 }; + let back_bottom_left_pos = Vec3 { x: -0.5, y: -0.5, z: 0.5 }; + let back_top_left_pos = Vec3 { x: -0.5, y: 0.5, z: 0.5 }; + + let back_normal = -calc_triangle_surface_normal( + &back_top_right_pos, + &back_bottom_right_pos, + &back_top_left_pos, + ); + + vertices[VertexIndex::BackTopRight as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(back_top_right_pos) + .normal(back_normal.clone()), + Side::Back, + Corner::TopRight, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::BackBottomRight as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(back_bottom_right_pos) + .normal(back_normal.clone()), + Side::Back, + Corner::BottomRight, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::BackBottomLeft as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(back_bottom_left_pos) + .normal(back_normal.clone()), + Side::Back, + Corner::BottomLeft, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::BackTopLeft as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(back_top_left_pos) + .normal(back_normal), + Side::Back, + Corner::TopLeft, + ) + .build() + .unwrap(), + ); + + let right_back_top_pos = Vec3 { x: 0.5, y: 0.5, z: 0.5 }; + let right_back_bottom_pos = Vec3 { x: 0.5, y: -0.5, z: 0.5 }; + let right_front_top_pos = Vec3 { x: 0.5, y: 0.5, z: -0.5 }; + let right_front_bottom_pos = Vec3 { x: 0.5, y: -0.5, z: -0.5 }; + + let right_normal = calc_triangle_surface_normal( + &right_back_top_pos, + &right_back_bottom_pos, + &right_front_top_pos, + ); + + vertices[VertexIndex::RightBackTop as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(right_back_top_pos) + .normal(right_normal.clone()), + Side::Right, + Corner::TopLeft, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::RightBackBottom as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(right_back_bottom_pos) + .normal(right_normal.clone()), + Side::Right, + Corner::BottomLeft, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::RightFrontTop as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(right_front_top_pos) + .normal(right_normal.clone()), + Side::Right, + Corner::TopRight, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::RightFrontBottom as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(right_front_bottom_pos) + .normal(right_normal), + Side::Right, + Corner::BottomRight, + ) + .build() + .unwrap(), + ); + + let left_back_top_pos = Vec3 { x: -0.5, y: 0.5, z: 0.5 }; + let left_back_bottom_pos = Vec3 { x: -0.5, y: -0.5, z: 0.5 }; + let left_front_top_pos = Vec3 { x: -0.5, y: 0.5, z: -0.5 }; + let left_front_bottom_pos = Vec3 { x: -0.5, y: -0.5, z: -0.5 }; + + let left_normal = -calc_triangle_surface_normal( + &left_back_top_pos, + &left_back_bottom_pos, + &left_front_top_pos, + ); + + vertices[VertexIndex::LeftBackTop as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(left_back_top_pos) + .normal(left_normal.clone()), + Side::Left, + Corner::TopRight, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::LeftBackBottom as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(left_back_bottom_pos) + .normal(left_normal.clone()), + Side::Left, + Corner::BottomRight, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::LeftFrontTop as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(left_front_top_pos) + .normal(left_normal.clone()), + Side::Left, + Corner::TopLeft, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::LeftFrontBottom as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(left_front_bottom_pos) + .normal(left_normal), + Side::Left, + Corner::BottomLeft, + ) + .build() + .unwrap(), + ); + + let top_back_right_pos = Vec3 { x: 0.5, y: 0.5, z: 0.5 }; + let top_back_left_pos = Vec3 { x: -0.5, y: 0.5, z: 0.5 }; + let top_front_left_pos = Vec3 { x: -0.5, y: 0.5, z: -0.5 }; + let top_front_right_pos = Vec3 { x: 0.5, y: 0.5, z: -0.5 }; + + let top_normal = -calc_triangle_surface_normal( + &top_back_right_pos, + &top_back_left_pos, + &top_front_right_pos, + ); + + vertices[VertexIndex::TopBackRight as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(top_back_right_pos) + .normal(top_normal.clone()), + Side::Top, + Corner::TopRight, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::TopBackLeft as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(top_back_left_pos) + .normal(top_normal.clone()), + Side::Top, + Corner::TopLeft, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::TopFrontLeft as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(top_front_left_pos) + .normal(top_normal.clone()), + Side::Top, + Corner::BottomLeft, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::TopFrontRight as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(top_front_right_pos) + .normal(top_normal), + Side::Top, + Corner::BottomRight, + ) + .build() + .unwrap(), + ); + + let bottom_back_right_pos = Vec3 { x: 0.5, y: -0.5, z: 0.5 }; + let bottom_back_left_pos = Vec3 { x: -0.5, y: -0.5, z: 0.5 }; + let bottom_front_right_pos = Vec3 { x: 0.5, y: -0.5, z: -0.5 }; + let bottom_front_left_pos = Vec3 { x: -0.5, y: -0.5, z: -0.5 }; + + let bottom_normal = calc_triangle_surface_normal( + &bottom_back_right_pos, + &bottom_back_left_pos, + &bottom_front_right_pos, + ); + + vertices[VertexIndex::BottomBackRight as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(bottom_back_right_pos) + .normal(bottom_normal.clone()), + Side::Bottom, + Corner::BottomRight, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::BottomBackLeft as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(bottom_back_left_pos) + .normal(bottom_normal.clone()), + Side::Bottom, + Corner::BottomLeft, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::BottomFrontRight as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(bottom_front_right_pos) + .normal(bottom_normal.clone()), + Side::Bottom, + Corner::TopRight, + ) + .build() + .unwrap(), + ); + + vertices[VertexIndex::BottomFrontLeft as usize] = Some( + vertex_builder_cb( + VertexBuilder::new() + .pos(bottom_front_left_pos) + .normal(bottom_normal), + Side::Bottom, + Corner::TopLeft, + ) + .build() + .unwrap(), + ); + + let front = [ + // 🮝 + VertexIndex::FrontTopRight, + VertexIndex::FrontBottomRight, + VertexIndex::FrontTopLeft, + // + // 🮟 + VertexIndex::FrontBottomRight, + VertexIndex::FrontBottomLeft, + VertexIndex::FrontTopLeft, + ]; + + let back = [ + // 🮝 + VertexIndex::BackTopRight, + VertexIndex::BackBottomRight, + VertexIndex::BackTopLeft, + // + // 🮟 + VertexIndex::BackBottomRight, + VertexIndex::BackBottomLeft, + VertexIndex::BackTopLeft, + ]; + + let right = [ + // 🮝 + VertexIndex::RightBackTop, + VertexIndex::RightBackBottom, + VertexIndex::RightFrontTop, + // + // 🮟 + VertexIndex::RightBackBottom, + VertexIndex::RightFrontBottom, + VertexIndex::RightFrontTop, + ]; + + let left = [ + // 🮝 + VertexIndex::LeftBackTop, + VertexIndex::LeftBackBottom, + VertexIndex::LeftFrontTop, + // + // 🮟 + VertexIndex::LeftBackBottom, + VertexIndex::LeftFrontBottom, + VertexIndex::LeftFrontTop, + ]; + + let top = [ + // 🮝 + VertexIndex::TopBackRight, + VertexIndex::TopBackLeft, + VertexIndex::TopFrontRight, + // + // 🮟 + VertexIndex::TopBackLeft, + VertexIndex::TopFrontLeft, + VertexIndex::TopFrontRight, + ]; + + let bottom = [ + // 🮝 + VertexIndex::BottomBackRight, + VertexIndex::BottomBackLeft, + VertexIndex::BottomFrontRight, + // + // 🮟 + VertexIndex::BottomBackLeft, + VertexIndex::BottomFrontLeft, + VertexIndex::BottomFrontRight, + ]; + + let indices = [front, back, right, left, top, bottom]; + + ObjectBuilder::new() + .vertices(vertices.map(Option::unwrap)) + .indices(indices.into_iter().flatten().map(|index| index as u32)) +} + +macro_rules! one { + ($tt: tt) => { + 1 + }; +} + +macro_rules! enum_with_variant_cnt { + ( + $(#[$attr: meta])* + enum $name: ident { + $($variant: ident,)* + } + ) => { + $(#[$attr])* + enum $name { + $($variant,)* + } + + impl $name { + const VARIANT_CNT: usize = 0 $(+ one!($variant))*; + } + }; +} + +enum_with_variant_cnt! { +#[repr(u32)] +enum VertexIndex +{ + FrontTopRight, + FrontBottomRight, + FrontBottomLeft, + FrontTopLeft, + + BackTopRight, + BackBottomRight, + BackBottomLeft, + BackTopLeft, + + RightBackTop, + RightBackBottom, + RightFrontTop, + RightFrontBottom, + + LeftBackTop, + LeftBackBottom, + LeftFrontTop, + LeftFrontBottom, + + TopBackRight, + TopBackLeft, + TopFrontRight, + TopFrontLeft, + + BottomBackRight, + BottomBackLeft, + BottomFrontRight, + BottomFrontLeft, +} +} |