touch axis

This commit is contained in:
2021-08-06 01:03:19 +02:00
parent 01a4e93f3f
commit 7c473e0c81
5 changed files with 126 additions and 28 deletions

View File

@@ -80,6 +80,10 @@ mouse_axis = "x"
name = "look_horizontal"
controller_axis = "RightStickX"
[[axis]]
name = "look_horizontal"
touch_axis = "horizontal"
[[axis]]
name = "look_vertical"
mouse_axis = "y"
@@ -88,5 +92,9 @@ mouse_axis = "y"
name = "look_vertical"
controller_axis = "RightStickY"
[[axis]]
name = "look_vertical"
touch_axis = "vertical"
[config]
line_height_px = 16

View File

@@ -1,8 +1,8 @@
vulkan_validation_layers = true
mesh_load_info = true
vulkan_validation_layers = false
mesh_load_info = false
[input]
mouse_motion = false
buttons = false
touch = true
touch = false
missing_bindings = true

View File

@@ -27,5 +27,9 @@ name = "move_sideways"
positive_button = "button_right"
negative_button = "button_left"
[[axis]]
name = "touch_drag"
touch_axis = "horizontal"
[config]
line_height_px = 16

View File

@@ -1,4 +1,4 @@
use cgmath::{Deg, InnerSpace, Matrix4, One, Quaternion, Rad, Rotation, Rotation3, SquareMatrix, Vector3, Vector4, vec3, vec4};
use cgmath::{Deg, InnerSpace, Matrix4, One, Quaternion, Rad, Rotation, Rotation3, SquareMatrix, Vector2, Vector3, Vector4, vec3, vec4};
use vulkano::buffer::TypedBufferAccess;
use crate::game::player::PlayerMovementMode::{FirstPerson, Flying};
@@ -52,9 +52,9 @@ impl Camera {
renderer.game_data.line_push_constants.projection = self.proj.into();
}
pub fn viewport_pos_to_ray_direction(&self, viewport_pos: [f64; 2], viewport_dimensions: [u32; 2]) -> Option<Vector3<f32>> {
let normalized_x = 2. * (viewport_pos[0] as f32 / viewport_dimensions[0] as f32) - 1.;
let normalized_y = 2. * (viewport_pos[1] as f32 / viewport_dimensions[1] as f32) - 1.;
pub fn viewport_pos_to_ray_direction(&self, viewport_pos: Vector2<f64>, viewport_dimensions: [u32; 2]) -> Option<Vector3<f32>> {
let normalized_x = 2. * (viewport_pos.x as f32 / viewport_dimensions[0] as f32) - 1.;
let normalized_y = 2. * (viewport_pos.y as f32 / viewport_dimensions[1] as f32) - 1.;
let click_start_screen = vec4(normalized_x, normalized_y, -1.0, 1.0);
let click_end_screen = vec4(normalized_x, normalized_y, 0.0, 1.0);

View File

@@ -5,6 +5,7 @@ use std::fs;
use std::hash::Hash;
use std::iter::FromIterator;
use cgmath::{InnerSpace, Vector2, Zero, vec2};
use gilrs;
use gilrs::{EventType, Gilrs};
use serde_derive::{Deserialize, Serialize};
@@ -16,12 +17,12 @@ use crate::config::LogConfig;
#[derive(Debug, Clone)]
pub struct VirtualButton {
pub digital_inputs: Vec<DigitalInput>,
pub touch_count: Option<u8>
pub touch_count: Option<u8>,
}
#[derive(Debug)]
pub struct VirtualAxis {
pub axis_inputs: Vec<AxisInput>
pub axis_inputs: Vec<AxisInput>,
}
#[derive(Debug, PartialEq, Eq, Hash)]
@@ -62,6 +63,7 @@ struct InputConfigAxis {
negative_button: Option<String>,
mouse_axis: Option<String>,
controller_axis: Option<String>,
touch_axis: Option<String>,
ctrl: Option<bool>,
shift: Option<bool>,
alt: Option<bool>,
@@ -74,11 +76,11 @@ pub struct InputState {
pub virtual_axes: HashMap<String, VirtualAxis>,
pub mouse_delta_x: f64,
pub mouse_delta_y: f64,
pub mouse_position: [f64; 2],
pub mouse_position: Vector2<f64>,
input_events: HashSet<DigitalInputEvent>,
pressed_scan_codes: HashSet<ScanCode>,
pressed_mouse_buttons: HashSet<MouseButton>,
pressed_touch_ids: HashSet<u64>,
pressed_touch_positions: HashMap<u64, Vector2<f64>>,
analog_wheel_state: f32,
config: InputConfigConfig,
log_config: LogConfig,
@@ -111,8 +113,8 @@ impl InputState {
let mut state = InputState { virtual_buttons: HashMap::new(), virtual_axes: HashMap::new(),
input_events: HashSet::new(), pressed_scan_codes: HashSet::new(),
pressed_mouse_buttons: HashSet::new(), pressed_touch_ids: HashSet::new(), touch_inputs: vec![], analog_wheel_state: 0.0,
config: config.config, mouse_delta_x: 0.0, mouse_delta_y: 0.0, mouse_position: [0., 0.], log_config,
pressed_mouse_buttons: HashSet::new(), pressed_touch_positions: HashMap::new(), touch_inputs: vec![], analog_wheel_state: 0.0,
config: config.config, mouse_delta_x: 0.0, mouse_delta_y: 0.0, mouse_position: Vector2::zero(), log_config,
controller_input: Gilrs::new().unwrap() };
// Create virtual buttons from config
@@ -201,7 +203,14 @@ impl InputState {
InputConfigAxis { controller_axis: Some(controller_axis_name), .. } => {
AxisInput::Controller(AnalogControllerInput { axis: string_to_axis(controller_axis_name).expect(&format!("Unknown controller axis: {}", controller_axis_name)) })
},
other => panic!("Axis {:?} needs either positive_button and negative_button or mouse_wheel or controller_axis must be set to true!", other.name)
InputConfigAxis { touch_axis: Some(touch_axis_name), .. } => {
if let Some(axis) = string_to_touch_axis(touch_axis_name) {
AxisInput::Touch(axis)
} else {
panic!("Unknown touch axis {:?}", touch_axis_name);
}
},
other => panic!("Axis {:?} needs either (positive_button and negative_button) or (touch_axis) or (mouse_wheel) or (controller_axis must be set to true)", other.name)
};
if let Some(virtual_axis) = state.virtual_axes.get_mut(&axis.name) {
@@ -260,7 +269,7 @@ impl InputState {
self.mouse_delta_y += *delta_y;
},
Event::WindowEvent { event: WindowEvent::CursorMoved { position, .. }, .. } => {
self.mouse_position = [position.x, position.y];
self.mouse_position = vec2(position.x, position.y);
},
Event::WindowEvent { event: WindowEvent::Touch(touch), .. } => {
if self.log_config.input.touch {
@@ -276,7 +285,7 @@ impl InputState {
match self.virtual_buttons.get(button_code) {
Some(virtual_button) => {
if let Some(count) = virtual_button.touch_count {
if self.pressed_touch_ids.len() == count as usize {
if self.pressed_touch_positions.len() == count as usize {
return true;
}
}
@@ -295,7 +304,7 @@ impl InputState {
match self.virtual_buttons.get(button_code) {
Some(virtual_button) => {
if let Some(count) = virtual_button.touch_count {
if self.pressed_touch_ids.len() == count as usize
if self.pressed_touch_positions.len() == count as usize
&& self.touch_inputs.iter().any(|ti| ti.phase == TouchPhase::Started) {
return true;
}
@@ -322,7 +331,7 @@ impl InputState {
match self.virtual_buttons.get(button_code) {
Some(virtual_button) => {
if let Some(count) = virtual_button.touch_count {
if self.pressed_touch_ids.len() < count as usize
if self.pressed_touch_positions.len() < count as usize
&& self.touch_inputs.iter().any(|ti| ti.phase == TouchPhase::Ended) {
return true;
}
@@ -348,7 +357,7 @@ impl InputState {
pub fn get_axis(self: &Self, axis_code: &str) -> f32 {
if let Some(axis) = self.virtual_axes.get(axis_code) {
axis.axis_inputs.iter().map(|item| {
match item {
match &item {
AxisInput::Wheel(modifiers) => {
if self.modifiers_are_pressed(modifiers) { self.analog_wheel_state } else { 0.0 }
},
@@ -369,7 +378,59 @@ impl InputState {
self.controller_input.gamepads()
.map(|(_id, gamepad)| gamepad.value(controller_input.axis))
.fold(0.0, fold_axis_value)
}
},
&AxisInput::Touch(touch_axis) => {
match touch_axis {
TouchAxis::Horizontal => {
if let Some(old_pos) = self.pressed_touch_positions.values().next() {
if let Some(newest_input) = self.touch_inputs.last() {
(newest_input.touch_location.x - old_pos.x) as f32
} else {
0.0
}
} else {
0.0
}
},
TouchAxis::Vertical => {
if let Some(old_pos) = self.pressed_touch_positions.values().next() {
if let Some(newest_input) = self.touch_inputs.last() {
(newest_input.touch_location.y - old_pos.y) as f32
} else {
0.0
}
} else {
0.0
}
},
TouchAxis::Rotate => {
if self.pressed_touch_positions.len() == 2 {
let mut positions = self.pressed_touch_positions.iter();
let (id_1, pos_1) = positions.next().unwrap();
let (id_2, pos_2) = positions.next().unwrap();
let mut vec_1 = None;
let mut vec_2 = None;
for input in &self.touch_inputs {
if input.id == *id_1 { vec_1 = Some(input.touch_location - pos_1) }
if input.id == *id_2 { vec_2 = Some(input.touch_location - pos_2) }
}
match (vec_1, vec_2) {
(Some(v1), Some(v2)) => {
let movement_length = (v1.magnitude() + v2.magnitude()) / 2.0;
let opposing = f64::abs(-v1.dot(v2));
let rotating = 1.0;
(movement_length * opposing * rotating) as f32
},
(Some(v1), None) => v1.magnitude() as f32,
(None, Some(v2)) => v2.magnitude() as f32,
(None, None) => 0.0
}
} else {
0.0
}
},
}
},
}
}).fold(0.0, fold_axis_value)
} else {
@@ -466,24 +527,27 @@ impl InputState {
}
pub fn on_touch_event(&mut self, event: &Touch) {
self.mouse_position = [event.location.x, event.location.y];
self.mouse_position = vec2(event.location.x, event.location.y);
match event.phase {
winit::event::TouchPhase::Started => {
self.pressed_touch_ids.insert(event.id);
self.touch_inputs.push(TouchInput { id: event.id, touch_location: [event.location.x, event.location.y], phase: event.phase });
self.pressed_touch_positions.insert(event.id, self.mouse_position);
self.touch_inputs.push(TouchInput { id: event.id, touch_location: self.mouse_position, phase: event.phase });
},
winit::event::TouchPhase::Moved => {
self.touch_inputs.push(TouchInput { id: event.id, touch_location: self.mouse_position, phase: event.phase });
},
winit::event::TouchPhase::Moved => {},
winit::event::TouchPhase::Ended => {
self.pressed_touch_ids.remove(&event.id);
self.touch_inputs.push(TouchInput { id: event.id, touch_location: [event.location.x, event.location.y], phase: event.phase });
self.pressed_touch_positions.remove(&event.id);
self.touch_inputs.push(TouchInput { id: event.id, touch_location: self.mouse_position, phase: event.phase });
},
winit::event::TouchPhase::Cancelled => {
self.pressed_touch_ids.remove(&event.id);
self.pressed_touch_positions.remove(&event.id);
},
}
}
pub fn frame_start(self: &mut Self) {
// Read out all controller events
while let Some(event) = self.controller_input.next_event() {
match event.event {
EventType::ButtonPressed(button, _) => {
@@ -511,6 +575,11 @@ impl InputState {
self.mouse_delta_x = 0.0;
self.mouse_delta_y = 0.0;
self.input_events.clear();
// Store final touch positions as base for next frame
for touch_input in &mut self.touch_inputs {
self.pressed_touch_positions.get_mut(&touch_input.id).map(|pos| *pos = touch_input.touch_location);
}
self.touch_inputs.clear();
}
}
@@ -529,6 +598,7 @@ pub enum AxisInput {
MouseMove(MouseMoveDirection, KeyboardModifierState),
Digital(VirtualButton, VirtualButton),
Controller(AnalogControllerInput),
Touch(TouchAxis)
}
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
@@ -565,7 +635,7 @@ pub struct ControllerInput {
#[derive(Debug, Clone)]
pub struct TouchInput {
id: u64,
touch_location: [f64; 2],
touch_location: Vector2<f64>,
phase: TouchPhase
}
@@ -584,6 +654,13 @@ impl Hash for TouchInput {
}
}
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
pub enum TouchAxis {
Horizontal,
Vertical,
Rotate
}
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
pub enum WheelInputDirection {
Up,
@@ -653,4 +730,13 @@ fn string_to_axis(axis_name: &str) -> Option<gilrs::Axis> {
"DPadY" => Some(gilrs::Axis::DPadY),
_ => None,
}
}
fn string_to_touch_axis(touch_axis_name: &str) -> Option<TouchAxis> {
match touch_axis_name {
"horizontal" => Some(TouchAxis::Horizontal),
"vertical" => Some(TouchAxis::Vertical),
"rotate" => Some(TouchAxis::Rotate),
_ => None,
}
}