multi-threaded generation

This commit is contained in:
2024-04-28 21:20:30 -04:00
parent 9de7bc53d0
commit c434b2eab0
6 changed files with 88 additions and 35 deletions

24
Cargo.lock generated
View File

@@ -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",
]

View File

@@ -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"

View File

@@ -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<Chunk> = 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<Chunk> = 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,

View File

@@ -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"

View File

@@ -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()

View File

@@ -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<PhosChunk>>,
camera: Query<&Transform, With<PhosCamera>>,
) {
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<PhosCamera>>,
// ) {
// 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;
// }
// }
// }