camera.rs
1 //! Camera and vision related settings. 2 3 use glam::{Vec2, vec2}; 4 5 /// The Camera scaling modes determine how far you can see when the aspect ratio changes. 6 /// 7 /// Each mode calculates how far the camera can see in world space units depending on the provided dimensions multiplied by the zoom value. 8 #[derive(Clone, Copy, Debug, Default)] 9 #[non_exhaustive] 10 pub enum CameraScaling { 11 /// Keeps the view size fixed from -1 to 1 in both axes regardless of provided dimensions. 12 #[default] 13 Stretch, 14 15 /// Preserves the total visible surface area regardless of shape. 16 /// 17 /// This means the narrower the dimensions are, the farther you can see in that direction. 18 /// 19 /// The product of width and height equals 1 here. 20 Linear, 21 22 /// Constrains the visible area to fit within a circle centered at the camera origin. 23 /// 24 /// Just like `Box`, but instead of a rectangular box bound, the extend fits within a circle. 25 /// 26 /// This prevents viewing further in extreme aspect ratios, a problem with `Linear`. 27 Circle, 28 29 /// The largest side of the view is always exactly -1 to 1. 30 /// 31 /// The smaller the dimensions are, the more limited the view in the smaller dimension is. 32 Box, 33 34 /// Makes the view grow with the render size. This is good for UI and pixel perfect rendering. 35 /// 36 /// Here one pixel equates to one unit of world space. Here you should set your zoom of the camera with this mode set. 37 Expand, 38 39 /// The horizontal view area is locked at -1 to 1 and allows the vertical axis to expand or shrink. 40 /// 41 /// This one is useful for platformers where consistent horizontal field of view is important. 42 KeepHorizontal, 43 44 /// The vertical view area is locked at -1 to 1 and allows the horizontal axis to expand or shrink. 45 /// 46 /// This one is great for top down or vertical scrolling games. 47 KeepVertical, 48 49 /// User defined scaling option. 50 Custom(fn(Vec2) -> Vec2), 51 } 52 53 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Default)] 54 pub enum CameraMode { 55 #[default] 56 Orthographic, 57 Perspective { 58 fov_y_rad: f32, 59 }, 60 Frustum, 61 } 62 63 impl CameraScaling { 64 /// Scales the given dimensions using the given scaling algorithm. 65 /// 66 /// Takes a dimension and outputs the maximum field of view in both axis using those dimensions. 67 pub fn scale(&self, dimensions: Vec2) -> Vec2 { 68 match self { 69 // Camera view x1 and y1 max and min. 70 CameraScaling::Stretch => Vec2::ONE, 71 CameraScaling::Linear => vec2( 72 0.5 / (dimensions.y / (dimensions.x + dimensions.y)), 73 0.5 / (dimensions.x / (dimensions.x + dimensions.y)), 74 ), 75 CameraScaling::Circle => { 76 let radius = 1.0 / dimensions.length(); 77 dimensions * radius 78 } 79 CameraScaling::Box => vec2( 80 1.0 / (dimensions.y / dimensions.x.clamp(0.0, dimensions.y)), 81 1.0 / (dimensions.x / dimensions.y.clamp(0.0, dimensions.x)), 82 ), 83 CameraScaling::Expand => dimensions, 84 CameraScaling::KeepHorizontal => vec2(1.0, 1.0 / (dimensions.x / dimensions.y)), 85 CameraScaling::KeepVertical => vec2(1.0 / (dimensions.y / dimensions.x), 1.0), 86 CameraScaling::Custom(f) => f(dimensions), 87 } 88 } 89 }