#![allow(dead_code)]
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct CameraRigKeyframe {
pub time: f32,
pub position: [f32; 3],
pub target: [f32; 3],
pub fov: f32,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct CameraRigExport {
pub name: String,
pub keyframes: Vec<CameraRigKeyframe>,
}
#[allow(dead_code)]
pub fn new_camera_rig_export(name: &str) -> CameraRigExport {
CameraRigExport {
name: name.to_string(),
keyframes: Vec::new(),
}
}
#[allow(dead_code)]
pub fn rig_add_keyframe(
rig: &mut CameraRigExport,
time: f32,
position: [f32; 3],
target: [f32; 3],
fov: f32,
) {
rig.keyframes.push(CameraRigKeyframe {
time,
position,
target,
fov,
});
}
#[allow(dead_code)]
pub fn rig_keyframe_count(rig: &CameraRigExport) -> usize {
rig.keyframes.len()
}
#[allow(dead_code)]
pub fn rig_duration(rig: &CameraRigExport) -> f32 {
if rig.keyframes.len() < 2 {
return 0.0;
}
rig.keyframes.last().map_or(0.0, |k| k.time) - rig.keyframes.first().map_or(0.0, |k| k.time)
}
#[allow(dead_code)]
pub fn rig_keyframe_at(rig: &CameraRigExport, idx: usize) -> Option<&CameraRigKeyframe> {
rig.keyframes.get(idx)
}
#[allow(dead_code)]
pub fn rig_clear(rig: &mut CameraRigExport) {
rig.keyframes.clear();
}
#[allow(dead_code)]
pub fn camera_rig_to_json(rig: &CameraRigExport) -> String {
format!(
"{{\"name\":\"{}\",\"keyframes\":{},\"duration\":{:.6}}}",
rig.name,
rig.keyframes.len(),
rig_duration(rig),
)
}
#[allow(dead_code)]
pub fn rig_validate(rig: &CameraRigExport) -> bool {
rig.keyframes.windows(2).all(|w| w[0].time <= w[1].time)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
let r = new_camera_rig_export("main");
assert_eq!(rig_keyframe_count(&r), 0);
}
#[test]
fn test_add_keyframe() {
let mut r = new_camera_rig_export("cam");
rig_add_keyframe(&mut r, 0.0, [0.0; 3], [0.0, 0.0, -1.0], 60.0);
assert_eq!(rig_keyframe_count(&r), 1);
}
#[test]
fn test_duration() {
let mut r = new_camera_rig_export("cam");
rig_add_keyframe(&mut r, 0.0, [0.0; 3], [0.0; 3], 60.0);
rig_add_keyframe(&mut r, 2.5, [1.0; 3], [0.0; 3], 60.0);
assert!((rig_duration(&r) - 2.5).abs() < 1e-6);
}
#[test]
fn test_duration_single() {
let mut r = new_camera_rig_export("cam");
rig_add_keyframe(&mut r, 1.0, [0.0; 3], [0.0; 3], 60.0);
assert!((rig_duration(&r)).abs() < 1e-6);
}
#[test]
fn test_keyframe_at() {
let mut r = new_camera_rig_export("cam");
rig_add_keyframe(&mut r, 0.0, [1.0, 2.0, 3.0], [0.0; 3], 45.0);
let kf = rig_keyframe_at(&r, 0).expect("should succeed");
assert!((kf.fov - 45.0).abs() < 1e-6);
}
#[test]
fn test_clear() {
let mut r = new_camera_rig_export("cam");
rig_add_keyframe(&mut r, 0.0, [0.0; 3], [0.0; 3], 60.0);
rig_clear(&mut r);
assert_eq!(rig_keyframe_count(&r), 0);
}
#[test]
fn test_to_json() {
let r = new_camera_rig_export("test");
assert!(camera_rig_to_json(&r).contains("\"name\":\"test\""));
}
#[test]
fn test_validate_sorted() {
let mut r = new_camera_rig_export("cam");
rig_add_keyframe(&mut r, 0.0, [0.0; 3], [0.0; 3], 60.0);
rig_add_keyframe(&mut r, 1.0, [0.0; 3], [0.0; 3], 60.0);
assert!(rig_validate(&r));
}
#[test]
fn test_validate_unsorted() {
let mut r = new_camera_rig_export("cam");
rig_add_keyframe(&mut r, 2.0, [0.0; 3], [0.0; 3], 60.0);
rig_add_keyframe(&mut r, 1.0, [0.0; 3], [0.0; 3], 60.0);
assert!(!rig_validate(&r));
}
#[test]
fn test_keyframe_at_oob() {
let r = new_camera_rig_export("cam");
assert!(rig_keyframe_at(&r, 0).is_none());
}
}