use image::{DynamicImage, GenericImageView};
#[derive(Clone, Debug, Default)]
pub struct RatatuiCameraDepthBuffer {
width: usize,
height: usize,
pub(crate) buffer: Vec<f32>,
}
impl RatatuiCameraDepthBuffer {
pub fn new(area: ratatui::layout::Rect) -> Self {
Self {
width: area.width as usize,
height: area.height as usize * 2,
buffer: vec![0.0; area.width as usize * area.height as usize * 2],
}
}
pub fn get(&self, x: usize, y: usize) -> Option<f32> {
let index = self.index(x, y)?;
Some(self.buffer[index])
}
pub fn set(&mut self, x: usize, y: usize, depth: f32) -> Option<f32> {
let index = self.index(x, y)?;
let previous = self.buffer[index];
self.buffer[index] = depth;
Some(previous)
}
pub fn compare_and_update(&mut self, x: usize, y: usize, depth: f32) -> Option<bool> {
let previous_depth = self.get(x, y)?;
if depth >= previous_depth {
self.set(x, y, depth);
return Some(true);
}
Some(false)
}
pub fn compare_and_update_from_image(
&mut self,
x: u32,
y: u32,
depth_image: &DynamicImage,
) -> Option<bool> {
if x > depth_image.width() || y > depth_image.height() {
return None;
}
let depth_bytes = depth_image.get_pixel(x, y);
let depth = f32::from_le_bytes(depth_bytes.0);
self.compare_and_update(x as usize, y as usize, depth)
}
fn index(&self, x: usize, y: usize) -> Option<usize> {
if !self.valid_coordinates(x, y) {
return None;
}
Some(x + y * self.width)
}
fn valid_coordinates(&self, x: usize, y: usize) -> bool {
x < self.width && y < self.height
}
}