generator tweaks
data fixes wip biome map visualization
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
use bevy::math::{UVec2, Vec3};
|
||||
use bevy::{
|
||||
math::{UVec2, Vec3},
|
||||
prelude::Resource,
|
||||
};
|
||||
use noise::NoiseFn;
|
||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||
|
||||
use super::chunk::Chunk;
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Resource)]
|
||||
pub struct BiomeMap {
|
||||
pub height: usize,
|
||||
pub width: usize,
|
||||
|
||||
@@ -7,7 +7,7 @@ use super::biome_map::BiomeData;
|
||||
pub struct Chunk {
|
||||
pub heights: [f32; Chunk::AREA],
|
||||
pub textures: [[u32; 2]; Chunk::AREA],
|
||||
pub biome_data: [BiomeData; Chunk::AREA],
|
||||
// pub biome_data: [BiomeData; Chunk::AREA],
|
||||
pub biome_id: [usize; Chunk::AREA],
|
||||
pub chunk_offset: IVec2,
|
||||
pub min_level: f32,
|
||||
@@ -19,7 +19,7 @@ impl Default for Chunk {
|
||||
Self {
|
||||
heights: [0.; Chunk::AREA],
|
||||
textures: [[0; 2]; Chunk::AREA],
|
||||
biome_data: [BiomeData::default(); Chunk::AREA],
|
||||
// biome_data: [BiomeData::default(); Chunk::AREA],
|
||||
biome_id: [0; Chunk::AREA],
|
||||
chunk_offset: Default::default(),
|
||||
min_level: 0.0,
|
||||
|
||||
@@ -16,6 +16,7 @@ pub struct Map {
|
||||
pub sea_level: f32,
|
||||
pub min_level: f32,
|
||||
pub max_level: f32,
|
||||
pub biome_count: usize,
|
||||
}
|
||||
|
||||
impl Map {
|
||||
@@ -72,7 +73,18 @@ impl Map {
|
||||
return pos.is_in_bounds(self.height * Chunk::SIZE, self.width * Chunk::SIZE);
|
||||
}
|
||||
|
||||
pub fn get_biome(&self, pos: &HexCoord) -> &BiomeData {
|
||||
|
||||
pub fn get_biome_id(&self, pos: &HexCoord) -> usize {
|
||||
assert!(
|
||||
self.is_in_bounds(pos),
|
||||
"The provided coordinate is not within the map bounds"
|
||||
);
|
||||
|
||||
let chunk = &self.chunks[pos.to_chunk_index(self.width)];
|
||||
return chunk.biome_id[pos.to_chunk_local_index()];
|
||||
}
|
||||
/*
|
||||
pub fn get_biome_noise(&self, pos: &HexCoord) -> &BiomeData {
|
||||
assert!(
|
||||
self.is_in_bounds(pos),
|
||||
"The provided coordinate is not within the map bounds"
|
||||
@@ -111,6 +123,7 @@ impl Map {
|
||||
let chunk = &self.chunks[pos.to_chunk_index(self.width)];
|
||||
return chunk.biome_data[pos.to_chunk_local_index()].continentality;
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn get_center(&self) -> Vec3 {
|
||||
let w = self.get_world_width();
|
||||
|
||||
@@ -2,9 +2,13 @@ use bevy::{math::VectorSpace, prelude::*};
|
||||
use image::ImageBuffer;
|
||||
use rayon::prelude::*;
|
||||
|
||||
use crate::hex_utils::HexCoord;
|
||||
use crate::{biome_painter::BiomePainter, hex_utils::HexCoord};
|
||||
|
||||
use super::{biome_map::BiomeMap, chunk::Chunk, map::Map};
|
||||
use super::{
|
||||
biome_map::{self, BiomeMap},
|
||||
chunk::Chunk,
|
||||
map::Map,
|
||||
};
|
||||
|
||||
pub fn render_image(
|
||||
size: UVec2,
|
||||
@@ -60,51 +64,58 @@ pub fn update_map(map: &Map, smooth: f32, image: &mut ImageBuffer<image::Rgba<u8
|
||||
let coord = HexCoord::from_grid_pos(x as usize, y as usize);
|
||||
let right = coord.get_neighbor(1);
|
||||
let height = map.sample_height(&coord);
|
||||
|
||||
let mut color = Hsla::hsl(138.0, 1.0, 0.4);
|
||||
if height < map.sea_level {
|
||||
color.hue = 217.0;
|
||||
}
|
||||
|
||||
if map.is_in_bounds(&right) {
|
||||
let h2 = map.sample_height(&right);
|
||||
let mut d = h2 - height;
|
||||
|
||||
if smooth == 0.0 || d.abs() > smooth {
|
||||
if d > 0.0 {
|
||||
color.lightness += 0.1;
|
||||
} else if d < 0.0 {
|
||||
color.lightness -= 0.1;
|
||||
}
|
||||
} else {
|
||||
if d.abs() <= smooth {
|
||||
d /= smooth;
|
||||
if d > 0.0 {
|
||||
let c2: LinearRgba = color.with_lightness(color.lightness + 0.1).into();
|
||||
color = LinearRgba::lerp(&color.into(), c2, d).into();
|
||||
} else {
|
||||
let c2: LinearRgba = color.with_lightness(color.lightness - 0.1).into();
|
||||
color = LinearRgba::lerp(&color.into(), c2, d.abs()).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
color = get_height_color_blend(color, height, h2, smooth);
|
||||
}
|
||||
|
||||
*pixel = to_pixel(&color.into());
|
||||
});
|
||||
}
|
||||
|
||||
pub fn render_biome_map(map: &Map) -> ImageBuffer<image::Rgba<u8>, Vec<u8>> {
|
||||
fn get_height_color_blend(base_color: Hsla, height: f32, height2: f32, smooth: f32) -> Hsla {
|
||||
let mut color = base_color;
|
||||
let mut d = height2 - height;
|
||||
if smooth == 0.0 || d.abs() > smooth {
|
||||
if d > 0.0 {
|
||||
color.lightness += 0.1;
|
||||
} else if d < 0.0 {
|
||||
color.lightness -= 0.1;
|
||||
}
|
||||
} else {
|
||||
if d.abs() <= smooth {
|
||||
d /= smooth;
|
||||
if d > 0.0 {
|
||||
let c2: LinearRgba = color.with_lightness(color.lightness + 0.1).into();
|
||||
color = LinearRgba::lerp(&color.into(), c2, d).into();
|
||||
} else {
|
||||
let c2: LinearRgba = color.with_lightness(color.lightness - 0.1).into();
|
||||
color = LinearRgba::lerp(&color.into(), c2, d.abs()).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
pub fn render_biome_noise_map(map: &BiomeMap) -> ImageBuffer<image::Rgba<u8>, Vec<u8>> {
|
||||
let mut image = ImageBuffer::new(
|
||||
map.width as u32 * Chunk::SIZE as u32,
|
||||
map.height as u32 * Chunk::SIZE as u32,
|
||||
);
|
||||
update_biome_map(map, &mut image);
|
||||
update_biome_noise_map(map, &mut image);
|
||||
return image;
|
||||
}
|
||||
|
||||
pub fn update_biome_map(map: &Map, image: &mut ImageBuffer<image::Rgba<u8>, Vec<u8>>) {
|
||||
pub fn update_biome_noise_map(map: &BiomeMap, image: &mut ImageBuffer<image::Rgba<u8>, Vec<u8>>) {
|
||||
image.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| {
|
||||
let coord = HexCoord::from_grid_pos(x as usize, y as usize);
|
||||
let tile = map.get_biome(&coord);
|
||||
let tile = map.get_biome_data(x as usize, y as usize);
|
||||
|
||||
let color = LinearRgba::rgb(
|
||||
tile.temperature / 100.0,
|
||||
@@ -114,3 +125,31 @@ pub fn update_biome_map(map: &Map, image: &mut ImageBuffer<image::Rgba<u8>, Vec<
|
||||
*pixel = to_pixel(&color);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn render_biome_map(map: &Map, biome_map: &BiomeMap) -> ImageBuffer<image::Rgba<u8>, Vec<u8>> {
|
||||
let mut image = ImageBuffer::new(
|
||||
map.width as u32 * Chunk::SIZE as u32,
|
||||
map.height as u32 * Chunk::SIZE as u32,
|
||||
);
|
||||
update_biome_map(map, biome_map, &mut image);
|
||||
return image;
|
||||
}
|
||||
|
||||
pub fn update_biome_map(map: &Map, biome_map: &BiomeMap, image: &mut ImageBuffer<image::Rgba<u8>, Vec<u8>>) {
|
||||
let map_biome_count = map.biome_count as f32;
|
||||
image.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| {
|
||||
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 right = coord.get_neighbor(1);
|
||||
let biome_id = map.get_biome_id(&coord) as f32;
|
||||
let hue = (biome_id / map_biome_count) * 360.0;
|
||||
let mut color = Hsla::hsl(hue, 0.8, 0.9);
|
||||
if map.is_in_bounds(&right) {
|
||||
let h1 = map.sample_height(&coord);
|
||||
let h2 = map.sample_height(&right);
|
||||
color = get_height_color_blend(color, h1, h2, 0.5);
|
||||
}
|
||||
|
||||
*pixel = to_pixel(&color.into());
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user