use std::cell::Cell;
#[derive(Clone, Copy, Debug, PartialEq)]
pub(crate) struct UpscaleCamera {
pub(crate) jitter_offset: [f32; 2],
pub(crate) elapsed: f32,
pub(crate) near: f32,
pub(crate) fov_y_radians: f32,
}
impl UpscaleCamera {
pub(crate) fn new(
jitter_offset: [f32; 2],
elapsed: f32,
near: f32,
fov_y_radians: f32,
) -> Self {
Self {
jitter_offset,
elapsed,
near: near.max(1e-3),
fov_y_radians,
}
}
}
#[derive(Debug, Default)]
pub(super) struct FrameClock {
prev_elapsed: Cell<f32>,
}
impl FrameClock {
pub(super) fn delta_ms(&self, now: f32) -> f32 {
let last = self.prev_elapsed.replace(now);
((now - last) * 1000.0).clamp(1.0, 100.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn frame_delta_is_clamped() {
let clock = FrameClock::default();
assert!((clock.delta_ms(10.0) - 100.0).abs() < 1e-3);
assert!((clock.delta_ms(10.016) - 16.0).abs() < 1e-2);
assert!((clock.delta_ms(10.016) - 1.0).abs() < 1e-3);
}
#[test]
fn near_plane_is_kept_off_zero() {
assert_eq!(UpscaleCamera::new([0.0; 2], 0.0, 0.0, 1.0).near, 1e-3);
assert_eq!(UpscaleCamera::new([0.0; 2], 0.0, 0.5, 1.0).near, 0.5);
}
}