#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct DepthRangeViewConfig {
pub near: f32,
pub far: f32,
pub gamma: f32,
pub invert: bool,
}
impl Default for DepthRangeViewConfig {
fn default() -> Self {
Self { near: 0.1, far: 1000.0, gamma: 1.0, invert: false }
}
}
#[derive(Debug, Clone)]
pub struct DepthRangeView {
pub config: DepthRangeViewConfig,
pub enabled: bool,
}
impl Default for DepthRangeView {
fn default() -> Self {
Self { config: DepthRangeViewConfig::default(), enabled: false }
}
}
pub fn drv_enable(view: &mut DepthRangeView) {
view.enabled = true;
}
pub fn drv_disable(view: &mut DepthRangeView) {
view.enabled = false;
}
pub fn drv_set_range(view: &mut DepthRangeView, near: f32, far: f32) {
view.config.near = near.max(0.0001);
view.config.far = far.max(view.config.near + 0.001);
}
pub fn drv_linearize(depth: f32, config: &DepthRangeViewConfig) -> f32 {
let n = config.near;
let f = config.far;
let linear = (2.0 * n) / (f + n - depth * (f - n));
let v = linear.clamp(0.0, 1.0).powf(1.0 / config.gamma.max(0.001));
if config.invert { 1.0 - v } else { v }
}
pub fn drv_depth_to_color(depth: f32, config: &DepthRangeViewConfig) -> [f32; 4] {
let v = drv_linearize(depth, config);
[v, v, v, 1.0]
}
pub fn drv_to_json(view: &DepthRangeView) -> String {
format!(
r#"{{"near":{:.4},"far":{:.2},"enabled":{}}}"#,
view.config.near, view.config.far, view.enabled
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_disabled() {
let v = DepthRangeView::default();
assert!(!v.enabled);
}
#[test]
fn test_enable_disable() {
let mut v = DepthRangeView::default();
drv_enable(&mut v);
assert!(v.enabled);
drv_disable(&mut v);
assert!(!v.enabled);
}
#[test]
fn test_set_range() {
let mut v = DepthRangeView::default();
drv_set_range(&mut v, 0.5, 500.0);
assert!((v.config.near - 0.5).abs() < 1e-6);
assert!((v.config.far - 500.0).abs() < 1e-5);
}
#[test]
fn test_near_minimum() {
let mut v = DepthRangeView::default();
drv_set_range(&mut v, 0.0, 100.0);
assert!(v.config.near > 0.0);
}
#[test]
fn test_linearize_range() {
let cfg = DepthRangeViewConfig::default();
let v = drv_linearize(0.5, &cfg);
assert!((0.0..=1.0).contains(&v));
}
#[test]
fn test_linearize_invert() {
let cfg = DepthRangeViewConfig::default();
let normal = drv_linearize(0.5, &cfg);
let inv_cfg = DepthRangeViewConfig { invert: true, ..cfg };
let inverted = drv_linearize(0.5, &inv_cfg);
assert!((normal + inverted - 1.0).abs() < 1e-5);
}
#[test]
fn test_depth_to_color_greyscale() {
let cfg = DepthRangeViewConfig::default();
let c = drv_depth_to_color(0.5, &cfg);
assert!((c[0] - c[1]).abs() < 1e-6);
assert!((c[1] - c[2]).abs() < 1e-6);
}
#[test]
fn test_depth_to_color_alpha() {
let cfg = DepthRangeViewConfig::default();
let c = drv_depth_to_color(0.5, &cfg);
assert!((c[3] - 1.0).abs() < 1e-6);
}
#[test]
fn test_to_json_contains_near() {
let v = DepthRangeView::default();
let json = drv_to_json(&v);
assert!(json.contains("near"));
}
}