biome sampling
This commit is contained in:
38
engine/world_generation/src/biome_asset.rs
Normal file
38
engine/world_generation/src/biome_asset.rs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
use asset_loader::create_asset_loader;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{prelude::GeneratorLayer, tile_mapper::TileMapperAsset};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Asset, TypePath, Debug, Clone)]
|
||||||
|
pub struct BiomeAsset {
|
||||||
|
pub moisture: f32,
|
||||||
|
pub temperature: f32,
|
||||||
|
pub continentality: f32,
|
||||||
|
pub name: String,
|
||||||
|
#[serde(skip)]
|
||||||
|
pub tile_mapper: Handle<TileMapperAsset>,
|
||||||
|
pub tile_mapper_path: String,
|
||||||
|
pub generator_layers: Vec<GeneratorLayer>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BiomeAsset {
|
||||||
|
pub fn distance(&self, moisture: f32, temperature: f32, continentality: f32) -> f32 {
|
||||||
|
let a = Vec3::new(
|
||||||
|
self.moisture - moisture,
|
||||||
|
self.temperature - temperature,
|
||||||
|
self.continentality - continentality,
|
||||||
|
);
|
||||||
|
return a.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
create_asset_loader!(
|
||||||
|
BiomeAssetPlugin,
|
||||||
|
BiomeAssetLoader,
|
||||||
|
BiomeAsset,
|
||||||
|
BiomeAssetLoadState,
|
||||||
|
&["bimoe.json"],
|
||||||
|
tile_mapper_path -> tile_mapper
|
||||||
|
;
|
||||||
|
?
|
||||||
|
);
|
||||||
@@ -2,23 +2,41 @@ use asset_loader::create_asset_loader;
|
|||||||
use bevy::{
|
use bevy::{
|
||||||
asset::{Asset, Handle},
|
asset::{Asset, Handle},
|
||||||
reflect::TypePath,
|
reflect::TypePath,
|
||||||
|
render::render_resource::encase::rts_array::Length,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::tile_mapper::TileMapperAsset;
|
use crate::biome_asset::BiomeAsset;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, TypePath, Asset, Clone)]
|
#[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<BiomeAsset>>,
|
||||||
pub biomes_path: [String; 16],
|
pub biomes_path: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BiomePainterAsset {
|
impl BiomePainterAsset {
|
||||||
pub fn sample_biome(&self, moisture: f32, temperature: f32) -> Handle<TileMapperAsset> {
|
pub fn sample_biome(
|
||||||
let x = (moisture.clamp(0., 1.) * 3.).ceil() as usize;
|
&self,
|
||||||
let y = (temperature.clamp(0., 1.) * 3.).ceil() as usize;
|
assets: &Assets<BiomeAsset>,
|
||||||
return self.biomes[x + y * 4].clone();
|
moisture: f32,
|
||||||
|
temperature: f32,
|
||||||
|
continentality: f32,
|
||||||
|
) -> Handle<BiomeAsset> {
|
||||||
|
assert!(self.biomes.length() != 0, "There are no biomes");
|
||||||
|
let mut biome = self.biomes.first().unwrap().clone();
|
||||||
|
let mut dist = f32::INFINITY;
|
||||||
|
|
||||||
|
for b in &self.biomes {
|
||||||
|
let asset = assets.get(b).unwrap();
|
||||||
|
let d = asset.distance(moisture, temperature, continentality);
|
||||||
|
if d < dist {
|
||||||
|
biome = b.clone();
|
||||||
|
dist = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return biome;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use crate::biome_painter::BiomePainterAsset;
|
|
||||||
use crate::hex_utils::HexCoord;
|
use crate::hex_utils::HexCoord;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::tile_manager::TileAsset;
|
use crate::tile_manager::TileAsset;
|
||||||
use crate::tile_mapper::TileMapperAsset;
|
use crate::tile_mapper::TileMapperAsset;
|
||||||
|
use crate::{biome_asset::BiomeAsset, biome_painter::BiomePainterAsset};
|
||||||
use bevy::{
|
use bevy::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
render::{
|
render::{
|
||||||
@@ -16,6 +16,7 @@ pub fn generate_packed_chunk_mesh(
|
|||||||
map: &Map,
|
map: &Map,
|
||||||
painter: &BiomePainterAsset,
|
painter: &BiomePainterAsset,
|
||||||
tiles: &Res<Assets<TileAsset>>,
|
tiles: &Res<Assets<TileAsset>>,
|
||||||
|
biomes: &Res<Assets<BiomeAsset>>,
|
||||||
mappers: &Res<Assets<TileMapperAsset>>,
|
mappers: &Res<Assets<TileMapperAsset>>,
|
||||||
) -> Mesh {
|
) -> Mesh {
|
||||||
let vertex_count: usize = Chunk::SIZE * Chunk::SIZE * 6;
|
let vertex_count: usize = Chunk::SIZE * Chunk::SIZE * 6;
|
||||||
@@ -31,8 +32,12 @@ pub fn generate_packed_chunk_mesh(
|
|||||||
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 biome = biomes
|
||||||
let tile_handle = biome.unwrap().sample_tile(height);
|
.get(painter.sample_biome(biomes, moisture, temperature, 1.))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mapper = mappers.get(biome.tile_mapper.clone());
|
||||||
|
let tile_handle = mapper.unwrap().sample_tile(height);
|
||||||
let tile = tiles.get(tile_handle).unwrap();
|
let tile = tiles.get(tile_handle).unwrap();
|
||||||
|
|
||||||
create_packed_tile(
|
create_packed_tile(
|
||||||
|
|||||||
@@ -8,3 +8,4 @@ pub mod prelude;
|
|||||||
pub mod states;
|
pub mod states;
|
||||||
pub mod tile_manager;
|
pub mod tile_manager;
|
||||||
pub mod tile_mapper;
|
pub mod tile_mapper;
|
||||||
|
pub mod biome_asset;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ impl GenerationConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Reflect, InspectorOptions, Serialize, Deserialize, Debug)]
|
#[derive(Reflect, InspectorOptions, Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct GeneratorLayer {
|
pub struct GeneratorLayer {
|
||||||
pub strength: f64,
|
pub strength: f64,
|
||||||
pub min_value: f64,
|
pub min_value: f64,
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ pub struct TileMapperAsset {
|
|||||||
pub tiles: Vec<Handle<TileAsset>>,
|
pub tiles: Vec<Handle<TileAsset>>,
|
||||||
pub tiles_path: Vec<String>,
|
pub tiles_path: Vec<String>,
|
||||||
pub thresholds: Vec<f32>,
|
pub thresholds: Vec<f32>,
|
||||||
pub generator_layers: Vec<GeneratorLayer>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TileMapperAsset {
|
impl TileMapperAsset {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use bevy_inspector_egui::quick::ResourceInspectorPlugin;
|
|||||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||||
use shared::states::{GameplayState, MenuState};
|
use shared::states::{GameplayState, MenuState};
|
||||||
use world_generation::{
|
use world_generation::{
|
||||||
|
biome_asset::BiomeAsset,
|
||||||
biome_painter::*,
|
biome_painter::*,
|
||||||
heightmap::generate_heightmap,
|
heightmap::generate_heightmap,
|
||||||
hex_utils::{offset_to_index, SHORT_DIAGONAL},
|
hex_utils::{offset_to_index, SHORT_DIAGONAL},
|
||||||
@@ -272,6 +273,7 @@ fn spawn_map(
|
|||||||
tile_assets: Res<Assets<TileAsset>>,
|
tile_assets: Res<Assets<TileAsset>>,
|
||||||
tile_mappers: Res<Assets<TileMapperAsset>>,
|
tile_mappers: Res<Assets<TileMapperAsset>>,
|
||||||
biome_painters: Res<Assets<BiomePainterAsset>>,
|
biome_painters: Res<Assets<BiomePainterAsset>>,
|
||||||
|
biome_assets: Res<Assets<BiomeAsset>>,
|
||||||
painter: Res<CurrentBiomePainter>,
|
painter: Res<CurrentBiomePainter>,
|
||||||
mut generator_state: ResMut<NextState<GeneratorState>>,
|
mut generator_state: ResMut<NextState<GeneratorState>>,
|
||||||
cur_game_state: Res<State<MenuState>>,
|
cur_game_state: Res<State<MenuState>>,
|
||||||
@@ -280,7 +282,7 @@ fn spawn_map(
|
|||||||
) {
|
) {
|
||||||
let b_painter = biome_painters.get(painter.handle.clone());
|
let b_painter = biome_painters.get(painter.handle.clone());
|
||||||
let cur_painter = b_painter.unwrap();
|
let cur_painter = b_painter.unwrap();
|
||||||
paint_map(&mut heightmap, cur_painter, &tile_assets, &tile_mappers);
|
paint_map(&mut heightmap, cur_painter, &tile_assets, &biome_assets, &tile_mappers);
|
||||||
|
|
||||||
let chunk_meshes: Vec<_> = heightmap
|
let chunk_meshes: Vec<_> = heightmap
|
||||||
.chunks
|
.chunks
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use bevy::{
|
|||||||
use bevy_rapier3d::geometry::{Collider, TriMeshFlags};
|
use bevy_rapier3d::geometry::{Collider, TriMeshFlags};
|
||||||
use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator};
|
||||||
use world_generation::{
|
use world_generation::{
|
||||||
|
biome_asset::BiomeAsset,
|
||||||
biome_painter::BiomePainterAsset,
|
biome_painter::BiomePainterAsset,
|
||||||
generators::{chunk_colliders::generate_chunk_collider, mesh_generator::generate_chunk_mesh},
|
generators::{chunk_colliders::generate_chunk_collider, mesh_generator::generate_chunk_mesh},
|
||||||
hex_utils::offset_to_world,
|
hex_utils::offset_to_world,
|
||||||
@@ -21,10 +22,11 @@ pub fn paint_map(
|
|||||||
map: &mut Map,
|
map: &mut Map,
|
||||||
painter: &BiomePainterAsset,
|
painter: &BiomePainterAsset,
|
||||||
tiles: &Res<Assets<TileAsset>>,
|
tiles: &Res<Assets<TileAsset>>,
|
||||||
|
biomes: &Res<Assets<BiomeAsset>>,
|
||||||
mappers: &Res<Assets<TileMapperAsset>>,
|
mappers: &Res<Assets<TileMapperAsset>>,
|
||||||
) {
|
) {
|
||||||
map.chunks.par_iter_mut().for_each(|chunk: &mut Chunk| {
|
map.chunks.par_iter_mut().for_each(|chunk: &mut Chunk| {
|
||||||
paint_chunk(chunk, painter, tiles, mappers);
|
paint_chunk(chunk, painter, tiles, biomes, mappers);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,6 +34,7 @@ pub fn paint_chunk(
|
|||||||
chunk: &mut Chunk,
|
chunk: &mut Chunk,
|
||||||
painter: &BiomePainterAsset,
|
painter: &BiomePainterAsset,
|
||||||
tiles: &Res<Assets<TileAsset>>,
|
tiles: &Res<Assets<TileAsset>>,
|
||||||
|
biomes: &Res<Assets<BiomeAsset>>,
|
||||||
mappers: &Res<Assets<TileMapperAsset>>,
|
mappers: &Res<Assets<TileMapperAsset>>,
|
||||||
) {
|
) {
|
||||||
for z in 0..Chunk::SIZE {
|
for z in 0..Chunk::SIZE {
|
||||||
@@ -40,8 +43,11 @@ pub fn paint_chunk(
|
|||||||
let height = chunk.heights[idx];
|
let height = chunk.heights[idx];
|
||||||
let moisture = chunk.moisture[idx];
|
let moisture = chunk.moisture[idx];
|
||||||
let temperature = chunk.temperature[idx];
|
let temperature = chunk.temperature[idx];
|
||||||
let biome = mappers.get(painter.sample_biome(moisture, temperature));
|
let biome = biomes
|
||||||
let tile_handle = biome.unwrap().sample_tile(height);
|
.get(painter.sample_biome(&biomes, moisture, temperature, 0.))
|
||||||
|
.unwrap();
|
||||||
|
let mapper = mappers.get(biome.tile_mapper.clone());
|
||||||
|
let tile_handle = mapper.unwrap().sample_tile(height);
|
||||||
let tile = tiles.get(tile_handle).unwrap();
|
let tile = tiles.get(tile_handle).unwrap();
|
||||||
chunk.textures[idx] = [tile.texture_id, tile.side_texture_id];
|
chunk.textures[idx] = [tile.texture_id, tile.side_texture_id];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user