preparation for improved biome generation

This commit is contained in:
2024-07-02 22:56:11 -04:00
parent b175a2f1fd
commit fa0ae8509f
5 changed files with 92 additions and 2 deletions

View 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]);
}
}

View File

@@ -1,5 +1,6 @@
use bevy::prelude::*;
use bevy_inspector_egui::InspectorOptions;
use serde::{Deserialize, Serialize};
use super::chunk::Chunk;
@@ -9,6 +10,7 @@ pub struct GenerationConfig {
pub noise_scale: f64,
pub sea_level: f64,
pub border_size: f32,
pub biome_blend: usize,
pub size: UVec2,
pub layers: Vec<GeneratorLayer>,
}
@@ -22,7 +24,7 @@ impl GenerationConfig {
}
}
#[derive(Reflect, InspectorOptions)]
#[derive(Reflect, InspectorOptions, Serialize, Deserialize, Debug)]
pub struct GeneratorLayer {
pub strength: f64,
pub min_value: f64,

View File

@@ -1,4 +1,5 @@
pub mod chunk;
pub mod mesh_chunk;
pub mod config;
pub mod map;
pub mod map;
pub mod biome_map;

View File

@@ -6,6 +6,7 @@ use bevy::{
};
use serde::{Deserialize, Serialize};
use crate::prelude::GeneratorLayer;
use crate::tile_manager::TileAsset;
pub struct TileMapper;
@@ -16,6 +17,7 @@ pub struct TileMapperAsset {
pub tiles: Vec<Handle<TileAsset>>,
pub tiles_path: Vec<String>,
pub thresholds: Vec<f32>,
pub generator_layers: Vec<GeneratorLayer>
}
impl TileMapperAsset {

View File

@@ -183,6 +183,7 @@ fn create_heightmap(
mut next_state: ResMut<NextState<GeneratorState>>,
) {
let config = GenerationConfig {
biome_blend: 3,
layers: vec![
GeneratorLayer {
base_roughness: 2.14,