//! # Camera Module //! //! Defines the `Camera` struct and related functionality for 3D viewing. //! Supports different camera types and projection configurations. //! //! ## Usage //! - Used by `Renderer` to compute view and projection matrices //! - Configurable for perspective and orthographic projections //! - Supports FPS-style and orbital movement patterns //! //! ## Related Types //! - `Camera`: Main struct for camera configuration //! - `view_matrix()`: Computes the view matrix //! - `projection_matrix()`: Computes the projection matrix use glam::{Mat4, Vec3}; /// Default vertical field of view in radians (45°). pub const DEFAULT_FOV: f32 = 45.0_f32.to_radians(); /// Near clipping plane distance used by the default perspective projection. pub const DEFAULT_NEAR: f32 = 0.1; /// Far clipping plane distance used by the default perspective projection. pub const DEFAULT_FAR: f32 = 100.0; /// Represents a 3D camera for viewing the scene. /// /// The camera defines the viewpoint (position/target/up), the projection parameters (fov, near, far) /// and can produce the view and projection matrices uploaded each frame to the `FrameUniforms` buffer /// (Étape 4.3). Use `Scene::set_camera` to install it as the scene's active camera. #[derive(Debug, Clone)] pub struct Camera { /// Position of the camera in world space pub position: Vec3, /// Target point the camera is looking at pub target: Vec3, /// Up vector defining the camera's orientation pub up: Vec3, /// Vertical field of view in radians (used by the perspective projection). pub fov: f32, /// Near clipping plane distance (used by the perspective projection). pub near: f32, /// Far clipping plane distance (used by the perspective projection). pub far: f32, } impl Default for Camera { /// Default camera : positioned at (0, 0, 3) looking at the origin with a 45° vertical fov, /// near 0.1 and far 100. Good enough to frame a unit-cube scene out of the box. fn default() -> Self { Self::new(Vec3::new(0.0, 0.0, 3.0), Vec3::ZERO, Vec3::Y) } } impl Camera { /// Creates a new perspective camera with the default fov/near/far. /// Inputs: position (world-space eye point), target (world-space look-at point), up (view up vector). /// Adjust the projection via [`Camera::with_perspective`] if the defaults don't fit. pub fn new(position: Vec3, target: Vec3, up: Vec3) -> Self { Self { position, target, up, fov: DEFAULT_FOV, near: DEFAULT_NEAR, far: DEFAULT_FAR, } } /// Sets the perspective projection parameters and returns the camera for chaining. /// Inputs: fov (vertical field of view in radians), near (near plane), far (far plane). pub fn with_perspective(mut self, fov: f32, near: f32, far: f32) -> Self { self.fov = fov; self.near = near; self.far = far; self } /// Computes the view matrix for this camera. /// /// # Returns /// A `Mat4` representing the view transformation matrix (world → view space) pub fn view_matrix(&self) -> Mat4 { glam::camera::rh::view::look_at_mat4(self.position, self.target, self.up) } /// Computes the perspective projection matrix for this camera using its stored fov/near/far. /// /// # Parameters /// - `aspect`: Aspect ratio of the viewport (width / height) /// /// # Returns /// A `Mat4` representing the projection transformation matrix (view → clip space) pub fn projection_matrix(&self, aspect: f32) -> Mat4 { glam::camera::rh::proj::opengl::perspective(self.fov, aspect, self.near, self.far) } }