Skip to content

Commit

Permalink
More camera settings
Browse files Browse the repository at this point in the history
  • Loading branch information
adrien-ben committed May 5, 2024
1 parent 003768c commit 38f4eba
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 31 deletions.
72 changes: 49 additions & 23 deletions crates/viewer/src/camera.rs
Original file line number Diff line number Diff line change
@@ -1,69 +1,95 @@
use crate::controls::*;
use math::cgmath::{InnerSpace, Matrix3, Matrix4, Point3, Rad, Vector3, Zero};
use math::cgmath::{Deg, InnerSpace, Matrix3, Matrix4, Point3, Rad, Vector3, Zero};
use math::clamp;

const MIN_ORBITAL_CAMERA_DISTANCE: f32 = 0.5;
const TARGET_MOVEMENT_SPEED: f32 = 0.003;
const ROTATION_SPEED_DEG: f32 = 0.4;
pub const DEFAULT_FPS_MOVE_SPEED: f32 = 6.0;

pub const DEFAULT_FOV: f32 = 45.0;
pub const DEFAULT_Z_NEAR: f32 = 0.01;
pub const DEFAULT_Z_FAR: f32 = 100.0;

#[derive(Debug, Clone, Copy)]
pub enum Camera {

pub struct Camera {
mode: Mode,
pub fov: Deg<f32>,
pub z_near: f32,
pub z_far: f32,
}

impl Default for Camera {
fn default() -> Self {
Self {
mode: Default::default(),
fov: Deg(DEFAULT_FOV),
z_near: DEFAULT_Z_NEAR,
z_far: DEFAULT_Z_FAR,
}
}
}

#[derive(Debug, Clone, Copy)]
enum Mode {
Orbital(Orbital),
Fps(Fps),
}

impl Default for Camera {
impl Default for Mode {
fn default() -> Self {
Self::Orbital(Default::default())
}
}

impl Camera {
pub fn update(&mut self, input: &InputState, delta_time_secs: f32) {
match self {
Self::Orbital(c) => c.update(input, delta_time_secs),
Self::Fps(c) => c.update(input, delta_time_secs),
match &mut self.mode {
Mode::Orbital(c) => c.update(input, delta_time_secs),
Mode::Fps(c) => c.update(input, delta_time_secs),
}
}

pub fn position(&self) -> Point3<f32> {
match self {
Self::Orbital(c) => c.position(),
Self::Fps(c) => c.position(),
match self.mode {
Mode::Orbital(c) => c.position(),
Mode::Fps(c) => c.position(),
}
}

pub fn target(&self) -> Point3<f32> {
match self {
Self::Orbital(c) => c.target(),
Self::Fps(c) => c.target(),
match self.mode {
Mode::Orbital(c) => c.target(),
Mode::Fps(c) => c.target(),
}
}

pub fn to_orbital(self) -> Self {
match self {
Self::Orbital(_) => self,
Self::Fps(c) => Self::Orbital(c.into()),
}
let mode = match self.mode {
Mode::Orbital(_) => self.mode,
Mode::Fps(c) => Mode::Orbital(c.into()),
};
Self { mode, ..self }
}

pub fn to_fps(self) -> Self {
match self {
Self::Fps(_) => self,
Self::Orbital(c) => Self::Fps(c.into()),
}
let mode = match self.mode {
Mode::Fps(_) => self.mode,
Mode::Orbital(c) => Mode::Fps(c.into()),
};
Self { mode, ..self }
}

pub fn set_move_speed(&mut self, move_speed: f32) {
if let Self::Fps(c) = self {
if let Mode::Fps(c) = &mut self.mode {
c.move_speed = move_speed;
}
}
}

#[derive(Debug, Clone, Copy)]
pub struct Orbital {
struct Orbital {
theta: f32,
phi: f32,
r: f32,
Expand Down Expand Up @@ -158,7 +184,7 @@ impl Orbital {
}

#[derive(Debug, Clone, Copy)]
pub struct Fps {
struct Fps {
position: Point3<f32>,
direction: Vector3<f32>,
move_speed: f32,
Expand Down
47 changes: 44 additions & 3 deletions crates/viewer/src/gui.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::camera::Camera;
use crate::renderer::{OutputMode, RendererSettings, ToneMapMode, DEFAULT_BLOOM_STRENGTH};
use crate::DEFAULT_FPS_MOVE_SPEED;
use crate::{DEFAULT_FOV, DEFAULT_FPS_MOVE_SPEED, DEFAULT_Z_FAR, DEFAULT_Z_NEAR};
use egui::{ClippedPrimitive, Context, TexturesDelta, Ui, ViewportId, Widget};
use egui_winit::State as EguiWinit;
use math::cgmath::Deg;
use model::{metadata::*, PlaybackState};
use vulkan::winit::event::WindowEvent;
use vulkan::winit::window::Window as WinitWindow;
Expand Down Expand Up @@ -142,6 +143,18 @@ impl Gui {
self.state.camera_mode
}

pub fn camera_fov(&self) -> Deg<f32> {
Deg(self.state.camera_fov)
}

pub fn camera_z_near(&self) -> f32 {
self.state.camera_z_near
}

pub fn camera_z_far(&self) -> f32 {
self.state.camera_z_far
}

pub fn camera_move_speed(&self) -> f32 {
self.state.camera_move_speed
}
Expand Down Expand Up @@ -247,14 +260,37 @@ fn build_camera_details_window(ui: &mut Ui, state: &mut State, camera: Option<Ca
});

if let CameraMode::Fps = state.camera_mode {
ui.add(egui::Slider::new(&mut state.camera_move_speed, 1.0..=10.0));
ui.add(
egui::Slider::new(&mut state.camera_move_speed, 1.0..=10.0)
.text("Move speed"),
);
}

ui.add(egui::Slider::new(&mut state.camera_fov, 30.0..=90.0).text("FOV"));
ui.add(
egui::Slider::new(&mut state.camera_z_near, 0.01..=10.0)
.text("Near plane")
.logarithmic(true)
.max_decimals(2),
);
ui.add(
egui::Slider::new(&mut state.camera_z_far, 10.0..=1000.0)
.text("Far plane")
.logarithmic(true),
);

let p = camera.position();
let t = camera.target();
ui.label(format!("Position: {:.3}, {:.3}, {:.3}", p.x, p.y, p.z));
ui.label(format!("Target: {:.3}, {:.3}, {:.3}", t.x, t.y, t.z));

state.reset_camera = ui.button("Reset").clicked();
if state.reset_camera {
state.camera_fov = DEFAULT_FOV;
state.camera_z_near = DEFAULT_Z_NEAR;
state.camera_z_far = DEFAULT_Z_FAR;
state.camera_move_speed = DEFAULT_FPS_MOVE_SPEED;
}
}
});
}
Expand Down Expand Up @@ -341,6 +377,9 @@ struct State {

camera_mode: CameraMode,
camera_move_speed: f32,
camera_fov: f32,
camera_z_near: f32,
camera_z_far: f32,
reset_camera: bool,

hdr_enabled: Option<bool>,
Expand Down Expand Up @@ -383,7 +422,6 @@ impl State {
ssao_kernel_size_index: self.ssao_kernel_size_index,
ssao_enabled: self.ssao_enabled,
camera_mode: self.camera_mode,
camera_move_speed: self.camera_move_speed,
..Default::default()
}
}
Expand Down Expand Up @@ -413,6 +451,9 @@ impl Default for State {

camera_mode: CameraMode::Orbital,
camera_move_speed: DEFAULT_FPS_MOVE_SPEED,
camera_fov: DEFAULT_FOV,
camera_z_near: DEFAULT_Z_NEAR,
camera_z_far: DEFAULT_Z_FAR,
reset_camera: false,

hdr_enabled: None,
Expand Down
3 changes: 3 additions & 0 deletions crates/viewer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ fn run(config: Config, enable_debug: bool, path: Option<PathBuf>) {
gui::CameraMode::Fps => camera.to_fps(),
};

camera.fov = gui.camera_fov();
camera.z_near = gui.camera_z_near();
camera.z_far = gui.camera_z_far();
camera.set_move_speed(gui.camera_move_speed());

if !gui.is_hovered() {
Expand Down
11 changes: 6 additions & 5 deletions crates/viewer/src/renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use ash::{vk, Device};
use egui::{ClippedPrimitive, TextureId};
use egui_ash_renderer::{DynamicRendering, Options, Renderer as GuiRenderer};
use environment::Environment;
use math::cgmath::{Deg, Matrix4, SquareMatrix, Vector3};
use math::cgmath::{Matrix4, SquareMatrix, Vector3};
use model_crate::Model;
use std::cell::RefCell;
use std::mem::size_of;
Expand Down Expand Up @@ -1030,12 +1030,13 @@ impl Renderer {
Vector3::new(0.0, 1.0, 0.0),
);

const Z_NEAR: f32 = 0.01;
const Z_FAR: f32 = 100.0;
let proj = math::perspective(Deg(45.0), aspect, Z_NEAR, Z_FAR);
let z_near = camera.z_near;
let z_far = camera.z_far;

let proj = math::perspective(camera.fov, aspect, z_near, z_far);
let inverted_proj = proj.invert().unwrap();

let ubo = CameraUBO::new(view, proj, inverted_proj, camera.position(), Z_NEAR, Z_FAR);
let ubo = CameraUBO::new(view, proj, inverted_proj, camera.position(), z_near, z_far);
let buffer = &mut self.camera_uniform_buffers[frame_index];
unsafe {
let data_ptr = buffer.map_memory();
Expand Down

0 comments on commit 38f4eba

Please sign in to comment.