Added ice to cold water

This commit is contained in:
Joshua Barretto
2021-12-08 00:47:08 +00:00
parent 78f76dde83
commit a2a3a20aad
5 changed files with 89 additions and 48 deletions

View File

@ -299,6 +299,11 @@ pub struct MapConfig<'a> {
/// ///
/// Defaults to true. /// Defaults to true.
pub is_water: bool, pub is_water: bool,
/// When `is_water` is true, controls whether an ice layer should appear on
/// that water.
///
/// Defaults to true.
pub is_ice: bool,
/// If true, 3D lighting and shading are turned on. Otherwise, a plain /// If true, 3D lighting and shading are turned on. Otherwise, a plain
/// altitude map is used. /// altitude map is used.
/// ///
@ -403,6 +408,7 @@ impl<'a> MapConfig<'a> {
is_basement: false, is_basement: false,
is_water: true, is_water: true,
is_ice: true,
is_shaded: true, is_shaded: true,
is_temperature: false, is_temperature: false,
is_humidity: false, is_humidity: false,
@ -581,6 +587,8 @@ impl<'a> MapConfig<'a> {
let g_water = 32.0 * water_color_factor; let g_water = 32.0 * water_color_factor;
let b_water = 64.0 * water_color_factor; let b_water = 64.0 * water_color_factor;
if has_river { if has_river {
// Rudimentary ice check
if !rgb.map(|e| e > 0.6).reduce_and() {
let water_rgb = Rgb::new(0, ((g_water) * 1.0) as u8, ((b_water) * 1.0) as u8) let water_rgb = Rgb::new(0, ((g_water) * 1.0) as u8, ((b_water) * 1.0) as u8)
.map(|e| e as f64 / 255.0); .map(|e| e as f64 / 255.0);
rgb = water_rgb; rgb = water_rgb;
@ -589,6 +597,7 @@ impl<'a> MapConfig<'a> {
k_a = water_rgb; k_a = water_rgb;
alpha = 0.255; alpha = 0.255;
} }
}
let downhill_alt = sample_wpos(downhill_wpos); let downhill_alt = sample_wpos(downhill_wpos);
let cross_pos = wposi let cross_pos = wposi

View File

@ -177,6 +177,7 @@ fn main() {
is_basement, is_basement,
is_water, is_water,
is_ice: true,
is_shaded, is_shaded,
is_temperature, is_temperature,
is_humidity, is_humidity,

View File

@ -54,7 +54,7 @@ impl<'a> BlockGen<'a> {
// Main sample // Main sample
let sample = column_gen.get((wpos, index, calendar))?; let sample = column_gen.get((wpos, index, calendar))?;
Some(ZCache { sample }) Some(ZCache { sample, calendar })
} }
pub fn get_with_z_cache(&mut self, wpos: Vec3<i32>, z_cache: Option<&ZCache>) -> Option<Block> { pub fn get_with_z_cache(&mut self, wpos: Vec3<i32>, z_cache: Option<&ZCache>) -> Option<Block> {
@ -74,8 +74,9 @@ impl<'a> BlockGen<'a> {
//tree_density, //tree_density,
//forest_kind, //forest_kind,
//close_structures, //close_structures,
// marble, marble,
// marble_small, marble_mid,
marble_small,
rock, rock,
// temp, // temp,
// humidity, // humidity,
@ -83,6 +84,8 @@ impl<'a> BlockGen<'a> {
snow_cover, snow_cover,
cliff_offset, cliff_offset,
cliff_height, cliff_height,
// water_vel,
ice_depth,
.. ..
} = sample; } = sample;
@ -204,8 +207,12 @@ impl<'a> BlockGen<'a> {
} }
}) })
.or_else(|| { .or_else(|| {
let over_water = height < water_height;
// Water // Water
if (wposf.z as f32) < water_height { if over_water && (wposf.z as f32 - water_height).abs() < ice_depth {
// TODO: Ice block
Some(Block::new(BlockKind::WeakRock, Rgb::new(200, 225, 255)))
} else if (wposf.z as f32) < water_height {
// Ocean // Ocean
Some(water) Some(water)
} else { } else {
@ -217,6 +224,7 @@ impl<'a> BlockGen<'a> {
pub struct ZCache<'a> { pub struct ZCache<'a> {
pub sample: ColumnSample<'a>, pub sample: ColumnSample<'a>,
pub calendar: Option<&'a Calendar>,
} }
impl<'a> ZCache<'a> { impl<'a> ZCache<'a> {
@ -232,7 +240,7 @@ impl<'a> ZCache<'a> {
let ground_max = self.sample.alt + warp + rocks + 2.0; let ground_max = self.sample.alt + warp + rocks + 2.0;
let max = ground_max.max(self.sample.water_level + 2.0); let max = ground_max.max(self.sample.water_level + 2.0 + self.sample.ice_depth);
(min, max) (min, max)
} }

View File

@ -91,6 +91,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
wpos, wpos,
|chunk| if chunk.river.near_water() { 1.0 } else { 0.0 }, |chunk| if chunk.river.near_water() { 1.0 } else { 0.0 },
)?; )?;
let water_vel = sim.get_interpolated(wpos, |chunk| chunk.river.velocity)?;
let alt = sim.get_interpolated_monotone(wpos, |chunk| chunk.alt)?; let alt = sim.get_interpolated_monotone(wpos, |chunk| chunk.alt)?;
let surface_veg = sim.get_interpolated_monotone(wpos, |chunk| chunk.surface_veg)?; let surface_veg = sim.get_interpolated_monotone(wpos, |chunk| chunk.surface_veg)?;
let sim_chunk = sim.get(chunk_pos)?; let sim_chunk = sim.get(chunk_pos)?;
@ -1081,7 +1082,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
// Snow covering // Snow covering
let thematic_snow = calendar.map_or(false, |c| c.is_event(CalendarEvent::Christmas)); let thematic_snow = calendar.map_or(false, |c| c.is_event(CalendarEvent::Christmas));
let snow_cover = temp let snow_factor = temp
.sub(if thematic_snow { .sub(if thematic_snow {
CONFIG.tropical_temp CONFIG.tropical_temp
} else { } else {
@ -1092,17 +1093,17 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
.add(((marble - 0.5) / 0.5) * 0.5) .add(((marble - 0.5) / 0.5) * 0.5)
.add(((marble_mid - 0.5) / 0.5) * 0.25) .add(((marble_mid - 0.5) / 0.5) * 0.25)
.add(((marble_small - 0.5) / 0.5) * 0.175); .add(((marble_small - 0.5) / 0.5) * 0.175);
let (alt, ground, sub_surface_color) = if snow_cover <= 0.0 && alt > water_level { let (alt, ground, sub_surface_color) = if snow_factor <= 0.0 && alt > water_level {
// Allow snow cover. // Allow snow cover.
( (
alt + 1.0 - snow_cover.max(0.0), alt + 1.0 - snow_factor.max(0.0),
Rgb::lerp(snow, ground, snow_cover), Rgb::lerp(snow, ground, snow_factor),
Lerp::lerp(sub_surface_color, ground, alt.sub(basement).mul(0.15)), Lerp::lerp(sub_surface_color, ground, alt.sub(basement).mul(0.15)),
) )
} else { } else {
(alt, ground, sub_surface_color) (alt, ground, sub_surface_color)
}; };
let snow_cover = snow_cover <= 0.0; let snow_cover = snow_factor <= 0.0;
// Make river banks not have grass // Make river banks not have grass
let ground = water_dist let ground = water_dist
@ -1116,6 +1117,16 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
let path = sim.get_nearest_path(wpos); let path = sim.get_nearest_path(wpos);
let cave = sim.get_nearest_cave(wpos); let cave = sim.get_nearest_cave(wpos);
let ice_depth = if snow_factor < -0.25
&& water_vel.magnitude_squared() < (0.1f32 + marble_mid * 0.2).powi(2)
{
((1.0 - Lerp::lerp(marble, Lerp::lerp(marble_mid, marble_small, 0.25), 0.5)) * 5.0
- 1.5)
.max(0.0)
} else {
0.0
};
Some(ColumnSample { Some(ColumnSample {
alt, alt,
riverless_alt, riverless_alt,
@ -1149,6 +1160,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
}, },
forest_kind: sim_chunk.forest_kind, forest_kind: sim_chunk.forest_kind,
marble, marble,
marble_mid,
marble_small, marble_small,
rock, rock,
temp, temp,
@ -1162,6 +1174,8 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
snow_cover, snow_cover,
cliff_offset, cliff_offset,
cliff_height, cliff_height,
water_vel,
ice_depth,
chunk: sim_chunk, chunk: sim_chunk,
}) })
@ -1181,6 +1195,7 @@ pub struct ColumnSample<'a> {
pub tree_density: f32, pub tree_density: f32,
pub forest_kind: ForestKind, pub forest_kind: ForestKind,
pub marble: f32, pub marble: f32,
pub marble_mid: f32,
pub marble_small: f32, pub marble_small: f32,
pub rock: f32, pub rock: f32,
pub temp: f32, pub temp: f32,
@ -1194,6 +1209,8 @@ pub struct ColumnSample<'a> {
pub snow_cover: bool, pub snow_cover: bool,
pub cliff_offset: f32, pub cliff_offset: f32,
pub cliff_height: f32, pub cliff_height: f32,
pub water_vel: Vec3<f32>,
pub ice_depth: f32,
pub chunk: &'a SimChunk, pub chunk: &'a SimChunk,
} }

View File

@ -81,6 +81,7 @@ pub fn sample_pos(
is_basement, is_basement,
is_water, is_water,
is_ice,
is_shaded, is_shaded,
is_temperature, is_temperature,
is_humidity, is_humidity,
@ -133,7 +134,7 @@ pub fn sample_pos(
let humidity = humidity.min(1.0).max(0.0); let humidity = humidity.min(1.0).max(0.0);
let temperature = temperature.min(1.0).max(-1.0) * 0.5 + 0.5; let temperature = temperature.min(1.0).max(-1.0) * 0.5 + 0.5;
let wpos = pos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32); let wpos = pos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32);
let column_rgb_alt = samples let column_data = samples
.and_then(|samples| { .and_then(|samples| {
chunk_idx chunk_idx
.and_then(|chunk_idx| samples.get(chunk_idx)) .and_then(|chunk_idx| samples.get(chunk_idx))
@ -162,14 +163,14 @@ pub fn sample_pos(
.map(|e| e as f64) .map(|e| e as f64)
}; };
(rgb, alt) (rgb, alt, sample.ice_depth)
}); });
let downhill_wpos = downhill.unwrap_or(wpos + TerrainChunkSize::RECT_SIZE.map(|e| e as i32)); let downhill_wpos = downhill.unwrap_or(wpos + TerrainChunkSize::RECT_SIZE.map(|e| e as i32));
let alt = if is_basement { let alt = if is_basement {
basement basement
} else { } else {
column_rgb_alt.map_or(alt, |(_, alt)| alt) column_data.map_or(alt, |(_, alt, _)| alt)
}; };
let true_water_alt = (alt.max(water_alt) as f64 - focus.z) / gain as f64; let true_water_alt = (alt.max(water_alt) as f64 - focus.z) / gain as f64;
@ -189,7 +190,7 @@ pub fn sample_pos(
if is_shaded { 1.0 } else { alt }, if is_shaded { 1.0 } else { alt },
if is_shaded || is_humidity { 1.0 } else { 0.0 }, if is_shaded || is_humidity { 1.0 } else { 0.0 },
); );
let column_rgb = column_rgb_alt.map(|(rgb, _)| rgb).unwrap_or(default_rgb); let column_rgb = column_data.map(|(rgb, _, _)| rgb).unwrap_or(default_rgb);
let mut connections = [None; 8]; let mut connections = [None; 8];
let mut has_connections = false; let mut has_connections = false;
// TODO: Support non-river connections. // TODO: Support non-river connections.
@ -213,7 +214,11 @@ pub fn sample_pos(
}); });
}); });
}; };
let rgb = match (river_kind, (is_water, true_alt >= true_sea_level)) { let rgb =
if is_water && is_ice && column_data.map_or(false, |(_, _, ice_depth)| ice_depth > 0.0) {
Rgb::new(200, 225, 255)
} else {
match (river_kind, (is_water, true_alt >= true_sea_level)) {
(_, (false, _)) | (None, (_, true)) | (Some(RiverKind::River { .. }), _) => { (_, (false, _)) | (None, (_, true)) | (Some(RiverKind::River { .. }), _) => {
let (r, g, b) = ( let (r, g, b) = (
(column_rgb.r (column_rgb.r
@ -239,6 +244,7 @@ pub fn sample_pos(
((g_water - water_depth * g_water) * 1.0) as u8, ((g_water - water_depth * g_water) * 1.0) as u8,
((b_water - water_depth * b_water) * 1.0) as u8, ((b_water - water_depth * b_water) * 1.0) as u8,
), ),
}
}; };
// TODO: Make principled. // TODO: Make principled.
let rgb = if is_path { let rgb = if is_path {