From 00c90916e58f891e948f7a7fa73d6b19575c3041 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Mon, 4 Nov 2024 20:18:04 +0200 Subject: [PATCH] feat(walls): draw tile walls --- src/lib.rs | 2 +- src/maze/grid.rs | 4 +- src/maze/plugin.rs | 9 ++- src/maze/prism.rs | 127 ++++++++++++++++++++++++++++++++++++------- src/maze/resource.rs | 14 ++--- 5 files changed, 118 insertions(+), 38 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 843efe6..f1e343c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -91,7 +91,7 @@ fn spawn_camera(mut commands: Commands) { commands.spawn(( Name::new("Camera"), Camera3dBundle { - transform: Transform::from_xyz(0., 100., 100.).looking_at(Vec3::ZERO, Vec3::Y), + transform: Transform::from_xyz(0., 300., 300.).looking_at(Vec3::ZERO, Vec3::Y), ..default() }, // Render all UI to this camera. diff --git a/src/maze/grid.rs b/src/maze/grid.rs index 98b41a1..bc4bc78 100644 --- a/src/maze/grid.rs +++ b/src/maze/grid.rs @@ -17,7 +17,7 @@ use hexx::{EdgeDirection, Hex}; use rand::{prelude::SliceRandom, rngs::ThreadRng, thread_rng}; use super::{ - resource::{Layout, MazeConfig}, + resource::{Layout, MazeConfig, HEX_SIZE}, tile::{Tile, TileBundle, Walls}, }; @@ -213,7 +213,7 @@ pub(super) fn render_maze( add_hex_tile( &mut commands, world_pos, - config.size, + HEX_SIZE, tile, walls, fill_color, diff --git a/src/maze/plugin.rs b/src/maze/plugin.rs index 8ff67cf..d59f509 100644 --- a/src/maze/plugin.rs +++ b/src/maze/plugin.rs @@ -1,6 +1,5 @@ use bevy::{ ecs::{system::RunSystemOnce, world::Command}, - pbr::wireframe::WireframePlugin, prelude::*, }; @@ -13,10 +12,10 @@ impl Plugin for MazePlugin { fn build(&self, app: &mut App) { app.add_plugins(prism::plugin); app.add_plugins(grid::plugin); - app.insert_resource(AmbientLight { - brightness: f32::MAX, - color: Color::WHITE, - }); + // app.insert_resource(AmbientLight { + // brightness: f32::MAX, + // color: Color::WHITE, + // }); } } diff --git a/src/maze/prism.rs b/src/maze/prism.rs index d5b27f9..c6d649c 100644 --- a/src/maze/prism.rs +++ b/src/maze/prism.rs @@ -1,12 +1,15 @@ -use bevy::{pbr::wireframe::Wireframe, prelude::*}; -use std::f32::consts::FRAC_PI_2; +use bevy::{pbr::UvChannel, prelude::*}; +use core::f32; +use hexx::{EdgeDirection, GridEdge, Hex}; +use std::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_6}; use super::{ - resource::{Layout, MazeConfig}, + resource::{Layout, MazeConfig, HEX_SIZE}, tile::Tile, }; pub(super) fn plugin(_app: &mut App) {} +const WALL_SIZE: f32 = 1.0; pub(super) fn setup( mut commands: Commands, @@ -17,11 +20,8 @@ pub(super) fn setup( ) { let radius = config.radius as i32; - let rotation = Quat::from_rotation_x(-FRAC_PI_2); - let material = materials.add(Color::WHITE); - let prism_mesh = generate_hex_prism_mesh(layout.hex_size.x, config.height); - let mesh = meshes.add(prism_mesh); - + let assets = create_base_assets(&mut meshes, &mut materials, &config); + // spawn_single_hex_tile(&mut commands, &assets, &config); commands .spawn(( Name::new("Floor"), @@ -30,33 +30,118 @@ pub(super) fn setup( ..default() }, )) - .with_children(|p| { + .with_children(|mut parent| { for q in -radius..=radius { let r1 = (-radius).max(-q - radius); let r2 = radius.min(-q + radius); for r in r1..=r2 { let tile = Tile::new(q, r); - let pos = tile.to_vec3(&layout); - p.spawn(( - Name::new(format!("Hex {}", &tile.to_string())), - PbrBundle { - mesh: mesh.clone(), - material: material.clone(), - transform: Transform::from_translation(pos).with_rotation(rotation), - ..default() - }, - )); + spawn_single_hex_tile(&mut parent, &tile, &layout, &assets, &config); } } }); } -fn generate_hex_prism_mesh(radius: f32, depth: f32) -> Mesh { +fn spawn_single_hex_tile( + parent: &mut ChildBuilder, + tile: &Tile, + layout: &Res, + assets: &MazeAssets, + config: &Res, +) { + let pos = tile.to_vec3(&layout); + parent + .spawn(( + Name::new(format!("Hex {}", &tile.to_string())), + PbrBundle { + mesh: assets.hex_mesh.clone(), + material: assets.hex_material.clone(), + transform: Transform::from_translation(pos), + ..default() + }, + )) + .with_children(|parent| spawn_walls(parent, assets, config)); +} + +fn spawn_walls(parent: &mut ChildBuilder, asstets: &MazeAssets, config: &Res) { + let y_offset = config.height / 2.; + let z_rotation = Quat::from_rotation_z(-FRAC_PI_2); + + for i in 0..6 { + let wall_angle = FRAC_PI_3 * i as f32; + + let x_offset = (HEX_SIZE - WALL_SIZE) * f32::cos(wall_angle); + let z_offset = (HEX_SIZE - WALL_SIZE) * f32::sin(wall_angle); + let pos = Vec3::new(x_offset, y_offset, z_offset); + + let x_rotation = Quat::from_rotation_x(wall_angle + FRAC_PI_2); + let final_rotation = z_rotation * x_rotation; + + spawn_single_wall(parent, asstets, final_rotation, pos); + } +} + +fn spawn_single_wall( + parent: &mut ChildBuilder, + asstets: &MazeAssets, + rotation: Quat, + offset: Vec3, +) { + parent.spawn(( + Name::new("Wall"), + PbrBundle { + mesh: asstets.wall_mesh.clone(), + material: asstets.wall_material.clone(), + transform: Transform::from_translation(offset).with_rotation(rotation), + ..default() + }, + )); +} + +fn create_base_assets( + meshes: &mut ResMut>, + materials: &mut ResMut>, + config: &Res, +) -> MazeAssets { + MazeAssets { + hex_mesh: meshes.add(generate_hex_mesh(HEX_SIZE, config.height)), + wall_mesh: meshes.add(generate_square_mesh(HEX_SIZE)), + hex_material: materials.add(white_material()), + wall_material: materials.add(Color::BLACK), + } +} + +fn generate_hex_mesh(radius: f32, depth: f32) -> Mesh { let hexagon = RegularPolygon { sides: 6, circumcircle: Circle::new(radius), }; let prism_shape = Extrusion::new(hexagon, depth); + let rotation = Quat::from_rotation_x(FRAC_PI_2); - Mesh::from(prism_shape) + Mesh::from(prism_shape).rotated_by(rotation) +} + +fn generate_square_mesh(depth: f32) -> Mesh { + let square = Rectangle::new(WALL_SIZE, WALL_SIZE); + let rectangular_prism = Extrusion::new(square, depth); + let rotation = Quat::from_rotation_x(FRAC_PI_2); + + Mesh::from(rectangular_prism).rotated_by(rotation) +} + +fn white_material() -> StandardMaterial { + let val = 10.; + StandardMaterial { + base_color: Color::WHITE, + emissive: LinearRgba::new(val, val, val, val), + ..default() + } +} + +struct MazeAssets { + hex_mesh: Handle, + wall_mesh: Handle, + hex_material: Handle, + wall_material: Handle, } diff --git a/src/maze/resource.rs b/src/maze/resource.rs index b12ad2b..a3c5326 100644 --- a/src/maze/resource.rs +++ b/src/maze/resource.rs @@ -2,11 +2,12 @@ use bevy::prelude::*; use hexx::{Hex, HexLayout, HexOrientation}; use rand::{thread_rng, Rng}; +pub(crate) const HEX_SIZE: f32 = 6.; + #[derive(Debug, Reflect, Resource)] #[reflect(Resource)] pub struct MazeConfig { pub radius: u32, - pub size: f32, pub height: f32, pub start_pos: Hex, pub end_pos: Hex, @@ -28,8 +29,7 @@ impl Default for MazeConfig { debug!("End pos: ({},{})", end_pos.x, end_pos.y); Self { radius: radius as u32, - size: 1., - height: 15., + height: 20., start_pos, end_pos, } @@ -41,14 +41,10 @@ impl Default for MazeConfig { pub struct Layout(pub HexLayout); impl FromWorld for Layout { - fn from_world(world: &mut World) -> Self { - let size = world - .get_resource::() - .unwrap_or(&MazeConfig::default()) - .size; + fn from_world(_world: &mut World) -> Self { Self(HexLayout { orientation: HexOrientation::Pointy, - hex_size: Vec2::splat(size), + hex_size: Vec2::splat(HEX_SIZE), ..default() }) }