resource load states
use biome painter
This commit is contained in:
@@ -6,6 +6,7 @@ pub mod macros {
|
|||||||
$plugin_name: ident,
|
$plugin_name: ident,
|
||||||
$loader_name: ident,
|
$loader_name: ident,
|
||||||
$asset_type: ident,
|
$asset_type: ident,
|
||||||
|
$asset_loadstate_name: ident,
|
||||||
$extensions: expr,
|
$extensions: expr,
|
||||||
$($string_name: ident -> $handle_name: ident)* ;
|
$($string_name: ident -> $handle_name: ident)* ;
|
||||||
$($string_array_name: ident -> $handle_array_name: ident)* ?
|
$($string_array_name: ident -> $handle_array_name: ident)* ?
|
||||||
@@ -18,6 +19,7 @@ pub mod macros {
|
|||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.init_asset::<$asset_type>()
|
app.init_asset::<$asset_type>()
|
||||||
.init_asset_loader::<$loader_name>()
|
.init_asset_loader::<$loader_name>()
|
||||||
|
.insert_resource($asset_loadstate_name::default())
|
||||||
.add_systems(Update, finalize);
|
.add_systems(Update, finalize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,10 +27,12 @@ pub mod macros {
|
|||||||
fn finalize(
|
fn finalize(
|
||||||
mut asset_events: EventReader<AssetEvent<$asset_type>>,
|
mut asset_events: EventReader<AssetEvent<$asset_type>>,
|
||||||
mut assets: ResMut<Assets<$asset_type>>,
|
mut assets: ResMut<Assets<$asset_type>>,
|
||||||
|
mut load_state: ResMut<$asset_loadstate_name>,
|
||||||
asset_server: Res<AssetServer>
|
asset_server: Res<AssetServer>
|
||||||
) {
|
) {
|
||||||
for event in asset_events.read() {
|
for event in asset_events.read() {
|
||||||
match event {
|
match event {
|
||||||
|
AssetEvent::Added { id } => load_state.added += 1,
|
||||||
AssetEvent::LoadedWithDependencies { id } => {
|
AssetEvent::LoadedWithDependencies { id } => {
|
||||||
let asset = assets.get_mut(id.clone()).unwrap();
|
let asset = assets.get_mut(id.clone()).unwrap();
|
||||||
|
|
||||||
@@ -40,12 +44,28 @@ pub mod macros {
|
|||||||
asset.$handle_array_name.push(asset_server.load(&asset.$string_array_name[i]));
|
asset.$handle_array_name.push(asset_server.load(&asset.$string_array_name[i]));
|
||||||
}
|
}
|
||||||
)?
|
)?
|
||||||
|
load_state.loaded += 1;
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Resource, Debug, Default)]
|
||||||
|
pub struct $asset_loadstate_name{
|
||||||
|
pub loaded: u32,
|
||||||
|
pub added: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl $asset_loadstate_name{
|
||||||
|
pub fn is_all_loaded(&self) -> bool{
|
||||||
|
if self.added == 0{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return self.loaded >= self.added;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct $loader_name;
|
pub struct $loader_name;
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ pub struct BiomePainterAsset {
|
|||||||
|
|
||||||
impl BiomePainterAsset {
|
impl BiomePainterAsset {
|
||||||
pub fn sample_biome(&self, moisture: f32, temperature: f32) -> Handle<TileMapperAsset> {
|
pub fn sample_biome(&self, moisture: f32, temperature: f32) -> Handle<TileMapperAsset> {
|
||||||
let x = (moisture.clamp(0., 1.) * 4.).ceil() as usize;
|
let x = (moisture.clamp(0., 1.) * 3.).ceil() as usize;
|
||||||
let y = (temperature.clamp(0., 1.) * 4.).ceil() as usize;
|
let y = (temperature.clamp(0., 1.) * 3.).ceil() as usize;
|
||||||
return self.biomes[x + y * 4].clone();
|
return self.biomes[x + y * 4].clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,6 +26,7 @@ create_asset_loader!(
|
|||||||
BiomePainterPlugin,
|
BiomePainterPlugin,
|
||||||
BiomePainterLoader,
|
BiomePainterLoader,
|
||||||
BiomePainterAsset,
|
BiomePainterAsset,
|
||||||
|
BiomePainterLoadState,
|
||||||
&["bimoes.json"],
|
&["bimoes.json"],
|
||||||
;
|
;
|
||||||
biomes_path -> biomes
|
biomes_path -> biomes
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ pub fn generate_chunk(chunk_x: f64, chunk_z: f64, cfg: &GenerationConfig, seed:
|
|||||||
&noise,
|
&noise,
|
||||||
) as f32;
|
) as f32;
|
||||||
temp[x + z * Chunk::SIZE] = sample_tempurature(
|
temp[x + z * Chunk::SIZE] = sample_tempurature(
|
||||||
x as f32 + chunk_x as f32 * Chunk::SIZE as f32,
|
|
||||||
z as f32 + chunk_z as f32 * Chunk::SIZE as f32,
|
z as f32 + chunk_z as f32 * Chunk::SIZE as f32,
|
||||||
sample,
|
sample,
|
||||||
100.
|
&cfg,
|
||||||
|
100.,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,8 +54,13 @@ pub fn generate_chunk(chunk_x: f64, chunk_z: f64, cfg: &GenerationConfig, seed:
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sample_tempurature(x: f32, z: f32, height: f32, equator: f32) -> f32 {
|
fn sample_tempurature(z: f32, height: f32, cfg: &GenerationConfig, equator: f32) -> f32 {
|
||||||
return height.remap(0., 100., 0., 1.).clamp(0., 1.);
|
let d = (equator - z).abs();
|
||||||
|
let max_d = equator.max(cfg.get_total_height() as f32 - equator);
|
||||||
|
let t_mod = d.remap(0., max_d, 0., 1.);
|
||||||
|
|
||||||
|
// let max_d = d.max()
|
||||||
|
return height.remap(0., 100., 0., 1.).clamp(0., 1.) * t_mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sample_point(x: f64, z: f64, cfg: &GenerationConfig, noise: &impl NoiseFn<f64, 2>) -> f32 {
|
fn sample_point(x: f64, z: f64, cfg: &GenerationConfig, noise: &impl NoiseFn<f64, 2>) -> f32 {
|
||||||
|
|||||||
@@ -20,6 +20,15 @@ pub mod prelude {
|
|||||||
pub layers: Vec<GeneratorLayer>,
|
pub layers: Vec<GeneratorLayer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GenerationConfig {
|
||||||
|
pub fn get_total_width(&self) -> usize {
|
||||||
|
return self.size.x as usize * Chunk::SIZE;
|
||||||
|
}
|
||||||
|
pub fn get_total_height(&self) -> usize {
|
||||||
|
return self.size.y as usize * Chunk::SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct GeneratorLayer {
|
pub struct GeneratorLayer {
|
||||||
pub strength: f64,
|
pub strength: f64,
|
||||||
pub min_value: f64,
|
pub min_value: f64,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::biome_painter::BiomePainterAsset;
|
||||||
use crate::hex_utils::HexCoord;
|
use crate::hex_utils::HexCoord;
|
||||||
use crate::tile_manager::TileAsset;
|
use crate::tile_manager::TileAsset;
|
||||||
use crate::tile_mapper::TileMapperAsset;
|
use crate::tile_mapper::TileMapperAsset;
|
||||||
@@ -26,8 +27,9 @@ const HEX_CORNERS: [Vec3; 6] = [
|
|||||||
pub fn generate_chunk_mesh(
|
pub fn generate_chunk_mesh(
|
||||||
chunk: &Chunk,
|
chunk: &Chunk,
|
||||||
map: &Map,
|
map: &Map,
|
||||||
tile_mapper: &TileMapperAsset,
|
painter: &BiomePainterAsset,
|
||||||
tiles: &Res<Assets<TileAsset>>,
|
tiles: &Res<Assets<TileAsset>>,
|
||||||
|
mappers: &Res<Assets<TileMapperAsset>>,
|
||||||
) -> Mesh {
|
) -> Mesh {
|
||||||
let vertex_count: usize = Chunk::SIZE * Chunk::SIZE * 6;
|
let vertex_count: usize = Chunk::SIZE * Chunk::SIZE * 6;
|
||||||
let mut verts = Vec::with_capacity(vertex_count);
|
let mut verts = Vec::with_capacity(vertex_count);
|
||||||
@@ -37,13 +39,16 @@ 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 height = chunk.heights[x + z * Chunk::SIZE];
|
||||||
|
let moisture = chunk.moisture[x + z * Chunk::SIZE];
|
||||||
|
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 = HexCoord::from_offset(
|
let coord = HexCoord::from_offset(
|
||||||
IVec2::new(x as i32, z as i32) + (chunk.chunk_offset * Chunk::SIZE as i32),
|
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 tile_handle = tile_mapper.sample_tile(height);
|
let biome = mappers.get(painter.sample_biome(moisture, temperature));
|
||||||
|
let tile_handle = biome.unwrap().sample_tile(height);
|
||||||
let tile = tiles.get(tile_handle).unwrap();
|
let tile = tiles.get(tile_handle).unwrap();
|
||||||
|
|
||||||
create_tile(
|
create_tile(
|
||||||
|
|||||||
@@ -37,4 +37,4 @@ pub struct TileAsset {
|
|||||||
pub side_texture: String,
|
pub side_texture: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
create_asset_loader!(TileAssetPlugin, TileAssetLoader, TileAsset, &["tile.json"],;?);
|
create_asset_loader!(TileAssetPlugin, TileAssetLoader, TileAsset, TileAssetLoadState, &["tile.json"],;?);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ create_asset_loader!(
|
|||||||
TileMapperAssetPlugin,
|
TileMapperAssetPlugin,
|
||||||
TileMapperAssetLoader,
|
TileMapperAssetLoader,
|
||||||
TileMapperAsset,
|
TileMapperAsset,
|
||||||
|
TileMapperLoadState,
|
||||||
&["mapper.json"],;
|
&["mapper.json"],;
|
||||||
tiles_path -> tiles
|
tiles_path -> tiles
|
||||||
?
|
?
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ impl Plugin for PhosCameraPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup(mut commands: Commands) {
|
fn setup(mut commands: Commands, mut msaa: ResMut<Msaa>) {
|
||||||
|
*msaa = Msaa::Off;
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Camera3dBundle {
|
Camera3dBundle {
|
||||||
transform: Transform::from_xyz(0., 30., 0.)
|
transform: Transform::from_xyz(0., 30., 0.)
|
||||||
@@ -42,7 +43,12 @@ fn update_camera(
|
|||||||
mut cam_query: Query<(&PhosCamera, &mut Transform)>,
|
mut cam_query: Query<(&PhosCamera, &mut Transform)>,
|
||||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
|
windows: Query<&Window>,
|
||||||
) {
|
) {
|
||||||
|
let window = windows.single();
|
||||||
|
if window.cursor.grab_mode != CursorGrabMode::Locked {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let (cam, mut transform) = cam_query.single_mut();
|
let (cam, mut transform) = cam_query.single_mut();
|
||||||
|
|
||||||
let mut move_vec = Vec3::ZERO;
|
let mut move_vec = Vec3::ZERO;
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use bevy::asset::LoadState;
|
use bevy::asset::LoadState;
|
||||||
|
use bevy::core_pipeline::experimental::taa::TemporalAntiAliasPlugin;
|
||||||
use bevy::pbr::ExtendedMaterial;
|
use bevy::pbr::ExtendedMaterial;
|
||||||
use bevy::{pbr::CascadeShadowConfig, prelude::*};
|
use bevy::{pbr::CascadeShadowConfig, prelude::*};
|
||||||
use bevy_rapier3d::plugin::{NoUserData, RapierPhysicsPlugin};
|
use bevy_rapier3d::plugin::{NoUserData, RapierPhysicsPlugin};
|
||||||
use bevy_rapier3d::render::RapierDebugRenderPlugin;
|
use bevy_rapier3d::render::RapierDebugRenderPlugin;
|
||||||
use camera_system::PhosCameraPlugin;
|
use camera_system::PhosCameraPlugin;
|
||||||
use iyes_perf_ui::prelude::*;
|
use iyes_perf_ui::prelude::*;
|
||||||
use world_generation::biome_painter::{BiomePainterAsset, BiomePainterPlugin};
|
use world_generation::biome_painter::{
|
||||||
|
self, BiomePainterAsset, BiomePainterLoadState, BiomePainterPlugin,
|
||||||
|
};
|
||||||
use world_generation::hex_utils::offset_to_world;
|
use world_generation::hex_utils::offset_to_world;
|
||||||
use world_generation::tile_manager::{self, TileAsset, TileAssetPlugin, TileManager};
|
use world_generation::tile_manager::{TileAsset, TileAssetLoadState, TileAssetPlugin, TileManager};
|
||||||
use world_generation::tile_mapper::{TileMapperAsset, TileMapperAssetPlugin};
|
use world_generation::tile_mapper::{TileMapperAsset, TileMapperAssetPlugin, TileMapperLoadState};
|
||||||
use world_generation::{
|
use world_generation::{
|
||||||
heightmap::generate_heightmap, mesh_generator::generate_chunk_mesh, prelude::*,
|
heightmap::generate_heightmap, mesh_generator::generate_chunk_mesh, prelude::*,
|
||||||
};
|
};
|
||||||
@@ -21,13 +24,14 @@ impl Plugin for PhosGamePlugin {
|
|||||||
app.add_plugins(PhosCameraPlugin)
|
app.add_plugins(PhosCameraPlugin)
|
||||||
.add_plugins(MaterialPlugin::<
|
.add_plugins(MaterialPlugin::<
|
||||||
ExtendedMaterial<StandardMaterial, ChunkMaterial>,
|
ExtendedMaterial<StandardMaterial, ChunkMaterial>,
|
||||||
>::default());
|
>::default())
|
||||||
|
.add_plugins(TemporalAntiAliasPlugin);
|
||||||
|
|
||||||
//Systems - Startup
|
//Systems - Startup
|
||||||
app.add_systems(Startup, init_game)
|
app.add_systems(Startup, init_game)
|
||||||
.add_systems(Startup, (load_textures, load_tiles, create_map).chain());
|
.add_systems(Startup, (load_textures, load_tiles, create_map).chain());
|
||||||
//Systems - Update
|
//Systems - Update
|
||||||
app.add_systems(Update, (finalize_texture, spawn_map, print_tiles));
|
app.add_systems(Update, (finalize_texture, spawn_map));
|
||||||
|
|
||||||
//Perf UI
|
//Perf UI
|
||||||
app.add_plugins(bevy::diagnostic::FrameTimeDiagnosticsPlugin)
|
app.add_plugins(bevy::diagnostic::FrameTimeDiagnosticsPlugin)
|
||||||
@@ -86,23 +90,24 @@ fn load_tiles(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||||||
commands.insert_resource(Painter(handle));
|
commands.insert_resource(Painter(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_tiles(tile_assets: Res<Assets<TileAsset>>) {
|
|
||||||
for (_, tile) in tile_assets.iter() {
|
|
||||||
println!("Tile: {}", tile.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn finalize_texture(
|
fn finalize_texture(
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
mut atlas: ResMut<ChunkAtlas>,
|
mut atlas: ResMut<ChunkAtlas>,
|
||||||
mut map: ResMut<PhosMap>,
|
mut map: ResMut<PhosMap>,
|
||||||
mut images: ResMut<Assets<Image>>,
|
mut images: ResMut<Assets<Image>>,
|
||||||
painter: Res<Painter>,
|
painter: Res<Painter>,
|
||||||
|
painter_load: Res<BiomePainterLoadState>,
|
||||||
|
tile_load: Res<TileAssetLoadState>,
|
||||||
|
mapper_load: Res<TileMapperLoadState>,
|
||||||
) {
|
) {
|
||||||
if atlas.is_loaded {
|
if atlas.is_loaded {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !painter_load.is_all_loaded() || !tile_load.is_all_loaded() || !mapper_load.is_all_loaded() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if asset_server.load_state(atlas.handle.clone()) != LoadState::Loaded {
|
if asset_server.load_state(atlas.handle.clone()) != LoadState::Loaded {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -191,36 +196,30 @@ fn spawn_map(
|
|||||||
atlas: Res<ChunkAtlas>,
|
atlas: Res<ChunkAtlas>,
|
||||||
mut map: ResMut<PhosMap>,
|
mut map: ResMut<PhosMap>,
|
||||||
tile_assets: Res<Assets<TileAsset>>,
|
tile_assets: Res<Assets<TileAsset>>,
|
||||||
tile_mapper: Res<Assets<TileMapperAsset>>,
|
tile_mappers: Res<Assets<TileMapperAsset>>,
|
||||||
|
biome_painters: Res<Assets<BiomePainterAsset>>,
|
||||||
|
painter: Res<Painter>,
|
||||||
) {
|
) {
|
||||||
if !map.ready || !map.regenerate {
|
if !map.ready || !map.regenerate {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mapper_opt = tile_mapper.iter().next();
|
let b_painter = biome_painters.get(painter.0.clone());
|
||||||
if mapper_opt.is_none() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let mapper = mapper_opt.unwrap().1;
|
|
||||||
|
|
||||||
for tile_handle in &mapper.tiles {
|
|
||||||
let t = tile_assets.get(tile_handle);
|
|
||||||
if t.is_none() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
map.regenerate = false;
|
map.regenerate = false;
|
||||||
let chunk_material = materials.add(ExtendedMaterial {
|
let chunk_material = materials.add(ExtendedMaterial {
|
||||||
base: StandardMaterial {
|
base: StandardMaterial::default(),
|
||||||
base_color: Color::WHITE,
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
extension: ChunkMaterial {
|
extension: ChunkMaterial {
|
||||||
array_texture: atlas.handle.clone(),
|
array_texture: atlas.handle.clone(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
for chunk in &heightmap.chunks {
|
for chunk in &heightmap.chunks {
|
||||||
let mesh = generate_chunk_mesh(&chunk, &heightmap, mapper, &tile_assets);
|
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 pos = offset_to_world(chunk.chunk_offset * Chunk::SIZE as i32, 0.);
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
MaterialMeshBundle {
|
MaterialMeshBundle {
|
||||||
|
|||||||
Reference in New Issue
Block a user