Skip to content

Commit

Permalink
Camera2d fov modes
Browse files Browse the repository at this point in the history
  • Loading branch information
kuviman committed Jun 21, 2024
1 parent 63dc729 commit b91459e
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 14 deletions.
38 changes: 36 additions & 2 deletions crates/geng-camera/src/camera_2d.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,52 @@
use super::*;

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Camera2dFov {
Vertical(f32),
Horizontal(f32),
MinSide(f32),
MaxSide(f32),
}
impl Camera2dFov {
pub fn value_mut(&mut self) -> &mut f32 {
match self {
Camera2dFov::Vertical(value) => value,
Camera2dFov::Horizontal(value) => value,
Camera2dFov::MinSide(value) => value,
Camera2dFov::MaxSide(value) => value,
}
}
pub fn value(&self) -> f32 {
match *self {
Camera2dFov::Vertical(value) => value,
Camera2dFov::Horizontal(value) => value,
Camera2dFov::MinSide(value) => value,
Camera2dFov::MaxSide(value) => value,
}
}
}

/// 2-dimensional camera.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Camera2d {
pub center: vec2<f32>,
pub rotation: Angle<f32>,
pub fov: f32,
pub fov: Camera2dFov,
}

impl AbstractCamera2d for Camera2d {
fn view_matrix(&self) -> mat3<f32> {
mat3::rotate(-self.rotation) * mat3::translate(-self.center)
}
fn projection_matrix(&self, framebuffer_size: vec2<f32>) -> mat3<f32> {
mat3::scale(vec2(2.0 * framebuffer_size.y / framebuffer_size.x, 2.0) / self.fov)
let aspect = framebuffer_size.aspect();
let (vertical, fov) = match self.fov {
Camera2dFov::Vertical(fov) => (true, fov),
Camera2dFov::Horizontal(fov) => (false, fov),
Camera2dFov::MinSide(fov) => (aspect > 1.0, fov),
Camera2dFov::MaxSide(fov) => (aspect < 1.0, fov),
};
let vertical_fov = if vertical { fov } else { fov / aspect };
mat3::scale(vec2(2.0 / aspect, 2.0) / vertical_fov)
}
}
2 changes: 1 addition & 1 deletion examples/03_moving.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl geng::State for State {
&geng::Camera2d {
center: vec2(0.0, 0.0),
rotation: Angle::ZERO,
fov: 15.0,
fov: Camera2dFov::Vertical(15.0),
},
"Use arrow keys to move around\nPress Space to reset",
vec2::splat(geng::TextAlign::CENTER),
Expand Down
7 changes: 4 additions & 3 deletions examples/04_camera_controls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl State {
camera: geng::Camera2d {
center: vec2(0.0, 0.0),
rotation: Angle::ZERO,
fov: 15.0,
fov: Camera2dFov::Vertical(15.0),
},
framebuffer_size: vec2(1.0, 1.0),
prev_touch_distance: 0.0,
Expand Down Expand Up @@ -63,7 +63,8 @@ impl geng::State for State {
}
// Scrolling to zoom
geng::Event::Wheel { delta } => {
self.camera.fov = (self.camera.fov * 1.01f32.powf(-delta as f32)).clamp(1.0, 30.0);
let fov = self.camera.fov.value_mut();
*fov = (*fov * 1.01f32.powf(-delta as f32)).clamp(1.0, 30.0);
}
// Drag start
geng::Event::MousePress {
Expand Down Expand Up @@ -126,7 +127,7 @@ impl geng::State for State {
} else if self.touches.len() == 2 {
let diff = self.touches[0].position - self.touches[1].position;
let now_dist = diff.len() as f32;
self.camera.fov /= now_dist / self.prev_touch_distance;
*self.camera.fov.value_mut() /= now_dist / self.prev_touch_distance;
self.prev_touch_distance = now_dist;
let now_angle = diff.map(|x| x as f32).arg();
let angle_diff = (now_angle - self.prev_touch_angle).normalized_pi();
Expand Down
2 changes: 1 addition & 1 deletion examples/crabrave/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl geng::State for CrabRave {
let camera = geng::Camera2d {
center: vec2::ZERO,
rotation: Angle::ZERO,
fov: 3.0,
fov: Camera2dFov::MinSide(3.0),
};
let x = (self.t / 10.0).cos();
let body = mat3::translate(
Expand Down
2 changes: 1 addition & 1 deletion examples/custom_font_shader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ impl geng::State for State {
geng::Camera2d {
center: size / 2.0,
rotation: Angle::ZERO,
fov: 3.0,
fov: Camera2dFov::Vertical(3.0),
}
.uniforms(framebuffer.size().map(|x| x as f32)),
),
Expand Down
2 changes: 1 addition & 1 deletion examples/draw/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl State {
camera: geng::Camera2d {
center: vec2::ZERO,
rotation: Angle::ZERO,
fov: 10.0,
fov: Camera2dFov::Vertical(10.0),
},
objects: vec![],
};
Expand Down
2 changes: 1 addition & 1 deletion examples/line_texture/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl geng::State for Example {
&geng::Camera2d {
center: vec2(0.0, 2.5),
rotation: Angle::ZERO,
fov: 10.0,
fov: Camera2dFov::Vertical(10.0),
},
&draw2d::TexturedPolygon::strip(
izip![points, ts]
Expand Down
2 changes: 1 addition & 1 deletion examples/pong/game_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl GameState {
camera: geng::Camera2d {
center: vec2(0.0, 0.0),
rotation: Angle::ZERO,
fov: 400.0,
fov: Camera2dFov::Vertical(400.0),
},
boundary: Aabb2::ZERO.extend_symmetric(vec2(ARENA_SIZE_X, ARENA_SIZE_Y) / 2.0),
ball: Self::new_ball(),
Expand Down
2 changes: 1 addition & 1 deletion examples/text_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl geng::State for State {
&geng::Camera2d {
center: vec2(0.0, 0.0),
rotation: Angle::ZERO,
fov: 15.0,
fov: Camera2dFov::Vertical(15.0),
},
&self.text,
vec2::splat(geng::TextAlign::CENTER),
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

pub mod prelude {
pub use crate::{asset::Hot, draw2d, Geng};
pub use crate::{AbstractCamera2d, AbstractCamera3d, Camera2d};
pub use crate::{AbstractCamera2d, AbstractCamera3d, Camera2d, Camera2dFov};
pub use ::batbox;
pub use ::batbox::prelude::*;
// pub use gilrs::{self, Gilrs};
Expand All @@ -50,7 +50,7 @@ pub use geng_async_state as async_state;
#[cfg(feature = "audio")]
pub use geng_audio::{self as audio, *};
pub use geng_camera::{
self as camera, AbstractCamera2d, AbstractCamera3d, Camera2d, PixelPerfectCamera,
self as camera, AbstractCamera2d, AbstractCamera3d, Camera2d, Camera2dFov, PixelPerfectCamera,
};
pub use geng_draw2d::{self as draw2d, Draw2d};
pub use geng_font::{self as font, Font, TextAlign};
Expand Down

0 comments on commit b91459e

Please sign in to comment.