preparation for improved biome generation
This commit is contained in:
84
engine/world_generation/src/map/biome_map.rs
Normal file
84
engine/world_generation/src/map/biome_map.rs
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
use bevy::math::UVec2;
|
||||||
|
|
||||||
|
use super::chunk::Chunk;
|
||||||
|
|
||||||
|
pub struct BiomeMap {
|
||||||
|
pub height: usize,
|
||||||
|
pub width: usize,
|
||||||
|
pub chunks: Vec<[Vec<f32>; Chunk::AREA]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BiomeMap {
|
||||||
|
pub fn new(size: UVec2) -> Self {
|
||||||
|
return BiomeMap {
|
||||||
|
height: size.y as usize,
|
||||||
|
width: size.x as usize,
|
||||||
|
chunks: Vec::with_capacity(size.length_squared() as usize),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn blend(&mut self, count: usize) {
|
||||||
|
for _ in 0..count {
|
||||||
|
self.blend_once();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn blend_once(&mut self) {
|
||||||
|
for y in 0..self.height {
|
||||||
|
for x in 0..self.width {
|
||||||
|
let kernel = self.get_kernel(x as i32, y as i32);
|
||||||
|
let r = kernel.iter().filter_map(|f| *f).fold(Vec::new(), |a, b| {
|
||||||
|
if a.len() != b.len() {
|
||||||
|
return b.iter().map(|f| *f).collect();
|
||||||
|
}
|
||||||
|
return a.iter().zip(b).map(|v| v.0 + v.1).collect();
|
||||||
|
});
|
||||||
|
|
||||||
|
let sum: f32 = r.iter().sum();
|
||||||
|
|
||||||
|
*self.get_biome_mut(x, y) = r.iter().map(|f| f / sum).collect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_biome_mut(&mut self, x: usize, y: usize) -> &mut Vec<f32> {
|
||||||
|
let cx = x as usize / Chunk::SIZE;
|
||||||
|
let cy = y as usize / Chunk::SIZE;
|
||||||
|
let chunk_index = cy * self.width as usize + cx;
|
||||||
|
let ix = x as usize - (x as usize * Chunk::SIZE);
|
||||||
|
let iy = y as usize - (y as usize * Chunk::SIZE);
|
||||||
|
let index = iy * self.width as usize + ix;
|
||||||
|
return &mut self.chunks[chunk_index][index];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_kernel(&self, x: i32, y: i32) -> [Option<&Vec<f32>>; 9] {
|
||||||
|
return [
|
||||||
|
self.get_biome(x - 1, y - 1),
|
||||||
|
self.get_biome(x, y - 1),
|
||||||
|
self.get_biome(x + 1, y - 1),
|
||||||
|
self.get_biome(x - 1, y),
|
||||||
|
self.get_biome(x, y),
|
||||||
|
self.get_biome(x + 1, y),
|
||||||
|
self.get_biome(x - 1, y + 1),
|
||||||
|
self.get_biome(x, y + 1),
|
||||||
|
self.get_biome(x + 1, y + 1),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_biome(&self, x: i32, y: i32) -> Option<&Vec<f32>> {
|
||||||
|
if x < 0 || y < 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if x >= self.width as i32 || y >= self.height as i32 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cx = x as usize / Chunk::SIZE;
|
||||||
|
let cy = y as usize / Chunk::SIZE;
|
||||||
|
let chunk_index = cy * self.width as usize + cx;
|
||||||
|
let ix = x as usize - (x as usize * Chunk::SIZE);
|
||||||
|
let iy = y as usize - (y as usize * Chunk::SIZE);
|
||||||
|
let index = iy * self.width as usize + ix;
|
||||||
|
return Some(&self.chunks[chunk_index][index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_inspector_egui::InspectorOptions;
|
use bevy_inspector_egui::InspectorOptions;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::chunk::Chunk;
|
use super::chunk::Chunk;
|
||||||
|
|
||||||
@@ -9,6 +10,7 @@ pub struct GenerationConfig {
|
|||||||
pub noise_scale: f64,
|
pub noise_scale: f64,
|
||||||
pub sea_level: f64,
|
pub sea_level: f64,
|
||||||
pub border_size: f32,
|
pub border_size: f32,
|
||||||
|
pub biome_blend: usize,
|
||||||
pub size: UVec2,
|
pub size: UVec2,
|
||||||
pub layers: Vec<GeneratorLayer>,
|
pub layers: Vec<GeneratorLayer>,
|
||||||
}
|
}
|
||||||
@@ -22,7 +24,7 @@ impl GenerationConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Reflect, InspectorOptions)]
|
#[derive(Reflect, InspectorOptions, Serialize, Deserialize, Debug)]
|
||||||
pub struct GeneratorLayer {
|
pub struct GeneratorLayer {
|
||||||
pub strength: f64,
|
pub strength: f64,
|
||||||
pub min_value: f64,
|
pub min_value: f64,
|
||||||
|
|||||||
@@ -2,3 +2,4 @@ pub mod chunk;
|
|||||||
pub mod mesh_chunk;
|
pub mod mesh_chunk;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod map;
|
pub mod map;
|
||||||
|
pub mod biome_map;
|
||||||
@@ -6,6 +6,7 @@ use bevy::{
|
|||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::prelude::GeneratorLayer;
|
||||||
use crate::tile_manager::TileAsset;
|
use crate::tile_manager::TileAsset;
|
||||||
|
|
||||||
pub struct TileMapper;
|
pub struct TileMapper;
|
||||||
@@ -16,6 +17,7 @@ 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 {
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ fn create_heightmap(
|
|||||||
mut next_state: ResMut<NextState<GeneratorState>>,
|
mut next_state: ResMut<NextState<GeneratorState>>,
|
||||||
) {
|
) {
|
||||||
let config = GenerationConfig {
|
let config = GenerationConfig {
|
||||||
|
biome_blend: 3,
|
||||||
layers: vec![
|
layers: vec![
|
||||||
GeneratorLayer {
|
GeneratorLayer {
|
||||||
base_roughness: 2.14,
|
base_roughness: 2.14,
|
||||||
|
|||||||
Reference in New Issue
Block a user