Skip to content

Commit

Permalink
pack heightmap more efficiently (more precision near zero)
Browse files Browse the repository at this point in the history
  • Loading branch information
Uriopass committed Jan 22, 2024
1 parent c61eded commit 584c30c
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 5 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ ordered-float = { version = "4.2.0", default-features = false }
oddio = "0.7.4"
derive_more = "0.99.17"
yakui = { git = "https://github.com/SecondHalfGames/yakui" }
mlua = { version = "0.9.4", features = ["luau"] }

# Set the settings for build scripts and proc-macros.
[profile.dev.build-override]
Expand Down
2 changes: 1 addition & 1 deletion geom/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ serde = { version = "1.0", features = ["derive"] }
fnv = "1.0.3"
inline_tweak = "1.0.8"
flat_spatial = { workspace = true }
mlua = "0.9.4"
mlua = { workspace = true }
46 changes: 43 additions & 3 deletions geom/src/heightmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use serde::{Deserialize, Serialize, Serializer};
pub type HeightmapChunkID = (u16, u16);

const MAX_HEIGHT_DIFF: f32 = 2048.0;
const MIN_HEIGHT: f32 = -40.0007;
const HALF_HEIGHT_DIFF: f32 = MAX_HEIGHT_DIFF / 4.0; // Point where half of the precision goes to
const MIN_HEIGHT: f32 = -39.96997;
const MAX_HEIGHT: f32 = MAX_HEIGHT_DIFF - MIN_HEIGHT;

/// Special value for heights_override to indicate that the height is not overridden
Expand Down Expand Up @@ -516,13 +517,52 @@ fn binary_search(min: f32, max: f32, mut f: impl FnMut(f32) -> bool) -> f32 {
mid
}

const HALF_U16: u16 = u16::MAX >> 1;

pub fn pack_height(height: f32) -> u16 {
let height = height.clamp(MIN_HEIGHT, MAX_HEIGHT);
((height - MIN_HEIGHT) / MAX_HEIGHT_DIFF * u16::MAX as f32) as u16

let height_off = height - MIN_HEIGHT;

if height < HALF_HEIGHT_DIFF {
return (height_off / HALF_HEIGHT_DIFF * HALF_U16 as f32) as u16;
}

let height_off = height_off - HALF_HEIGHT_DIFF;
return (HALF_U16 as f32 + height_off / HALF_HEIGHT_DIFF * HALF_U16 as f32) as u16;
}

fn unpack_height(height: u16) -> f32 {
height as f32 / u16::MAX as f32 * MAX_HEIGHT_DIFF + MIN_HEIGHT
if height < HALF_U16 {
return MIN_HEIGHT + height as f32 / HALF_U16 as f32 * HALF_HEIGHT_DIFF;
}

let height = height - HALF_U16;
return MIN_HEIGHT + HALF_HEIGHT_DIFF + height as f32 / HALF_U16 as f32 * HALF_HEIGHT_DIFF;
}

#[cfg(test)]
#[allow(dead_code)]
mod tests {
use super::*;
// #[test]
fn find_pack_zero() {
let mut min_height = -40.0;

for _ in 0..10000 {
min_height += 0.00001;

let height_off = 0.0 - min_height;

let packed = (height_off / HALF_HEIGHT_DIFF * HALF_U16 as f32) as u16;

let unpacked = min_height + packed as f32 / HALF_U16 as f32 * HALF_HEIGHT_DIFF;

if unpacked >= 0.0 {
println!("{} {}", min_height, unpacked);
}
}
}
}

impl<const RESOLUTION: usize, const SIZE: u32> Serialize for HeightmapChunk<RESOLUTION, SIZE> {
Expand Down
2 changes: 1 addition & 1 deletion prototypes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ edition = "2021"
common = { path = "../common" }
geom = { path = "../geom" }
egui-inspect = { path = "../egui-inspect" }
mlua = { version = "0.9.4", features = ["luau"] }
mlua = { workspace = true }
slotmapd = "1.0.10"
serde = "1.0.195"
thiserror = "1.0.56"
Expand Down

0 comments on commit 584c30c

Please sign in to comment.