This commit is contained in:
Robin Appelman 2022-02-20 15:03:59 +01:00
commit becad66e92
4 changed files with 122 additions and 14 deletions

2
Cargo.lock generated
View file

@ -2300,8 +2300,6 @@ dependencies = [
[[package]]
name = "vbsp"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c7d0e90c80972e04953605910a6bf5ea463673abd4e05924e38e9f3b47bc0ac"
dependencies = [
"arrayvec 0.7.2",
"binrw",

View file

@ -7,7 +7,7 @@ license = "MIT"
[dependencies]
three-d = "0.10.2"
vbsp = "0.1.0"
vbsp = { version = "0.1.0", path = "../bsp" }
miette = { version = "3.2.0", features = ["fancy"] }
thiserror = "1.0.30"
delaunator = "1.0.1"

105
src/camera.rs Normal file
View file

@ -0,0 +1,105 @@
use three_d::*;
pub struct FirstPerson {
control: CameraControl,
speed: f32,
}
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,
}
}
pub fn handle_events(
&mut self,
camera: &mut Camera,
events: &mut [Event],
) -> ThreeDResult<bool> {
let mut change = self.control.handle_events(camera, events)?;
for event in events.iter_mut() {
change |= match event {
Event::KeyPress { kind, handled, .. } => {
if let Some((action, x)) = self.key_to_action(kind) {
*handled = true;
self.handle_action(camera, action, x)?;
true
} else {
false
}
}
_ => false,
};
}
Ok(change)
}
fn key_to_action(&self, key: &Key) -> Option<(CameraAction, f64)> {
match key {
Key::W => Some((CameraAction::Forward { speed: self.speed }, 1.0)),
Key::S => Some((CameraAction::Forward { speed: self.speed }, -1.0)),
Key::A => Some((CameraAction::Left { speed: self.speed }, 1.0)),
Key::D => Some((CameraAction::Left { speed: self.speed }, -1.0)),
_ => None,
}
}
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)
}
}

View file

@ -1,3 +1,6 @@
mod camera;
use camera::FirstPerson;
use miette::Diagnostic;
use std::env::args;
use std::fs;
@ -64,7 +67,7 @@ fn main() -> Result<(), Error> {
30.0,
)
.unwrap();
let mut control = OrbitControl::new(*camera.target(), 1.0, 100.0);
let mut control = FirstPerson::new(0.05);
let mut gui = three_d::GUI::new(&context).unwrap();
let material = PhysicalMaterial {
@ -85,18 +88,15 @@ fn main() -> Result<(), Error> {
intensity: 0.2,
..Default::default()
}),
directional: vec![DirectionalLight::new(
&context,
1.0,
Color::WHITE,
&vec3(0.0, -1.0, 0.0),
)
.unwrap()],
directional: vec![
DirectionalLight::new(&context, 1.0, Color::WHITE, &vec3(0.0, -1.0, 0.0))?,
DirectionalLight::new(&context, 1.0, Color::WHITE, &vec3(0.0, 1.0, 0.0))?,
],
..Default::default()
};
// main loop
let mut shadows_enabled = true;
let mut shadows_enabled = false;
let mut directional_intensity = lights.directional[0].intensity();
let mut current_pipeline = Pipeline::Forward;
@ -120,9 +120,11 @@ fn main() -> Result<(), Error> {
.text("Directional intensity"),
);
lights.directional[0].set_intensity(directional_intensity);
lights.directional[1].set_intensity(directional_intensity);
if ui.checkbox(&mut shadows_enabled, "Shadows").clicked() {
if !shadows_enabled {
lights.directional[0].clear_shadow_map();
lights.directional[1].clear_shadow_map();
}
}
@ -195,6 +197,9 @@ fn main() -> Result<(), Error> {
lights.directional[0]
.generate_shadow_map(4.0, 1024, 1024, &[&model])
.unwrap();
lights.directional[1]
.generate_shadow_map(4.0, 1024, 1024, &[&model])
.unwrap();
}
// Geometry pass
@ -278,13 +283,13 @@ fn model_to_mesh(model: Handle<vbsp::data::Model>) -> CPUMesh {
.into_iter()
.max_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap()
/ 10.0;
/ 50.0;
let positions: Vec<f32> = model
.faces()
.filter(|face| face.is_visible())
.flat_map(|face| face.triangulate())
.flat_map(|triangle| triangle.into_iter())
.flat_map(|vertex| [vertex.x, vertex.z, vertex.y])
.flat_map(|vertex| [-vertex.x, vertex.z, vertex.y])
.map(|c| c / size)
.collect();