Implement axises to input actions, use input actions with the free fly camera
This commit is contained in:
parent
6242abb35b
commit
22b582c3f8
|
@ -2,7 +2,7 @@ use std::{ops::Deref, ptr::NonNull};
|
|||
|
||||
use lyra_engine::{
|
||||
game::Game,
|
||||
input::{InputButtons, KeyCode, MouseMotion},
|
||||
input::{InputButtons, KeyCode, MouseMotion, ActionHandler},
|
||||
math::{Quat, Vec3, EulerRot},
|
||||
plugin::Plugin, ecs::{system::{System, IntoSystem}, world::World, Access, Component}, DeltaTime, EventQueue, scene::CameraComponent,
|
||||
};
|
||||
|
@ -21,8 +21,8 @@ impl Default for FreeFlyCamera {
|
|||
Self {
|
||||
speed: 4.0,
|
||||
slow_speed_factor: 0.25,
|
||||
look_speed: 0.09,
|
||||
mouse_sensitivity: 0.4,
|
||||
look_speed: 0.3,
|
||||
mouse_sensitivity: 1.0,
|
||||
look_with_keys: false,
|
||||
}
|
||||
}
|
||||
|
@ -50,15 +50,19 @@ impl System for FreeFlyCameraPlugin {
|
|||
|
||||
let delta_time = **world.get_resource::<DeltaTime>();
|
||||
|
||||
let events = world
|
||||
.try_get_resource::<EventQueue>()
|
||||
.and_then(|q| q.read_events::<MouseMotion>());
|
||||
let handler = world.get_resource::<ActionHandler>();
|
||||
|
||||
let keys = world
|
||||
.try_get_resource::<InputButtons<KeyCode>>()
|
||||
.map(|r| r.deref().clone());
|
||||
/* if let Some(look_x) = handler.get_axis_modifier("look_left_right") {
|
||||
camera_rot.x += look_x;
|
||||
}
|
||||
|
||||
if let Some(keys) = keys.as_ref() {
|
||||
if let Some(look_y) = handler.get_axis_modifier("look_up_down") {
|
||||
camera_rot.y += look_y;
|
||||
} */
|
||||
|
||||
|
||||
|
||||
/* if let Some(keys) = keys.as_ref() {
|
||||
if keys.is_pressed(KeyCode::Left) {
|
||||
camera_rot.y += 1.0;
|
||||
}
|
||||
|
@ -82,7 +86,7 @@ impl System for FreeFlyCameraPlugin {
|
|||
if keys.is_pressed(KeyCode::Q) {
|
||||
camera_rot.z += 1.0;
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
for (mut cam, fly) in world
|
||||
.view_iter::<(&mut CameraComponent, &FreeFlyCamera)>()
|
||||
|
@ -92,22 +96,15 @@ impl System for FreeFlyCameraPlugin {
|
|||
let up = Vec3::Y;
|
||||
|
||||
// handle camera movement
|
||||
if let Some(keys) = keys.as_ref() {
|
||||
/* if let Some(keys) = keys.as_ref() {
|
||||
let mut velocity = Vec3::ZERO;
|
||||
if keys.is_pressed(KeyCode::A) {
|
||||
velocity -= left;
|
||||
|
||||
if let Some(m) = handler.get_pressed_modifier("forward_backward") {
|
||||
velocity += m * forward;
|
||||
}
|
||||
|
||||
if keys.is_pressed(KeyCode::D) {
|
||||
velocity += left;
|
||||
}
|
||||
|
||||
if keys.is_pressed(KeyCode::W) {
|
||||
velocity += forward;
|
||||
}
|
||||
|
||||
if keys.is_pressed(KeyCode::S) {
|
||||
velocity -= forward;
|
||||
if let Some(m) = handler.get_pressed_modifier("left_right") {
|
||||
velocity += m * left;
|
||||
}
|
||||
|
||||
if keys.is_pressed(KeyCode::C) {
|
||||
|
@ -127,15 +124,33 @@ impl System for FreeFlyCameraPlugin {
|
|||
|
||||
cam.transform.translation += velocity.normalize() * temp;
|
||||
}
|
||||
} */
|
||||
|
||||
let mut velocity = Vec3::ZERO;
|
||||
|
||||
let move_y = handler.get_axis_modifier("up_down").unwrap_or(0.0);
|
||||
let move_x = handler.get_axis_modifier("left_right").unwrap_or(0.0);
|
||||
let move_z = handler.get_axis_modifier("forward_backward").unwrap_or(0.0);
|
||||
velocity += move_y * up;
|
||||
velocity += move_x * left;
|
||||
velocity += move_z * forward;
|
||||
|
||||
if velocity != Vec3::ZERO {
|
||||
cam.transform.translation += velocity.normalize() * fly.speed * delta_time; // TODO: speeding up
|
||||
}
|
||||
|
||||
// handle camera rotation
|
||||
if let Some(mut events) = events.clone() {
|
||||
/* if let Some(mut events) = events.clone() {
|
||||
while let Some(motion) = events.pop_front() {
|
||||
camera_rot.x -= motion.delta.y * fly.mouse_sensitivity;
|
||||
camera_rot.y -= motion.delta.x * fly.mouse_sensitivity;
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
let motion_x = handler.get_axis_modifier("look_left_right").unwrap_or(0.0);
|
||||
let motion_y = handler.get_axis_modifier("look_up_down").unwrap_or(0.0);
|
||||
camera_rot.y -= motion_x * fly.mouse_sensitivity;
|
||||
camera_rot.x -= motion_y * fly.mouse_sensitivity;
|
||||
|
||||
if camera_rot != Vec3::ZERO {
|
||||
let look_velocity = camera_rot * fly.look_speed * delta_time;
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
use std::ptr::NonNull;
|
||||
|
||||
use lyra_engine::{math::{self, Vec3}, math::Transform, input::{KeyCode, ActionHandler, Action, ActionKind, LayoutId, ActionMapping, ActionSource, ActionMappingId, InputActionPlugin}, game::Game, render::{window::{CursorGrabMode, WindowOptions}, light::{PointLight, directional::DirectionalLight, SpotLight}}, change_tracker::Ct, ecs::{system::{Criteria, CriteriaSchedule, BatchedSystem, IntoSystem}, world::World, Component}, DeltaTime, scene::{TransformComponent, ModelComponent, CameraComponent}};
|
||||
use lyra_engine::{math::{self, Vec3}, math::Transform, input::{KeyCode, ActionHandler, Action, ActionKind, LayoutId, ActionMapping, ActionSource, ActionMappingId, InputActionPlugin, MouseInput, MouseAxis}, game::Game, render::{window::{CursorGrabMode, WindowOptions}, light::{PointLight, directional::DirectionalLight, SpotLight}}, change_tracker::Ct, ecs::{system::{Criteria, CriteriaSchedule, BatchedSystem, IntoSystem}, world::World, Component}, DeltaTime, scene::{TransformComponent, ModelComponent, CameraComponent}};
|
||||
use lyra_engine::assets::{ResourceManager, Model};
|
||||
|
||||
mod free_fly_camera;
|
||||
use free_fly_camera::{FreeFlyCameraPlugin, FreeFlyCamera};
|
||||
use tracing::debug;
|
||||
|
||||
struct FixedTimestep {
|
||||
max_tps: u32,
|
||||
|
@ -233,38 +232,48 @@ async fn main() {
|
|||
let action_handler_plugin = |game: &mut Game| {
|
||||
let action_handler = ActionHandler::new()
|
||||
.add_layout(LayoutId::from(0))
|
||||
.add_action("forward_backward", Action::new(ActionKind::Button))
|
||||
.add_action("left_right", Action::new(ActionKind::Button))
|
||||
|
||||
.add_action("forward_backward", Action::new(ActionKind::Axis))
|
||||
.add_action("left_right", Action::new(ActionKind::Axis))
|
||||
.add_action("up_down", Action::new(ActionKind::Axis))
|
||||
.add_action("look_left_right", Action::new(ActionKind::Axis))
|
||||
.add_action("look_up_down", Action::new(ActionKind::Axis))
|
||||
.add_action("look_rotate", Action::new(ActionKind::Axis))
|
||||
|
||||
.add_mapping(ActionMapping::new(LayoutId::from(0), ActionMappingId::from(0))
|
||||
.bind("forward_backward", &[
|
||||
ActionSource::Keyboard(KeyCode::W).into_binding_modifier(1.0),
|
||||
ActionSource::Keyboard(KeyCode::S).into_binding_modifier(-1.0)
|
||||
])
|
||||
.bind("left_right", &[
|
||||
ActionSource::Keyboard(KeyCode::A).into_binding_modifier(1.0),
|
||||
ActionSource::Keyboard(KeyCode::D).into_binding_modifier(-1.0)
|
||||
ActionSource::Keyboard(KeyCode::A).into_binding_modifier(-1.0),
|
||||
ActionSource::Keyboard(KeyCode::D).into_binding_modifier(1.0)
|
||||
])
|
||||
.bind("up_down", &[
|
||||
ActionSource::Keyboard(KeyCode::C).into_binding_modifier(1.0),
|
||||
ActionSource::Keyboard(KeyCode::Z).into_binding_modifier(-1.0)
|
||||
])
|
||||
.bind("look_left_right", &[
|
||||
ActionSource::Mouse(MouseInput::Axis(MouseAxis::X)).into_binding(),
|
||||
ActionSource::Keyboard(KeyCode::Left).into_binding_modifier(-1.0),
|
||||
ActionSource::Keyboard(KeyCode::Right).into_binding_modifier(1.0),
|
||||
//ActionSource::Gamepad(GamepadFormat::DualAxis, GamepadInput::Axis(GamepadAxis::RThumbstickX)).into_binding(),
|
||||
])
|
||||
.bind("look_up_down", &[
|
||||
ActionSource::Mouse(MouseInput::Axis(MouseAxis::Y)).into_binding(),
|
||||
ActionSource::Keyboard(KeyCode::Up).into_binding_modifier(-1.0),
|
||||
ActionSource::Keyboard(KeyCode::Down).into_binding_modifier(1.0),
|
||||
//ActionSource::Gamepad(GamepadFormat::DualAxis, GamepadInput::Axis(GamepadAxis::RThumbstickY)).into_binding(),
|
||||
])
|
||||
.bind("look_rotate", &[
|
||||
ActionSource::Keyboard(KeyCode::E).into_binding_modifier(-1.0),
|
||||
ActionSource::Keyboard(KeyCode::Q).into_binding_modifier(1.0),
|
||||
])
|
||||
.finish()
|
||||
);
|
||||
|
||||
#[allow(unused_variables)]
|
||||
let test_system = |world: &mut World| -> anyhow::Result<()> {
|
||||
let handler = world.get_resource::<ActionHandler>();
|
||||
|
||||
if let Some(alpha) = handler.get_pressed_modifier("forward_backward") {
|
||||
debug!("'forward_backward': {alpha}");
|
||||
}
|
||||
|
||||
if let Some(alpha) = handler.get_pressed_modifier("left_right") {
|
||||
debug!("'left_right': {alpha}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
};
|
||||
|
||||
game.world().add_resource(action_handler);
|
||||
game.with_plugin(InputActionPlugin);
|
||||
//game.with_system("test_actions", test_system, &[]);
|
||||
};
|
||||
|
||||
Game::initialize().await
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use std::{collections::HashMap, ops::Deref};
|
||||
|
||||
use glam::Vec2;
|
||||
use lyra_ecs::world::World;
|
||||
|
||||
use crate::{plugin::Plugin, game::GameStages};
|
||||
use crate::{plugin::Plugin, game::GameStages, EventQueue};
|
||||
|
||||
use super::{Button, KeyCode, InputButtons};
|
||||
use super::{Button, KeyCode, InputButtons, MouseMotion};
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
|
@ -55,11 +56,36 @@ pub enum GamepadInput {
|
|||
Axis(GamepadAxis),
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub enum MouseButton {
|
||||
Left,
|
||||
Right,
|
||||
Middle,
|
||||
Other(u16),
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub enum MouseAxis {
|
||||
X,
|
||||
Y,
|
||||
ScrollWheel,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub enum MouseInput {
|
||||
Button(MouseButton),
|
||||
Axis(MouseAxis),
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub enum ActionSource {
|
||||
Keyboard(KeyCode),
|
||||
Gamepad(GamepadFormat, GamepadInput),
|
||||
Mouse(MouseInput)
|
||||
}
|
||||
|
||||
impl ActionSource {
|
||||
|
@ -83,6 +109,7 @@ pub struct Binding {
|
|||
impl Binding {
|
||||
/// Create a binding from a Source. Uses a default value of `1.0` as the modifier.
|
||||
pub fn from_source(source: ActionSource) -> Self {
|
||||
// TODO: Some types of input will have a default modifier, mainly axis'
|
||||
Self {
|
||||
source,
|
||||
modifier: 1.0,
|
||||
|
@ -202,6 +229,8 @@ impl ActionMapping {
|
|||
let action_binds = self.action_binds.entry(action_label.to_string()).or_default();
|
||||
action_binds.append(&mut bindings);
|
||||
|
||||
println!("Creating action label {}", action_label);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -344,37 +373,88 @@ impl ActionHandler {
|
|||
fn actions_system(world: &mut World) -> anyhow::Result<()> {
|
||||
let keys = world.try_get_resource::<InputButtons<KeyCode>>()
|
||||
.map(|r| r.deref().clone());
|
||||
let mouse_events = world
|
||||
.try_get_resource::<EventQueue>()
|
||||
.and_then(|q| q.read_events::<MouseMotion>());
|
||||
//let mouse = world.try_get_resource()
|
||||
|
||||
if let Some(keys) = keys {
|
||||
// clear the states of all axises each frame
|
||||
{
|
||||
let mut handler = world.try_get_resource_mut::<ActionHandler>()
|
||||
.expect("No Input Action handler was created in the world!");
|
||||
|
||||
let layout = handler.layouts.get(&handler.current_layout).expect("No active layout");
|
||||
let mapping = layout.mappings.get(&layout.active_mapping).expect("No active mapping");
|
||||
|
||||
for (action_name, binds) in mapping.action_binds.clone().iter() { // TODO: dont clone
|
||||
for (action_name, _) in mapping.action_binds.clone().iter() {
|
||||
let action = handler.actions.get_mut(action_name).expect("Action name for binding is invalid!");
|
||||
if action.kind == ActionKind::Axis {
|
||||
action.state = ActionState::Axis(0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let motion_avg = if let Some(mut mouse_events) = mouse_events {
|
||||
let count = mouse_events.len();
|
||||
let mut sum = Vec2::ZERO;
|
||||
while let Some(mm) = mouse_events.pop_front() {
|
||||
sum += mm.delta;
|
||||
}
|
||||
Some(sum / count as f32)
|
||||
} else { None };
|
||||
|
||||
let mut handler = world.try_get_resource_mut::<ActionHandler>()
|
||||
.expect("No Input Action handler was created in the world!");
|
||||
|
||||
let layout = handler.layouts.get(&handler.current_layout).expect("No active layout");
|
||||
let mapping = layout.mappings.get(&layout.active_mapping).expect("No active mapping");
|
||||
|
||||
for (action_name, binds) in mapping.action_binds.clone().iter() {
|
||||
let action = handler.actions.get_mut(action_name).expect("Action name for binding is invalid!");
|
||||
let mut new_state = None;
|
||||
|
||||
for bind in binds.iter() {
|
||||
match bind.source {
|
||||
ActionSource::Keyboard(key) => {
|
||||
ActionSource::Keyboard(key) => if let Some(keys) = &keys {
|
||||
// JustPressed needs to be first, since is_pressed includes buttons that
|
||||
// were just pressed.
|
||||
match action.kind {
|
||||
ActionKind::Button => {
|
||||
if keys.was_just_pressed(key) {
|
||||
new_state = Some(ActionState::JustPressed(bind.modifier));
|
||||
} else if keys.is_pressed(key) {
|
||||
new_state = Some(ActionState::Pressed(bind.modifier));
|
||||
}
|
||||
},
|
||||
ActionSource::Gamepad(_, _) => todo!(),
|
||||
ActionKind::Axis => {
|
||||
if keys.is_pressed(key) {
|
||||
new_state = Some(ActionState::Axis(bind.modifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let action = handler.actions.get_mut(action_name).expect("Action name for binding is invalid!");
|
||||
},
|
||||
ActionSource::Gamepad(_, _) => todo!(),
|
||||
ActionSource::Mouse(m) => match m {
|
||||
MouseInput::Button(_) => todo!(),
|
||||
MouseInput::Axis(a) => if let Some(motion_avg) = motion_avg {
|
||||
match a {
|
||||
MouseAxis::X => {
|
||||
new_state = Some(ActionState::Axis(motion_avg.x));
|
||||
},
|
||||
MouseAxis::Y => {
|
||||
new_state = Some(ActionState::Axis(motion_avg.y));
|
||||
},
|
||||
MouseAxis::ScrollWheel => todo!(),
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(new_state) = new_state {
|
||||
action.state = new_state;
|
||||
} else {
|
||||
} else if action.kind == ActionKind::Button {
|
||||
match action.state {
|
||||
ActionState::Idle => {},
|
||||
ActionState::JustReleased => action.state = ActionState::Idle,
|
||||
|
@ -382,7 +462,6 @@ fn actions_system(world: &mut World) -> anyhow::Result<()> {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue