From c434b2eab0b715d0dcad0161ea51d4936d005527 Mon Sep 17 00:00:00 2001 From: Amatsugu Date: Sun, 28 Apr 2024 21:20:30 -0400 Subject: [PATCH] multi-threaded generation --- Cargo.lock | 24 +++++++- engine/world_generation/Cargo.toml | 1 + engine/world_generation/src/heightmap.rs | 16 +++-- game/main/Cargo.toml | 1 + game/main/src/main.rs | 3 +- game/main/src/phos.rs | 78 ++++++++++++++++-------- 6 files changed, 88 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ceebda1..60e3e3d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2022,7 +2022,7 @@ dependencies = [ "vec_map", "wasm-bindgen", "web-sys", - "windows 0.48.0", + "windows 0.54.0", ] [[package]] @@ -3070,6 +3070,7 @@ dependencies = [ "camera_system", "iyes_perf_ui", "noise 0.8.2", + "rayon", "world_generation", ] @@ -3309,6 +3310,26 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "rectangle-pack" version = "0.4.2" @@ -4538,6 +4559,7 @@ dependencies = [ "asset_loader", "bevy", "noise 0.9.0", + "rayon", "serde", "serde_json", ] diff --git a/engine/world_generation/Cargo.toml b/engine/world_generation/Cargo.toml index f01df4e..464a7a2 100644 --- a/engine/world_generation/Cargo.toml +++ b/engine/world_generation/Cargo.toml @@ -11,3 +11,4 @@ noise = "0.9.0" serde = {version="1.0.197", features=["derive"]} serde_json = "1.0.115" asset_loader = {path = "../asset_loader"} +rayon = "1.10.0" diff --git a/engine/world_generation/src/heightmap.rs b/engine/world_generation/src/heightmap.rs index 6ca4530..16b95e2 100644 --- a/engine/world_generation/src/heightmap.rs +++ b/engine/world_generation/src/heightmap.rs @@ -1,16 +1,20 @@ use bevy::math::IVec2; use bevy::prelude::{FloatExt, Vec2}; use noise::{NoiseFn, SuperSimplex}; +use rayon::iter::{IntoParallelIterator, ParallelIterator}; use crate::prelude::*; pub fn generate_heightmap(cfg: &GenerationConfig, seed: u32) -> Map { - let mut chunks: Vec = Vec::with_capacity(cfg.size.length_squared() as usize); - for z in 0..cfg.size.y { - for x in 0..cfg.size.x { - chunks.push(generate_chunk(x as f64, z as f64, cfg, seed)); - } - } + // let mut chunks: Vec = Vec::with_capacity(cfg.size.length_squared() as usize); + let chunks = (0..cfg.size.y) + .into_par_iter() + .flat_map(|z| { + (0..cfg.size.x) + .into_par_iter() + .map(move |x| generate_chunk(x as f64, z as f64, cfg, seed)) + }) + .collect(); return Map { chunks, height: cfg.size.y as usize, diff --git a/game/main/Cargo.toml b/game/main/Cargo.toml index 0c251db..9aba5e3 100644 --- a/game/main/Cargo.toml +++ b/game/main/Cargo.toml @@ -14,3 +14,4 @@ noise = "0.8.2" world_generation ={path="../../engine/world_generation"} camera_system={path = "../camera_system"} bevy_rapier3d = { version = "0.25.0", features = [ "simd-stable", "debug-render-3d" ] } +rayon = "1.10.0" diff --git a/game/main/src/main.rs b/game/main/src/main.rs index 08a3283..22a1955 100644 --- a/game/main/src/main.rs +++ b/game/main/src/main.rs @@ -16,8 +16,9 @@ fn main() { primary_window: Some(Window { title: "Phos".into(), name: Some("phos".into()), + resolution: (1920., 1080.).into(), present_mode: PresentMode::AutoNoVsync, - mode: bevy::window::WindowMode::BorderlessFullscreen, + // mode: bevy::window::WindowMode::BorderlessFullscreen, ..default() }), ..default() diff --git a/game/main/src/phos.rs b/game/main/src/phos.rs index 4599d40..11b2c7e 100644 --- a/game/main/src/phos.rs +++ b/game/main/src/phos.rs @@ -2,13 +2,12 @@ use crate::prelude::*; use crate::shader_extensions::chunk_material::ChunkMaterial; use bevy::asset::LoadState; use bevy::pbr::ExtendedMaterial; -use bevy::render::view::visibility; use bevy::{pbr::CascadeShadowConfig, prelude::*}; use bevy_rapier3d::plugin::{NoUserData, RapierPhysicsPlugin}; use bevy_rapier3d::render::RapierDebugRenderPlugin; -use camera_system::prelude::PhosCamera; use camera_system::PhosCameraPlugin; use iyes_perf_ui::prelude::*; +use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use world_generation::biome_painter::{ BiomePainterAsset, BiomePainterLoadState, BiomePainterPlugin, }; @@ -32,8 +31,6 @@ impl Plugin for PhosGamePlugin { app.add_systems(Startup, init_game) .add_systems(Startup, (load_textures, load_tiles, create_map).chain()); - //Systems - PreUpdate - app.add_systems(PreUpdate, render_distance_system); //Systems - Update app.add_systems(Update, (finalize_texture, spawn_map)); @@ -216,15 +213,22 @@ fn spawn_map( }, }); - for chunk in &heightmap.chunks { - let mesh = generate_chunk_mesh( - &chunk, - &heightmap, - b_painter.unwrap(), - &tile_assets, - &tile_mappers, - ); - let pos = offset_to_world(chunk.chunk_offset * Chunk::SIZE as i32, 0.); + let cur_painter = b_painter.unwrap(); + + let chunk_meshes: Vec<_> = heightmap + .chunks + .par_iter() + .map(|chunk: &Chunk| { + let mesh = + generate_chunk_mesh(chunk, &heightmap, cur_painter, &tile_assets, &tile_mappers); + return ( + mesh, + offset_to_world(chunk.chunk_offset * Chunk::SIZE as i32, 0.), + ); + }) + .collect(); + + for (mesh, pos) in chunk_meshes { commands.spawn(( MaterialMeshBundle { mesh: meshes.add(mesh), @@ -235,19 +239,39 @@ fn spawn_map( PhosChunk, )); } + + // for chunk in &heightmap.chunks { + // let mesh = generate_chunk_mesh( + // &chunk, + // &heightmap, + // b_painter.unwrap(), + // &tile_assets, + // &tile_mappers, + // ); + // let pos = offset_to_world(chunk.chunk_offset * Chunk::SIZE as i32, 0.); + // commands.spawn(( + // MaterialMeshBundle { + // mesh: meshes.add(mesh), + // material: chunk_material.clone(), + // transform: Transform::from_translation(pos), + // ..default() + // }, + // PhosChunk::from_translation(pos), + // )); + // } } -fn render_distance_system( - mut chunks: Query<(&Transform, &mut Visibility), With>, - camera: Query<&Transform, With>, -) { - let cam = camera.single(); - for (transform, mut visibility) in chunks.iter_mut() { - let dist = (transform.translation - cam.translation).length_squared(); - if dist > 1000000. { - *visibility = Visibility::Hidden; - } else { - *visibility = Visibility::Visible; - } - } -} +// fn render_distance_system( +// mut chunks: Query<(&PhosChunk, &mut Visibility)>, +// camera: Query<&Transform, With>, +// ) { +// let cam = camera.single(); +// for (transform, mut visibility) in chunks.iter_mut() { +// let dist = (transform.center - cam.translation).length(); +// if dist > 500. { +// *visibility = Visibility::Hidden; +// } else { +// *visibility = Visibility::Visible; +// } +// } +// }