diff --git a/kubi/src/client_physics.rs b/kubi/src/client_physics.rs index 7bb2aad..f23ba00 100644 --- a/kubi/src/client_physics.rs +++ b/kubi/src/client_physics.rs @@ -25,12 +25,14 @@ impl Default for GlobalClPhysicsConfig { //XXX: maybe a capsule? (or configurable hull?) #[derive(Component)] pub struct ClPhysicsActor { + pub disable: bool, pub offset: Vec3, pub forces: Vec3, pub velocity: Vec3, pub terminal_velocity: f32, //TODO: this should be configurable per block pub friction_agains_ground: f32, + pub gravity_scale: f32, flag_ground: bool, flag_collision: bool, } @@ -49,11 +51,13 @@ impl Default for ClPhysicsActor { fn default() -> Self { Self { //HACK: for player + disable: false, offset: vec3(0., 1.5, 0.), forces: Vec3::ZERO, velocity: Vec3::ZERO, terminal_velocity: 40., friction_agains_ground: 0.5, + gravity_scale: 1., flag_ground: false, flag_collision: false, } @@ -93,6 +97,11 @@ pub fn update_client_physics_late( dt: UniqueView, ) { for (mut actor, mut transform) in (&mut actors, &mut transforms).iter() { + if actor.disable { + actor.forces = Vec3::ZERO; + continue; + } + //apply forces let actor_forces = actor.forces; actor.velocity += (actor_forces + conf.gravity) * dt.0.as_secs_f32(); @@ -137,7 +146,7 @@ pub fn update_client_physics_late( //Apply velocity actor_position += actor.velocity * dt.0.as_secs_f32(); actor_position += actor.offset; - transform.0 = Mat4::from_scale_rotation_translation(scale, rotation, actor_position); + transform.0 = Mat4::from_scale_rotation_translation(scale, rotation.normalize(), actor_position); } // for (_, mut transform) in (&controllers, &mut transforms).iter() { // let (scale, rotation, mut translation) = transform.0.to_scale_rotation_translation(); diff --git a/kubi/src/input.rs b/kubi/src/input.rs index 91f445a..c24081e 100644 --- a/kubi/src/input.rs +++ b/kubi/src/input.rs @@ -187,7 +187,7 @@ fn update_input_state ( inputs.look += raw_inputs.mouse_delta.as_vec2(); inputs.action_a |= raw_inputs.button_state[0]; inputs.action_b |= raw_inputs.button_state[1]; - inputs.jump |= raw_inputs.button_state[2]; + inputs.jump |= raw_inputs.keyboard_state.contains(KeyCode::Space as u32); } fn update_input_state_gamepad ( diff --git a/kubi/src/lib.rs b/kubi/src/lib.rs index 9fe125b..9fc7b42 100644 --- a/kubi/src/lib.rs +++ b/kubi/src/lib.rs @@ -57,7 +57,7 @@ use events::{ player_actions::generate_move_events, }; use input::{init_input, process_inputs}; -use player_controller::update_player_controllers; +use player_controller::{debug_switch_ctl_type, update_player_controllers}; use rendering::{ Renderer, RenderTarget, @@ -133,6 +133,7 @@ fn update() -> Workload { update_loaded_world_around_player, ).into_sequential_workload().run_if(is_ingame_or_loading), ( + debug_switch_ctl_type, update_player_controllers, update_client_physics_late, generate_move_events, diff --git a/kubi/src/player_controller.rs b/kubi/src/player_controller.rs index 402e4ce..ba2efa9 100644 --- a/kubi/src/player_controller.rs +++ b/kubi/src/player_controller.rs @@ -1,7 +1,8 @@ -use glam::{Vec3, Mat4, Quat, EulerRot, Vec2}; -use shipyard::{Component, View, ViewMut, IntoIter, UniqueView, Workload, IntoWorkload, track}; +use glam::{EulerRot, Mat4, Quat, Vec2, Vec2Swizzles, Vec3, Vec3Swizzles}; +use shipyard::{track, Component, Get, IntoIter, IntoWithId, IntoWorkload, Unique, UniqueView, View, ViewMut, Workload}; +use winit::keyboard::KeyCode; use std::f32::consts::PI; -use crate::{transform::Transform, input::Inputs, settings::GameSettings, delta_time::DeltaTime}; +use crate::{client_physics::ClPhysicsActor, delta_time::DeltaTime, input::{Inputs, RawKbmInputState}, settings::GameSettings, transform::Transform}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum PlayerControllerType { @@ -18,7 +19,7 @@ pub struct PlayerController { impl PlayerController { pub const DEFAULT_FLY_CAM: Self = Self { control_type: PlayerControllerType::FlyCam, - speed: 30., + speed: 50., }; pub const DEFAULT_FPS_CTL: Self = Self { @@ -59,16 +60,51 @@ fn update_look( fn update_movement( controllers: View, mut transforms: ViewMut, + mut actors: ViewMut, inputs: UniqueView, dt: UniqueView, ) { - if inputs.movement == Vec2::ZERO { return } - let movement = inputs.movement * dt.0.as_secs_f32(); - for (ctl, mut transform) in (&controllers, &mut transforms).iter() { + if (inputs.movement == Vec2::ZERO) && !inputs.jump { return } + let movement = inputs.movement.extend(inputs.jump as u32 as f32).xzy(); + for (id, (ctl, mut transform)) in (&controllers, &mut transforms).iter().with_id() { let (scale, rotation, mut translation) = transform.0.to_scale_rotation_translation(); let rotation_norm = rotation.normalize(); - translation += (rotation_norm * Vec3::NEG_Z).normalize() * movement.y * ctl.speed; - translation += (rotation_norm * Vec3::X).normalize() * movement.x * ctl.speed; - transform.0 = Mat4::from_scale_rotation_translation(scale, rotation_norm, translation); + match ctl.control_type { + PlayerControllerType::FlyCam => { + translation += (rotation_norm * Vec3::NEG_Z).normalize() * movement.z * ctl.speed * dt.0.as_secs_f32(); + translation += (rotation_norm * Vec3::X).normalize() * movement.x * ctl.speed * dt.0.as_secs_f32(); + translation += Vec3::Y * movement.y * ctl.speed * dt.0.as_secs_f32(); + transform.0 = Mat4::from_scale_rotation_translation(scale, rotation_norm, translation); + }, + PlayerControllerType::FpsCtl => { + let actor = (&mut actors).get(id).unwrap(); + + let euler = rotation_norm.to_euler(EulerRot::YZX); + let right = Vec2::from_angle(-euler.0).extend(0.).xzy(); + let forward = Vec2::from_angle(-(euler.0 + PI/2.)).extend(0.).xzy(); + + translation += forward * movement.z * ctl.speed * dt.0.as_secs_f32(); + translation += right * movement.x * ctl.speed * dt.0.as_secs_f32(); + translation += Vec3::Y * movement.y * ctl.speed * dt.0.as_secs_f32(); + + transform.0 = Mat4::from_scale_rotation_translation(scale, rotation_norm, translation); + } + } + } +} + +pub fn debug_switch_ctl_type( + mut controllers: ViewMut, + mut actors: ViewMut, + kbm_state: UniqueView, +) { + for (mut controller, mut actor) in (&mut controllers, &mut actors).iter() { + if kbm_state.keyboard_state.contains(KeyCode::F4 as u32) { + *controller = PlayerController::DEFAULT_FPS_CTL; + actor.disable = false; + } else if kbm_state.keyboard_state.contains(KeyCode::F5 as u32) { + *controller = PlayerController::DEFAULT_FLY_CAM; + actor.disable = true; + } } }