From c471382f6fd3293442fac66f90ee0df3c6b82880 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Sat, 12 Oct 2024 15:59:17 +0300 Subject: [PATCH] feat(grid): draw 3d hex grid --- src/lib.rs | 4 +- src/maze/mod.rs | 28 ++---------- src/maze/plugin.rs | 25 ++++++++++ src/maze/prism.rs | 106 ++++++++++++++++++++----------------------- src/maze/resource.rs | 4 +- src/maze/tile.rs | 11 ++++- 6 files changed, 93 insertions(+), 85 deletions(-) create mode 100644 src/maze/plugin.rs diff --git a/src/lib.rs b/src/lib.rs index d58e021..83b126f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -63,7 +63,7 @@ impl Plugin for AppPlugin { #[cfg(feature = "demo")] demo::plugin, #[cfg(not(feature = "demo"))] - maze::MazePlugin, + maze::plugin::MazePlugin::default(), screens::plugin, theme::plugin, )); @@ -91,7 +91,7 @@ fn spawn_camera(mut commands: Commands) { commands.spawn(( Name::new("Camera"), Camera3dBundle { - transform: Transform::from_xyz(0., 15., 10.).looking_at(Vec3::ZERO, Vec3::Y), + transform: Transform::from_xyz(0., 100., 0.).looking_at(Vec3::ZERO, Vec3::Y), ..default() }, // Render all UI to this camera. diff --git a/src/maze/mod.rs b/src/maze/mod.rs index 6392dd4..31264df 100644 --- a/src/maze/mod.rs +++ b/src/maze/mod.rs @@ -1,31 +1,11 @@ -use bevy::{ - ecs::{system::RunSystemOnce, world::Command}, - prelude::*, -}; -use grid::{generate_maze, plugin, render_maze, spawn_hex_grid}; +use bevy::{ecs::world::Command, prelude::*}; +use plugin::MazePlugin; pub mod grid; +pub mod plugin; pub mod prism; pub mod resource; pub mod tile; -pub struct MazePlugin; - -impl Plugin for MazePlugin { - fn build(&self, app: &mut App) { - app.add_plugins(prism::plugin); - app.add_plugins(plugin); - } -} - -impl Command for MazePlugin { - fn apply(self, world: &mut World) { - // world.run_system_once(spawn_hex_grid); - // world.run_system_once(generate_maze); - // world.run_system_once(render_maze); - world.run_system_once(prism::setup); - } -} - pub fn spawn_grid(world: &mut World) { - MazePlugin.apply(world); + MazePlugin::default().apply(world); } diff --git a/src/maze/plugin.rs b/src/maze/plugin.rs new file mode 100644 index 0000000..11584e0 --- /dev/null +++ b/src/maze/plugin.rs @@ -0,0 +1,25 @@ +use bevy::{ + ecs::{system::RunSystemOnce, world::Command}, + prelude::*, +}; + +use super::{grid, prism}; + +#[derive(Default)] +pub(crate) struct MazePlugin; + +impl Plugin for MazePlugin { + fn build(&self, app: &mut App) { + app.add_plugins(prism::plugin); + app.add_plugins(grid::plugin); + } +} + +impl Command for MazePlugin { + fn apply(self, world: &mut World) { + // world.run_system_once(spawn_hex_grid); + // world.run_system_once(generate_maze); + // world.run_system_once(render_maze); + world.run_system_once(prism::setup); + } +} diff --git a/src/maze/prism.rs b/src/maze/prism.rs index 9833d5d..8fd4119 100644 --- a/src/maze/prism.rs +++ b/src/maze/prism.rs @@ -1,48 +1,20 @@ use bevy::prelude::*; use std::f32::consts::FRAC_PI_2; +use super::{ + resource::{Layout, MazeConfig}, + tile::Tile, +}; + pub(super) fn plugin(app: &mut App) { - app.add_systems(Update, spawn_light); -} - -#[derive(Debug, Reflect, Component)] -#[reflect(Component)] -struct Prism { - radius: f32, - height: f32, -} - -struct PrismParams { - position: Vec3, - radius: f32, - height: f32, -} - -impl From for PrismParams { - fn from(value: Vec3) -> Self { - Self { - position: value, - ..default() - } - } -} - -impl Default for PrismParams { - fn default() -> Self { - Self { - position: Vec3::ZERO, - radius: 2., - height: 4., - } - } + app.add_systems(Startup, spawn_light); } pub(super) fn spawn_light(mut commands: Commands) { commands.spawn(( Name::new("Light Source"), PointLightBundle { - point_light: PointLight { ..default() }, - transform: Transform::from_xyz(5., 10., 5.), + transform: Transform::from_xyz(0., 50., 0.), ..default() }, )); @@ -52,31 +24,51 @@ pub(super) fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, + config: Res, + layout: Res, ) { - let prism_material = materials.add(Color::WHITE); + let radius = config.radius as i32; - let prisms: Vec = vec![Vec3::ZERO.into()]; + 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); - for params in prisms { - let hexagon = RegularPolygon { - sides: 6, - circumcircle: Circle::new(params.radius), - }; - let prism_shape = Extrusion::new(hexagon, params.height); - let prism_mesh = meshes.add(Mesh::from(prism_shape)); - - commands.spawn(( - PbrBundle { - mesh: prism_mesh, - material: prism_material.clone(), - transform: Transform::from_translation(params.position) - .with_rotation(Quat::from_rotation_x(FRAC_PI_2)), + commands + .spawn(( + Name::new("Floor"), + SpatialBundle { + transform: Transform::from_translation(Vec3::ZERO), ..default() }, - Prism { - radius: params.radius, - height: params.height, - }, - )); - } + )) + .with_children(|p| { + 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() + }, + )); + } + } + }); +} + +fn generate_hex_prism_mesh(radius: f32, depth: f32) -> Mesh { + let hexagon = RegularPolygon { + sides: 6, + circumcircle: Circle::new(radius), + }; + let prism_shape = Extrusion::new(hexagon, depth); + + Mesh::from(prism_shape) } diff --git a/src/maze/resource.rs b/src/maze/resource.rs index 7ecb034..e6485d2 100644 --- a/src/maze/resource.rs +++ b/src/maze/resource.rs @@ -7,6 +7,7 @@ use rand::{thread_rng, Rng}; pub struct MazeConfig { pub radius: u32, pub size: f32, + pub height: f32, pub start_pos: Hex, pub end_pos: Hex, } @@ -27,7 +28,8 @@ impl Default for MazeConfig { debug!("End pos: ({},{})", end_pos.x, end_pos.y); Self { radius: radius as u32, - size: 10., + size: 5., + height: 5., start_pos, end_pos, } diff --git a/src/maze/tile.rs b/src/maze/tile.rs index bda8302..0548edc 100644 --- a/src/maze/tile.rs +++ b/src/maze/tile.rs @@ -1,7 +1,7 @@ use std::fmt::Display; use bevy::prelude::*; -use hexx::Hex; +use hexx::{Hex, HexLayout}; #[derive(Debug, Reflect, Component, Default, PartialEq, Eq, Hash, Clone)] #[reflect(Component)] @@ -31,6 +31,15 @@ impl Tile { pub fn visit(&mut self) { self.visited = true; } + + pub fn to_vec2(&self, layout: &HexLayout) -> Vec2 { + layout.hex_to_world_pos(self.hex) + } + + pub fn to_vec3(&self, layout: &HexLayout) -> Vec3 { + let pos = self.to_vec2(layout); + Vec3::new(pos.x, 0., pos.y) + } } impl Display for Tile {