70 lines
2.2 KiB
Rust
Raw Normal View History

2025-05-05 20:07:20 +02:00
use cgmath::{Matrix4, Point3, Vector3, Deg, perspective, InnerSpace, Rotation, Quaternion, Rotation3, Rad};
#[derive(Debug)]
pub struct Camera {
pub eye: Point3<f32>,
pub target: Point3<f32>,
pub up: Vector3<f32>,
pub fov_y: Deg<f32>,
pub aspect: f32,
pub znear: f32,
pub zfar: f32,
}
impl Camera {
pub fn new(aspect: f32) -> Self {
Self {
eye: Point3::new(0.0, 0.0, 5.0),
target: Point3::new(0.0, 0.0, 0.0),
up: Vector3::unit_y(),
fov_y: Deg(45.0),
aspect,
znear: 0.1,
zfar: 100.0,
}
}
pub fn build_view_projection_matrix(&self) -> Matrix4<f32> {
let view = Matrix4::look_at_rh(self.eye, self.target, self.up);
let proj = perspective(self.fov_y, self.aspect, self.znear, self.zfar);
proj * view
}
2025-05-07 19:45:35 +02:00
pub fn build_view_matrix(&self) -> Matrix4<f32> {
Matrix4::look_at_rh(self.eye, self.target, self.up)
}
2025-05-05 20:07:20 +02:00
pub fn rotate_yaw_pitch(&mut self, yaw: f32, pitch: f32) {
let offset = self.eye - self.target;
let distance = offset.magnitude();
2025-05-05 20:07:20 +02:00
let yaw_q = Quaternion::from_axis_angle(Vector3::unit_y(), Rad(yaw.to_radians()));
let right = offset.cross(self.up).normalize();
let pitch_q = Quaternion::from_axis_angle(right, Rad(pitch.to_radians()));
2025-05-05 20:07:20 +02:00
let rotation = yaw_q * pitch_q;
let new_offset = rotation.rotate_vector(offset);
self.eye = self.target + new_offset;
self.up = rotation.rotate_vector(self.up);
}
pub fn translate(&mut self, translation: Vector3<f32>) {
let dir = (self.target - self.eye).normalize();
let horizontal = Vector3::unit_y().cross(dir).normalize();
let vertical = horizontal.cross(dir).normalize();
2025-05-05 20:07:20 +02:00
self.eye += horizontal * translation.x + vertical * translation.y;
self.target += horizontal * translation.x + vertical * translation.y;
2025-05-05 20:07:20 +02:00
}
pub fn zoom(&mut self, amount: f32) {
let dir = (self.target - self.eye).normalize();
self.eye += dir * amount;
}
pub fn set_aspect(&mut self, aspect: f32) {
self.aspect = aspect;
}
}