Update Biome colors
0ebf1dfc012a07325fc6c0bd28d1917bdeb4834e
This commit is contained in:
parent
234579f553
commit
e7d73755e2
5 changed files with 102 additions and 103 deletions
|
@ -185,8 +185,16 @@ impl<'de> Deserialize<'de> for World {
|
|||
let width = width.ok_or_else(|| Error::missing_field("width"))?;
|
||||
let height = height.ok_or_else(|| Error::missing_field("height"))?;
|
||||
let seed = seed.ok_or_else(|| Error::missing_field("seed"))?;
|
||||
let terrain: Vec<Vec<TerrainCell>> =
|
||||
let mut terrain: Vec<Vec<TerrainCell>> =
|
||||
terrain.ok_or_else(|| Error::missing_field("terrain"))?;
|
||||
|
||||
for x in 0..width as usize {
|
||||
for y in 0..height as usize {
|
||||
terrain[y][x].x = x;
|
||||
terrain[y][x].y = y;
|
||||
}
|
||||
}
|
||||
|
||||
let continent_offsets =
|
||||
continent_offsets.ok_or_else(|| Error::missing_field("continent_offsets"))?;
|
||||
let continent_widths =
|
||||
|
|
|
@ -97,11 +97,16 @@ pub struct TerrainCell {
|
|||
pub rainfall: f32,
|
||||
pub temperature: f32,
|
||||
|
||||
#[serde(skip)]
|
||||
pub x: usize,
|
||||
#[serde(skip)]
|
||||
pub y: usize,
|
||||
|
||||
pub biome_presences: Vec<(BiomeType, f32)>,
|
||||
}
|
||||
|
||||
impl World {
|
||||
const ALTITUDE_SPAN: f32 = World::MAX_ALTITUDE - World::MIN_ALTITUDE;
|
||||
pub(crate) const ALTITUDE_SPAN: f32 = World::MAX_ALTITUDE - World::MIN_ALTITUDE;
|
||||
const CONTINENT_MAX_SIZE_FACTOR: f32 = 6.0;
|
||||
const CONTINENT_MIN_SIZE_FACTOR: f32 = 2.5;
|
||||
pub(crate) const MAX_ALTITUDE: f32 = 15000.0;
|
||||
|
@ -300,6 +305,9 @@ impl World {
|
|||
if altitude < self.min_altitude {
|
||||
self.min_altitude = altitude;
|
||||
}
|
||||
|
||||
self.terrain[y][x].x = x;
|
||||
self.terrain[y][x].y = y;
|
||||
}
|
||||
}
|
||||
info!("Done generating altitude");
|
||||
|
@ -547,90 +555,79 @@ impl World {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn cell_neighbors(&self, x: usize, y: usize) -> HashMap<CompassDirection, (usize, usize)> {
|
||||
pub fn cell_neighbors(&self, x: usize, y: usize) -> HashMap<CompassDirection, &TerrainCell> {
|
||||
let mut neighbors = HashMap::new();
|
||||
|
||||
let height = self.height as usize;
|
||||
let width = self.width as usize;
|
||||
|
||||
let west_x = (width + x - 1) % width;
|
||||
let east_x = (x + 1) % width;
|
||||
|
||||
let north_edge = y >= height - 1;
|
||||
let east_edge = x >= width - 1;
|
||||
let south_edge = y == 0;
|
||||
let west_edge = x == 0;
|
||||
|
||||
if !north_edge {
|
||||
_ = neighbors.insert_unique_unchecked(CompassDirection::North, (y + 1, x));
|
||||
}
|
||||
if !north_edge && !east_edge {
|
||||
_ = neighbors.insert_unique_unchecked(CompassDirection::NorthEast, (y + 1, x + 1));
|
||||
}
|
||||
if !east_edge {
|
||||
_ = neighbors.insert_unique_unchecked(CompassDirection::East, (y, x + 1));
|
||||
}
|
||||
if !south_edge && !east_edge {
|
||||
_ = neighbors.insert_unique_unchecked(CompassDirection::SouthEast, (y - 1, x + 1));
|
||||
_ = neighbors
|
||||
.insert_unique_unchecked(CompassDirection::NorthWest, &self.terrain[y + 1][west_x]);
|
||||
_ = neighbors.insert_unique_unchecked(CompassDirection::North, &self.terrain[y + 1][x]);
|
||||
_ = neighbors
|
||||
.insert_unique_unchecked(CompassDirection::NorthEast, &self.terrain[y + 1][east_x]);
|
||||
}
|
||||
|
||||
_ = neighbors.insert_unique_unchecked(CompassDirection::West, &self.terrain[y][east_x]);
|
||||
_ = neighbors.insert_unique_unchecked(CompassDirection::East, &self.terrain[y][west_x]);
|
||||
|
||||
if !south_edge {
|
||||
_ = neighbors.insert_unique_unchecked(CompassDirection::South, (y - 1, x));
|
||||
_ = neighbors
|
||||
.insert_unique_unchecked(CompassDirection::SouthWest, &self.terrain[y - 1][west_x]);
|
||||
_ = neighbors.insert_unique_unchecked(CompassDirection::South, &self.terrain[y - 1][x]);
|
||||
_ = neighbors
|
||||
.insert_unique_unchecked(CompassDirection::SouthEast, &self.terrain[y - 1][east_x]);
|
||||
}
|
||||
if !south_edge && !west_edge {
|
||||
_ = neighbors.insert_unique_unchecked(CompassDirection::SouthWest, (y - 1, x - 1));
|
||||
}
|
||||
if !west_edge {
|
||||
_ = neighbors.insert_unique_unchecked(CompassDirection::West, (y, x - 1));
|
||||
};
|
||||
if !north_edge && !west_edge {
|
||||
_ = neighbors.insert_unique_unchecked(CompassDirection::NorthWest, (y + 1, x - 1));
|
||||
};
|
||||
|
||||
neighbors
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_slant(&self, x: usize, y: usize) -> f32 {
|
||||
let neighbors = self.cell_neighbors(x, y);
|
||||
let terrain = &self.terrain;
|
||||
pub fn get_slant(&self, cell: &TerrainCell) -> f32 {
|
||||
let neighbors = self.cell_neighbors(cell.x, cell.y);
|
||||
|
||||
let mut west_altitude = f32::MIN;
|
||||
if let Some(neighbor_coords) = neighbors.get(&CompassDirection::North) {
|
||||
west_altitude = f32::max(
|
||||
west_altitude,
|
||||
terrain[neighbor_coords.0][neighbor_coords.1].altitude,
|
||||
);
|
||||
let mut west_altitude = 0.0;
|
||||
let mut neighbor_count = 0u8;
|
||||
|
||||
if let Some(neighbor) = neighbors.get(&CompassDirection::North) {
|
||||
west_altitude = f32::max(west_altitude, neighbor.altitude);
|
||||
neighbor_count += 1;
|
||||
}
|
||||
if let Some(neighbor_coords) = neighbors.get(&CompassDirection::NorthWest) {
|
||||
west_altitude = f32::max(
|
||||
west_altitude,
|
||||
terrain[neighbor_coords.0][neighbor_coords.1].altitude,
|
||||
);
|
||||
if let Some(neighbor) = neighbors.get(&CompassDirection::NorthWest) {
|
||||
west_altitude = f32::max(west_altitude, neighbor.altitude);
|
||||
neighbor_count += 1;
|
||||
}
|
||||
if let Some(neighbor_coords) = neighbors.get(&CompassDirection::West) {
|
||||
west_altitude = f32::max(
|
||||
west_altitude,
|
||||
terrain[neighbor_coords.0][neighbor_coords.1].altitude,
|
||||
);
|
||||
if let Some(neighbor) = neighbors.get(&CompassDirection::West) {
|
||||
west_altitude = f32::max(west_altitude, neighbor.altitude);
|
||||
neighbor_count += 1;
|
||||
}
|
||||
|
||||
west_altitude /= f32::from(neighbor_count);
|
||||
neighbor_count = 0;
|
||||
|
||||
let mut east_altitude = f32::MIN;
|
||||
if let Some(neighbor_coords) = neighbors.get(&CompassDirection::North) {
|
||||
east_altitude = f32::max(
|
||||
east_altitude,
|
||||
terrain[neighbor_coords.0][neighbor_coords.1].altitude,
|
||||
);
|
||||
if let Some(neighbor) = neighbors.get(&CompassDirection::North) {
|
||||
east_altitude = f32::max(east_altitude, neighbor.altitude);
|
||||
neighbor_count += 1;
|
||||
}
|
||||
if let Some(neighbor_coords) = neighbors.get(&CompassDirection::NorthWest) {
|
||||
east_altitude = f32::max(
|
||||
east_altitude,
|
||||
terrain[neighbor_coords.0][neighbor_coords.1].altitude,
|
||||
);
|
||||
if let Some(neighbor) = neighbors.get(&CompassDirection::NorthWest) {
|
||||
east_altitude = f32::max(east_altitude, neighbor.altitude);
|
||||
neighbor_count += 1;
|
||||
}
|
||||
if let Some(neighbor_coords) = neighbors.get(&CompassDirection::West) {
|
||||
east_altitude = f32::max(
|
||||
east_altitude,
|
||||
terrain[neighbor_coords.0][neighbor_coords.1].altitude,
|
||||
);
|
||||
if let Some(neighbor) = neighbors.get(&CompassDirection::West) {
|
||||
east_altitude = f32::max(east_altitude, neighbor.altitude);
|
||||
neighbor_count += 1;
|
||||
}
|
||||
|
||||
east_altitude /= f32::from(neighbor_count);
|
||||
|
||||
west_altitude - east_altitude
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,31 +175,19 @@ impl WorldManager {
|
|||
#[cfg(feature = "render")]
|
||||
#[must_use]
|
||||
fn generate_color(&self, cell: &TerrainCell, render_settings: &WorldRenderSettings) -> Color {
|
||||
if render_settings.view == WorldView::Biomes {
|
||||
return WorldManager::biome_color(cell);
|
||||
}
|
||||
let base_color = match render_settings.view {
|
||||
WorldView::Biomes => self.biome_color(cell),
|
||||
WorldView::Topography => WorldManager::altitude_contour_color(cell.altitude),
|
||||
};
|
||||
let mut normalizer = 1.0;
|
||||
|
||||
let altitude_color = WorldManager::altitude_contour_color(cell.altitude);
|
||||
// let altitude_color = if self.contours {
|
||||
// WorldManager::altitude_contour_color(cell.altitude)
|
||||
// } else {
|
||||
// WorldManager::altitude_color(cell.altitude)
|
||||
// };
|
||||
|
||||
let mut layer_count = 1.0;
|
||||
|
||||
let mut red = altitude_color.r();
|
||||
let mut green = altitude_color.g();
|
||||
let mut blue = altitude_color.b();
|
||||
let mut red = base_color.r();
|
||||
let mut green = base_color.g();
|
||||
let mut blue = base_color.b();
|
||||
|
||||
if render_settings.overlay_visible(&WorldOverlay::Rainfall) {
|
||||
layer_count += 1.0;
|
||||
normalizer += 1.0;
|
||||
let rainfall_color = self.rainfall_contour_color(cell.rainfall);
|
||||
// if self.contours {
|
||||
// self.rainfall_contour_color(cell.rainfall)
|
||||
// } else {
|
||||
// WorldManager::rainfall_color(cell.rainfall)
|
||||
// };
|
||||
|
||||
red += rainfall_color.r();
|
||||
green += rainfall_color.g();
|
||||
|
@ -207,20 +195,15 @@ impl WorldManager {
|
|||
}
|
||||
|
||||
if render_settings.overlay_visible(&WorldOverlay::Temperature) {
|
||||
layer_count += 1.0;
|
||||
normalizer += 1.0;
|
||||
let temperature_color = self.temperature_contour_color(cell.temperature);
|
||||
// if self.contours {
|
||||
// self.temperature_contour_color(cell.temperature)
|
||||
// } else {
|
||||
// WorldManager::temperature_color(cell.temperature)
|
||||
// };
|
||||
|
||||
red += temperature_color.r();
|
||||
green += temperature_color.g();
|
||||
blue += temperature_color.b();
|
||||
}
|
||||
|
||||
Color::rgb(red / layer_count, green / layer_count, blue / layer_count)
|
||||
Color::rgb(red / normalizer, green / normalizer, blue / normalizer)
|
||||
}
|
||||
|
||||
// #[cfg(feature = "render")]
|
||||
|
@ -280,19 +263,28 @@ impl WorldManager {
|
|||
|
||||
#[cfg(feature = "render")]
|
||||
#[must_use]
|
||||
fn biome_color(cell: &TerrainCell) -> Color {
|
||||
cell.biome_presences
|
||||
.iter()
|
||||
.fold(Color::BLACK, |color, (biome_type, presence)| {
|
||||
let biome: BiomeStats = (*biome_type).into();
|
||||
let biome_color = biome.color;
|
||||
fn biome_color(&self, cell: &TerrainCell) -> Color {
|
||||
let slant = self.world().get_slant(cell);
|
||||
|
||||
Color::rgb(
|
||||
color.r() + (biome_color.r() * presence),
|
||||
color.g() + (biome_color.g() * presence),
|
||||
color.b() + (biome_color.b() * presence),
|
||||
)
|
||||
})
|
||||
let slant_factor = f32::min(1.0, (4.0 + (10.0 * slant / World::ALTITUDE_SPAN)) / 5.0);
|
||||
let altitude_factor = f32::min(
|
||||
1.0,
|
||||
(0.5 + (cell.altitude - World::MIN_ALTITUDE) / World::ALTITUDE_SPAN) / 1.5,
|
||||
);
|
||||
|
||||
let mut red = 0.0;
|
||||
let mut green = 0.0;
|
||||
let mut blue = 0.0;
|
||||
|
||||
for (biome, presence) in cell.biome_presences.iter() {
|
||||
red += BiomeStats::from(biome).color.r() * presence;
|
||||
green += BiomeStats::from(biome).color.g() * presence;
|
||||
blue += BiomeStats::from(biome).color.b() * presence;
|
||||
}
|
||||
red *= slant_factor * altitude_factor;
|
||||
green *= slant_factor * altitude_factor;
|
||||
blue *= slant_factor * altitude_factor;
|
||||
Color::rgb(red, green, blue)
|
||||
}
|
||||
|
||||
// #[cfg(feature = "render")]
|
||||
|
|
|
@ -24,9 +24,6 @@ impl WindowSystem for TileInfo<'_, '_> {
|
|||
let cursor_position = world.resource::<CursorMapPosition>();
|
||||
let cursor_y = cursor_position.y;
|
||||
let cursor_x = cursor_position.x;
|
||||
_ = ui.label("Coordinates");
|
||||
_ = ui.label(cursor_position.to_string());
|
||||
ui.end_row();
|
||||
|
||||
let world_manager = world.resource::<WorldManager>();
|
||||
if cursor_x >= 0
|
||||
|
@ -39,8 +36,13 @@ impl WindowSystem for TileInfo<'_, '_> {
|
|||
rainfall,
|
||||
temperature,
|
||||
biome_presences,
|
||||
x,
|
||||
y,
|
||||
} = &world_manager.world().terrain[cursor_y as usize][cursor_x as usize];
|
||||
|
||||
_ = ui.label("Coordinates");
|
||||
_ = ui.label(format!("{x}:{y}"));
|
||||
ui.end_row();
|
||||
_ = ui.label("Altitude");
|
||||
_ = ui.label(format!("{altitude:.2}"));
|
||||
ui.end_row();
|
||||
|
|
Loading…
Reference in a new issue