Skip to main content

oxihuman_export/
depth_map_export.rs

1// Copyright (C) 2026 COOLJAPAN OU (Team KitaSan)
2// SPDX-License-Identifier: Apache-2.0
3#![allow(dead_code)]
4
5/// A depth image buffer.
6pub struct DepthMap {
7    pub width: usize,
8    pub height: usize,
9    pub data: Vec<f32>,
10    pub near_plane: f32,
11    pub far_plane: f32,
12}
13
14pub fn new_depth_map(width: usize, height: usize, near: f32, far: f32) -> DepthMap {
15    DepthMap {
16        width,
17        height,
18        data: vec![far; width * height],
19        near_plane: near,
20        far_plane: far,
21    }
22}
23
24pub fn depth_map_set(m: &mut DepthMap, x: usize, y: usize, depth: f32) {
25    if x < m.width && y < m.height {
26        m.data[y * m.width + x] = depth;
27    }
28}
29
30pub fn depth_map_get(m: &DepthMap, x: usize, y: usize) -> f32 {
31    if x < m.width && y < m.height {
32        m.data[y * m.width + x]
33    } else {
34        m.far_plane
35    }
36}
37
38pub fn depth_map_to_u16(m: &DepthMap) -> Vec<u16> {
39    let range = (m.far_plane - m.near_plane).max(1e-9);
40    m.data
41        .iter()
42        .map(|&d| {
43            let t = ((d - m.near_plane) / range).clamp(0.0, 1.0);
44            (t * 65535.0) as u16
45        })
46        .collect()
47}
48
49pub fn depth_map_min(m: &DepthMap) -> f32 {
50    m.data.iter().cloned().fold(f32::INFINITY, f32::min)
51}
52
53pub fn depth_map_max(m: &DepthMap) -> f32 {
54    m.data.iter().cloned().fold(f32::NEG_INFINITY, f32::max)
55}
56
57pub fn depth_map_normalize(m: &DepthMap) -> Vec<f32> {
58    let mn = depth_map_min(m);
59    let mx = depth_map_max(m);
60    let range = (mx - mn).max(1e-9);
61    m.data.iter().map(|&d| (d - mn) / range).collect()
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn test_new_depth_map_size() {
70        let m = new_depth_map(4, 4, 0.1, 100.0);
71        assert_eq!(m.data.len(), 16);
72    }
73
74    #[test]
75    fn test_depth_map_set_get() {
76        let mut m = new_depth_map(4, 4, 0.1, 100.0);
77        depth_map_set(&mut m, 2, 1, 5.0);
78        assert!((depth_map_get(&m, 2, 1) - 5.0).abs() < 1e-6);
79    }
80
81    #[test]
82    fn test_depth_map_get_oob() {
83        let m = new_depth_map(4, 4, 0.1, 100.0);
84        assert!((depth_map_get(&m, 10, 10) - 100.0).abs() < 1e-6);
85    }
86
87    #[test]
88    fn test_depth_map_to_u16_range() {
89        let mut m = new_depth_map(2, 1, 0.0, 1.0);
90        depth_map_set(&mut m, 0, 0, 0.0);
91        depth_map_set(&mut m, 1, 0, 1.0);
92        let u16s = depth_map_to_u16(&m);
93        assert_eq!(u16s[0], 0);
94        assert_eq!(u16s[1], 65535);
95    }
96
97    #[test]
98    fn test_depth_map_min() {
99        let mut m = new_depth_map(3, 1, 0.0, 10.0);
100        depth_map_set(&mut m, 0, 0, 2.0);
101        depth_map_set(&mut m, 1, 0, 5.0);
102        depth_map_set(&mut m, 2, 0, 8.0);
103        assert!((depth_map_min(&m) - 2.0).abs() < 1e-5);
104    }
105
106    #[test]
107    fn test_depth_map_max() {
108        let mut m = new_depth_map(3, 1, 0.0, 10.0);
109        depth_map_set(&mut m, 0, 0, 2.0);
110        depth_map_set(&mut m, 1, 0, 9.0);
111        depth_map_set(&mut m, 2, 0, 4.0);
112        assert!((depth_map_max(&m) - 9.0).abs() < 1e-5);
113    }
114
115    #[test]
116    fn test_depth_map_normalize_range() {
117        let mut m = new_depth_map(2, 1, 0.0, 10.0);
118        depth_map_set(&mut m, 0, 0, 0.0);
119        depth_map_set(&mut m, 1, 0, 10.0);
120        let n = depth_map_normalize(&m);
121        assert!((n[0] - 0.0).abs() < 1e-5);
122        assert!((n[1] - 1.0).abs() < 1e-5);
123    }
124
125    #[test]
126    fn test_depth_map_default_far() {
127        let m = new_depth_map(2, 2, 0.1, 50.0);
128        assert!((m.data[0] - 50.0).abs() < 1e-5);
129    }
130}