Skip to main content

arcane_engine/renderer/
camera.rs

1/// 2D camera with position, zoom, and viewport.
2pub struct Camera2D {
3    pub x: f32,
4    pub y: f32,
5    pub zoom: f32,
6    pub viewport_size: [f32; 2],
7}
8
9impl Default for Camera2D {
10    fn default() -> Self {
11        Self {
12            x: 0.0,
13            y: 0.0,
14            zoom: 1.0,
15            viewport_size: [800.0, 600.0],
16        }
17    }
18}
19
20impl Camera2D {
21    /// Compute the view-projection matrix as a column-major 4x4 array.
22    ///
23    /// Maps world coordinates to clip space:
24    /// - Camera position is centered on screen
25    /// - Zoom scales the view (larger zoom = more zoomed in)
26    /// - Y-axis points down (screen coordinates)
27    pub fn view_proj(&self) -> [f32; 16] {
28        let half_w = self.viewport_size[0] / (2.0 * self.zoom);
29        let half_h = self.viewport_size[1] / (2.0 * self.zoom);
30
31        let left = self.x - half_w;
32        let right = self.x + half_w;
33        let top = self.y - half_h;
34        let bottom = self.y + half_h;
35
36        // Orthographic projection (column-major)
37        let sx = 2.0 / (right - left);
38        let sy = 2.0 / (top - bottom); // flipped: top < bottom in screen coords
39        let tx = -(right + left) / (right - left);
40        let ty = -(top + bottom) / (top - bottom);
41
42        [
43            sx, 0.0, 0.0, 0.0,
44            0.0, sy, 0.0, 0.0,
45            0.0, 0.0, 1.0, 0.0,
46            tx, ty, 0.0, 1.0,
47        ]
48    }
49}