Files
wsg/lib/src/resources/camera.rs
T
Jérôme Bousquié f10e249898 feat(renderer): active camera wired to frame uniforms (Étape 4.3)
- Camera enrichie: fov/near/far stockés, Default (pos (0,0,3), 45°, near 0.1,
  far 100), with_perspective(), projection_matrix(aspect) depuis les params
  stockés (au lieu de les passer en argument).
- Scene porte une caméra active: set_camera()/camera() (défaut Camera::default).
- Renderer::render_scene(view, scene, aspect) écrit chaque frame view/proj/
  cam_pos réels dans le buffer frame (write_frame_uniforms) avant de dessiner;
  le Renderer garde le handle du frame_buffer. Le chemin bas-niveau render()
  conserve les valeurs par défaut (identité).
- App::render_scene calcule l'aspect depuis window.inner_size() (le Renderer
  reste indépendant de la fenêtre).

Docs synchronisées: DRAFT (4.3 coche), README (statut 3D-infra + quick ref),
PLAN (caméras), ROADMAP (1.1/1.3/1.5/2.3).

Validation: check workspace+examples 0 warning, test (Pod + wgsl) OK, doc 0
warning, fmt propre. Le rendu 3D visible attend Étape 5 (brancher standard).
2026-09-16 17:25:50 +02:00

97 lines
3.7 KiB
Rust

//! # 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)
}
}