map visualization
This commit is contained in:
@@ -153,7 +153,7 @@ pub struct BiomeChunk {
|
|||||||
|
|
||||||
impl BiomeChunk {
|
impl BiomeChunk {
|
||||||
pub fn get_biome(&self, x: usize, y: usize) -> &Vec<f32> {
|
pub fn get_biome(&self, x: usize, y: usize) -> &Vec<f32> {
|
||||||
return &self.tiles[x as usize + y as usize * Chunk::SIZE];
|
return &self.tiles[x + y * Chunk::SIZE];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_biome_data(&self, x: usize, y: usize) -> &BiomeData {
|
pub fn get_biome_data(&self, x: usize, y: usize) -> &BiomeData {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::ops::Add;
|
||||||
|
|
||||||
use bevy::{math::VectorSpace, prelude::*};
|
use bevy::{math::VectorSpace, prelude::*};
|
||||||
use image::ImageBuffer;
|
use image::ImageBuffer;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
@@ -105,10 +107,7 @@ fn get_height_color_blend(base_color: Hsla, height: f32, height2: f32, smooth: f
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_biome_noise_map(map: &BiomeMap) -> ImageBuffer<image::Rgba<u8>, Vec<u8>> {
|
pub fn render_biome_noise_map(map: &BiomeMap) -> ImageBuffer<image::Rgba<u8>, Vec<u8>> {
|
||||||
let mut image = ImageBuffer::new(
|
let mut image = ImageBuffer::new(map.width as u32, map.height as u32);
|
||||||
map.width as u32 * Chunk::SIZE as u32,
|
|
||||||
map.height as u32 * Chunk::SIZE as u32,
|
|
||||||
);
|
|
||||||
update_biome_noise_map(map, &mut image);
|
update_biome_noise_map(map, &mut image);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
@@ -139,15 +138,18 @@ pub fn update_biome_map(map: &Map, biome_map: &BiomeMap, image: &mut ImageBuffer
|
|||||||
let map_biome_count = map.biome_count as f32;
|
let map_biome_count = map.biome_count as f32;
|
||||||
image.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| {
|
image.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| {
|
||||||
let coord = HexCoord::from_grid_pos(x as usize, y as usize);
|
let coord = HexCoord::from_grid_pos(x as usize, y as usize);
|
||||||
let biome_blend = biome_map.get_biome(x as i32, y as i32);
|
let biome_blend = biome_map.get_biome(x as i32, y as i32).unwrap();
|
||||||
let right = coord.get_neighbor(1);
|
let right = coord.get_neighbor(1);
|
||||||
let biome_id = map.get_biome_id(&coord) as f32;
|
let mut color = Oklaba::BLACK;
|
||||||
let hue = (biome_id / map_biome_count) * 360.0;
|
for i in 0..biome_blend.len() {
|
||||||
let mut color = Hsla::hsl(hue, 0.8, 0.9);
|
let mut c: Oklaba = Hsla::hsl((i as f32 / map_biome_count) * 360.0, 0.8, 0.7).into();
|
||||||
|
c *= biome_blend[i];
|
||||||
|
color = Oklaba::add(c, color.into()).into();
|
||||||
|
}
|
||||||
if map.is_in_bounds(&right) {
|
if map.is_in_bounds(&right) {
|
||||||
let h1 = map.sample_height(&coord);
|
let h1 = map.sample_height(&coord);
|
||||||
let h2 = map.sample_height(&right);
|
let h2 = map.sample_height(&right);
|
||||||
color = get_height_color_blend(color, h1, h2, 0.5);
|
color = get_height_color_blend(color.into(), h1, h2, 0.5).into();
|
||||||
}
|
}
|
||||||
|
|
||||||
*pixel = to_pixel(&color.into());
|
*pixel = to_pixel(&color.into());
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ fn create_heightmap(
|
|||||||
biome_blend: 16,
|
biome_blend: 16,
|
||||||
biome_dither: 16.,
|
biome_dither: 16.,
|
||||||
continent_noise: NoiseConfig {
|
continent_noise: NoiseConfig {
|
||||||
scale: 500.,
|
scale: 1000.,
|
||||||
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: 500.,
|
scale: 900.,
|
||||||
layers: vec![GeneratorLayer {
|
layers: vec![GeneratorLayer {
|
||||||
base_roughness: 2.14,
|
base_roughness: 2.14,
|
||||||
roughness: 0.87,
|
roughness: 0.87,
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
use bevy::{prelude::*, render::render_asset::RenderAssetUsages};
|
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 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_map, prelude::Map, states::GeneratorState};
|
use world_generation::{map::map_utils::render_map, prelude::Map, states::GeneratorState};
|
||||||
|
|
||||||
pub struct EditorPlugin;
|
pub struct EditorPlugin;
|
||||||
@@ -10,7 +13,10 @@ impl Plugin for EditorPlugin {
|
|||||||
app.init_resource::<UIState>();
|
app.init_resource::<UIState>();
|
||||||
|
|
||||||
app.add_systems(PostUpdate, prepare_image.run_if(in_state(GeneratorState::SpawnMap)));
|
app.add_systems(PostUpdate, prepare_image.run_if(in_state(GeneratorState::SpawnMap)));
|
||||||
app.add_systems(Update, (render_map_ui).run_if(in_state(GeneratorState::Idle)));
|
app.add_systems(
|
||||||
|
Update,
|
||||||
|
(render_map_ui, update_map_render).run_if(in_state(GeneratorState::Idle)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,23 +33,72 @@ pub fn prepare_image(mut images: ResMut<Assets<Image>>, heightmap: Res<Map>, mut
|
|||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
struct UIState {
|
struct UIState {
|
||||||
pub is_open: bool,
|
pub is_open: bool,
|
||||||
|
pub target_map_type: MapDisplayType,
|
||||||
|
pub cur_map_type: MapDisplayType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for UIState {
|
impl Default for UIState {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { is_open: true }
|
Self {
|
||||||
|
is_open: true,
|
||||||
|
target_map_type: default(),
|
||||||
|
cur_map_type: default(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
|
||||||
|
enum MapDisplayType {
|
||||||
|
#[default]
|
||||||
|
HeightMap,
|
||||||
|
Biomes,
|
||||||
|
BiomeNoise,
|
||||||
|
}
|
||||||
|
|
||||||
fn render_map_ui(image: Res<MapImage>, mut contexts: EguiContexts, mut state: ResMut<UIState>) {
|
fn render_map_ui(image: Res<MapImage>, 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 ctx = contexts.ctx_mut();
|
let ctx = contexts.ctx_mut();
|
||||||
egui::Window::new("Map").open(&mut state.is_open).show(ctx, |ui| {
|
egui::Window::new("Map").open(&mut state.is_open).show(ctx, |ui| {
|
||||||
ui.label("Map Test");
|
ui.label("Map Test");
|
||||||
|
egui::ComboBox::from_label("Display Type")
|
||||||
|
.selected_text(format!("{:?}", map_type))
|
||||||
|
.show_ui(ui, |ui| {
|
||||||
|
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::BiomeNoise, "Biome Noise");
|
||||||
|
});
|
||||||
|
|
||||||
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],
|
||||||
)));
|
)));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
state.target_map_type = map_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_map_render(
|
||||||
|
mut state: ResMut<UIState>,
|
||||||
|
mut images: ResMut<Assets<Image>>,
|
||||||
|
heightmap: Res<Map>,
|
||||||
|
biome_map: Res<BiomeMap>,
|
||||||
|
image: Res<MapImage>,
|
||||||
|
) {
|
||||||
|
if state.cur_map_type == state.target_map_type {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = match 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(
|
||||||
|
image.0.id(),
|
||||||
|
Image::from_dynamic(result.into(), true, RenderAssetUsages::RENDER_WORLD),
|
||||||
|
);
|
||||||
|
|
||||||
|
state.cur_map_type = state.target_map_type;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user