mirror of
https://codeberg.org/icewind/vbspview.git
synced 2026-06-03 18:24:09 +02:00
democam
This commit is contained in:
parent
90a5966682
commit
bc82d29c4f
6 changed files with 309 additions and 173 deletions
135
src/camera.rs
135
src/camera.rs
|
|
@ -1,135 +0,0 @@
|
||||||
use three_d::*;
|
|
||||||
|
|
||||||
pub struct FirstPerson {
|
|
||||||
control: CameraControl,
|
|
||||||
speed: f32,
|
|
||||||
keys: [bool; 4],
|
|
||||||
pub debug: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FirstPerson {
|
|
||||||
pub fn new(speed: f32) -> Self {
|
|
||||||
Self {
|
|
||||||
control: CameraControl {
|
|
||||||
left_drag_horizontal: CameraAction::Yaw {
|
|
||||||
speed: std::f32::consts::PI / 1800.0,
|
|
||||||
},
|
|
||||||
left_drag_vertical: CameraAction::Pitch {
|
|
||||||
speed: std::f32::consts::PI / 1800.0,
|
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
speed,
|
|
||||||
keys: [false; 4],
|
|
||||||
debug: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle_events(
|
|
||||||
&mut self,
|
|
||||||
camera: &mut Camera,
|
|
||||||
events: &mut [Event],
|
|
||||||
) -> ThreeDResult<bool> {
|
|
||||||
let change = self.control.handle_events(camera, events)?;
|
|
||||||
for event in events.iter_mut() {
|
|
||||||
match event {
|
|
||||||
Event::Text(text) => {
|
|
||||||
if text == "`" {
|
|
||||||
self.debug = !self.debug;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Event::KeyPress { kind, .. } => {
|
|
||||||
self.key_press(kind);
|
|
||||||
}
|
|
||||||
Event::KeyRelease { kind, .. } => {
|
|
||||||
self.key_release(kind);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.keys[0] {
|
|
||||||
self.handle_action(camera, CameraAction::Forward { speed: self.speed }, 1.0)?;
|
|
||||||
}
|
|
||||||
if self.keys[1] {
|
|
||||||
self.handle_action(camera, CameraAction::Forward { speed: self.speed }, -1.0)?;
|
|
||||||
}
|
|
||||||
if self.keys[2] {
|
|
||||||
self.handle_action(camera, CameraAction::Left { speed: self.speed }, 1.0)?;
|
|
||||||
}
|
|
||||||
if self.keys[3] {
|
|
||||||
self.handle_action(camera, CameraAction::Left { speed: self.speed }, -1.0)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(self.keys.iter().fold(change, |change, key| change && *key))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn key_press(&mut self, key: &Key) {
|
|
||||||
match key {
|
|
||||||
Key::W => self.keys[0] = true,
|
|
||||||
Key::S => self.keys[1] = true,
|
|
||||||
Key::A => self.keys[2] = true,
|
|
||||||
Key::D => self.keys[3] = true,
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn key_release(&mut self, key: &Key) {
|
|
||||||
match key {
|
|
||||||
Key::W => self.keys[0] = false,
|
|
||||||
Key::S => self.keys[1] = false,
|
|
||||||
Key::A => self.keys[2] = false,
|
|
||||||
Key::D => self.keys[3] = false,
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_action(
|
|
||||||
&mut self,
|
|
||||||
camera: &mut Camera,
|
|
||||||
control_type: CameraAction,
|
|
||||||
x: f64,
|
|
||||||
) -> ThreeDResult<bool> {
|
|
||||||
match control_type {
|
|
||||||
CameraAction::Pitch { speed } => {
|
|
||||||
camera.pitch(radians(speed * x as f32))?;
|
|
||||||
}
|
|
||||||
CameraAction::OrbitUp { speed, target } => {
|
|
||||||
camera.rotate_around_with_fixed_up(&target, 0.0, speed * x as f32)?;
|
|
||||||
}
|
|
||||||
CameraAction::Yaw { speed } => {
|
|
||||||
camera.yaw(radians(speed * x as f32))?;
|
|
||||||
}
|
|
||||||
CameraAction::OrbitLeft { speed, target } => {
|
|
||||||
camera.rotate_around_with_fixed_up(&target, speed * x as f32, 0.0)?;
|
|
||||||
}
|
|
||||||
CameraAction::Roll { speed } => {
|
|
||||||
camera.roll(radians(speed * x as f32))?;
|
|
||||||
}
|
|
||||||
CameraAction::Left { speed } => {
|
|
||||||
let change = -camera.right_direction() * x as f32 * speed;
|
|
||||||
camera.translate(&change)?;
|
|
||||||
}
|
|
||||||
CameraAction::Up { speed } => {
|
|
||||||
let right = camera.right_direction();
|
|
||||||
let up = right.cross(camera.view_direction());
|
|
||||||
let change = up * x as f32 * speed;
|
|
||||||
camera.translate(&change)?;
|
|
||||||
}
|
|
||||||
CameraAction::Forward { speed } => {
|
|
||||||
let change = camera.view_direction() * speed * x as f32;
|
|
||||||
camera.translate(&change)?;
|
|
||||||
}
|
|
||||||
CameraAction::Zoom {
|
|
||||||
target,
|
|
||||||
speed,
|
|
||||||
min,
|
|
||||||
max,
|
|
||||||
} => {
|
|
||||||
camera.zoom_towards(&target, speed * x as f32, min, max)?;
|
|
||||||
}
|
|
||||||
CameraAction::None => {}
|
|
||||||
}
|
|
||||||
Ok(control_type != CameraAction::None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
264
src/control.rs
Normal file
264
src/control.rs
Normal file
|
|
@ -0,0 +1,264 @@
|
||||||
|
use crate::DemoInfo;
|
||||||
|
use three_d::*;
|
||||||
|
use tracing::{debug, info};
|
||||||
|
|
||||||
|
pub trait Control {
|
||||||
|
fn handle(
|
||||||
|
&mut self,
|
||||||
|
camera: &mut Camera,
|
||||||
|
events: &mut [Event],
|
||||||
|
elapsed_time: f64,
|
||||||
|
accumulated_time: f64,
|
||||||
|
) -> ThreeDResult<bool>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FirstPerson {
|
||||||
|
control: CameraControl,
|
||||||
|
speed: f32,
|
||||||
|
keys: [bool; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Control for FirstPerson {
|
||||||
|
fn handle(
|
||||||
|
&mut self,
|
||||||
|
camera: &mut Camera,
|
||||||
|
events: &mut [Event],
|
||||||
|
_elapsed_time: f64,
|
||||||
|
_accumulated_time: f64,
|
||||||
|
) -> ThreeDResult<bool> {
|
||||||
|
let change = self.control.handle_events(camera, events)?;
|
||||||
|
for event in events.iter_mut() {
|
||||||
|
match event {
|
||||||
|
Event::KeyPress { kind, .. } => {
|
||||||
|
self.key_press(kind);
|
||||||
|
}
|
||||||
|
Event::KeyRelease { kind, .. } => {
|
||||||
|
self.key_release(kind);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.keys[0] {
|
||||||
|
apply_camera_action(camera, CameraAction::Forward { speed: self.speed }, 1.0)?;
|
||||||
|
}
|
||||||
|
if self.keys[1] {
|
||||||
|
apply_camera_action(camera, CameraAction::Forward { speed: self.speed }, -1.0)?;
|
||||||
|
}
|
||||||
|
if self.keys[2] {
|
||||||
|
apply_camera_action(camera, CameraAction::Left { speed: self.speed }, 1.0)?;
|
||||||
|
}
|
||||||
|
if self.keys[3] {
|
||||||
|
apply_camera_action(camera, CameraAction::Left { speed: self.speed }, -1.0)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(self.keys.iter().fold(change, |change, key| change && *key))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FirstPerson {
|
||||||
|
pub fn new(speed: f32) -> Self {
|
||||||
|
Self {
|
||||||
|
control: CameraControl {
|
||||||
|
left_drag_horizontal: CameraAction::Yaw {
|
||||||
|
speed: std::f32::consts::PI / 1800.0,
|
||||||
|
},
|
||||||
|
left_drag_vertical: CameraAction::Pitch {
|
||||||
|
speed: std::f32::consts::PI / 1800.0,
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
speed,
|
||||||
|
keys: [false; 4],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn key_press(&mut self, key: &Key) {
|
||||||
|
match key {
|
||||||
|
Key::W => self.keys[0] = true,
|
||||||
|
Key::S => self.keys[1] = true,
|
||||||
|
Key::A => self.keys[2] = true,
|
||||||
|
Key::D => self.keys[3] = true,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn key_release(&mut self, key: &Key) {
|
||||||
|
match key {
|
||||||
|
Key::W => self.keys[0] = false,
|
||||||
|
Key::S => self.keys[1] = false,
|
||||||
|
Key::A => self.keys[2] = false,
|
||||||
|
Key::D => self.keys[3] = false,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DebugToggle {
|
||||||
|
pub enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Control for DebugToggle {
|
||||||
|
fn handle(
|
||||||
|
&mut self,
|
||||||
|
_camera: &mut Camera,
|
||||||
|
events: &mut [Event],
|
||||||
|
_elapsed_time: f64,
|
||||||
|
_accumulated_time: f64,
|
||||||
|
) -> ThreeDResult<bool> {
|
||||||
|
for event in events.iter_mut() {
|
||||||
|
match event {
|
||||||
|
Event::Text(text) => {
|
||||||
|
if text == "`" {
|
||||||
|
self.enabled = !self.enabled;
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DebugToggle {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
DebugToggle { enabled: true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DemoCamera {
|
||||||
|
demo: DemoInfo,
|
||||||
|
playing: bool,
|
||||||
|
start_tick: f64,
|
||||||
|
playback_start_time: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Control for DemoCamera {
|
||||||
|
fn handle(
|
||||||
|
&mut self,
|
||||||
|
_camera: &mut Camera,
|
||||||
|
events: &mut [Event],
|
||||||
|
_elapsed_time: f64,
|
||||||
|
accumulated_time: f64,
|
||||||
|
) -> ThreeDResult<bool> {
|
||||||
|
let mut change = false;
|
||||||
|
for event in events.iter_mut() {
|
||||||
|
match event {
|
||||||
|
Event::Text(text) => {
|
||||||
|
if text == "p" {
|
||||||
|
change = true;
|
||||||
|
self.playing = !self.playing;
|
||||||
|
dbg!(self.playing);
|
||||||
|
if self.playing {
|
||||||
|
self.playback_start_time = accumulated_time;
|
||||||
|
} else {
|
||||||
|
self.start_tick = self.tick(accumulated_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.playing {
|
||||||
|
let tick = self.tick(accumulated_time);
|
||||||
|
if self.demo.positions.len() as f64 <= tick {
|
||||||
|
self.playing = false;
|
||||||
|
self.start_tick = self.tick(accumulated_time);
|
||||||
|
change = true;
|
||||||
|
info!(
|
||||||
|
tick = tick,
|
||||||
|
length = self.demo.positions.len(),
|
||||||
|
"end of demo"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
debug!(
|
||||||
|
tick = tick,
|
||||||
|
start_tick = self.start_tick,
|
||||||
|
play_time = accumulated_time - self.playback_start_time,
|
||||||
|
"playing tick"
|
||||||
|
);
|
||||||
|
// todo: interpolate
|
||||||
|
let (position, yaw, pitch) = self.demo.positions[tick as usize];
|
||||||
|
self.apply_view(_camera, position, yaw, pitch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(self.playing | change)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DemoCamera {
|
||||||
|
pub fn new(demo: DemoInfo) -> Self {
|
||||||
|
DemoCamera {
|
||||||
|
demo,
|
||||||
|
playing: false,
|
||||||
|
start_tick: 0.0,
|
||||||
|
playback_start_time: 0.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tick(&self, time: f64) -> f64 {
|
||||||
|
let playback_time = (time - self.playback_start_time) / 1000.0;
|
||||||
|
self.start_tick + playback_time / self.demo.time_per_tick
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_view(&self, camera: &mut Camera, position: Vec3, yaw: f32, pitch: f32) {
|
||||||
|
let forward = vec4(0.0, 0.0, 1.0, 1.0);
|
||||||
|
let angle_transform = Mat4::from_angle_y(degrees(yaw)) * Mat4::from_angle_x(degrees(pitch));
|
||||||
|
let target = position + (angle_transform * forward).truncate();
|
||||||
|
camera
|
||||||
|
.set_view(position, target, vec3(0.0, 1.0, 0.0))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_camera_action(
|
||||||
|
camera: &mut Camera,
|
||||||
|
control_type: CameraAction,
|
||||||
|
x: f64,
|
||||||
|
) -> ThreeDResult<bool> {
|
||||||
|
match control_type {
|
||||||
|
CameraAction::Pitch { speed } => {
|
||||||
|
camera.pitch(radians(speed * x as f32))?;
|
||||||
|
}
|
||||||
|
CameraAction::OrbitUp { speed, target } => {
|
||||||
|
camera.rotate_around_with_fixed_up(&target, 0.0, speed * x as f32)?;
|
||||||
|
}
|
||||||
|
CameraAction::Yaw { speed } => {
|
||||||
|
camera.yaw(radians(speed * x as f32))?;
|
||||||
|
}
|
||||||
|
CameraAction::OrbitLeft { speed, target } => {
|
||||||
|
camera.rotate_around_with_fixed_up(&target, speed * x as f32, 0.0)?;
|
||||||
|
}
|
||||||
|
CameraAction::Roll { speed } => {
|
||||||
|
camera.roll(radians(speed * x as f32))?;
|
||||||
|
}
|
||||||
|
CameraAction::Left { speed } => {
|
||||||
|
let change = -camera.right_direction() * x as f32 * speed;
|
||||||
|
camera.translate(&change)?;
|
||||||
|
}
|
||||||
|
CameraAction::Up { speed } => {
|
||||||
|
let right = camera.right_direction();
|
||||||
|
let up = right.cross(camera.view_direction());
|
||||||
|
let change = up * x as f32 * speed;
|
||||||
|
camera.translate(&change)?;
|
||||||
|
}
|
||||||
|
CameraAction::Forward { speed } => {
|
||||||
|
let change = camera.view_direction() * speed * x as f32;
|
||||||
|
camera.translate(&change)?;
|
||||||
|
}
|
||||||
|
CameraAction::Zoom {
|
||||||
|
target,
|
||||||
|
speed,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
} => {
|
||||||
|
camera.zoom_towards(&target, speed * x as f32, min, max)?;
|
||||||
|
}
|
||||||
|
CameraAction::None => {}
|
||||||
|
}
|
||||||
|
Ok(control_type != CameraAction::None)
|
||||||
|
}
|
||||||
|
|
@ -11,6 +11,7 @@ pub struct DemoInfo {
|
||||||
pub map: String,
|
pub map: String,
|
||||||
pub positions: Vec<(Vec3, f32, f32)>,
|
pub positions: Vec<(Vec3, f32, f32)>,
|
||||||
pub start_tick: u32,
|
pub start_tick: u32,
|
||||||
|
pub time_per_tick: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DemoInfo {
|
impl DemoInfo {
|
||||||
|
|
@ -69,6 +70,7 @@ impl DemoInfo {
|
||||||
map: header.map,
|
map: header.map,
|
||||||
positions,
|
positions,
|
||||||
start_tick,
|
start_tick,
|
||||||
|
time_per_tick: ticker.parser_state().demo_meta.interval_per_tick as f64,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,15 +64,17 @@ impl Loader {
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
pub fn load(&self, name: &str) -> Result<Vec<u8>, Error> {
|
pub fn load(&self, name: &str) -> Result<Vec<u8>, Error> {
|
||||||
debug!("loading {}", name);
|
debug!("loading {}", name);
|
||||||
let path = self.tf_dir.join(name);
|
if name.ends_with("bsp") {
|
||||||
if path.exists() {
|
let path = self.tf_dir.join(name);
|
||||||
debug!("found in tf2 dir");
|
if path.exists() {
|
||||||
return Ok(fs::read(path)?);
|
debug!("found in tf2 dir");
|
||||||
}
|
return Ok(fs::read(path)?);
|
||||||
let path = self.download.join(name);
|
}
|
||||||
if path.exists() {
|
let path = self.download.join(name);
|
||||||
debug!("found in download dir");
|
if path.exists() {
|
||||||
return Ok(fs::read(path)?);
|
debug!("found in download dir");
|
||||||
|
return Ok(fs::read(path)?);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let Some(pack) = &self.pack {
|
if let Some(pack) = &self.pack {
|
||||||
if let Some(data) = pack.get(name)? {
|
if let Some(data) = pack.get(name)? {
|
||||||
|
|
|
||||||
31
src/main.rs
31
src/main.rs
|
|
@ -1,5 +1,5 @@
|
||||||
mod bsp;
|
mod bsp;
|
||||||
mod camera;
|
mod control;
|
||||||
mod demo;
|
mod demo;
|
||||||
mod loader;
|
mod loader;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
|
|
@ -7,10 +7,11 @@ mod ui;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
use crate::bsp::load_map;
|
use crate::bsp::load_map;
|
||||||
|
use crate::control::DemoCamera;
|
||||||
use crate::demo::DemoInfo;
|
use crate::demo::DemoInfo;
|
||||||
use crate::renderer::Renderer;
|
use crate::renderer::Renderer;
|
||||||
use crate::ui::DebugUI;
|
use crate::ui::DebugUI;
|
||||||
use camera::FirstPerson;
|
use control::FirstPerson;
|
||||||
use loader::Loader;
|
use loader::Loader;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use three_d::*;
|
use three_d::*;
|
||||||
|
|
@ -21,8 +22,8 @@ use tracing_tree::HierarchicalLayer;
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[clap(author, version, about, long_about = None)]
|
#[clap(author, version, about, long_about = None)]
|
||||||
struct Args {
|
struct Args {
|
||||||
/// Path of the demo file
|
/// Path of the demo or map file
|
||||||
demo: String,
|
path: String,
|
||||||
/// Name of the player to follow
|
/// Name of the player to follow
|
||||||
player: String,
|
player: String,
|
||||||
}
|
}
|
||||||
|
|
@ -70,16 +71,16 @@ fn main() -> Result<(), Error> {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
let window = Window::new(WindowSettings {
|
let window = Window::new(WindowSettings {
|
||||||
title: args.demo.clone(),
|
title: args.path.clone(),
|
||||||
max_size: Some((1920, 1080)),
|
max_size: Some((1920, 1080)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let demo = DemoInfo::new(args.demo, &args.player)?;
|
let demo = DemoInfo::new(args.path, &args.player)?;
|
||||||
let mut loader = Loader::new()?;
|
let mut loader = Loader::new()?;
|
||||||
let map = loader.load(&format!("maps/{}.bsp", demo.map))?;
|
let map = loader.load(&format!("maps/{}.bsp", demo.map))?;
|
||||||
|
|
||||||
let mut renderer = Renderer::new(&window)?;
|
let mut renderer = Renderer::new(&window, DemoCamera::new(demo))?;
|
||||||
|
|
||||||
let meshes = load_map(&map, &mut loader)?;
|
let meshes = load_map(&map, &mut loader)?;
|
||||||
let material = PhysicalMaterial {
|
let material = PhysicalMaterial {
|
||||||
|
|
@ -97,21 +98,7 @@ fn main() -> Result<(), Error> {
|
||||||
.map(|mesh| Model::new_with_material(&renderer.context, &mesh, material.clone()))
|
.map(|mesh| Model::new_with_material(&renderer.context, &mesh, material.clone()))
|
||||||
.collect::<Result<_, _>>()?;
|
.collect::<Result<_, _>>()?;
|
||||||
|
|
||||||
let mut positions = demo.positions.into_iter();
|
window.render_loop(move |frame_input| renderer.render(frame_input).unwrap())?;
|
||||||
let forward = vec4(0.0, 0.0, 1.0, 1.0);
|
|
||||||
|
|
||||||
window.render_loop(move |frame_input| {
|
|
||||||
if let Some((position, angle, pitch)) = positions.next() {
|
|
||||||
let angle_transform =
|
|
||||||
Mat4::from_angle_y(degrees(angle)) * Mat4::from_angle_x(degrees(pitch));
|
|
||||||
let target = position + (angle_transform * forward).truncate();
|
|
||||||
renderer
|
|
||||||
.camera
|
|
||||||
.set_view(position, target, vec3(0.0, 1.0, 0.0))
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
renderer.render(frame_input).unwrap()
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,20 @@
|
||||||
|
use crate::control::{Control, DebugToggle};
|
||||||
use crate::{DebugUI, FirstPerson};
|
use crate::{DebugUI, FirstPerson};
|
||||||
use three_d::*;
|
use three_d::*;
|
||||||
|
|
||||||
pub struct Renderer {
|
pub struct Renderer<C: Control> {
|
||||||
gui: DebugUI,
|
gui: DebugUI,
|
||||||
pub models: Vec<Model<PhysicalMaterial>>,
|
pub models: Vec<Model<PhysicalMaterial>>,
|
||||||
lights: Lights,
|
lights: Lights,
|
||||||
pub context: Context,
|
pub context: Context,
|
||||||
pipeline: ForwardPipeline,
|
pipeline: ForwardPipeline,
|
||||||
control: FirstPerson,
|
control: C,
|
||||||
|
debug_toggle: DebugToggle,
|
||||||
pub camera: Camera,
|
pub camera: Camera,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl<C: Control> Renderer<C> {
|
||||||
pub fn new(window: &Window) -> ThreeDResult<Self> {
|
pub fn new(window: &Window, control: C) -> ThreeDResult<Self> {
|
||||||
let context = window.gl().unwrap();
|
let context = window.gl().unwrap();
|
||||||
let forward_pipeline = ForwardPipeline::new(&context).unwrap();
|
let forward_pipeline = ForwardPipeline::new(&context).unwrap();
|
||||||
let camera = Camera::new_perspective(
|
let camera = Camera::new_perspective(
|
||||||
|
|
@ -38,7 +40,7 @@ impl Renderer {
|
||||||
],
|
],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let control = FirstPerson::new(0.1);
|
// let control = FirstPerson::new(0.1);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
models: Vec::new(),
|
models: Vec::new(),
|
||||||
|
|
@ -47,6 +49,7 @@ impl Renderer {
|
||||||
lights,
|
lights,
|
||||||
context,
|
context,
|
||||||
control,
|
control,
|
||||||
|
debug_toggle: DebugToggle::new(),
|
||||||
camera,
|
camera,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +89,20 @@ impl Renderer {
|
||||||
};
|
};
|
||||||
self.camera.set_viewport(viewport).unwrap();
|
self.camera.set_viewport(viewport).unwrap();
|
||||||
self.control
|
self.control
|
||||||
.handle_events(&mut self.camera, &mut frame_input.events)
|
.handle(
|
||||||
|
&mut self.camera,
|
||||||
|
&mut frame_input.events,
|
||||||
|
frame_input.elapsed_time,
|
||||||
|
frame_input.accumulated_time,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
self.debug_toggle
|
||||||
|
.handle(
|
||||||
|
&mut self.camera,
|
||||||
|
&mut frame_input.events,
|
||||||
|
frame_input.elapsed_time,
|
||||||
|
frame_input.accumulated_time,
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Light pass
|
// Light pass
|
||||||
|
|
@ -149,7 +165,7 @@ impl Renderer {
|
||||||
.render_pass(&self.camera, &self.models, &self.lights)?
|
.render_pass(&self.camera, &self.models, &self.lights)?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if self.control.debug {
|
if self.debug_toggle.enabled {
|
||||||
self.gui.render()?;
|
self.gui.render()?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue