rewrite the camera for the specific use case
This commit is contained in:
parent
712110d5c2
commit
801c0b4495
|
|
@ -1,40 +1,51 @@
|
||||||
use glam::{Mat3, Vec3};
|
use glam::{Vec3, vec3};
|
||||||
|
|
||||||
pub fn ypr_to_mat(ypr: Vec3) -> Mat3 {
|
/// A camera always directed at the origin.
|
||||||
glam::Mat3::from_euler(glam::EulerRot::ZXZEx, ypr.x, ypr.y, ypr.z)
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct OrbitalCamera {
|
||||||
|
/// Horizontal position (angle), in radians from +X towards +Y.
|
||||||
|
pub position_yaw: f32,
|
||||||
|
|
||||||
|
/// Vertical position (angle), in radians from XY plane towards +Z.
|
||||||
|
pub position_pitch: f32,
|
||||||
|
|
||||||
|
/// Distance from the origin.
|
||||||
|
pub distance: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OrbitalCamera {
|
||||||
|
pub fn position(&self) -> Vec3 {
|
||||||
|
let (y, x) = self.position_yaw.sin_cos();
|
||||||
|
let (z, xy) = self.position_pitch.sin_cos();
|
||||||
|
self.distance * vec3(xy * x, xy * y, z)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::f32::consts::PI;
|
|
||||||
|
|
||||||
use approx::assert_ulps_eq;
|
use approx::assert_ulps_eq;
|
||||||
use glam::vec3;
|
use glam::vec3;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ypr_to_mat() {
|
fn test_orbital_camera_position() {
|
||||||
assert_ulps_eq!(ypr_to_mat(vec3(0., 0., 0.)), Mat3::IDENTITY, max_ulps = 3);
|
fn camera_pos_deg(yaw: f32, pitch: f32) -> Vec3 {
|
||||||
assert_ulps_eq!(
|
OrbitalCamera {
|
||||||
ypr_to_mat(vec3(PI / 2., 0., 0.)),
|
position_yaw: yaw.to_radians(),
|
||||||
Mat3::from_cols_array_2d(&[[0., 1., 0.], [-1., 0., 0.], [0., 0., 1.]]),
|
position_pitch: pitch.to_radians(),
|
||||||
max_ulps = 3,
|
distance: 1.0,
|
||||||
);
|
}
|
||||||
assert_ulps_eq!(
|
.position()
|
||||||
ypr_to_mat(vec3(0., 0., PI / 2.)),
|
}
|
||||||
Mat3::from_cols_array_2d(&[[0., 1., 0.], [-1., 0., 0.], [0., 0., 1.]]),
|
assert_ulps_eq!(camera_pos_deg(0., 0.), vec3(1., 0., 0.), max_ulps = 3);
|
||||||
max_ulps = 3,
|
assert_ulps_eq!(camera_pos_deg(90., 0.), vec3(0., 1., 0.), max_ulps = 3);
|
||||||
);
|
assert_ulps_eq!(camera_pos_deg(0., 90.), vec3(0., 0., 1.), max_ulps = 3);
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(camera_pos_deg(90., 90.), vec3(0., 0., 1.), max_ulps = 3);
|
||||||
ypr_to_mat(vec3(0., PI / 2., 0.)),
|
|
||||||
Mat3::from_cols_array_2d(&[[1., 0., 0.], [0., 0., 1.], [0., -1., 0.]]),
|
let s2 = 0.5f32.sqrt();
|
||||||
max_ulps = 3,
|
assert_ulps_eq!(camera_pos_deg(45., 0.), vec3(s2, s2, 0.), max_ulps = 3);
|
||||||
);
|
assert_ulps_eq!(camera_pos_deg(0., 45.), vec3(s2, 0., s2), max_ulps = 3);
|
||||||
assert_ulps_eq!(
|
assert_ulps_eq!(camera_pos_deg(45., 45.), vec3(0.5, 0.5, s2), max_ulps = 3);
|
||||||
ypr_to_mat(vec3(PI / 2., PI / 2., 0.)),
|
|
||||||
Mat3::from_cols_array_2d(&[[0., 0., 1.], [-1., 0., 0.], [0., -1., 0.]]),
|
|
||||||
max_ulps = 3,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user