save tile texture id into map

This commit is contained in:
2024-05-27 13:05:38 -04:00
parent 710eb80bf0
commit dcf6fc5972
8 changed files with 76 additions and 61 deletions

View File

@@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
use crate::tile_mapper::TileMapperAsset; use crate::tile_mapper::TileMapperAsset;
#[derive(Serialize, Deserialize, Debug, TypePath, Asset)] #[derive(Serialize, Deserialize, Debug, TypePath, Asset, Clone)]
pub struct BiomePainterAsset { pub struct BiomePainterAsset {
#[serde(skip)] #[serde(skip)]
pub biomes: Vec<Handle<TileMapperAsset>>, pub biomes: Vec<Handle<TileMapperAsset>>,

View File

@@ -1,5 +1,6 @@
use bevy::math::IVec2; use bevy::math::IVec2;
use bevy::prelude::{FloatExt, Vec2}; use bevy::prelude::{FloatExt, Vec2};
use bevy::utils::default;
use noise::{NoiseFn, SuperSimplex}; use noise::{NoiseFn, SuperSimplex};
use rayon::iter::{IntoParallelIterator, ParallelIterator}; use rayon::iter::{IntoParallelIterator, ParallelIterator};
@@ -50,6 +51,7 @@ pub fn generate_chunk(chunk_x: f64, chunk_z: f64, cfg: &GenerationConfig, seed:
moisture: moisture, moisture: moisture,
temperature: temp, temperature: temp,
chunk_offset: IVec2::new(chunk_x as i32, chunk_z as i32), chunk_offset: IVec2::new(chunk_x as i32, chunk_z as i32),
..default()
}; };
} }

View File

@@ -70,11 +70,24 @@ pub mod prelude {
pub struct Chunk { pub struct Chunk {
pub heights: [f32; Chunk::SIZE * Chunk::SIZE], pub heights: [f32; Chunk::SIZE * Chunk::SIZE],
pub textures: [[u32; 2]; Chunk::SIZE * Chunk::SIZE],
pub moisture: [f32; Chunk::SIZE * Chunk::SIZE], pub moisture: [f32; Chunk::SIZE * Chunk::SIZE],
pub temperature: [f32; Chunk::SIZE * Chunk::SIZE], pub temperature: [f32; Chunk::SIZE * Chunk::SIZE],
pub chunk_offset: IVec2, 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 { impl Chunk {
pub const SIZE: usize = 64; pub const SIZE: usize = 64;
pub const WORLD_WIDTH: f32 = Chunk::SIZE as f32 * SHORT_DIAGONAL; pub const WORLD_WIDTH: f32 = Chunk::SIZE as f32 * SHORT_DIAGONAL;

View File

@@ -13,13 +13,7 @@ use bevy::{
}, },
}; };
pub fn generate_chunk_mesh( pub fn generate_chunk_mesh(chunk: &Chunk, map: &Map) -> Mesh {
chunk: &Chunk,
map: &Map,
painter: &BiomePainterAsset,
tiles: &Res<Assets<TileAsset>>,
mappers: &Res<Assets<TileMapperAsset>>,
) -> Mesh {
#[cfg(feature = "tracing")] #[cfg(feature = "tracing")]
let span = info_span!("generate_chunk_mesh").entered(); let span = info_span!("generate_chunk_mesh").entered();
@@ -31,17 +25,13 @@ pub fn generate_chunk_mesh(
for z in 0..Chunk::SIZE { for z in 0..Chunk::SIZE {
for x in 0..Chunk::SIZE { for x in 0..Chunk::SIZE {
let height = chunk.heights[x + z * Chunk::SIZE]; let idx = x + z * Chunk::SIZE;
let moisture = chunk.moisture[x + z * Chunk::SIZE]; let height = chunk.heights[idx];
let temperature = chunk.temperature[x + z * Chunk::SIZE];
let off_pos = Vec3::new(x as f32, height, z as f32); let off_pos = Vec3::new(x as f32, height, z as f32);
let tile_pos = offset3d_to_world(off_pos); let tile_pos = offset3d_to_world(off_pos);
let coord = let coord =
HexCoord::from_offset(IVec2::new(x as i32, z as i32) + (chunk.chunk_offset * Chunk::SIZE as i32)); 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 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( create_tile(
tile_pos, tile_pos,
@@ -51,8 +41,8 @@ pub fn generate_chunk_mesh(
&mut indices, &mut indices,
&mut normals, &mut normals,
// &mut tex, // &mut tex,
tile.texture_id, chunk.textures[idx][0],
tile.side_texture_id, chunk.textures[idx][1],
); );
} }
} }

View File

@@ -24,7 +24,7 @@ impl TileManager {
} }
} }
#[derive(Serialize, Deserialize, Debug, TypePath, Asset)] #[derive(Serialize, Deserialize, Debug, TypePath, Asset, Clone)]
pub struct TileAsset { pub struct TileAsset {
#[serde(skip)] #[serde(skip)]
pub id: usize, pub id: usize,

View File

@@ -44,43 +44,30 @@ fn chunk_rebuilder(
mut chunks: ResMut<PhosChunkRegistry>, mut chunks: ResMut<PhosChunkRegistry>,
atlas: Res<ChunkAtlas>, atlas: Res<ChunkAtlas>,
heightmap: Res<Map>, heightmap: Res<Map>,
tile_assets: Res<Assets<TileAsset>>,
tile_mappers: Res<Assets<TileMapperAsset>>,
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
biome_painters: Res<Assets<BiomePainterAsset>>,
painter: Res<CurrentBiomePainter>,
) { ) {
if queue.queue.len() == 0 { if queue.queue.len() == 0 {
return; return;
} }
queue.queue.dedup(); queue.queue.dedup();
let chunk_indices = queue.queue.clone();
let pool = AsyncComputeTaskPool::get();
for chunk_index in &queue.queue { for chunk_index in &queue.queue {
let chunk = chunks.chunks[*chunk_index]; let chunk = chunks.chunks[*chunk_index];
// commands.entity(chunk).remove::<Handle<Mesh>>(); // commands.entity(chunk).remove::<Handle<Mesh>>();
commands.entity(chunk).despawn(); commands.entity(chunk).despawn();
} }
let b_painter = biome_painters.get(painter.handle.clone());
let cur_painter = b_painter.unwrap();
let chunk_meshes: Vec<_> = queue let chunk_meshes: Vec<_> = queue
.queue .queue
.par_iter() .par_iter()
.map(|idx| { .map(|idx| {
return prepare_chunk_mesh( return prepare_chunk_mesh(&heightmap.chunks[*idx], &heightmap);
&heightmap.chunks[*idx],
&heightmap,
cur_painter,
&tile_assets,
&tile_mappers,
);
}) })
.collect(); .collect();
let pool = AsyncComputeTaskPool::get();
for (mesh, collider_data, pos, index) in chunk_meshes { for (mesh, collider_data, pos, index) in chunk_meshes {
let mut chunk = commands.spawn(( let mut chunk = commands.spawn((
MaterialMeshBundle { MaterialMeshBundle {

View File

@@ -13,7 +13,7 @@ use crate::{
prelude::{ChunkAtlas, PhosChunk, PhosChunkRegistry, PhosMap}, prelude::{ChunkAtlas, PhosChunk, PhosChunkRegistry, PhosMap},
shader_extensions::chunk_material::ChunkMaterial, shader_extensions::chunk_material::ChunkMaterial,
utlis::{ 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, render_distance_system::RenderDistanceVisibility,
}, },
}; };
@@ -110,7 +110,14 @@ fn finalize_texture(
map.regenerate = true; map.regenerate = true;
} }
fn create_map(mut commands: Commands, mut cam: Query<(&mut Transform, Entity), With<PhosCamera>>) { fn create_map(
mut commands: Commands,
mut cam: Query<(&mut Transform, Entity), With<PhosCamera>>,
tile_assets: Res<Assets<TileAsset>>,
tile_mappers: Res<Assets<TileMapperAsset>>,
biome_painters: Res<Assets<BiomePainterAsset>>,
painter: Res<CurrentBiomePainter>,
) {
let config = GenerationConfig { let config = GenerationConfig {
layers: vec![ layers: vec![
GeneratorLayer { 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(1024 / Chunk::SIZE as u32),
// size: UVec2::splat(1), // 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(); let (mut cam_t, cam_entity) = cam.single_mut();
cam_t.translation = heightmap.get_center(); cam_t.translation = heightmap.get_center();
@@ -197,24 +208,17 @@ fn spawn_map(
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
atlas: Res<ChunkAtlas>, atlas: Res<ChunkAtlas>,
mut map: ResMut<PhosMap>, mut map: ResMut<PhosMap>,
tile_assets: Res<Assets<TileAsset>>,
tile_mappers: Res<Assets<TileMapperAsset>>,
biome_painters: Res<Assets<BiomePainterAsset>>,
painter: Res<CurrentBiomePainter>,
) { ) {
if !map.ready || !map.regenerate { if !map.ready || !map.regenerate {
return; return;
} }
let b_painter = biome_painters.get(painter.handle.clone());
map.regenerate = false; map.regenerate = false;
let cur_painter = b_painter.unwrap();
let chunk_meshes: Vec<_> = heightmap let chunk_meshes: Vec<_> = heightmap
.chunks .chunks
.par_iter() .par_iter()
.map(|chunk: &Chunk| { .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(); .collect();

View File

@@ -2,6 +2,7 @@
use bevy::log::*; use bevy::log::*;
use bevy::{asset::Assets, ecs::system::Res, math::Vec3, render::mesh::Mesh}; use bevy::{asset::Assets, ecs::system::Res, math::Vec3, render::mesh::Mesh};
use bevy_rapier3d::geometry::{Collider, TriMeshFlags}; use bevy_rapier3d::geometry::{Collider, TriMeshFlags};
use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator};
use world_generation::{ use world_generation::{
biome_painter::BiomePainterAsset, biome_painter::BiomePainterAsset,
chunk_colliders::generate_chunk_collider, chunk_colliders::generate_chunk_collider,
@@ -12,16 +13,41 @@ use world_generation::{
tile_mapper::TileMapperAsset, tile_mapper::TileMapperAsset,
}; };
pub fn prepare_chunk_mesh( pub fn paint_map(
chunk: &Chunk, map: &mut Map,
heightmap: &Map,
painter: &BiomePainterAsset, painter: &BiomePainterAsset,
tile_assets: &Res<Assets<TileAsset>>, tiles: &Res<Assets<TileAsset>>,
tile_mappers: &Res<Assets<TileMapperAsset>>, mappers: &Res<Assets<TileMapperAsset>>,
) -> (Mesh, (Vec<Vec3>, Vec<[u32; 3]>), Vec3, usize) { ) {
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<Assets<TileAsset>>,
mappers: &Res<Assets<TileMapperAsset>>,
) {
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<Vec3>, Vec<[u32; 3]>), Vec3, usize) {
#[cfg(feature = "tracing")] #[cfg(feature = "tracing")]
let _gen_mesh = info_span!("Generate Chunk").entered(); 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); let col_data = generate_chunk_collider(chunk, &heightmap);
return ( return (
@@ -32,15 +58,8 @@ pub fn prepare_chunk_mesh(
); );
} }
pub fn prepare_chunk_mesh_with_collider( pub fn prepare_chunk_mesh_with_collider(chunk: &Chunk, heightmap: &Map) -> (Mesh, Collider, Vec3, usize) {
chunk: &Chunk, let (mesh, (col_verts, col_indicies), pos, index) = prepare_chunk_mesh(chunk, heightmap);
heightmap: &Map,
painter: &BiomePainterAsset,
tile_assets: &Res<Assets<TileAsset>>,
tile_mappers: &Res<Assets<TileMapperAsset>>,
) -> (Mesh, Collider, Vec3, usize) {
let (mesh, (col_verts, col_indicies), pos, index) =
prepare_chunk_mesh(chunk, heightmap, painter, tile_assets, tile_mappers);
let collider: Collider; let collider: Collider;
{ {
#[cfg(feature = "tracing")] #[cfg(feature = "tracing")]