Skip to content

Commit

Permalink
Added generation of images based on the map
Browse files Browse the repository at this point in the history
Tweaks to consistency with DIRECTIONS and HEX_CORNERS
Misc debug visualizations
  • Loading branch information
Amatsugu committed Aug 5, 2024
1 parent bde2543 commit f7a3a56
Show file tree
Hide file tree
Showing 13 changed files with 671 additions and 21 deletions.
426 changes: 420 additions & 6 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions engine/world_generation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ bevy_asset_loader = { version = "0.21.0", features = [
"3d",
] }
ron = "0.8.1"
image = "0.25.2"

[features]
tracing = ["bevy/trace_tracy"]
6 changes: 3 additions & 3 deletions engine/world_generation/src/generators/chunk_colliders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn create_tile_collider(pos: Vec3, verts: &mut Vec<Vec3>, indices: &mut Vec<[u32
verts.push(p);
}

//Top Surfave
//Top Surface
indices.push([idx, idx + 1, idx + 5]);
indices.push([idx + 1, idx + 2, idx + 5]);
indices.push([idx + 2, idx + 4, idx + 5]);
Expand All @@ -43,7 +43,7 @@ fn create_tile_collider(pos: Vec3, verts: &mut Vec<Vec3>, indices: &mut Vec<[u32
create_tile_wall_collider(
idx,
Vec3::new(pos.x, n_height.min(pos.y - OUTER_RADIUS / 2.), pos.z),
i,
(i + 1) % 6,
verts,
indices,
);
Expand All @@ -54,7 +54,7 @@ fn create_tile_collider(pos: Vec3, verts: &mut Vec<Vec3>, indices: &mut Vec<[u32
fn create_tile_wall_collider(idx: u32, pos: Vec3, dir: usize, verts: &mut Vec<Vec3>, indices: &mut Vec<[u32; 3]>) {
let idx2 = verts.len() as u32;

verts.push(pos + HEX_CORNERS[dir]);
verts.push(pos + HEX_CORNERS[(dir) % 6]);
verts.push(pos + HEX_CORNERS[(dir + 1) % 6]);

let off = dir as u32;
Expand Down
61 changes: 57 additions & 4 deletions engine/world_generation/src/heightmap.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use core::f32;

use bevy::math::{IVec2, UVec2};
use bevy::prelude::{FloatExt, Vec2};
use bevy::render::render_resource::encase::internal::BufferMut;
use bevy::utils::default;
use noise::{NoiseFn, SuperSimplex};
use rayon::iter::{IntoParallelIterator, ParallelIterator};
Expand All @@ -11,7 +14,7 @@ use crate::prelude::*;
pub fn generate_heightmap(cfg: &GenerationConfig, seed: u32, painter: &BiomePainter) -> Map {
let biomes = &generate_biomes(cfg, seed, painter);
// let mut chunks: Vec<Chunk> = Vec::with_capacity(cfg.size.length_squared() as usize);
let chunks = (0..cfg.size.y)
let chunks: Vec<Chunk> = (0..cfg.size.y)
.into_par_iter()
.flat_map(|z| {
(0..cfg.size.x).into_par_iter().map(move |x| {
Expand All @@ -20,11 +23,24 @@ pub fn generate_heightmap(cfg: &GenerationConfig, seed: u32, painter: &BiomePain
})
})
.collect();
let mut min = f32::MAX;
let mut max = f32::MIN;
for chunk in &chunks {
if chunk.min_level < min {
min = chunk.min_level;
}
if chunk.max_level > max {
max = chunk.max_level;
}
}

return Map {
chunks,
height: cfg.size.y as usize,
width: cfg.size.x as usize,
sea_level: cfg.sea_level as f32,
min_level: min,
max_level: max,
};
}

Expand Down Expand Up @@ -66,23 +82,23 @@ pub fn generate_biome_chunk(
&cfg.moisture_noise,
&noise_m,
cfg.size.as_vec2(),
cfg.border_size,
0.0,
);
let temperature = sample_point(
x as f64 + chunk_x as f64 * Chunk::SIZE as f64,
z as f64 + chunk_y as f64 * Chunk::SIZE as f64,
&cfg.temperature_noise,
&noise_t,
cfg.size.as_vec2(),
cfg.border_size,
0.0,
);
let continentality = sample_point(
x as f64 + chunk_x as f64 * Chunk::SIZE as f64,
z as f64 + chunk_y as f64 * Chunk::SIZE as f64,
&cfg.continent_noise,
&noise_c,
cfg.size.as_vec2(),
cfg.border_size,
0.0,
);
let data = BiomeData {
moisture: moisture.clamp(0., 100.),
Expand All @@ -100,6 +116,29 @@ pub fn generate_biome_chunk(
return chunk;
}

pub fn generate_noise_map(size: UVec2, seed: u32, cfg: &NoiseConfig, border_size: f32) -> Vec<f32> {
let noise = SuperSimplex::new(seed);

let data: Vec<_> = (0..(size.y as usize * Chunk::SIZE))
.into_par_iter()
.flat_map(|y| {
let mut row = Vec::with_capacity(size.x as usize * Chunk::SIZE);
for x in 0..row.capacity() {
row.push(sample_point(
x as f64,
y as f64,
cfg,
&noise,
size.as_vec2(),
border_size,
));
}
return row;
})
.collect();
return data;
}

pub fn generate_chunk(
chunk_x: u32,
chunk_z: u32,
Expand All @@ -112,6 +151,8 @@ pub fn generate_chunk(
let mut data = [BiomeData::default(); Chunk::AREA];
let mut biome_ids = [0; Chunk::AREA];
let noise = SuperSimplex::new(seed);
let mut min = f32::MAX;
let mut max = f32::MIN;
for z in 0..Chunk::SIZE {
for x in 0..Chunk::SIZE {
let biome_data = biome_chunk.get_biome_data(x, z);
Expand All @@ -135,6 +176,12 @@ pub fn generate_chunk(
let idx = x + z * Chunk::SIZE;
biome_ids[idx] = biome_chunk.get_biome_id_dithered(x, z, &noise, cfg.biome_dither);
result[idx] = sample;
if sample > max {
max = sample;
}
if sample < min {
min = sample;
}
data[idx] = biome_data.clone();
}
}
Expand All @@ -143,6 +190,8 @@ pub fn generate_chunk(
biome_data: data,
biome_id: biome_ids,
chunk_offset: IVec2::new(chunk_x as i32, chunk_z as i32),
max_level: max,
min_level: min,
..default()
};
}
Expand Down Expand Up @@ -171,6 +220,10 @@ fn sample_point(x: f64, z: f64, cfg: &NoiseConfig, noise: &impl NoiseFn<f64, 2>,
}
}

if border_size == 0.0 {
return elevation as f32;
}

let outer = size * Chunk::SIZE as f32;

let p = Vec2::new(x as f32, z as f32);
Expand Down
8 changes: 4 additions & 4 deletions engine/world_generation/src/hex_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ impl Display for HexCoord {

impl HexCoord {
pub const DIRECTIONS: [IVec3; 6] = [
IVec3::new(0, 1, -1),
IVec3::new(1, 0, -1),
IVec3::new(1, -1, 0),
IVec3::new(0, -1, 1),
IVec3::new(-1, 0, 1),
IVec3::new(1, 0, -1),
IVec3::new(0, 1, -1),
IVec3::new(-1, 1, 0),
IVec3::new(-1, 0, 1),
IVec3::new(0, -1, 1),
];

pub const ZERO: HexCoord = HexCoord { hex: IVec3::ZERO };
Expand Down
1 change: 1 addition & 0 deletions engine/world_generation/src/map/biome_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use rayon::iter::{IntoParallelIterator, ParallelIterator};

use super::chunk::Chunk;

#[derive(Clone)]
pub struct BiomeMap {
pub height: usize,
pub width: usize,
Expand Down
4 changes: 4 additions & 0 deletions engine/world_generation/src/map/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ pub struct Chunk {
pub biome_data: [BiomeData; Chunk::AREA],
pub biome_id: [usize; Chunk::AREA],
pub chunk_offset: IVec2,
pub min_level: f32,
pub max_level: f32,
}

impl Default for Chunk {
Expand All @@ -20,6 +22,8 @@ impl Default for Chunk {
biome_data: [BiomeData::default(); Chunk::AREA],
biome_id: [0; Chunk::AREA],
chunk_offset: Default::default(),
min_level: 0.0,
max_level: 0.0,
}
}
}
Expand Down
50 changes: 48 additions & 2 deletions engine/world_generation/src/map/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@ use bevy::prelude::*;

use crate::hex_utils::*;

use super::{chunk::Chunk, mesh_chunk::MeshChunkData};
use super::{
biome_map::{BiomeData, BiomeMap},
chunk::Chunk,
mesh_chunk::MeshChunkData,
};

#[derive(Resource, Clone)]
pub struct Map {
pub chunks: Vec<Chunk>,
pub height: usize,
pub width: usize,
pub sea_level: f32,
pub min_level: f32,
pub max_level: f32,
}

impl Map {
Expand Down Expand Up @@ -43,11 +49,21 @@ impl Map {
}

pub fn sample_height(&self, pos: &HexCoord) -> f32 {
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.heights[pos.to_chunk_local_index()];
}

pub fn sample_height_mut(&mut self, pos: &HexCoord) -> &mut f32 {
assert!(
self.is_in_bounds(pos),
"The provided coordinate is not within the map bounds"
);

let chunk = &mut self.chunks[pos.to_chunk_index(self.width)];
return &mut chunk.heights[pos.to_chunk_local_index()];
}
Expand All @@ -56,16 +72,46 @@ impl Map {
return pos.is_in_bounds(self.height * Chunk::SIZE, self.width * Chunk::SIZE);
}

pub fn get_biome(&self, pos: &HexCoord) -> &BiomeData {
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_data[pos.to_chunk_local_index()];
}

pub fn get_moisture(&self, pos: &HexCoord) -> f32 {
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_data[pos.to_chunk_local_index()].moisture;
}

pub fn get_tempurature(&self, pos: &HexCoord) -> f32 {
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_data[pos.to_chunk_local_index()].temperature;
}

pub fn get_continentality(&self, pos: &HexCoord) -> f32 {
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_data[pos.to_chunk_local_index()].continentality;
}

pub fn get_center(&self) -> Vec3 {
let w = self.get_world_width();
let h = self.get_world_height();
Expand Down Expand Up @@ -96,7 +142,7 @@ impl Map {
let h2 = cur - depth;
*h = h2.lerp(cur, d * d).max(0.);

return (*p, *h);
return (*p, *h);
});

return tiles;
Expand Down
Loading

0 comments on commit f7a3a56

Please sign in to comment.