rendering, physics, player and camera WIP
This commit is contained in:
188
src/utility/input.rs
Executable file
188
src/utility/input.rs
Executable file
@@ -0,0 +1,188 @@
|
||||
use glam::Vec2;
|
||||
use sdl3::{event::Event, keyboard::Keycode};
|
||||
|
||||
pub struct InputState
|
||||
{
|
||||
pub w: bool,
|
||||
pub a: bool,
|
||||
pub s: bool,
|
||||
pub d: bool,
|
||||
pub space: bool,
|
||||
pub shift: bool,
|
||||
|
||||
pub space_just_pressed: bool,
|
||||
pub noclip_just_pressed: bool,
|
||||
|
||||
pub mouse_delta: (f32, f32),
|
||||
pub mouse_captured: bool,
|
||||
pub noclip_mode: bool,
|
||||
pub quit_requested: bool,
|
||||
}
|
||||
|
||||
impl InputState
|
||||
{
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
w: false,
|
||||
a: false,
|
||||
s: false,
|
||||
d: false,
|
||||
space: false,
|
||||
shift: false,
|
||||
space_just_pressed: false,
|
||||
noclip_just_pressed: false,
|
||||
mouse_delta: (0.0, 0.0),
|
||||
mouse_captured: true,
|
||||
noclip_mode: false,
|
||||
quit_requested: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_event(&mut self, event: &Event) -> bool
|
||||
{
|
||||
match event
|
||||
{
|
||||
Event::Quit { .. } =>
|
||||
{
|
||||
self.quit_requested = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
Event::KeyDown {
|
||||
keycode: Some(key),
|
||||
repeat,
|
||||
..
|
||||
} =>
|
||||
{
|
||||
if !repeat
|
||||
{
|
||||
self.handle_keydown(*key);
|
||||
|
||||
if *key == Keycode::Escape
|
||||
{
|
||||
self.quit_requested = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if *key == Keycode::I
|
||||
{
|
||||
self.mouse_captured = !self.mouse_captured;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Event::KeyUp {
|
||||
keycode: Some(key), ..
|
||||
} =>
|
||||
{
|
||||
self.handle_keyup(*key);
|
||||
}
|
||||
|
||||
Event::MouseMotion { xrel, yrel, .. } =>
|
||||
{
|
||||
self.handle_mouse_motion(*xrel as f32, *yrel as f32);
|
||||
}
|
||||
|
||||
_ =>
|
||||
{}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
pub fn handle_keydown(&mut self, key: Keycode)
|
||||
{
|
||||
match key
|
||||
{
|
||||
Keycode::W => self.w = true,
|
||||
Keycode::A => self.a = true,
|
||||
Keycode::S => self.s = true,
|
||||
Keycode::D => self.d = true,
|
||||
Keycode::Space =>
|
||||
{
|
||||
if !self.space
|
||||
{
|
||||
self.space_just_pressed = true;
|
||||
}
|
||||
self.space = true;
|
||||
}
|
||||
Keycode::LShift | Keycode::RShift => self.shift = true,
|
||||
Keycode::N => self.noclip_just_pressed = true,
|
||||
_ =>
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_keyup(&mut self, key: Keycode)
|
||||
{
|
||||
match key
|
||||
{
|
||||
Keycode::W => self.w = false,
|
||||
Keycode::A => self.a = false,
|
||||
Keycode::S => self.s = false,
|
||||
Keycode::D => self.d = false,
|
||||
Keycode::Space => self.space = false,
|
||||
Keycode::LShift | Keycode::RShift => self.shift = false,
|
||||
_ =>
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_mouse_motion(&mut self, xrel: f32, yrel: f32)
|
||||
{
|
||||
if self.mouse_captured
|
||||
{
|
||||
self.mouse_delta = (xrel, yrel);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_post_events(&mut self)
|
||||
{
|
||||
if self.noclip_just_pressed
|
||||
{
|
||||
self.noclip_mode = !self.noclip_mode;
|
||||
println!(
|
||||
"Noclip mode: {}",
|
||||
if self.noclip_mode { "ON" } else { "OFF" }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_just_pressed(&mut self)
|
||||
{
|
||||
self.space_just_pressed = false;
|
||||
self.noclip_just_pressed = false;
|
||||
self.mouse_delta = (0.0, 0.0);
|
||||
}
|
||||
|
||||
pub fn get_movement_input(&self) -> Vec2
|
||||
{
|
||||
let mut input = Vec2::ZERO;
|
||||
|
||||
if self.w
|
||||
{
|
||||
input.y += 1.0;
|
||||
}
|
||||
if self.s
|
||||
{
|
||||
input.y -= 1.0;
|
||||
}
|
||||
if self.a
|
||||
{
|
||||
input.x -= 1.0;
|
||||
}
|
||||
if self.d
|
||||
{
|
||||
input.x += 1.0;
|
||||
}
|
||||
|
||||
if input.length_squared() > 1.0
|
||||
{
|
||||
input = input.normalize();
|
||||
}
|
||||
|
||||
input
|
||||
}
|
||||
}
|
||||
3
src/utility/mod.rs
Normal file
3
src/utility/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub(crate) mod input;
|
||||
pub(crate) mod time;
|
||||
pub(crate) mod transform;
|
||||
22
src/utility/time.rs
Normal file
22
src/utility/time.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use std::sync::OnceLock;
|
||||
use std::time::Instant;
|
||||
|
||||
static GAME_START: OnceLock<Instant> = OnceLock::new();
|
||||
|
||||
pub struct Time;
|
||||
|
||||
impl Time
|
||||
{
|
||||
pub fn init()
|
||||
{
|
||||
GAME_START.get_or_init(Instant::now);
|
||||
}
|
||||
|
||||
pub fn get_time_elapsed() -> f32
|
||||
{
|
||||
GAME_START
|
||||
.get()
|
||||
.map(|start| start.elapsed().as_secs_f32())
|
||||
.unwrap_or(0.0)
|
||||
}
|
||||
}
|
||||
143
src/utility/transform.rs
Normal file
143
src/utility/transform.rs
Normal file
@@ -0,0 +1,143 @@
|
||||
use glam::{Mat4, Quat, Vec3};
|
||||
use nalgebra::{self as na, Isometry3};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Transform
|
||||
{
|
||||
pub position: Vec3,
|
||||
pub rotation: Quat,
|
||||
pub scale: Vec3,
|
||||
}
|
||||
|
||||
impl Transform
|
||||
{
|
||||
pub const IDENTITY: Self = Self {
|
||||
position: Vec3::ZERO,
|
||||
rotation: Quat::IDENTITY,
|
||||
scale: Vec3::ONE,
|
||||
};
|
||||
|
||||
pub fn from_position(position: Vec3) -> Self
|
||||
{
|
||||
Self::IDENTITY.translated(position)
|
||||
}
|
||||
|
||||
pub fn to_matrix(&self) -> Mat4
|
||||
{
|
||||
Mat4::from_scale_rotation_translation(self.scale, self.rotation, self.position)
|
||||
}
|
||||
|
||||
pub fn get_matrix(&self) -> Mat4
|
||||
{
|
||||
self.to_matrix()
|
||||
}
|
||||
|
||||
pub fn translated(mut self, new_position: Vec3) -> Self
|
||||
{
|
||||
self.set_position(new_position);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_position(&self) -> Vec3
|
||||
{
|
||||
self.position
|
||||
}
|
||||
|
||||
pub fn set_position(&mut self, position: Vec3)
|
||||
{
|
||||
self.position = position;
|
||||
}
|
||||
|
||||
pub fn set_rotation(&mut self, rotation: Quat)
|
||||
{
|
||||
self.rotation = rotation;
|
||||
}
|
||||
|
||||
pub fn set_scale(&mut self, scale: Vec3)
|
||||
{
|
||||
self.scale = scale;
|
||||
}
|
||||
|
||||
pub fn set_uniform_scale(&mut self, scale: f32)
|
||||
{
|
||||
self.scale = Vec3::splat(scale);
|
||||
}
|
||||
|
||||
pub fn set_matrix(&mut self, matrix: Mat4)
|
||||
{
|
||||
let (scale, rotation, translation) = matrix.to_scale_rotation_translation();
|
||||
self.position = translation;
|
||||
self.rotation = rotation;
|
||||
self.scale = scale;
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Transform
|
||||
{
|
||||
fn default() -> Self
|
||||
{
|
||||
Self::IDENTITY
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Transform> for Mat4
|
||||
{
|
||||
fn from(t: Transform) -> Self
|
||||
{
|
||||
t.to_matrix()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Transform> for Mat4
|
||||
{
|
||||
fn from(t: &Transform) -> Self
|
||||
{
|
||||
t.to_matrix()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Transform> for Isometry3<f32>
|
||||
{
|
||||
fn from(t: Transform) -> Self
|
||||
{
|
||||
let translation = na::Vector3::new(t.position.x, t.position.y, t.position.z);
|
||||
let rotation = na::UnitQuaternion::from_quaternion(na::Quaternion::new(
|
||||
t.rotation.w,
|
||||
t.rotation.x,
|
||||
t.rotation.y,
|
||||
t.rotation.z,
|
||||
));
|
||||
Isometry3::from_parts(translation.into(), rotation)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Transform> for Isometry3<f32>
|
||||
{
|
||||
fn from(t: &Transform) -> Self
|
||||
{
|
||||
(*t).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Isometry3<f32>> for Transform
|
||||
{
|
||||
fn from(iso: Isometry3<f32>) -> Self
|
||||
{
|
||||
let pos = iso.translation.vector;
|
||||
let rot = iso.rotation;
|
||||
|
||||
Self {
|
||||
position: Vec3::new(pos.x, pos.y, pos.z),
|
||||
rotation: Quat::from_xyzw(rot.i, rot.j, rot.k, rot.w),
|
||||
scale: Vec3::ONE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Isometry3<f32>> for Transform
|
||||
{
|
||||
fn from(iso: &Isometry3<f32>) -> Self
|
||||
{
|
||||
(*iso).into()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user