Add approximate chunk terrain normals into sim

This commit is contained in:
laundmo 2023-06-10 01:50:55 +02:00 committed by juliancoffee
parent 4c97f3f624
commit 59bf62a453
4 changed files with 69 additions and 38 deletions

View File

@ -141,8 +141,7 @@ pub struct TerrainChunkMeta {
contains_cave: bool,
contains_river: bool,
river_velocity: Vec3<f32>,
downhill_chunk: Option<Vec2<i32>>,
gradient: Option<f32>,
approx_chunk_terrain_normal: Option<Vec3<f32>>,
rockiness: f32,
cliff_height: f32,
temp: f32,
@ -166,8 +165,7 @@ impl TerrainChunkMeta {
temp: f32,
humidity: f32,
site: Option<SiteKindMeta>,
downhill_chunk: Option<Vec2<i32>>,
gradient: Option<f32>,
approx_chunk_terrain_normal: Option<Vec3<f32>>,
rockiness: f32,
cliff_height: f32,
) -> Self {
@ -186,10 +184,9 @@ impl TerrainChunkMeta {
debug_points: Vec::new(),
debug_lines: Vec::new(),
sprite_cfgs: HashMap::default(),
downhill_chunk,
approx_chunk_terrain_normal,
rockiness,
cliff_height,
gradient,
}
}
@ -209,8 +206,7 @@ impl TerrainChunkMeta {
debug_points: Vec::new(),
debug_lines: Vec::new(),
sprite_cfgs: HashMap::default(),
downhill_chunk: None,
gradient: None,
approx_chunk_terrain_normal: None,
rockiness: 0.0,
cliff_height: 0.0,
}
@ -258,9 +254,9 @@ impl TerrainChunkMeta {
self.sprite_cfgs.insert(rpos, sprite_cfg);
}
pub fn downhill_chunk(&self) -> Option<Vec2<i32>> { self.downhill_chunk }
pub fn gradient(&self) -> Option<f32> { self.gradient }
pub fn approx_chunk_terrain_normal(&self) -> Option<Vec3<f32>> {
self.approx_chunk_terrain_normal
}
pub fn rockiness(&self) -> f32 { self.rockiness }

View File

@ -692,31 +692,35 @@ impl<'a> PhysicsData<'a> {
// === Ridge/Wave lift ===
let mut ridge_lift = meta
.downhill_chunk()
.map(|cpos| {
let upwards: Vec2<f32> = -(chunk_pos.cpos_to_wpos_center().as_()
- cpos.cpos_to_wpos_center().as_());
match read.terrain.get_key(cpos).map(|c| c.meta()) {
Some(other_meta) => {
let wind = dbg!(
(upwards + wind_velocity)
.clamped(Vec2::zero(), Vec2::broadcast(1.0))
);
let vertical_distance =
((meta.alt() - other_meta.alt()) / 20.0).clamp(0.0, 14.0); // just guessing, 50 blocks seems like a decent max
if wind.magnitude_squared().is_positive() {
0.5 + dbg!(wind.magnitude()).clamp(0.0, 1.0)
+ dbg!(vertical_distance)
} else {
1.0
}
},
None => 0.0,
}
})
.unwrap_or(0.0);
dbg!(ridge_lift);
// TODO: reimplement with chunk terrain normals
let mut ridge_lift = 1.;
// let mut ridge_lift = meta
// .downhill_chunk()
// .map(|cpos| {
// let upwards: Vec2<f32> = -(chunk_pos.cpos_to_wpos_center().as_()
// - cpos.cpos_to_wpos_center().as_());
// match read.terrain.get_key(cpos).map(|c| c.meta()) {
// Some(other_meta) => {
// let wind = dbg!(
// (upwards + wind_velocity)
// .clamped(Vec2::zero(), Vec2::broadcast(1.0))
// );
// let vertical_distance =
// ((meta.alt() - other_meta.alt()) / 20.0).clamp(0.0,
// 14.0); // just guessing, 50 blocks seems like a decent max
// if wind.magnitude_squared().is_positive() {
// 0.5 + dbg!(wind.magnitude()).clamp(0.0, 1.0)
// + dbg!(vertical_distance)
// } else {
// 1.0
// }
// },
// None => 0.0,
// }
// })
// .unwrap_or(0.0);
// dbg!(ridge_lift);
// Cliffs mean more lift
ridge_lift *= 0.9 + (meta.cliff_height() / 44.0) * 1.2; // 44 seems to be max, according to a lerp in WorldSim::generate_cliffs

View File

@ -404,8 +404,7 @@ impl World {
.sites
.iter()
.find_map(|site| index.sites[*site].kind.convert_to_meta()),
sim_chunk.downhill.map(|e| e.wpos_to_cpos()),
self.sim.get_gradient_approx(chunk_pos),
self.sim.approx_chunk_terrain_normal(chunk_pos),
sim_chunk.rockiness,
sim_chunk.cliff_height,
);

View File

@ -1636,6 +1636,38 @@ impl WorldSim {
TerrainChunk::water(CONFIG.sea_level as i32)
}
pub fn approx_chunk_terrain_normal(&self, chunk_pos: Vec2<i32>) -> Option<Vec3<f32>> {
let curr_chunk = self.get(chunk_pos)?;
let downhill_chunk_pos = curr_chunk.downhill?.wpos_to_cpos();
let downhill_chunk = self.get(downhill_chunk_pos)?;
// special case if chunks are flat
if (curr_chunk.alt - downhill_chunk.alt) == 0. {
return Some(Vec3::unit_z());
}
let calc_zero = chunk_pos
.cpos_to_wpos_center()
.as_()
.with_z(downhill_chunk.alt);
let downhill = calc_zero
- Vec3::<f32>::from((
downhill_chunk_pos.cpos_to_wpos_center().as_(),
downhill_chunk.alt,
));
let curr = Vec3::zero().with_z(curr_chunk.alt);
let flat_dist = downhill.magnitude();
let f = curr.z.powi(2) / flat_dist;
let neg_normal = Vec3::new(
(-downhill.x / flat_dist) * f,
(-downhill.y / flat_dist) * f,
0.,
);
let normal = neg_normal - curr;
Some(normal.normalized())
}
/// Draw a map of the world based on chunk information. Returns a buffer of
/// u32s.
pub fn get_map(&self, index: IndexRef, calendar: Option<&Calendar>) -> WorldMapMsg {