From dcf6fc5972ca6cd9910357c1243d15d968cc7336 Mon Sep 17 00:00:00 2001 From: Amatsugu Date: Mon, 27 May 2024 13:05:38 -0400 Subject: [PATCH] save tile texture id into map --- engine/world_generation/src/biome_painter.rs | 2 +- engine/world_generation/src/heightmap.rs | 2 + engine/world_generation/src/lib.rs | 13 +++++ engine/world_generation/src/mesh_generator.rs | 20 ++------ engine/world_generation/src/tile_manager.rs | 2 +- game/main/src/map_rendering/chunk_rebuild.rs | 21 ++------ game/main/src/map_rendering/map_init.rs | 26 ++++++---- game/main/src/utlis/chunk_utils.rs | 51 +++++++++++++------ 8 files changed, 76 insertions(+), 61 deletions(-) diff --git a/engine/world_generation/src/biome_painter.rs b/engine/world_generation/src/biome_painter.rs index c10a02e..1dcf3db 100644 --- a/engine/world_generation/src/biome_painter.rs +++ b/engine/world_generation/src/biome_painter.rs @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize}; use crate::tile_mapper::TileMapperAsset; -#[derive(Serialize, Deserialize, Debug, TypePath, Asset)] +#[derive(Serialize, Deserialize, Debug, TypePath, Asset, Clone)] pub struct BiomePainterAsset { #[serde(skip)] pub biomes: Vec>, diff --git a/engine/world_generation/src/heightmap.rs b/engine/world_generation/src/heightmap.rs index 7e56568..94f7dea 100644 --- a/engine/world_generation/src/heightmap.rs +++ b/engine/world_generation/src/heightmap.rs @@ -1,5 +1,6 @@ use bevy::math::IVec2; use bevy::prelude::{FloatExt, Vec2}; +use bevy::utils::default; use noise::{NoiseFn, SuperSimplex}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; @@ -50,6 +51,7 @@ pub fn generate_chunk(chunk_x: f64, chunk_z: f64, cfg: &GenerationConfig, seed: moisture: moisture, temperature: temp, chunk_offset: IVec2::new(chunk_x as i32, chunk_z as i32), + ..default() }; } diff --git a/engine/world_generation/src/lib.rs b/engine/world_generation/src/lib.rs index 02720a6..0a35d39 100644 --- a/engine/world_generation/src/lib.rs +++ b/engine/world_generation/src/lib.rs @@ -70,11 +70,24 @@ pub mod prelude { pub struct Chunk { pub heights: [f32; Chunk::SIZE * Chunk::SIZE], + pub textures: [[u32; 2]; Chunk::SIZE * Chunk::SIZE], pub moisture: [f32; Chunk::SIZE * Chunk::SIZE], pub temperature: [f32; Chunk::SIZE * Chunk::SIZE], pub chunk_offset: IVec2, } + impl Default for Chunk { + fn default() -> Self { + Self { + heights: [0.; 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(), + } + } + } + impl Chunk { pub const SIZE: usize = 64; pub const WORLD_WIDTH: f32 = Chunk::SIZE as f32 * SHORT_DIAGONAL; diff --git a/engine/world_generation/src/mesh_generator.rs b/engine/world_generation/src/mesh_generator.rs index 22ab132..22ff1b3 100644 --- a/engine/world_generation/src/mesh_generator.rs +++ b/engine/world_generation/src/mesh_generator.rs @@ -13,13 +13,7 @@ use bevy::{ }, }; -pub fn generate_chunk_mesh( - chunk: &Chunk, - map: &Map, - painter: &BiomePainterAsset, - tiles: &Res>, - mappers: &Res>, -) -> Mesh { +pub fn generate_chunk_mesh(chunk: &Chunk, map: &Map) -> Mesh { #[cfg(feature = "tracing")] let span = info_span!("generate_chunk_mesh").entered(); @@ -31,17 +25,13 @@ pub fn generate_chunk_mesh( for z in 0..Chunk::SIZE { for x in 0..Chunk::SIZE { - let height = chunk.heights[x + z * Chunk::SIZE]; - let moisture = chunk.moisture[x + z * Chunk::SIZE]; - let temperature = chunk.temperature[x + z * Chunk::SIZE]; + let idx = x + z * Chunk::SIZE; + let height = chunk.heights[idx]; let off_pos = Vec3::new(x as f32, height, z as f32); let tile_pos = offset3d_to_world(off_pos); let coord = HexCoord::from_offset(IVec2::new(x as i32, z as i32) + (chunk.chunk_offset * Chunk::SIZE as i32)); let n = map.get_neighbors(&coord); - let biome = mappers.get(painter.sample_biome(moisture, temperature)); - let tile_handle = biome.unwrap().sample_tile(height); - let tile = tiles.get(tile_handle).unwrap(); create_tile( tile_pos, @@ -51,8 +41,8 @@ pub fn generate_chunk_mesh( &mut indices, &mut normals, // &mut tex, - tile.texture_id, - tile.side_texture_id, + chunk.textures[idx][0], + chunk.textures[idx][1], ); } } diff --git a/engine/world_generation/src/tile_manager.rs b/engine/world_generation/src/tile_manager.rs index fe57c82..302d241 100644 --- a/engine/world_generation/src/tile_manager.rs +++ b/engine/world_generation/src/tile_manager.rs @@ -24,7 +24,7 @@ impl TileManager { } } -#[derive(Serialize, Deserialize, Debug, TypePath, Asset)] +#[derive(Serialize, Deserialize, Debug, TypePath, Asset, Clone)] pub struct TileAsset { #[serde(skip)] pub id: usize, diff --git a/game/main/src/map_rendering/chunk_rebuild.rs b/game/main/src/map_rendering/chunk_rebuild.rs index 289021f..2b70fa3 100644 --- a/game/main/src/map_rendering/chunk_rebuild.rs +++ b/game/main/src/map_rendering/chunk_rebuild.rs @@ -44,43 +44,30 @@ fn chunk_rebuilder( mut chunks: ResMut, atlas: Res, heightmap: Res, - tile_assets: Res>, - tile_mappers: Res>, mut meshes: ResMut>, - biome_painters: Res>, - painter: Res, ) { 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 b_painter = biome_painters.get(painter.handle.clone()); - - let cur_painter = b_painter.unwrap(); - let chunk_meshes: Vec<_> = queue .queue .par_iter() .map(|idx| { - return prepare_chunk_mesh( - &heightmap.chunks[*idx], - &heightmap, - cur_painter, - &tile_assets, - &tile_mappers, - ); + return prepare_chunk_mesh(&heightmap.chunks[*idx], &heightmap); }) .collect(); - let pool = AsyncComputeTaskPool::get(); - for (mesh, collider_data, pos, index) in chunk_meshes { let mut chunk = commands.spawn(( MaterialMeshBundle { diff --git a/game/main/src/map_rendering/map_init.rs b/game/main/src/map_rendering/map_init.rs index 31e8555..38b318d 100644 --- a/game/main/src/map_rendering/map_init.rs +++ b/game/main/src/map_rendering/map_init.rs @@ -13,7 +13,7 @@ use crate::{ prelude::{ChunkAtlas, PhosChunk, PhosChunkRegistry, PhosMap}, shader_extensions::chunk_material::ChunkMaterial, utlis::{ - chunk_utils::{prepare_chunk_mesh, prepare_chunk_mesh_with_collider}, + chunk_utils::{paint_map, prepare_chunk_mesh, prepare_chunk_mesh_with_collider}, render_distance_system::RenderDistanceVisibility, }, }; @@ -110,7 +110,14 @@ fn finalize_texture( map.regenerate = true; } -fn create_map(mut commands: Commands, mut cam: Query<(&mut Transform, Entity), With>) { +fn create_map( + mut commands: Commands, + mut cam: Query<(&mut Transform, Entity), With>, + tile_assets: Res>, + tile_mappers: Res>, + biome_painters: Res>, + painter: Res, +) { let config = GenerationConfig { layers: vec![ GeneratorLayer { @@ -180,7 +187,11 @@ fn create_map(mut commands: Commands, mut cam: Query<(&mut Transform, Entity), W size: UVec2::splat(1024 / Chunk::SIZE as u32), // size: UVec2::splat(1), }; - let heightmap = generate_heightmap(&config, 4); + 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 (mut cam_t, cam_entity) = cam.single_mut(); cam_t.translation = heightmap.get_center(); @@ -197,24 +208,17 @@ fn spawn_map( 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; } - let b_painter = biome_painters.get(painter.handle.clone()); map.regenerate = false; - let cur_painter = b_painter.unwrap(); - let chunk_meshes: Vec<_> = heightmap .chunks .par_iter() .map(|chunk: &Chunk| { - return prepare_chunk_mesh_with_collider(chunk, &heightmap, cur_painter, &tile_assets, &tile_mappers); + return prepare_chunk_mesh_with_collider(chunk, &heightmap); }) .collect(); diff --git a/game/main/src/utlis/chunk_utils.rs b/game/main/src/utlis/chunk_utils.rs index 925ba95..e8c8161 100644 --- a/game/main/src/utlis/chunk_utils.rs +++ b/game/main/src/utlis/chunk_utils.rs @@ -2,6 +2,7 @@ use bevy::log::*; use bevy::{asset::Assets, ecs::system::Res, math::Vec3, render::mesh::Mesh}; use bevy_rapier3d::geometry::{Collider, TriMeshFlags}; +use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator}; use world_generation::{ biome_painter::BiomePainterAsset, chunk_colliders::generate_chunk_collider, @@ -12,16 +13,41 @@ use world_generation::{ tile_mapper::TileMapperAsset, }; -pub fn prepare_chunk_mesh( - chunk: &Chunk, - heightmap: &Map, +pub fn paint_map( + map: &mut Map, painter: &BiomePainterAsset, - tile_assets: &Res>, - tile_mappers: &Res>, -) -> (Mesh, (Vec, Vec<[u32; 3]>), Vec3, usize) { + tiles: &Res>, + mappers: &Res>, +) { + map.chunks.par_iter_mut().for_each(|chunk: &mut Chunk| { + paint_chunk(chunk, painter, tiles, mappers); + }); +} + +pub fn paint_chunk( + chunk: &mut Chunk, + painter: &BiomePainterAsset, + tiles: &Res>, + mappers: &Res>, +) { + for z in 0..Chunk::SIZE { + for x in 0..Chunk::SIZE { + let idx = x + z * Chunk::SIZE; + let height = chunk.heights[idx]; + let moisture = chunk.moisture[idx]; + let temperature = chunk.temperature[idx]; + let biome = mappers.get(painter.sample_biome(moisture, temperature)); + let tile_handle = biome.unwrap().sample_tile(height); + let tile = tiles.get(tile_handle).unwrap(); + chunk.textures[idx] = [tile.texture_id, tile.side_texture_id]; + } + } +} + +pub fn prepare_chunk_mesh(chunk: &Chunk, heightmap: &Map) -> (Mesh, (Vec, Vec<[u32; 3]>), Vec3, usize) { #[cfg(feature = "tracing")] let _gen_mesh = info_span!("Generate Chunk").entered(); - let mesh = generate_chunk_mesh(chunk, &heightmap, painter, &tile_assets, &tile_mappers); + let mesh = generate_chunk_mesh(chunk, &heightmap); let col_data = generate_chunk_collider(chunk, &heightmap); return ( @@ -32,15 +58,8 @@ pub fn prepare_chunk_mesh( ); } -pub fn prepare_chunk_mesh_with_collider( - chunk: &Chunk, - heightmap: &Map, - painter: &BiomePainterAsset, - tile_assets: &Res>, - tile_mappers: &Res>, -) -> (Mesh, Collider, Vec3, usize) { - let (mesh, (col_verts, col_indicies), pos, index) = - prepare_chunk_mesh(chunk, heightmap, painter, tile_assets, tile_mappers); +pub fn prepare_chunk_mesh_with_collider(chunk: &Chunk, heightmap: &Map) -> (Mesh, Collider, Vec3, usize) { + let (mesh, (col_verts, col_indicies), pos, index) = prepare_chunk_mesh(chunk, heightmap); let collider: Collider; { #[cfg(feature = "tracing")]