misc fixes
This commit is contained in:
@@ -3,12 +3,12 @@ use core::f32;
|
|||||||
use bevy::math::{IVec2, UVec2};
|
use bevy::math::{IVec2, UVec2};
|
||||||
use bevy::prelude::{FloatExt, Vec2};
|
use bevy::prelude::{FloatExt, Vec2};
|
||||||
use bevy::utils::default;
|
use bevy::utils::default;
|
||||||
use noise::{NoiseFn, SuperSimplex};
|
use noise::{NoiseFn, Simplex, SuperSimplex};
|
||||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||||
|
|
||||||
use crate::biome_painter::BiomePainter;
|
use crate::biome_painter::BiomePainter;
|
||||||
use crate::map::biome_map::{BiomeChunk, BiomeData, BiomeMap};
|
use crate::map::biome_map::{BiomeChunk, BiomeData, BiomeMap};
|
||||||
use crate::prelude::*;
|
use crate::{map, prelude::*};
|
||||||
|
|
||||||
pub fn generate_heightmap(cfg: &GenerationConfig, seed: u32, painter: &BiomePainter) -> (Map, BiomeMap) {
|
pub fn generate_heightmap(cfg: &GenerationConfig, seed: u32, painter: &BiomePainter) -> (Map, BiomeMap) {
|
||||||
let biomes = generate_biomes(cfg, seed, painter);
|
let biomes = generate_biomes(cfg, seed, painter);
|
||||||
@@ -74,9 +74,9 @@ pub fn generate_biome_chunk(
|
|||||||
data: [BiomeData::default(); Chunk::AREA],
|
data: [BiomeData::default(); Chunk::AREA],
|
||||||
tiles: Vec::with_capacity(Chunk::AREA),
|
tiles: Vec::with_capacity(Chunk::AREA),
|
||||||
};
|
};
|
||||||
let noise_m = SuperSimplex::new(seed + 1);
|
let noise_m = Simplex::new(seed + 1);
|
||||||
let noise_t = SuperSimplex::new(seed + 2);
|
let noise_t = Simplex::new(seed + 2);
|
||||||
let noise_c = SuperSimplex::new(seed + 3);
|
let noise_c = Simplex::new(seed + 3);
|
||||||
|
|
||||||
for z in 0..Chunk::SIZE {
|
for z in 0..Chunk::SIZE {
|
||||||
for x in 0..Chunk::SIZE {
|
for x in 0..Chunk::SIZE {
|
||||||
@@ -86,7 +86,8 @@ pub fn generate_biome_chunk(
|
|||||||
&cfg.moisture_noise,
|
&cfg.moisture_noise,
|
||||||
&noise_m,
|
&noise_m,
|
||||||
cfg.size.as_vec2(),
|
cfg.size.as_vec2(),
|
||||||
0.0,
|
cfg.border_size,
|
||||||
|
100.0,
|
||||||
);
|
);
|
||||||
let temperature = sample_point(
|
let temperature = sample_point(
|
||||||
x as f64 + chunk_x as f64 * Chunk::SIZE as f64,
|
x as f64 + chunk_x as f64 * Chunk::SIZE as f64,
|
||||||
@@ -94,7 +95,8 @@ pub fn generate_biome_chunk(
|
|||||||
&cfg.temperature_noise,
|
&cfg.temperature_noise,
|
||||||
&noise_t,
|
&noise_t,
|
||||||
cfg.size.as_vec2(),
|
cfg.size.as_vec2(),
|
||||||
0.0,
|
cfg.border_size,
|
||||||
|
50.0,
|
||||||
);
|
);
|
||||||
let continentality = sample_point(
|
let continentality = sample_point(
|
||||||
x as f64 + chunk_x as f64 * Chunk::SIZE as f64,
|
x as f64 + chunk_x as f64 * Chunk::SIZE as f64,
|
||||||
@@ -102,6 +104,7 @@ pub fn generate_biome_chunk(
|
|||||||
&cfg.continent_noise,
|
&cfg.continent_noise,
|
||||||
&noise_c,
|
&noise_c,
|
||||||
cfg.size.as_vec2(),
|
cfg.size.as_vec2(),
|
||||||
|
cfg.border_size,
|
||||||
0.0,
|
0.0,
|
||||||
);
|
);
|
||||||
let data = BiomeData {
|
let data = BiomeData {
|
||||||
@@ -135,6 +138,7 @@ pub fn generate_noise_map(size: UVec2, seed: u32, cfg: &NoiseConfig, border_size
|
|||||||
&noise,
|
&noise,
|
||||||
size.as_vec2(),
|
size.as_vec2(),
|
||||||
border_size,
|
border_size,
|
||||||
|
0.0,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
return row;
|
return row;
|
||||||
@@ -154,7 +158,7 @@ pub fn generate_chunk(
|
|||||||
let mut result: [f32; Chunk::SIZE * Chunk::SIZE] = [0.; Chunk::AREA];
|
let mut result: [f32; Chunk::SIZE * Chunk::SIZE] = [0.; Chunk::AREA];
|
||||||
let mut data = [BiomeData::default(); Chunk::AREA];
|
let mut data = [BiomeData::default(); Chunk::AREA];
|
||||||
let mut biome_ids = [0; Chunk::AREA];
|
let mut biome_ids = [0; Chunk::AREA];
|
||||||
let noise = SuperSimplex::new(seed);
|
let noise = Simplex::new(seed);
|
||||||
let mut min = f32::MAX;
|
let mut min = f32::MAX;
|
||||||
let mut max = f32::MIN;
|
let mut max = f32::MIN;
|
||||||
for z in 0..Chunk::SIZE {
|
for z in 0..Chunk::SIZE {
|
||||||
@@ -175,6 +179,7 @@ pub fn generate_chunk(
|
|||||||
&noise,
|
&noise,
|
||||||
cfg.size.as_vec2(),
|
cfg.size.as_vec2(),
|
||||||
cfg.border_size,
|
cfg.border_size,
|
||||||
|
0.0,
|
||||||
) * blend;
|
) * blend;
|
||||||
}
|
}
|
||||||
let idx = x + z * Chunk::SIZE;
|
let idx = x + z * Chunk::SIZE;
|
||||||
@@ -199,7 +204,15 @@ pub fn generate_chunk(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sample_point(x: f64, z: f64, cfg: &NoiseConfig, noise: &impl NoiseFn<f64, 2>, size: Vec2, border_size: f32) -> f32 {
|
fn sample_point(
|
||||||
|
x: f64,
|
||||||
|
z: f64,
|
||||||
|
cfg: &NoiseConfig,
|
||||||
|
noise: &impl NoiseFn<f64, 2>,
|
||||||
|
size: Vec2,
|
||||||
|
border_size: f32,
|
||||||
|
border_value: f32,
|
||||||
|
) -> f32 {
|
||||||
let x_s = x / cfg.scale;
|
let x_s = x / cfg.scale;
|
||||||
let z_s = z / cfg.scale;
|
let z_s = z / cfg.scale;
|
||||||
|
|
||||||
@@ -235,7 +248,7 @@ fn sample_point(x: f64, z: f64, cfg: &NoiseConfig, noise: &impl NoiseFn<f64, 2>,
|
|||||||
let d2 = od.x.min(od.y);
|
let d2 = od.x.min(od.y);
|
||||||
let d = d1.min(d2).min(border_size).remap(0., border_size, 0., 1.);
|
let d = d1.min(d2).min(border_size).remap(0., border_size, 0., 1.);
|
||||||
|
|
||||||
return (elevation as f32) * d;
|
return border_value.lerp(elevation as f32, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mask(mask: f64, value: f64) -> f64 {
|
fn mask(mask: f64, value: f64) -> f64 {
|
||||||
|
|||||||
@@ -106,20 +106,20 @@ fn get_height_color_blend(base_color: Hsla, height: f32, height2: f32, smooth: f
|
|||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_biome_noise_map(map: &BiomeMap) -> ImageBuffer<image::Rgba<u8>, Vec<u8>> {
|
pub fn render_biome_noise_map(map: &BiomeMap, multi: Vec3) -> ImageBuffer<image::Rgba<u8>, Vec<u8>> {
|
||||||
let mut image = ImageBuffer::new(map.width as u32, map.height as u32);
|
let mut image = ImageBuffer::new(map.width as u32, map.height as u32);
|
||||||
update_biome_noise_map(map, &mut image);
|
update_biome_noise_map(map, multi, &mut image);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_biome_noise_map(map: &BiomeMap, image: &mut ImageBuffer<image::Rgba<u8>, Vec<u8>>) {
|
pub fn update_biome_noise_map(map: &BiomeMap, multi: Vec3, image: &mut ImageBuffer<image::Rgba<u8>, Vec<u8>>) {
|
||||||
image.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| {
|
image.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| {
|
||||||
let tile = map.get_biome_data(x as usize, y as usize);
|
let tile = map.get_biome_data(x as usize, y as usize);
|
||||||
|
|
||||||
let color = LinearRgba::rgb(
|
let color = LinearRgba::rgb(
|
||||||
tile.temperature / 100.0,
|
(tile.temperature / 100.0) * multi.x,
|
||||||
tile.continentality / 100.0,
|
(tile.continentality / 100.0) * multi.y,
|
||||||
tile.moisture / 100.0,
|
(tile.moisture / 100.0) * multi.z,
|
||||||
);
|
);
|
||||||
*pixel = to_pixel(&color);
|
*pixel = to_pixel(&color);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -162,10 +162,10 @@ fn create_heightmap(
|
|||||||
biome_painter: Res<BiomePainter>,
|
biome_painter: Res<BiomePainter>,
|
||||||
) {
|
) {
|
||||||
let config = GenerationConfig {
|
let config = GenerationConfig {
|
||||||
biome_blend: 16,
|
biome_blend: 32,
|
||||||
biome_dither: 16.,
|
biome_dither: 16.,
|
||||||
continent_noise: NoiseConfig {
|
continent_noise: NoiseConfig {
|
||||||
scale: 1000.,
|
scale: 800.,
|
||||||
layers: vec![GeneratorLayer {
|
layers: vec![GeneratorLayer {
|
||||||
base_roughness: 2.14,
|
base_roughness: 2.14,
|
||||||
roughness: 0.87,
|
roughness: 0.87,
|
||||||
@@ -180,7 +180,7 @@ fn create_heightmap(
|
|||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
moisture_noise: NoiseConfig {
|
moisture_noise: NoiseConfig {
|
||||||
scale: 500.,
|
scale: 900.,
|
||||||
layers: vec![GeneratorLayer {
|
layers: vec![GeneratorLayer {
|
||||||
base_roughness: 2.14,
|
base_roughness: 2.14,
|
||||||
roughness: 0.87,
|
roughness: 0.87,
|
||||||
@@ -195,7 +195,7 @@ fn create_heightmap(
|
|||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
temperature_noise: NoiseConfig {
|
temperature_noise: NoiseConfig {
|
||||||
scale: 900.,
|
scale: 700.,
|
||||||
layers: vec![GeneratorLayer {
|
layers: vec![GeneratorLayer {
|
||||||
base_roughness: 2.14,
|
base_roughness: 2.14,
|
||||||
roughness: 0.87,
|
roughness: 0.87,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use bevy::{prelude::*, render::render_asset::RenderAssetUsages};
|
|||||||
use bevy_inspector_egui::bevy_egui::EguiContexts;
|
use bevy_inspector_egui::bevy_egui::EguiContexts;
|
||||||
use bevy_inspector_egui::egui::{self};
|
use bevy_inspector_egui::egui::{self};
|
||||||
use bevy_rapier3d::rapier::crossbeam::deque::Steal;
|
use bevy_rapier3d::rapier::crossbeam::deque::Steal;
|
||||||
|
use image::{ImageBuffer, Rgba};
|
||||||
use world_generation::map::biome_map::{self, BiomeMap};
|
use world_generation::map::biome_map::{self, BiomeMap};
|
||||||
use world_generation::map::map_utils::{render_biome_map, render_biome_noise_map, update_map};
|
use world_generation::map::map_utils::{render_biome_map, render_biome_noise_map, update_map};
|
||||||
use world_generation::{map::map_utils::render_map, prelude::Map, states::GeneratorState};
|
use world_generation::{map::map_utils::render_map, prelude::Map, states::GeneratorState};
|
||||||
@@ -53,9 +54,12 @@ enum MapDisplayType {
|
|||||||
HeightMap,
|
HeightMap,
|
||||||
Biomes,
|
Biomes,
|
||||||
BiomeNoise,
|
BiomeNoise,
|
||||||
|
BiomeNoiseTemp,
|
||||||
|
BiomeNoiseContinent,
|
||||||
|
BiomeNoiseMoisture,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_map_ui(image: Res<MapImage>, mut contexts: EguiContexts, mut state: ResMut<UIState>) {
|
fn render_map_ui(image: Res<MapImage>, heightmap: Res<Map>, biome_map: Res<BiomeMap>, mut contexts: EguiContexts, mut state: ResMut<UIState>) {
|
||||||
let id = contexts.add_image(image.0.clone_weak());
|
let id = contexts.add_image(image.0.clone_weak());
|
||||||
|
|
||||||
let mut map_type = state.target_map_type;
|
let mut map_type = state.target_map_type;
|
||||||
@@ -68,12 +72,32 @@ fn render_map_ui(image: Res<MapImage>, mut contexts: EguiContexts, mut state: Re
|
|||||||
ui.selectable_value(&mut map_type, MapDisplayType::HeightMap, "Heightmap");
|
ui.selectable_value(&mut map_type, MapDisplayType::HeightMap, "Heightmap");
|
||||||
ui.selectable_value(&mut map_type, MapDisplayType::Biomes, "Biomes");
|
ui.selectable_value(&mut map_type, MapDisplayType::Biomes, "Biomes");
|
||||||
ui.selectable_value(&mut map_type, MapDisplayType::BiomeNoise, "Biome Noise");
|
ui.selectable_value(&mut map_type, MapDisplayType::BiomeNoise, "Biome Noise");
|
||||||
|
ui.selectable_value(
|
||||||
|
&mut map_type,
|
||||||
|
MapDisplayType::BiomeNoiseTemp,
|
||||||
|
"Biome Noise: Tempurature",
|
||||||
|
);
|
||||||
|
ui.selectable_value(
|
||||||
|
&mut map_type,
|
||||||
|
MapDisplayType::BiomeNoiseContinent,
|
||||||
|
"Biome Noise: Continent",
|
||||||
|
);
|
||||||
|
ui.selectable_value(
|
||||||
|
&mut map_type,
|
||||||
|
MapDisplayType::BiomeNoiseMoisture,
|
||||||
|
"Biome Noise: Moisture",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.add(egui::widgets::Image::new(egui::load::SizedTexture::new(
|
ui.add(egui::widgets::Image::new(egui::load::SizedTexture::new(
|
||||||
id,
|
id,
|
||||||
[512.0, 512.0],
|
[512.0, 512.0],
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
if ui.button("Save Image").clicked() {
|
||||||
|
let img = get_map_image(&heightmap, &biome_map, map_type);
|
||||||
|
_ = img.save(format!("{:?}.png", map_type));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
state.target_map_type = map_type;
|
state.target_map_type = map_type;
|
||||||
@@ -90,11 +114,7 @@ fn update_map_render(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = match state.target_map_type {
|
let result = get_map_image(&heightmap, &biome_map, state.target_map_type);
|
||||||
MapDisplayType::HeightMap => render_map(&heightmap, 0.1),
|
|
||||||
MapDisplayType::Biomes => render_biome_map(&heightmap, &biome_map),
|
|
||||||
MapDisplayType::BiomeNoise => render_biome_noise_map(&biome_map),
|
|
||||||
};
|
|
||||||
images.insert(
|
images.insert(
|
||||||
image.0.id(),
|
image.0.id(),
|
||||||
Image::from_dynamic(result.into(), true, RenderAssetUsages::RENDER_WORLD),
|
Image::from_dynamic(result.into(), true, RenderAssetUsages::RENDER_WORLD),
|
||||||
@@ -102,3 +122,14 @@ fn update_map_render(
|
|||||||
|
|
||||||
state.cur_map_type = state.target_map_type;
|
state.cur_map_type = state.target_map_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_map_image(heightmap: &Map, biome_map: &BiomeMap, map_type: MapDisplayType) -> ImageBuffer<Rgba<u8>, Vec<u8>> {
|
||||||
|
return match map_type {
|
||||||
|
MapDisplayType::HeightMap => render_map(&heightmap, 0.1),
|
||||||
|
MapDisplayType::Biomes => render_biome_map(&heightmap, &biome_map),
|
||||||
|
MapDisplayType::BiomeNoise => render_biome_noise_map(&biome_map, Vec3::ONE),
|
||||||
|
MapDisplayType::BiomeNoiseTemp => render_biome_noise_map(&biome_map, Vec3::X),
|
||||||
|
MapDisplayType::BiomeNoiseContinent => render_biome_noise_map(&biome_map, Vec3::Y),
|
||||||
|
MapDisplayType::BiomeNoiseMoisture => render_biome_noise_map(&biome_map, Vec3::Z),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user