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::{
|
||||
asset::{Asset, Handle},
|
||||
reflect::TypePath,
|
||||
render::render_resource::encase::rts_array::Length,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::tile_mapper::TileMapperAsset;
|
||||
use crate::biome_asset::BiomeAsset;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, TypePath, Asset, Clone)]
|
||||
pub struct BiomePainterAsset {
|
||||
#[serde(skip)]
|
||||
pub biomes: Vec<Handle<TileMapperAsset>>,
|
||||
pub biomes_path: [String; 16],
|
||||
pub biomes: Vec<Handle<BiomeAsset>>,
|
||||
pub biomes_path: Vec<String>,
|
||||
}
|
||||
|
||||
impl BiomePainterAsset {
|
||||
pub fn sample_biome(&self, moisture: f32, temperature: f32) -> Handle<TileMapperAsset> {
|
||||
let x = (moisture.clamp(0., 1.) * 3.).ceil() as usize;
|
||||
let y = (temperature.clamp(0., 1.) * 3.).ceil() as usize;
|
||||
return self.biomes[x + y * 4].clone();
|
||||
pub fn sample_biome(
|
||||
&self,
|
||||
assets: &Assets<BiomeAsset>,
|
||||
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::prelude::*;
|
||||
use crate::tile_manager::TileAsset;
|
||||
use crate::tile_mapper::TileMapperAsset;
|
||||
use crate::{biome_asset::BiomeAsset, biome_painter::BiomePainterAsset};
|
||||
use bevy::{
|
||||
prelude::*,
|
||||
render::{
|
||||
@@ -16,6 +16,7 @@ pub fn generate_packed_chunk_mesh(
|
||||
map: &Map,
|
||||
painter: &BiomePainterAsset,
|
||||
tiles: &Res<Assets<TileAsset>>,
|
||||
biomes: &Res<Assets<BiomeAsset>>,
|
||||
mappers: &Res<Assets<TileMapperAsset>>,
|
||||
) -> Mesh {
|
||||
let vertex_count: usize = Chunk::SIZE * Chunk::SIZE * 6;
|
||||
@@ -31,8 +32,12 @@ pub fn generate_packed_chunk_mesh(
|
||||
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 biome = biomes
|
||||
.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();
|
||||
|
||||
create_packed_tile(
|
||||
|
||||
@@ -8,3 +8,4 @@ pub mod prelude;
|
||||
pub mod states;
|
||||
pub mod tile_manager;
|
||||
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 strength: f64,
|
||||
pub min_value: f64,
|
||||
|
||||
@@ -17,7 +17,6 @@ pub struct TileMapperAsset {
|
||||
pub tiles: Vec<Handle<TileAsset>>,
|
||||
pub tiles_path: Vec<String>,
|
||||
pub thresholds: Vec<f32>,
|
||||
pub generator_layers: Vec<GeneratorLayer>
|
||||
}
|
||||
|
||||
impl TileMapperAsset {
|
||||
|
||||
Reference in New Issue
Block a user