@@ -1,6 +1,6 @@
|
||||
use std::ops::Add;
|
||||
|
||||
use bevy::{asset::AssetLoader, math::VectorSpace, prelude::*};
|
||||
use bevy::{math::VectorSpace, prelude::*};
|
||||
use image::ImageBuffer;
|
||||
use rayon::prelude::*;
|
||||
|
||||
@@ -13,7 +13,8 @@ pub fn render_image(
|
||||
data: &Vec<f32>,
|
||||
color1: LinearRgba,
|
||||
color2: LinearRgba,
|
||||
) -> ImageBuffer<image::Rgba<u8>, Vec<u8>> {
|
||||
) -> ImageBuffer<image::Rgba<u8>, Vec<u8>>
|
||||
{
|
||||
let mut image = ImageBuffer::new(size.x * Chunk::SIZE as u32, size.y * Chunk::SIZE as u32);
|
||||
update_image(size, data, color1, color2, &mut image);
|
||||
|
||||
@@ -26,7 +27,8 @@ pub fn update_image(
|
||||
color1: LinearRgba,
|
||||
color2: LinearRgba,
|
||||
image: &mut ImageBuffer<image::Rgba<u8>, Vec<u8>>,
|
||||
) {
|
||||
)
|
||||
{
|
||||
let min = *data.iter().min_by(|a, b| a.partial_cmp(b).unwrap()).unwrap_or(&0.0);
|
||||
let max = *data.iter().min_by(|a, b| a.partial_cmp(b).unwrap()).unwrap_or(&1.0);
|
||||
|
||||
@@ -41,7 +43,8 @@ pub fn update_image(
|
||||
});
|
||||
}
|
||||
|
||||
fn to_pixel(col: &LinearRgba) -> image::Rgba<u8> {
|
||||
fn to_pixel(col: &LinearRgba) -> image::Rgba<u8>
|
||||
{
|
||||
return image::Rgba([
|
||||
(col.red * 255.0) as u8,
|
||||
(col.green * 255.0) as u8,
|
||||
@@ -49,7 +52,8 @@ fn to_pixel(col: &LinearRgba) -> image::Rgba<u8> {
|
||||
255,
|
||||
]);
|
||||
}
|
||||
pub fn render_map(map: &Map, smooth: f32) -> ImageBuffer<image::Rgba<u8>, Vec<u8>> {
|
||||
pub fn render_map(map: &Map, smooth: f32) -> 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,
|
||||
@@ -57,18 +61,21 @@ pub fn render_map(map: &Map, smooth: f32) -> ImageBuffer<image::Rgba<u8>, Vec<u8
|
||||
update_map(map, smooth, &mut image);
|
||||
return image;
|
||||
}
|
||||
pub fn update_map(map: &Map, smooth: f32, image: &mut ImageBuffer<image::Rgba<u8>, Vec<u8>>) {
|
||||
pub fn update_map(map: &Map, smooth: f32, 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 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.sealevel {
|
||||
if height < map.sealevel
|
||||
{
|
||||
color.hue = 217.0;
|
||||
}
|
||||
|
||||
if map.is_in_bounds(&right) {
|
||||
if map.is_in_bounds(&right)
|
||||
{
|
||||
let h2 = map.sample_height(&right);
|
||||
color = get_height_color_blend(color, height, h2, smooth);
|
||||
}
|
||||
@@ -77,22 +84,33 @@ pub fn update_map(map: &Map, smooth: f32, image: &mut ImageBuffer<image::Rgba<u8
|
||||
});
|
||||
}
|
||||
|
||||
fn get_height_color_blend(base_color: Hsla, height: f32, height2: f32, smooth: f32) -> Hsla {
|
||||
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 {
|
||||
if smooth == 0.0 || d.abs() > smooth
|
||||
{
|
||||
if d > 0.0
|
||||
{
|
||||
color.lightness += 0.1;
|
||||
} else if d < 0.0 {
|
||||
}
|
||||
else if d < 0.0
|
||||
{
|
||||
color.lightness -= 0.1;
|
||||
}
|
||||
} else {
|
||||
if d.abs() <= smooth {
|
||||
}
|
||||
else
|
||||
{
|
||||
if d.abs() <= smooth
|
||||
{
|
||||
d /= smooth;
|
||||
if d > 0.0 {
|
||||
if d > 0.0
|
||||
{
|
||||
let c2: LinearRgba = color.with_lightness(color.lightness + 0.1).into();
|
||||
color = LinearRgba::lerp(color.into(), c2, d).into();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
let c2: LinearRgba = color.with_lightness(color.lightness - 0.1).into();
|
||||
color = LinearRgba::lerp(color.into(), c2, d.abs()).into();
|
||||
}
|
||||
@@ -102,13 +120,15 @@ fn get_height_color_blend(base_color: Hsla, height: f32, height2: f32, smooth: f
|
||||
return color;
|
||||
}
|
||||
|
||||
pub fn render_biome_noise_map(map: &BiomeMap, multi: Vec3) -> 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);
|
||||
update_biome_noise_map(map, multi, &mut image);
|
||||
return image;
|
||||
}
|
||||
|
||||
pub fn update_biome_noise_map(map: &BiomeMap, multi: Vec3, 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)| {
|
||||
let tile = map.get_biome_data(x as usize, y as usize);
|
||||
|
||||
@@ -121,7 +141,8 @@ pub fn update_biome_noise_map(map: &BiomeMap, multi: Vec3, image: &mut ImageBuff
|
||||
});
|
||||
}
|
||||
|
||||
pub fn render_biome_map(map: &Map, biome_map: &BiomeMap) -> ImageBuffer<image::Rgba<u8>, Vec<u8>> {
|
||||
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,
|
||||
@@ -130,19 +151,22 @@ pub fn render_biome_map(map: &Map, biome_map: &BiomeMap) -> ImageBuffer<image::R
|
||||
return image;
|
||||
}
|
||||
|
||||
pub fn update_biome_map(map: &Map, biome_map: &BiomeMap, image: &mut ImageBuffer<image::Rgba<u8>, Vec<u8>>) {
|
||||
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).unwrap();
|
||||
let right = coord.get_neighbor(1);
|
||||
let mut color = Oklaba::BLACK;
|
||||
for i in 0..biome_blend.len() {
|
||||
for i in 0..biome_blend.len()
|
||||
{
|
||||
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 h2 = map.sample_height(&right);
|
||||
color = get_height_color_blend(color.into(), h1, h2, 0.5).into();
|
||||
|
||||
@@ -6,7 +6,8 @@ use crate::hex_utils::HexCoord;
|
||||
|
||||
use super::chunk::Chunk;
|
||||
|
||||
pub struct MeshChunkData {
|
||||
pub struct MeshChunkData
|
||||
{
|
||||
pub heights: [f32; Chunk::AREA],
|
||||
pub textures: [[u32; 2]; Chunk::AREA],
|
||||
pub min_height: f32,
|
||||
@@ -14,13 +15,17 @@ pub struct MeshChunkData {
|
||||
pub distance_to_land: [f32; Chunk::AREA],
|
||||
}
|
||||
|
||||
impl MeshChunkData {
|
||||
pub fn get_neighbors(&self, coord: &HexCoord) -> [f32; 6] {
|
||||
impl MeshChunkData
|
||||
{
|
||||
pub fn get_neighbors(&self, coord: &HexCoord) -> [f32; 6]
|
||||
{
|
||||
let mut data = [self.min_height; 6];
|
||||
let n_tiles = coord.get_neighbors();
|
||||
for i in 0..6 {
|
||||
for i in 0..6
|
||||
{
|
||||
let n = n_tiles[i];
|
||||
if !n.is_in_bounds(Chunk::SIZE, Chunk::SIZE) {
|
||||
if !n.is_in_bounds(Chunk::SIZE, Chunk::SIZE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
data[i] = self.heights[n.to_index(Chunk::SIZE)];
|
||||
@@ -29,56 +34,70 @@ impl MeshChunkData {
|
||||
return data;
|
||||
}
|
||||
|
||||
pub fn get_neighbors_with_water_info(&self, coord: &HexCoord) -> ([(f32, Option<f32>); 6], bool) {
|
||||
pub fn get_neighbors_with_water_info(&self, coord: &HexCoord) -> ([(f32, Option<f32>); 6], bool)
|
||||
{
|
||||
let mut has_land = false;
|
||||
let mut data = [(self.min_height, None); 6];
|
||||
let n_tiles = coord.get_neighbors();
|
||||
for i in 0..6 {
|
||||
for i in 0..6
|
||||
{
|
||||
let n = n_tiles[i];
|
||||
if !n.is_in_bounds(Chunk::SIZE, Chunk::SIZE) {
|
||||
if !n.is_in_bounds(Chunk::SIZE, Chunk::SIZE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let idx = n.to_index(Chunk::SIZE);
|
||||
data[i] = (self.heights[idx], Some(self.distance_to_land[idx]));
|
||||
if data[i].0 > self.sealevel {
|
||||
if data[i].0 > self.sealevel
|
||||
{
|
||||
has_land = true;
|
||||
}
|
||||
}
|
||||
return (data, has_land);
|
||||
}
|
||||
|
||||
pub fn caluclate_water_distances(data: &mut Vec<MeshChunkData>, height: usize, width: usize, range: usize) {
|
||||
pub fn caluclate_water_distances(data: &mut Vec<MeshChunkData>, height: usize, width: usize, _range: usize)
|
||||
{
|
||||
let mut open: VecDeque<(HexCoord, f32, usize)> = VecDeque::new();
|
||||
let mut closed: Vec<(HexCoord, f32)> = Vec::new();
|
||||
for z in 0..height {
|
||||
for x in 0..width {
|
||||
// let mut closed: Vec<(HexCoord, f32)> = Vec::new();
|
||||
for z in 0..height
|
||||
{
|
||||
for x in 0..width
|
||||
{
|
||||
let chunk = &mut data[z * height + x];
|
||||
chunk.prepare_chunk_open(x * Chunk::SIZE, z * Chunk::SIZE, &mut open);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn prepare_chunk_open(&mut self, offset_x: usize, offset_z: usize, open: &mut VecDeque<(HexCoord, f32, usize)>) {
|
||||
for z in 0..Chunk::SIZE {
|
||||
for x in 0..Chunk::SIZE {
|
||||
fn prepare_chunk_open(&mut self, offset_x: usize, offset_z: usize, open: &mut VecDeque<(HexCoord, f32, usize)>)
|
||||
{
|
||||
for z in 0..Chunk::SIZE
|
||||
{
|
||||
for x in 0..Chunk::SIZE
|
||||
{
|
||||
let coord = HexCoord::from_grid_pos(x + offset_x, z + offset_z);
|
||||
let idx = coord.to_chunk_local_index();
|
||||
let h = self.heights[idx];
|
||||
self.distance_to_land[idx] = if h > self.sealevel { 0.0 } else { 4.0 };
|
||||
if h > self.sealevel {
|
||||
if h > self.sealevel
|
||||
{
|
||||
open.push_back((coord, h, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[allow(unused)]
|
||||
fn fill_chunk_borders(
|
||||
&mut self,
|
||||
chunks: &Vec<MeshChunkData>,
|
||||
offset: IVec2,
|
||||
open: &mut VecDeque<(HexCoord, f32, usize)>,
|
||||
closed: &mut Vec<(HexCoord, f32)>,
|
||||
) {
|
||||
)
|
||||
{
|
||||
self.prepare_chunk_open(offset.x as usize * Chunk::SIZE, offset.y as usize * Chunk::SIZE, open);
|
||||
todo!("Fill closed list with bordering tiles")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user