Pass joystick axis information
This commit is contained in:
parent
cf3d4f142a
commit
7d8f24a463
5 changed files with 104 additions and 47 deletions
|
@ -20,7 +20,7 @@ pub enum EngineEvent<'a> {
|
||||||
|
|
||||||
JoystickButtonDown(&'a Joystick),
|
JoystickButtonDown(&'a Joystick),
|
||||||
JoystickButtonUp(&'a Joystick),
|
JoystickButtonUp(&'a Joystick),
|
||||||
JoystickAxis(&'a Joystick),
|
JoystickAxis(&'a Joystick, u8, i16),
|
||||||
JoystickAdded(&'a Joystick),
|
JoystickAdded(&'a Joystick),
|
||||||
JoystickRemoved(&'a Joystick),
|
JoystickRemoved(&'a Joystick),
|
||||||
|
|
||||||
|
@ -91,9 +91,10 @@ impl Engine {
|
||||||
Self::controller_removed(world, consumer, controller)?
|
Self::controller_removed(world, consumer, controller)?
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::JoystickAxis(joystick) => {
|
Event::JoystickAxis(joystick, axis_index, value) => consumer.event(
|
||||||
consumer.event(world, EngineEvent::JoystickAxis(joystick))?
|
world,
|
||||||
}
|
EngineEvent::JoystickAxis(joystick, axis_index, value),
|
||||||
|
)?,
|
||||||
Event::JoystickButtonDown(joystick) => {
|
Event::JoystickButtonDown(joystick) => {
|
||||||
consumer.event(world, EngineEvent::JoystickButtonDown(joystick))?
|
consumer.event(world, EngineEvent::JoystickButtonDown(joystick))?
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,10 @@ pub struct FreeSpaceControl {
|
||||||
rotation: Vector3<Deg<f32>>,
|
rotation: Vector3<Deg<f32>>,
|
||||||
position: Vector3<f32>,
|
position: Vector3<f32>,
|
||||||
|
|
||||||
|
current_translation: Matrix4<f32>,
|
||||||
|
current_rotation: Matrix3<f32>,
|
||||||
|
current_transform: Matrix4<f32>,
|
||||||
|
|
||||||
/// (yaw, pitch, roll)
|
/// (yaw, pitch, roll)
|
||||||
input_rotation: Vector3<f32>,
|
input_rotation: Vector3<f32>,
|
||||||
/// (forward, sideward, upward)
|
/// (forward, sideward, upward)
|
||||||
|
@ -60,6 +64,10 @@ impl FreeSpaceControl {
|
||||||
rotation: vec3(Deg(0.0), Deg(0.0), Deg(0.0)),
|
rotation: vec3(Deg(0.0), Deg(0.0), Deg(0.0)),
|
||||||
position: Vector3::zero(),
|
position: Vector3::zero(),
|
||||||
|
|
||||||
|
current_translation: Matrix4::one(),
|
||||||
|
current_rotation: Matrix3::one(),
|
||||||
|
current_transform: Matrix4::one(),
|
||||||
|
|
||||||
input_rotation: Vector3::zero(),
|
input_rotation: Vector3::zero(),
|
||||||
input_position: Vector3::zero(),
|
input_position: Vector3::zero(),
|
||||||
|
|
||||||
|
@ -125,12 +133,12 @@ impl FreeSpaceControl {
|
||||||
* Matrix3::from_angle_x(self.rotation.z)
|
* Matrix3::from_angle_x(self.rotation.z)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, now: Duration) -> Option<Matrix4<f32>> {
|
pub fn update(&mut self, now: Duration) {
|
||||||
let diff = match self.last_update {
|
let diff = match self.last_update {
|
||||||
Some(last_update) => now - last_update,
|
Some(last_update) => now - last_update,
|
||||||
None => {
|
None => {
|
||||||
self.last_update = Some(now);
|
self.last_update = Some(now);
|
||||||
return None;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -140,7 +148,21 @@ impl FreeSpaceControl {
|
||||||
self.add_rotation(rotation_changes);
|
self.add_rotation(rotation_changes);
|
||||||
self.position += rotated_position_changes;
|
self.position += rotated_position_changes;
|
||||||
|
|
||||||
Some(Matrix4::from_translation(self.position) * Matrix4::from(self.rotation_matrix()))
|
self.current_translation = Matrix4::from_translation(self.position);
|
||||||
|
self.current_rotation = self.rotation_matrix();
|
||||||
|
self.current_transform = self.current_translation * Matrix4::from(self.current_rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn translation(&self) -> Matrix4<f32> {
|
||||||
|
self.current_translation
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rotation(&self) -> Matrix3<f32> {
|
||||||
|
self.current_rotation
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transform(&self) -> Matrix4<f32> {
|
||||||
|
self.current_transform
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
|
|
@ -65,7 +65,7 @@ void main()
|
||||||
|
|
||||||
if (pay_load.distance == -1.0) {
|
if (pay_load.distance == -1.0) {
|
||||||
position = vec3(INFINITY);
|
position = vec3(INFINITY);
|
||||||
} else {
|
} else if (pay_load.color.w > 0.0) {
|
||||||
position = origin.xyz + pay_load.distance * direction.xyz;
|
position = origin.xyz + pay_load.distance * direction.xyz;
|
||||||
imageStore(output_image, ivec2(gl_LaunchIDEXT.xy), vec4(pay_load.color.xyz, 1.0));
|
imageStore(output_image, ivec2(gl_LaunchIDEXT.xy), vec4(pay_load.color.xyz, 1.0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,10 @@ use std::collections::HashMap;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use ecs::*;
|
use ecs::*;
|
||||||
use engine::prelude::*;
|
use engine::prelude::{
|
||||||
|
cgmath::{Vector3, Vector4},
|
||||||
|
*,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
struct PlayerEntity(Entity);
|
struct PlayerEntity(Entity);
|
||||||
|
@ -33,35 +36,35 @@ enum Control {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct ControllerSettings {
|
struct InputSettings {
|
||||||
mappings: HashMap<(String, Input), Control>,
|
mappings: HashMap<(String, Input), Control>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ControllerSettings {
|
impl Default for InputSettings {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
mappings: [
|
mappings: [
|
||||||
(
|
(
|
||||||
("Controller 1".to_string(), Input::Axis(0)),
|
("Joystick 1".to_string(), Input::Axis(0)),
|
||||||
Control::Throttle,
|
Control::Throttle,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
("Controller 1".to_string(), Input::Axis(1)),
|
("Joystick 1".to_string(), Input::Axis(1)),
|
||||||
Control::StrafeHorizontal,
|
Control::StrafeHorizontal,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
("Controller 1".to_string(), Input::Axis(2)),
|
("Joystick 1".to_string(), Input::Axis(2)),
|
||||||
Control::StrafeVertical,
|
Control::StrafeVertical,
|
||||||
),
|
),
|
||||||
(("Controller 1".to_string(), Input::Axis(3)), Control::Pitch),
|
(("Joystick 1".to_string(), Input::Axis(3)), Control::Pitch),
|
||||||
(
|
(
|
||||||
("Controller 1".to_string(), Input::Button(Button::One)),
|
("Joystick 1".to_string(), Input::Button(Button::One)),
|
||||||
Control::PrimaryWeapon,
|
Control::PrimaryWeapon,
|
||||||
),
|
),
|
||||||
(("Controller 2".to_string(), Input::Axis(1)), Control::Yaw),
|
(("Joystick 2".to_string(), Input::Axis(1)), Control::Yaw),
|
||||||
(("Controller 2".to_string(), Input::Axis(0)), Control::Roll),
|
(("Joystick 2".to_string(), Input::Axis(0)), Control::Roll),
|
||||||
(
|
(
|
||||||
("Controller 2".to_string(), Input::Button(Button::One)),
|
("Joystick 2".to_string(), Input::Button(Button::One)),
|
||||||
Control::SecondaryWeapon,
|
Control::SecondaryWeapon,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
@ -71,14 +74,10 @@ impl Default for ControllerSettings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ControllerSettings {
|
impl InputSettings {
|
||||||
pub fn map_axis(
|
pub fn map_axis(&self, device_name: impl ToString, axis: u8) -> Option<Control> {
|
||||||
&self,
|
|
||||||
controller_name: impl ToString,
|
|
||||||
axes: ControllerAxis,
|
|
||||||
) -> Vec<(Control, f32)> {
|
|
||||||
self.mappings
|
self.mappings
|
||||||
.get(&controller_name.to_string())
|
.get(&(device_name.to_string(), Input::Axis(axis)))
|
||||||
.map(|control| *control)
|
.map(|control| *control)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,26 +91,30 @@ impl Game {
|
||||||
|
|
||||||
pub fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> {
|
pub fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> {
|
||||||
let player = world.resources.get::<PlayerEntity>();
|
let player = world.resources.get::<PlayerEntity>();
|
||||||
let fighter_object = world.entity_mut(player.0)?;
|
let (fighter_object, resources) = world.entity_resources(player.0)?;
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
EngineEvent::MouseButtonDown(MouseButton::Left) => {
|
EngineEvent::JoystickAxis(joystick, axis_index, value) => {
|
||||||
let camera_control = world.resources.get_mut::<FreeCameraControl>();
|
let normalized = value as f32 * (i16::MAX as f32).recip();
|
||||||
camera_control.mouse_down();
|
let input_settings = resources.get::<InputSettings>();
|
||||||
}
|
let player_control = fighter_object.get_component_mut::<FreeSpaceControl>()?;
|
||||||
EngineEvent::MouseButtonUp(MouseButton::Left) => {
|
|
||||||
let camera_control = world.resources.get_mut::<FreeCameraControl>();
|
|
||||||
camera_control.mouse_release();
|
|
||||||
}
|
|
||||||
EngineEvent::MouseMotion(x, y) => {
|
|
||||||
let mut resources = world.resources.multi_mut();
|
|
||||||
let scene = resources.get::<Scene>();
|
|
||||||
let camera_control = resources.get::<FreeCameraControl>();
|
|
||||||
|
|
||||||
camera_control.mouse_move(x, y, scene.view_mut())?;
|
if let Some(control) = input_settings.map_axis(joystick.name(), axis_index) {
|
||||||
}
|
match control {
|
||||||
|
Control::Throttle => player_control.set_throttle(normalized),
|
||||||
|
Control::StrafeHorizontal => {
|
||||||
|
player_control.set_left_right_strafe(normalized)
|
||||||
|
}
|
||||||
|
Control::StrafeVertical => player_control.set_up_down_strafe(normalized),
|
||||||
|
Control::Yaw => player_control.set_yaw(normalized),
|
||||||
|
Control::Pitch => player_control.set_pitch(normalized),
|
||||||
|
Control::Roll => player_control.set_roll(normalized),
|
||||||
|
|
||||||
EngineEvent::ControllerAxis(controller, axis) => {}
|
Control::PrimaryWeapon => (),
|
||||||
|
Control::SecondaryWeapon => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
@ -129,6 +132,8 @@ impl Game {
|
||||||
EmptyFilter,
|
EmptyFilter,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
world_builder.add_update("camera_position", 1_000, Self::camera_update, EmptyFilter)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +143,7 @@ impl Game {
|
||||||
|
|
||||||
let player = PlayerEntity(world.add_entity(fighter)?);
|
let player = PlayerEntity(world.add_entity(fighter)?);
|
||||||
world.resources.insert(player);
|
world.resources.insert(player);
|
||||||
|
world.resources.insert(InputSettings::default());
|
||||||
|
|
||||||
world.commit_entity_changes()
|
world.commit_entity_changes()
|
||||||
}
|
}
|
||||||
|
@ -151,10 +157,23 @@ impl Game {
|
||||||
draw: &mut Draw,
|
draw: &mut Draw,
|
||||||
control: &mut FreeSpaceControl,
|
control: &mut FreeSpaceControl,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
if let Some(transform) = control.update(world.now()) {
|
control.update(world.now());
|
||||||
draw.set_transform(transform)?;
|
draw.set_transform(control.transform())
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
fn camera_update(
|
||||||
|
world: &mut World,
|
||||||
|
_entity: Entity,
|
||||||
|
control: &mut FreeSpaceControl,
|
||||||
|
) -> Result<()> {
|
||||||
|
let scene = world.resources.get_mut::<Scene>();
|
||||||
|
let view = scene.view_mut();
|
||||||
|
|
||||||
|
view.camera_mut()
|
||||||
|
.set_center((control.translation() * Vector4::unit_w()).truncate());
|
||||||
|
view.camera_mut()
|
||||||
|
.set_eye_dir(control.rotation() * Vector3::unit_y());
|
||||||
|
|
||||||
|
view.update_buffer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ pub enum Event<'a> {
|
||||||
ControllerRemoved(&'a Controller),
|
ControllerRemoved(&'a Controller),
|
||||||
|
|
||||||
// joystick events
|
// joystick events
|
||||||
JoystickAxis(&'a Joystick),
|
JoystickAxis(&'a Joystick, u8, i16),
|
||||||
JoystickButtonDown(&'a Joystick),
|
JoystickButtonDown(&'a Joystick),
|
||||||
JoystickButtonUp(&'a Joystick),
|
JoystickButtonUp(&'a Joystick),
|
||||||
JoystickAdded(&'a Joystick),
|
JoystickAdded(&'a Joystick),
|
||||||
|
@ -349,6 +349,21 @@ impl EventSystem {
|
||||||
event_callback(Event::JoystickAdded(&joystick))?;
|
event_callback(Event::JoystickAdded(&joystick))?;
|
||||||
self.connected_joysticks.insert(joystick.id(), joystick);
|
self.connected_joysticks.insert(joystick.id(), joystick);
|
||||||
}
|
}
|
||||||
|
SdlEvent::JoyDeviceRemoved { which, .. } => {
|
||||||
|
if let Some(joysticks) = self.connected_joysticks.remove(&which) {
|
||||||
|
event_callback(Event::JoystickRemoved(&joysticks))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SdlEvent::JoyAxisMotion {
|
||||||
|
which,
|
||||||
|
axis_idx,
|
||||||
|
value,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
if let Some(joysticks) = self.connected_joysticks.get(&which) {
|
||||||
|
event_callback(Event::JoystickAxis(&joysticks, axis_idx, value))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
SdlEvent::DropFile { filename, .. } => {
|
SdlEvent::DropFile { filename, .. } => {
|
||||||
event_callback(Event::FileDrop(filename))?;
|
event_callback(Event::FileDrop(filename))?;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue