#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Camera {
pub pos: [f64; 3],
pub right: [f64; 3],
pub down: [f64; 3],
pub forward: [f64; 3],
}
impl Default for Camera {
fn default() -> Self {
Self {
pos: [1024.0, 1024.0, 128.0],
right: [1.0, 0.0, 0.0],
down: [0.0, 0.0, 1.0],
forward: [0.0, 1.0, 0.0],
}
}
}
impl Camera {
#[must_use]
pub fn from_yaw_pitch(pos: [f64; 3], yaw: f64, pitch: f64) -> Self {
let (sy, cy) = yaw.sin_cos();
let (sp, cp) = pitch.sin_cos();
Self {
pos,
right: [-sy, cy, 0.0],
down: [-cy * sp, -sy * sp, cp],
forward: [cy * cp, sy * cp, sp],
}
}
#[must_use]
pub fn orbit(yaw: f64, pitch: f64, dist: f64, center: [f64; 3]) -> Self {
let mut cam = Self::from_yaw_pitch([0.0; 3], yaw, pitch);
cam.pos = [
center[0] - cam.forward[0] * dist,
center[1] - cam.forward[1] * dist,
center[2] - cam.forward[2] * dist,
];
cam
}
#[must_use]
pub fn look_at(eye: [f64; 3], target: [f64; 3]) -> Self {
let fx = target[0] - eye[0];
let fy = target[1] - eye[1];
let fz = target[2] - eye[2];
let yaw = fy.atan2(fx);
let horiz = (fx * fx + fy * fy).sqrt();
let pitch = fz.atan2(horiz);
Self::from_yaw_pitch(eye, yaw, pitch)
}
}