From 1a861f1a9a88597412eeb4b6d5ac4cebea314fd2 Mon Sep 17 00:00:00 2001 From: Amatsugu Date: Mon, 27 May 2024 14:30:00 -0400 Subject: [PATCH] misc --- engine/world_generation/src/lib.rs | 5 +- game/main/src/map_rendering/chunk_rebuild.rs | 93 ++++++------------- game/main/src/map_rendering/map_init.rs | 24 ++--- .../src/map_rendering/terraforming_test.rs | 20 ++-- game/main/src/prelude.rs | 3 + 5 files changed, 57 insertions(+), 88 deletions(-) diff --git a/engine/world_generation/src/lib.rs b/engine/world_generation/src/lib.rs index 0a35d39..ca084e0 100644 --- a/engine/world_generation/src/lib.rs +++ b/engine/world_generation/src/lib.rs @@ -68,6 +68,7 @@ pub mod prelude { pub first_layer_mask: bool, } + #[derive(Clone)] pub struct Chunk { pub heights: [f32; Chunk::SIZE * Chunk::SIZE], pub textures: [[u32; 2]; Chunk::SIZE * Chunk::SIZE], @@ -80,7 +81,7 @@ pub mod prelude { fn default() -> Self { Self { heights: [0.; Chunk::SIZE * Chunk::SIZE], - textures: [[0;2]; Chunk::SIZE * Chunk::SIZE], + textures: [[0; 2]; Chunk::SIZE * Chunk::SIZE], moisture: [0.; Chunk::SIZE * Chunk::SIZE], temperature: [0.; Chunk::SIZE * Chunk::SIZE], chunk_offset: Default::default(), @@ -95,7 +96,7 @@ pub mod prelude { pub const WORLD_SIZE: Vec2 = Vec2::new(Chunk::WORLD_WIDTH, Chunk::WORLD_HEIGHT); } - #[derive(Resource)] + #[derive(Resource, Clone)] pub struct Map { pub chunks: Vec, pub height: usize, diff --git a/game/main/src/map_rendering/chunk_rebuild.rs b/game/main/src/map_rendering/chunk_rebuild.rs index 2b70fa3..7fde5e8 100644 --- a/game/main/src/map_rendering/chunk_rebuild.rs +++ b/game/main/src/map_rendering/chunk_rebuild.rs @@ -1,26 +1,17 @@ -use std::thread; - use bevy::ecs::system::CommandQueue; use bevy::prelude::*; use bevy::tasks::futures_lite::future; use bevy::tasks::*; use bevy_rapier3d::geometry::Collider; use bevy_rapier3d::geometry::TriMeshFlags; -use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; -use world_generation::{ - biome_painter::BiomePainterAsset, - hex_utils::SHORT_DIAGONAL, - prelude::{Chunk, Map}, - tile_manager::TileAsset, - tile_mapper::TileMapperAsset, -}; +use world_generation::prelude::Map; +use crate::prelude::RebuildChunk; use crate::{ - prelude::{ChunkAtlas, PhosChunk, PhosChunkRegistry}, - utlis::{chunk_utils::prepare_chunk_mesh, render_distance_system::RenderDistanceVisibility}, + prelude::{PhosChunk, PhosChunkRegistry}, + utlis::chunk_utils::prepare_chunk_mesh, }; -use super::prelude::CurrentBiomePainter; pub struct ChunkRebuildPlugin; impl Plugin for ChunkRebuildPlugin { @@ -37,81 +28,55 @@ pub struct ChunkRebuildQueue { pub queue: Vec, } -//Todo: Re-use existing entity/collider until new collider is generated fn chunk_rebuilder( mut commands: Commands, - mut queue: ResMut, - mut chunks: ResMut, - atlas: Res, + chunk_query: Query<(Entity, &PhosChunk), With>, heightmap: Res, - mut meshes: ResMut>, ) { - if queue.queue.len() == 0 { - return; - } - queue.queue.dedup(); - - let chunk_indices = queue.queue.clone(); let pool = AsyncComputeTaskPool::get(); - for chunk_index in &queue.queue { - let chunk = chunks.chunks[*chunk_index]; - // commands.entity(chunk).remove::>(); - commands.entity(chunk).despawn(); - } - - let chunk_meshes: Vec<_> = queue - .queue - .par_iter() - .map(|idx| { - return prepare_chunk_mesh(&heightmap.chunks[*idx], &heightmap); - }) - .collect(); - - for (mesh, collider_data, pos, index) in chunk_meshes { - let mut chunk = commands.spawn(( - MaterialMeshBundle { - mesh: meshes.add(mesh), - material: atlas.chunk_material_handle.clone(), - transform: Transform::from_translation(pos), - ..default() - }, - PhosChunk::new(index), - RenderDistanceVisibility::default().with_offset(Vec3::new( - (Chunk::SIZE / 2) as f32 * SHORT_DIAGONAL, - 0., - (Chunk::SIZE / 2) as f32 * 1.5, - )), - )); - let entity = chunk.id(); + for (chunk, idx) in &chunk_query { + #[cfg(feature = "tracing")] + let _spawn_span = info_span!("Rebuild Chunk").entered(); + let map = heightmap.clone(); + let chunk_index = idx.index; let task = pool.spawn(async move { + #[cfg(feature = "tracing")] + let _spawn_span = info_span!("Rebuild Task").entered(); let mut queue = CommandQueue::default(); + let (mesh, collider_data, _, _) = prepare_chunk_mesh(&map.chunks[chunk_index], &map); let c = Collider::trimesh_with_flags( collider_data.0, collider_data.1, TriMeshFlags::DELETE_DUPLICATE_TRIANGLES, ); queue.push(move |world: &mut World| { - world.entity_mut(entity).insert(c).remove::(); + world.entity_mut(chunk).insert(c).remove::(); }); - return queue; + return (queue, mesh); }); - chunk.insert(ColliderTask { task }); - chunks.chunks[index] = chunk.id(); + commands + .entity(chunk) + .insert(ChunkRebuildTask { task }) + .remove::(); } - queue.queue.clear(); } -fn collider_task_resolver(mut chunks: Query<&mut ColliderTask, With>, mut commands: Commands) { - for mut task in &mut chunks { - if let Some(mut c) = block_on(future::poll_once(&mut task.task)) { +fn collider_task_resolver( + mut chunks: Query<(&mut ChunkRebuildTask, &Handle), With>, + mut commands: Commands, + mut meshes: ResMut>, +) { + for (mut task, mesh_handle) in &mut chunks { + if let Some((mut c, mesh)) = block_on(future::poll_once(&mut task.task)) { commands.append(&mut c); + meshes.insert(mesh_handle, mesh); } } } #[derive(Component)] -struct ColliderTask { - pub task: Task, +struct ChunkRebuildTask { + pub task: Task<(CommandQueue, Mesh)>, } diff --git a/game/main/src/map_rendering/map_init.rs b/game/main/src/map_rendering/map_init.rs index 38b318d..ab591ef 100644 --- a/game/main/src/map_rendering/map_init.rs +++ b/game/main/src/map_rendering/map_init.rs @@ -110,14 +110,7 @@ fn finalize_texture( map.regenerate = true; } -fn create_map( - mut commands: Commands, - mut cam: Query<(&mut Transform, Entity), With>, - tile_assets: Res>, - tile_mappers: Res>, - biome_painters: Res>, - painter: Res, -) { +fn create_map(mut commands: Commands, mut cam: Query<(&mut Transform, Entity), With>) { let config = GenerationConfig { layers: vec![ GeneratorLayer { @@ -187,11 +180,7 @@ fn create_map( size: UVec2::splat(1024 / Chunk::SIZE as u32), // size: UVec2::splat(1), }; - let mut heightmap = generate_heightmap(&config, 4); - - let b_painter = biome_painters.get(painter.handle.clone()); - let cur_painter = b_painter.unwrap(); - paint_map(&mut heightmap, cur_painter, &tile_assets, &tile_mappers); + let heightmap = generate_heightmap(&config, 4); let (mut cam_t, cam_entity) = cam.single_mut(); cam_t.translation = heightmap.get_center(); @@ -203,16 +192,23 @@ fn create_map( } fn spawn_map( - heightmap: Res, + mut heightmap: ResMut, mut commands: Commands, mut meshes: ResMut>, atlas: Res, mut map: ResMut, + tile_assets: Res>, + tile_mappers: Res>, + biome_painters: Res>, + painter: Res, ) { if !map.ready || !map.regenerate { return; } map.regenerate = false; + let b_painter = biome_painters.get(painter.handle.clone()); + let cur_painter = b_painter.unwrap(); + paint_map(&mut heightmap, cur_painter, &tile_assets, &tile_mappers); let chunk_meshes: Vec<_> = heightmap .chunks diff --git a/game/main/src/map_rendering/terraforming_test.rs b/game/main/src/map_rendering/terraforming_test.rs index 8bd7e9c..e58a908 100644 --- a/game/main/src/map_rendering/terraforming_test.rs +++ b/game/main/src/map_rendering/terraforming_test.rs @@ -2,7 +2,10 @@ use bevy::{prelude::*, window::PrimaryWindow}; use bevy_rapier3d::{pipeline::QueryFilter, plugin::RapierContext}; use world_generation::{hex_utils::HexCoord, prelude::Map}; -use crate::{camera_system::components::PhosCamera, prelude::PhosChunkRegistry}; +use crate::{ + camera_system::components::PhosCamera, + prelude::{PhosChunkRegistry, RebuildChunk}, +}; use super::chunk_rebuild::ChunkRebuildQueue; @@ -16,11 +19,12 @@ impl Plugin for TerraFormingTestPlugin { fn deform( cam_query: Query<(&GlobalTransform, &Camera), With>, + mut commands: Commands, window: Query<&Window, With>, mouse: Res>, rapier_context: Res, mut heightmap: ResMut, - mut rebuild: ResMut, + chunks: Res, time: Res