125 lines
4.4 KiB
Rust
125 lines
4.4 KiB
Rust
use std::time::Duration;
|
|
|
|
use nalgebra::Rotation3;
|
|
use ndarray::Array3;
|
|
use winit::{keyboard::KeyCode as Key, window::CursorGrabMode};
|
|
|
|
use crate::common::{component::{chunk, VoxelGrid, VoxelGridBundle}, ServerMessage};
|
|
|
|
use super::{render::voxel::VoxelColor, Client};
|
|
|
|
impl Client<'_> {
|
|
pub fn handle_input(&mut self, dt: &Duration) {
|
|
let dt = dt.as_secs_f32();
|
|
let Client {
|
|
input,
|
|
state,
|
|
window,
|
|
..
|
|
} = self;
|
|
|
|
// cursor lock
|
|
if input.just_pressed(Key::Escape) {
|
|
self.grabbed_cursor = !self.grabbed_cursor;
|
|
if self.grabbed_cursor {
|
|
window.set_cursor_visible(false);
|
|
window
|
|
.set_cursor_grab(CursorGrabMode::Locked)
|
|
.or_else(|_| window.set_cursor_grab(CursorGrabMode::Confined))
|
|
.expect("cursor lock");
|
|
} else {
|
|
window.set_cursor_visible(true);
|
|
window
|
|
.set_cursor_grab(CursorGrabMode::None)
|
|
.expect("cursor unlock");
|
|
};
|
|
return;
|
|
}
|
|
|
|
// camera orientation
|
|
let old_camera = state.camera;
|
|
if self.grabbed_cursor {
|
|
let delta = input.mouse_delta * 0.003 / state.camera.scale;
|
|
if delta.x != 0.0 {
|
|
state.camera.orientation = Rotation3::from_axis_angle(&state.camera.up(), delta.x)
|
|
* state.camera.orientation;
|
|
}
|
|
if delta.y != 0.0 {
|
|
state.camera.orientation =
|
|
Rotation3::from_axis_angle(&state.camera.right(), delta.y)
|
|
* state.camera.orientation;
|
|
}
|
|
}
|
|
let rot_dist = 1.0 * dt;
|
|
if input.pressed(Key::KeyQ) {
|
|
state.camera.orientation =
|
|
Rotation3::from_axis_angle(&state.camera.forward(), rot_dist)
|
|
* state.camera.orientation;
|
|
}
|
|
if input.pressed(Key::KeyE) {
|
|
state.camera.orientation =
|
|
Rotation3::from_axis_angle(&state.camera.forward(), -rot_dist)
|
|
* state.camera.orientation;
|
|
}
|
|
state.camera.orientation.renormalize();
|
|
|
|
// zoom
|
|
if input.scroll_delta != 0.0 {
|
|
if input.pressed(Key::ControlLeft) {
|
|
state.camera_scroll += input.scroll_delta;
|
|
state.camera.scale = (state.camera_scroll * 0.2).exp();
|
|
} else {
|
|
state.speed += input.scroll_delta * 0.2;
|
|
}
|
|
}
|
|
|
|
// camera position
|
|
let move_dist = dt * state.speed.exp() * (chunk::SIDE_LENGTH / 16) as f32;
|
|
if input.pressed(Key::KeyW) {
|
|
state.camera.pos += *state.camera.forward() * move_dist;
|
|
}
|
|
if input.pressed(Key::KeyA) {
|
|
state.camera.pos += *state.camera.left() * move_dist;
|
|
}
|
|
if input.pressed(Key::KeyS) {
|
|
state.camera.pos += *state.camera.backward() * move_dist;
|
|
}
|
|
if input.pressed(Key::KeyD) {
|
|
state.camera.pos += *state.camera.right() * move_dist;
|
|
}
|
|
if input.pressed(Key::Space) {
|
|
state.camera.pos += *state.camera.up() * move_dist;
|
|
}
|
|
if input.pressed(Key::ShiftLeft) {
|
|
state.camera.pos += *state.camera.down() * move_dist;
|
|
}
|
|
if state.camera != old_camera {
|
|
self.render_commands
|
|
.push(super::render::RenderCommand::ViewUpdate(state.camera));
|
|
}
|
|
|
|
// fun
|
|
if input.just_pressed(Key::KeyF) {
|
|
self.server
|
|
.send(ServerMessage::SpawnVoxelGrid(VoxelGridBundle {
|
|
pos: (state.camera.pos + 135.0 * 2.0 * *state.camera.forward()).into(),
|
|
orientation: state.camera.orientation.into(),
|
|
grid: VoxelGrid::new(Array3::from_shape_fn((135, 135, 135), |(x, y, z)| {
|
|
if x == 0 || y == 0 || z == 0 || x == 134 || y == 134 || z == 134 {
|
|
VoxelColor::white()
|
|
} else {
|
|
VoxelColor::none()
|
|
}
|
|
})),
|
|
}));
|
|
}
|
|
|
|
if input.just_pressed(Key::KeyR) {
|
|
self.renderer.update_shader();
|
|
}
|
|
if input.just_pressed(Key::KeyT) {
|
|
self.renderer.reset_shader();
|
|
}
|
|
}
|
|
}
|