use cgmath::*;
pub enum CameraProjection {
Perspective {
fov: Deg<f32>, aspect_ratio: f32, near: f32, far: f32, },
Orthographic {
left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32, },
}
pub struct Camera {
pub position: Vector3<f32>,
pub target: Vector3<f32>,
pub up: Vector3<f32>,
pub projection: CameraProjection,
}
impl Camera {
pub fn new(
position: Vector3<f32>,
target: Vector3<f32>,
up: Vector3<f32>,
projection: CameraProjection,
) -> Self {
Self {
position,
target,
up,
projection,
}
}
pub fn view_matrix(&self) -> Matrix4<f32> {
Matrix4::look_at_rh(
Point3::from_vec(self.position),
Point3::from_vec(self.target),
self.up,
)
}
pub fn projection_matrix(&self) -> Matrix4<f32> {
match &self.projection {
CameraProjection::Perspective {
fov,
aspect_ratio,
near,
far,
} => PerspectiveFov {
fovy: Rad::from(*fov),
aspect: *aspect_ratio,
near: *near,
far: *far,
}
.into(),
CameraProjection::Orthographic {
left,
right,
bottom,
top,
near,
far,
} => ortho(*left, *right, *bottom, *top, *near, *far),
}
}
pub fn move_to(&mut self, position: Vector3<f32>) {
self.position = position;
}
pub fn look_at(&mut self, target: Vector3<f32>) {
self.target = target;
}
pub fn set_orthographic(
&mut self,
left: f32,
right: f32,
bottom: f32,
top: f32,
near: f32,
far: f32,
) {
self.projection = CameraProjection::Orthographic {
left,
right,
bottom,
top,
near,
far,
};
}
pub fn set_perspective(&mut self, fov: Deg<f32>, aspect_ratio: f32, near: f32, far: f32) {
self.projection = CameraProjection::Perspective {
fov,
aspect_ratio,
near,
far,
};
}
}