diff --git a/Cargo.toml b/Cargo.toml index d6a9e7c..709cd34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,14 +1,14 @@ [workspace] -members = [ - "game/main", - "engine/world_generation" -, "game/camera_system"] +members = [ + "game/main", + "engine/world_generation" + , "game/camera_system"] resolver = "2" # Enable a small amount of optimization in debug mode -[profile.dev] -opt-level = 1 +#[profile.dev] +#opt-level = 1 # Enable high optimizations for dependencies (incl. Bevy), but not for our code: [profile.dev.package."*"] diff --git a/engine/world_generation/src/hex_utils.rs b/engine/world_generation/src/hex_utils.rs index 3e1240e..288a573 100644 --- a/engine/world_generation/src/hex_utils.rs +++ b/engine/world_generation/src/hex_utils.rs @@ -5,151 +5,173 @@ pub const OUTER_RADIUS: f32 = 1.; pub const INNER_RADIUS: f32 = OUTER_RADIUS * 0.866025404; pub fn offset3d_to_world(offset: Vec3) -> Vec3 { - let x = (offset.x + offset.z * 0.5 - (offset.z / 2.).floor()) * (INNER_RADIUS * 2.); - return Vec3::new(x, offset.y, offset.z * OUTER_RADIUS * 1.5); + let x = (offset.x + (offset.z * 0.5) - (offset.z / 2.).floor()) * (INNER_RADIUS * 2.); + return Vec3::new(x, offset.y, offset.z * OUTER_RADIUS * 1.5); } -pub fn offset_to_world(offset: IVec2) -> Vec3 { - let x = (offset.x as f32 + offset.y as f32 * 0.5 - (offset.y as f32 / 2.).floor()) - * (INNER_RADIUS * 2.); - return Vec3::new(x, 0., offset.y as f32 * OUTER_RADIUS * 1.5); +pub fn offset_to_world(offset: IVec2, height: f32) -> Vec3 { + let off = offset.as_vec2(); + let x = (off.x + (off.y * 0.5) - (off.y / 2.).floor()) * (INNER_RADIUS * 2.); + return Vec3::new(x, height, off.y * OUTER_RADIUS * 1.5); } pub fn offset_to_hex(offset: IVec2) -> IVec3 { - return IVec3 { - x: offset.x, - y: offset.y, - z: -offset.x - offset.y, - }; + return IVec3 { + x: offset.x, + y: offset.y, + z: -offset.x - offset.y, + }; } pub fn snap_to_hex_grid(world_pos: Vec3) -> Vec3 { - return offset_to_world(world_to_offset_pos(world_pos)); + return offset_to_world(world_to_offset_pos(world_pos), world_pos.y); } pub fn world_to_offset_pos(world_pos: Vec3) -> IVec2 { - let offset = world_pos.z / (OUTER_RADIUS * 3.); - let x = (world_pos.x / (INNER_RADIUS * 2.)) - offset; - let z = -world_pos.x - offset; + let offset = world_pos.z / (OUTER_RADIUS * 3.); + let x = (world_pos.x / (INNER_RADIUS * 2.)) - offset; + let z = -world_pos.x - offset; - let ix = x.round() as i32; - let iz = z.round() as i32; - let ox = ix + iz / 2; - let oz = iz; - return IVec2::new(ox, oz); + let ix = x.round() as i32; + let iz = z.round() as i32; + let ox = ix + iz / 2; + let oz = iz; + return IVec2::new(ox, oz); } pub fn tile_to_world_distance(dist: i32) -> f32 { - return dist as f32 * (2. * INNER_RADIUS); + return dist as f32 * (2. * INNER_RADIUS); } -pub fn get_tile_count(radius: i32)->i32{ +pub fn get_tile_count(radius: i32) -> i32 { return 1 + 3 * (radius + 1) * radius; } -#[derive(Default, Clone, Copy)] +#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)] pub struct HexCoord { - pub hex: IVec3, - pub offset: IVec2, - pub world: Vec3, + pub hex: IVec3, } -impl PartialEq for HexCoord { - fn eq(&self, other: &Self) -> bool { - return self.offset == other.offset; - } -} - -impl Eq for HexCoord {} - impl HexCoord { - pub const DIRECTIONS: [IVec3; 6] = [ - IVec3::new(1, -1, 0), - IVec3::new(1, 0, -1), - IVec3::new(0, 1, -1), - IVec3::new(-1, 1, 0), - IVec3::new(-1, 0, 1), - IVec3::new(0, -1, 1), - ]; + pub const DIRECTIONS: [IVec3; 6] = [ + IVec3::new(1, 1, 0), + IVec3::new(1, 0, -1), + IVec3::new(1, -1, 0), + IVec3::new(0, -1, 1), + IVec3::new(-1, 0, 1), + IVec3::new(0, 1, -1), + ]; - pub const ZERO: HexCoord = HexCoord { - offset: IVec2::ZERO, - hex: IVec3::ZERO, - world: Vec3::ZERO, - }; + pub const ZERO: HexCoord = HexCoord { hex: IVec3::ZERO }; - pub fn new(x: i32, z: i32) -> Self { - return Self::from_offset(IVec2::new(x, z)); - } - pub fn from_grid_pos(x: usize, z: usize) -> Self { - return HexCoord::new(x as i32, z as i32); - } - pub fn from_offset(offset_pos: IVec2) -> Self { - return HexCoord { - offset: offset_pos, - hex: offset_to_hex(offset_pos), - world: offset3d_to_world(offset_pos.extend(0).xzy().as_vec3()), - }; - } + pub fn new(x: i32, z: i32) -> Self { + return Self::from_offset(IVec2::new(x, z)); + } + pub fn from_grid_pos(x: usize, z: usize) -> Self { + return HexCoord::new(x as i32, z as i32); + } + pub fn from_offset(offset_pos: IVec2) -> Self { + return HexCoord { + hex: offset_to_hex(offset_pos), + }; + } - pub fn to_chunk_pos(&self) -> IVec2 { - return IVec2 { - x: (self.offset.x as f32 / Chunk::SIZE as f32).floor() as i32, - y: (self.offset.y as f32 / Chunk::SIZE as f32).floor() as i32, - }; - } + pub fn is_in_bounds(&self, map_height: usize, map_width: usize) -> bool { + if self.hex.x < 0 || self.hex.y < 0 { + return false; + } - pub fn to_chunk_index(&self, width: usize) -> usize { - let pos = self.to_chunk_pos(); - return pos.x as usize + pos.y as usize * width; - } + if self.hex.x >= map_width as i32 || self.hex.y >= map_height as i32 { + return false; + } - pub fn distance(&self, other: &HexCoord) -> i32 { - return (self.hex.x - other.hex.x).abs() - + (self.hex.y - other.hex.y).abs() - + (self.hex.z - other.hex.z).abs(); - } + return true; + } - pub fn rotate_around(&self, center: &HexCoord, angle: i32) -> HexCoord { - if self == center || angle == 0 { - return self.clone(); - } + pub fn to_chunk_pos(&self) -> IVec2 { + return IVec2 { + x: (self.hex.x as f32 / Chunk::SIZE as f32).floor() as i32, + y: (self.hex.y as f32 / Chunk::SIZE as f32).floor() as i32, + }; + } - let mut a = angle % 6; - let mut pc = self.hex - center.hex; + pub fn to_chunk(&self) -> HexCoord { + let c_pos = self.to_chunk_pos(); + return HexCoord::from_offset( + ( + self.hex.x - (c_pos.x * Chunk::SIZE as i32), + self.hex.y - (c_pos.y * Chunk::SIZE as i32), + ) + .into(), + ); + } - if a > 0 { - for _ in 0..a { - pc = Self::slide_right(pc); - } - } else { - a = a.abs(); - for _ in 0..a { - pc = Self::slide_left(pc); - } - } - return HexCoord::from_offset(pc.xy() + center.hex.xy()); - } + pub fn to_world(&self, height: f32) -> Vec3 { + return offset_to_world(self.hex.xy(), height); + } - fn slide_left(hex: IVec3) -> IVec3 { - return (hex * -1).yzx(); - } + pub fn to_offset(&self) -> IVec2 { + return self.hex.xy(); + } - fn slide_right(hex: IVec3) -> IVec3 { - return (hex * -1).zxy(); - } + pub fn to_index(&self, width: usize) -> i32 { + return self.hex.x + self.hex.y * width as i32 + self.hex.y / 2; + } + pub fn to_chunk_index(&self, width: usize) -> i32 { + let pos = self.to_chunk_pos(); + return pos.x + pos.y * width as i32; + } - pub fn scale(&self, dir: i32, radius: usize)-> HexCoord{ + pub fn to_chunk_local_index(&self) -> i32 { + return self.to_chunk().to_index(Chunk::SIZE); + } + + pub fn distance(&self, other: &HexCoord) -> i32 { + return (self.hex.x - other.hex.x).abs() + + (self.hex.y - other.hex.y).abs() + + (self.hex.z - other.hex.z).abs(); + } + + pub fn rotate_around(&self, center: &HexCoord, angle: i32) -> HexCoord { + if self == center || angle == 0 { + return self.clone(); + } + + let mut a = angle % 6; + let mut pc = self.hex - center.hex; + + if a > 0 { + for _ in 0..a { + pc = Self::slide_right(pc); + } + } else { + a = a.abs(); + for _ in 0..a { + pc = Self::slide_left(pc); + } + } + return HexCoord::from_offset(pc.xy() + center.hex.xy()); + } + + fn slide_left(hex: IVec3) -> IVec3 { + return (hex * -1).yzx(); + } + + fn slide_right(hex: IVec3) -> IVec3 { + return (hex * -1).zxy(); + } + + pub fn scale(&self, dir: i32, radius: usize) -> HexCoord { let s = Self::DIRECTIONS[(dir % 6) as usize] * radius as i32; return Self::from_offset(self.hex.xy() + s.xy()); } - pub fn get_neighbor(&self, dir: usize)-> HexCoord{ + pub fn get_neighbor(&self, dir: usize) -> HexCoord { let d = Self::DIRECTIONS[dir % 6]; return Self::from_offset(self.hex.xy() + d.xy()); } - pub fn get_neighbors(&self) -> [HexCoord; 6]{ + pub fn get_neighbors(&self) -> [HexCoord; 6] { return [ self.get_neighbor(0), self.get_neighbor(1), @@ -157,6 +179,6 @@ impl HexCoord { self.get_neighbor(3), self.get_neighbor(4), self.get_neighbor(5), - ] + ]; } } diff --git a/engine/world_generation/src/lib.rs b/engine/world_generation/src/lib.rs index e4c6c42..70cff2d 100644 --- a/engine/world_generation/src/lib.rs +++ b/engine/world_generation/src/lib.rs @@ -1,5 +1,7 @@ pub mod prelude { + use crate::hex_utils::HexCoord; use bevy::math::IVec2; + use bevy::prelude::Resource; pub struct GenerationConfig { pub noise_scale: f64, @@ -26,24 +28,33 @@ pub mod prelude { impl Chunk { pub const SIZE: usize = 32; } + + #[derive(Resource)] pub struct Map { pub chunks: Vec, pub height: usize, pub width: usize, } + + impl Map { + pub fn get_neighbors(&self, pos: &HexCoord) -> [Option; 6] { + let mut results: [Option; 6] = [None; 6]; + let n_tiles = pos.get_neighbors(); + for i in 0..6 { + let n_tile = n_tiles[i]; + if !n_tile.is_in_bounds(self.height, self.width) { + continue; + } + let c_idx = n_tile.to_chunk_index(self.width); + let chunk = &self.chunks[c_idx as usize]; + let local = n_tile.to_chunk_local_index(); + results[i] = (Some(chunk.points[local as usize])); + } + return results; + } + } } pub mod heightmap; pub mod hex_utils; pub mod mesh_generator; - -#[cfg(test)] -mod tests { - use super::*; - - // #[test] - // fn it_works() { - // let result = add(2, 2); - // assert_eq!(result, 4); - // } -} diff --git a/engine/world_generation/src/mesh_generator.rs b/engine/world_generation/src/mesh_generator.rs index 1c275df..440252d 100644 --- a/engine/world_generation/src/mesh_generator.rs +++ b/engine/world_generation/src/mesh_generator.rs @@ -1,3 +1,4 @@ +use crate::hex_utils::HexCoord; use crate::{ hex_utils::{offset3d_to_world, INNER_RADIUS, OUTER_RADIUS}, prelude::*, @@ -19,7 +20,7 @@ const HEX_CORNERS: [Vec3; 6] = [ Vec3::new(-INNER_RADIUS, 0., 0.5 * OUTER_RADIUS), ]; -pub fn generate_chunk_mesh(chunk: &Chunk) -> Mesh { +pub fn generate_chunk_mesh(chunk: &Chunk, map: &Map) -> Mesh { let vertex_count: usize = Chunk::SIZE * Chunk::SIZE; let mut verts = Vec::with_capacity(vertex_count); let mut uvs = Vec::with_capacity(vertex_count); @@ -28,10 +29,22 @@ pub fn generate_chunk_mesh(chunk: &Chunk) -> Mesh { for z in 0..Chunk::SIZE { for x in 0..Chunk::SIZE { - let height = chunk.points[x + z * Chunk::SIZE]; + let coord = HexCoord::from_grid_pos(x, z); + let height = chunk.points[coord.to_index(Chunk::SIZE) as usize]; let off_pos = Vec3::new(x as f32, height, z as f32); let grid_pos = offset3d_to_world(off_pos); - create_tile(grid_pos, &mut verts, &mut uvs, &mut normals, &mut indices); + let n = map.get_neighbors(&HexCoord::from_offset( + coord.to_offset() + chunk.chunk_offset, + )); + create_tile( + grid_pos, + &n, + &mut verts, + &mut uvs, + &mut normals, + &mut indices, + 0, + ); } } @@ -51,10 +64,12 @@ pub fn generate_chunk_mesh(chunk: &Chunk) -> Mesh { //TODO: figure out texture index fn create_tile( pos: Vec3, + neighbors: &[Option; 6], verts: &mut Vec, uvs: &mut Vec, normals: &mut Vec, indices: &mut Vec, + texture_index: u32, ) { let idx = verts.len() as u32; let center = Vec3::new(pos.x, 0., pos.z); @@ -70,4 +85,69 @@ fn create_tile( indices.push(idx + 1 + i as u32); indices.push(idx + 1 + ((i as u32 + 1) % 6)); } + + for i in 0..neighbors.len() { + let cur_n = neighbors[i]; + match cur_n { + Some(n_height) => { + if true { + create_tile_wall( + pos, + i, + pos.y + 1., + verts, + uvs, + normals, + indices, + texture_index, + ); + } + } + _ => {} + } + } +} + +fn create_tile_wall( + pos: Vec3, + dir: usize, + height: f32, + verts: &mut Vec, + uvs: &mut Vec, + normals: &mut Vec, + indices: &mut Vec, + _texture_index: u32, +) { + println!("{dir}"); + let p1 = HEX_CORNERS[(dir + 1) % 6] + pos; + let p2 = HEX_CORNERS[(dir + 2) % 6] + pos; + let p3 = Vec3::new(p1.x, height, p1.z); + let p4 = Vec3::new(p2.x, height, p2.z); + + let normal = Vec3::Y; + + let idx = verts.len() as u32; + + verts.push(p1); + verts.push(p2); + verts.push(p3); + verts.push(p4); + + normals.push(normal); + normals.push(normal); + normals.push(normal); + normals.push(normal); + + indices.push(idx); + indices.push(idx + 2); + indices.push(idx + 1); + + indices.push(idx + 1); + indices.push(idx + 2); + indices.push(idx + 3); + + uvs.push(Vec2::new(0., 0.)); + uvs.push(Vec2::new(1., 0.)); + uvs.push(Vec2::new(0., 1.)); + uvs.push(Vec2::new(1., 1.)); } diff --git a/game/camera_system/src/lib.rs b/game/camera_system/src/lib.rs index 15ffe97..72594ab 100644 --- a/game/camera_system/src/lib.rs +++ b/game/camera_system/src/lib.rs @@ -18,20 +18,22 @@ pub struct PhosCameraPlugin; impl Plugin for PhosCameraPlugin { fn build(&self, app: &mut App) { - app.add_systems(Startup, setup) - .add_systems(Update, (update_camera, grab_mouse, update_camera_mouse)); + app.add_systems(Startup, setup).add_systems( + Update, + (grab_mouse, (update_camera, update_camera_mouse).chain()), + ); } } fn setup(mut commands: Commands) { commands.spawn(( Camera3dBundle { - transform: Transform::from_xyz(-200., 300., -200.) + transform: Transform::from_xyz(0., 30., 0.) .looking_at(Vec3::new(1000., 0., 1000.), Vec3::Y), ..default() }, PhosCamera { - speed: 100., + speed: 50., ..default() }, )); @@ -56,17 +58,18 @@ fn update_camera( if keyboard_input.pressed(KeyCode::KeyS) { move_vec += Vec3::Z; } + + let rot = transform.rotation; + move_vec = (rot * move_vec.normalize_or_zero()) * cam.speed * time.delta_seconds(); + if keyboard_input.pressed(KeyCode::ShiftLeft) { - move_vec += Vec3::NEG_Y; + move_vec += Vec3::from(transform.down()); } if keyboard_input.pressed(KeyCode::Space) { - move_vec += Vec3::Y; + move_vec += Vec3::from(transform.up()); } - if move_vec.length_squared() == 0. { - return; - } - let rot = transform.rotation; - transform.translation += (rot * move_vec.normalize()) * cam.speed * time.delta_seconds(); + + transform.translation += move_vec.normalize_or_zero() * cam.speed * time.delta_seconds(); } fn update_camera_mouse( @@ -80,19 +83,25 @@ fn update_camera_mouse( return; } let mut transform = cam_query.single_mut(); - let cam_rot = mouse_move.read().map(|event| event.delta).sum::() * time.delta_seconds(); + let window_scale = window.height().min(window.width()); - let (mut pitch, mut yaw, _) = transform.rotation.to_euler(EulerRot::XYZ); + for ev in mouse_move.read() { + let (mut yaw, mut pitch, _) = transform.rotation.to_euler(EulerRot::YXZ); + match window.cursor.grab_mode { + CursorGrabMode::None => (), + _ => { + // Using smallest of height or width ensures equal vertical and horizontal sensitivity + pitch -= (ev.delta.y * time.delta_seconds() * 5.).to_radians(); + yaw -= (ev.delta.x * time.delta_seconds() * 5.).to_radians(); + } + } - pitch -= cam_rot.y.to_radians(); - yaw -= cam_rot.x.to_radians(); - pitch = pitch.clamp(-1.54, 1.54); - // if rot_x > PI && cam_rot.x < 2. * PI { - // rot_x = PI; - // } + pitch = pitch.clamp(-1.54, 1.54); - transform.rotation = - Quat::from_axis_angle(Vec3::Y, yaw) * Quat::from_axis_angle(Vec3::X, pitch); + // Order is important to prevent unintended roll + transform.rotation = + Quat::from_axis_angle(Vec3::Y, yaw) * Quat::from_axis_angle(Vec3::X, pitch); + } } fn grab_mouse( diff --git a/game/main/src/main.rs b/game/main/src/main.rs index da774a9..0beba06 100644 --- a/game/main/src/main.rs +++ b/game/main/src/main.rs @@ -20,7 +20,6 @@ fn main() { }), ..default() }), - WireframePlugin, WorldInspectorPlugin::new(), PhosGamePlugin, )) diff --git a/game/main/src/phos.rs b/game/main/src/phos.rs index d3a0a25..4ba9abe 100644 --- a/game/main/src/phos.rs +++ b/game/main/src/phos.rs @@ -1,7 +1,9 @@ +use bevy::asset::io::memory::Value::Vec; +use bevy::pbr::wireframe::{WireframeConfig, WireframePlugin}; use bevy::{pbr::CascadeShadowConfig, prelude::*}; use camera_system::PhosCameraPlugin; use iyes_perf_ui::prelude::*; -use world_generation::hex_utils::offset_to_world; +use world_generation::hex_utils::{offset_to_world, HexCoord}; use world_generation::{ heightmap::generate_heightmap, hex_utils::offset3d_to_world, mesh_generator::generate_chunk_mesh, prelude::*, @@ -13,11 +15,17 @@ impl Plugin for PhosGamePlugin { fn build(&self, app: &mut App) { app.add_plugins(PhosCameraPlugin); app.add_systems(Startup, init_game) - .add_systems(Startup, create_map); + .add_systems(Startup, create_map) + .add_systems(Update, draw_gizmos); app.add_plugins(bevy::diagnostic::FrameTimeDiagnosticsPlugin) .add_plugins(bevy::diagnostic::EntityCountDiagnosticsPlugin) .add_plugins(bevy::diagnostic::SystemInformationDiagnosticsPlugin) .add_plugins(PerfUiPlugin); + app.add_plugins(WireframePlugin); + // app.insert_resource(WireframeConfig { + // global: true, + // default_color: Color::CYAN, + // }); } } @@ -30,76 +38,103 @@ fn init_game(mut commands: Commands) { commands.spawn(DirectionalLightBundle { directional_light: DirectionalLight { - shadows_enabled: false, + shadows_enabled: true, ..default() }, cascade_shadow_config: CascadeShadowConfig { - bounds: vec![20., 40., 80., 1000., 5000., 19000., 20000.], + bounds: vec![500., 1000., 5000., 10000.], ..default() }, - transform: Transform::from_xyz(0.0, 16.0, 5.).looking_at(Vec3::ZERO, Vec3::Y), + transform: Transform::from_xyz(500., 160.0, 500.).looking_at(Vec3::ZERO, Vec3::Y), ..default() }); } +fn draw_gizmos(mut gizmos: Gizmos, hm: Res) { + gizmos.arrow(Vec3::ZERO, Vec3::Y * 1.5, Color::GREEN); + gizmos.arrow(Vec3::ZERO, Vec3::Z * 1.5, Color::BLUE); + gizmos.arrow(Vec3::ZERO, Vec3::X * 1.5, Color::RED); + + let ch = &hm.chunks[0]; + let coord = HexCoord::new(16, 16); + let h = ch.points[coord.to_chunk_local_index() as usize]; + gizmos.ray(coord.to_world(h), Vec3::Y, Color::RED); + gizmos.ray(coord.to_world(h), Vec3::Z * 1.5, Color::BLUE); + + // let t = coord.get_neighbor(5); + // let h = ch.points[t.to_chunk_local_index() as usize]; + // gizmos.ray(t.to_world(h), Vec3::Y * 1., Color::PINK); + let n = coord.get_neighbors(); + for i in 0..6 { + let t = n[i]; + let h = ch.points[t.to_chunk_local_index() as usize]; + gizmos.ray(t.to_world(h), Vec3::Y * (i + 1) as f32, Color::CYAN); + } +} + fn create_map( mut commands: Commands, mut materials: ResMut>, mut meshes: ResMut>, ) { let heightmap = generate_heightmap( - 32, - 32, + 1, + 1, &GenerationConfig { - layers: vec![GeneratorLayer { - base_roughness: 2.14, - roughness: 0.87, - strength: 2.93, - min_value: -0.2, - persistence: 0.77, - is_rigid: false, - weight: 0., - weight_multi: 0., - layers: 4, - first_layer_mask: false, - },GeneratorLayer { - base_roughness: 2.85, - roughness: 2., - strength: -0.23, - min_value: -0., - persistence: 1., - is_rigid: false, - weight: 0., - weight_multi: 0., - layers: 4, - first_layer_mask: false, - },GeneratorLayer { - base_roughness: 2.6, - roughness: 4., - strength: 10.44, - min_value: 0., - persistence: 1.57, - is_rigid: true, - weight: 1., - weight_multi: 0.35, - layers: 4, - first_layer_mask: true, - },GeneratorLayer { - base_roughness: 3.87, - roughness: 5.8, - strength: -1., - min_value: 0., - persistence: 0., - is_rigid: true, - weight: 1., - weight_multi: 4.57, - layers: 3, - first_layer_mask: true, - }], + layers: vec![ + GeneratorLayer { + base_roughness: 2.14, + roughness: 0.87, + strength: 2.93, + min_value: -0.2, + persistence: 0.77, + is_rigid: false, + weight: 0., + weight_multi: 0., + layers: 4, + first_layer_mask: false, + }, + GeneratorLayer { + base_roughness: 2.85, + roughness: 2., + strength: -0.23, + min_value: -0., + persistence: 1., + is_rigid: false, + weight: 0., + weight_multi: 0., + layers: 4, + first_layer_mask: false, + }, + GeneratorLayer { + base_roughness: 2.6, + roughness: 4., + strength: 10.44, + min_value: 0., + persistence: 1.57, + is_rigid: true, + weight: 1., + weight_multi: 0.35, + layers: 4, + first_layer_mask: true, + }, + GeneratorLayer { + base_roughness: 3.87, + roughness: 5.8, + strength: -1., + min_value: 0., + persistence: 0., + is_rigid: true, + weight: 1., + weight_multi: 4.57, + layers: 3, + first_layer_mask: true, + }, + ], noise_scale: 350., sea_level: 4., }, - 1, + 2, ); let debug_material = materials.add(StandardMaterial { @@ -107,9 +142,9 @@ fn create_map( ..default() }); - for chunk in heightmap.chunks { - let mesh = generate_chunk_mesh(&chunk); - let pos = offset_to_world(chunk.chunk_offset * Chunk::SIZE as i32); + for chunk in &heightmap.chunks { + let mesh = generate_chunk_mesh(&chunk, &heightmap); + let pos = offset_to_world(chunk.chunk_offset * Chunk::SIZE as i32, 0.); commands.spawn(PbrBundle { mesh: meshes.add(mesh), material: debug_material.clone(), @@ -117,4 +152,6 @@ fn create_map( ..default() }); } + + commands.insert_resource(heightmap); }