analog wheel input

This commit is contained in:
2019-07-27 19:26:11 +02:00
parent d53170c5ce
commit 3ec4f59f58
4 changed files with 91 additions and 45 deletions

View File

@@ -2,14 +2,6 @@
name = "QUIT" name = "QUIT"
scan_code = 1 scan_code = 1
[[button]]
name = "FORWARD"
mouse = "WheelUp"
[[button]]
name = "BACKWARD"
mouse = "WheelDown"
[[button]] [[button]]
name = "RELOAD_SHADERS" name = "RELOAD_SHADERS"
scan_code = 19 scan_code = 19
@@ -17,5 +9,8 @@ ctrl = true
[[axis]] [[axis]]
name = "FORWARD_AXIS" name = "FORWARD_AXIS"
positive_button = "FORWARD" mouse_wheel = true
negative_button = "BACKWARD" ctrl = true
[config]
line_height_px = 16

View File

@@ -1 +1 @@
input = true input = false

View File

@@ -18,15 +18,6 @@ pub struct VirtualAxis {
pub axis_inputs: Vec<AxisInput> pub axis_inputs: Vec<AxisInput>
} }
#[derive(Debug)]
pub struct InputState {
pub virtual_buttons: HashMap<String, VirtualButton>,
pub virtual_axes: HashMap<String, VirtualAxis>,
input_events: HashSet<DigitalInputEvent>,
pressed_scan_codes: HashSet<ScanCode>,
pressed_mouse_buttons: HashSet<MouseButton>,
}
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
pub enum DigitalInputEvent { pub enum DigitalInputEvent {
Pressed(DigitalInput), Pressed(DigitalInput),
@@ -35,10 +26,16 @@ pub enum DigitalInputEvent {
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct InputConfig { struct InputConfig {
config: InputConfigConfig,
button: Vec<InputConfigButton>, button: Vec<InputConfigButton>,
axis: Vec<InputConfigAxis>, axis: Vec<InputConfigAxis>,
} }
#[derive(Debug, Serialize, Deserialize)]
struct InputConfigConfig {
line_height_px: f32,
}
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct InputConfigButton { struct InputConfigButton {
name: String, name: String,
@@ -53,17 +50,35 @@ struct InputConfigButton {
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct InputConfigAxis { struct InputConfigAxis {
name: String, name: String,
positive_button: String, positive_button: Option<String>,
negative_button: String, negative_button: Option<String>,
mouse_wheel: Option<bool>,
ctrl: Option<bool>,
shift: Option<bool>,
alt: Option<bool>,
logo: Option<bool>,
}
#[derive(Debug)]
pub struct InputState {
pub virtual_buttons: HashMap<String, VirtualButton>,
pub virtual_axes: HashMap<String, VirtualAxis>,
input_events: HashSet<DigitalInputEvent>,
pressed_scan_codes: HashSet<ScanCode>,
pressed_mouse_buttons: HashSet<MouseButton>,
analog_wheel_state: f32,
config: InputConfigConfig,
} }
impl InputState { impl InputState {
pub fn new(toml_path: &str) -> InputState { pub fn new(toml_path: &str) -> 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() };
let config: InputConfig = toml::from_slice(&fs::read(toml_path).expect("Failed to read input config!")).expect("Failed to parse input config!"); let config: InputConfig = toml::from_slice(&fs::read(toml_path).expect("Failed to read input config!")).expect("Failed to parse input config!");
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(), analog_wheel_state: 0.0,
config: config.config };
config.button.iter().for_each(|bn| { config.button.iter().for_each(|bn| {
let modifiers = ModifiersState { let modifiers = ModifiersState {
shift: bn.shift.is_some(), shift: bn.shift.is_some(),
@@ -95,10 +110,28 @@ impl InputState {
}); });
config.axis.iter().for_each(|a| { config.axis.iter().for_each(|a| {
let positive_button = state.virtual_buttons.get(&a.positive_button).expect(&format!("Button {:?} of axis {:?} not found!", a.positive_button, a.name)).clone(); let axis_input = match a {
let negative_button = state.virtual_buttons.get(&a.negative_button).expect(&format!("Button {:?} of axis {:?} not found!", a.positive_button, a.name)).clone(); InputConfigAxis { positive_button: Some(pos_button_name), negative_button: Some(neg_button_name), .. } => {
let positive_button = state.virtual_buttons.get(pos_button_name)
.expect(&format!("Button {:?} of axis {:?} not found!", a.positive_button, a.name))
.clone();
let negative_button = state.virtual_buttons.get(neg_button_name)
.expect(&format!("Button {:?} of axis {:?} not found!", a.positive_button, a.name))
.clone();
let axis_input = AxisInput::Digital(positive_button, negative_button); AxisInput::Digital(positive_button, negative_button)
},
InputConfigAxis { mouse_wheel: Some(true), .. } => {
let modifiers = ModifiersState {
shift: a.shift.is_some(),
ctrl: a.ctrl.is_some(),
alt: a.alt.is_some(),
logo: a.logo.is_some()
};
AxisInput::Wheel(modifiers)
},
other => panic!("Axis {:?} needs either positive_button and negative_button or mouse_wheel must be set to true!", other.name)
};
if let Some(virtual_axis) = state.virtual_axes.get_mut(&a.name) { if let Some(virtual_axis) = state.virtual_axes.get_mut(&a.name) {
virtual_axis.axis_inputs.push(axis_input); virtual_axis.axis_inputs.push(axis_input);
@@ -162,7 +195,7 @@ impl InputState {
if let Some(axis) = self.virtual_axes.get(axis_code) { if let Some(axis) = self.virtual_axes.get(axis_code) {
axis.axis_inputs.iter().fold(0.0, |fold, item| { axis.axis_inputs.iter().fold(0.0, |fold, item| {
let val = match item { let val = match item {
AxisInput::Analog(_) => 0.0, //TODO AxisInput::Wheel(modifiers) => if self.modifiers_are_pressed(*modifiers) { self.analog_wheel_state } else { 0.0 },
AxisInput::Digital(positive_button, negative_button) => self.virtual_button_to_float(positive_button) - self.virtual_button_to_float(negative_button), AxisInput::Digital(positive_button, negative_button) => self.virtual_button_to_float(positive_button) - self.virtual_button_to_float(negative_button),
}; };
if f32::abs(val) > fold { if f32::abs(val) > fold {
@@ -233,16 +266,33 @@ impl InputState {
} }
pub fn on_mouse_wheel_event(self: &mut Self, delta: &MouseScrollDelta, modifiers: &ModifiersState) { pub fn on_mouse_wheel_event(self: &mut Self, delta: &MouseScrollDelta, modifiers: &ModifiersState) {
let direction = match delta { let vertical_direction = match delta {
MouseScrollDelta::LineDelta(_x, y) => if *y >= 0.0 { WheelInputDirection::Up } else { WheelInputDirection::Down }, MouseScrollDelta::LineDelta(_x, y) => {
MouseScrollDelta::PixelDelta(pixels) => if pixels.y >= 0.0 { WheelInputDirection::Up } else { WheelInputDirection::Down }, if *y > 0.0 { Some(WheelInputDirection::Up) }
else if *y < 0.0 { Some(WheelInputDirection::Down) }
else { None }
},
MouseScrollDelta::PixelDelta(pixels) => {
if pixels.y > 0.0 { Some(WheelInputDirection::Up) }
else if pixels.y < 0.0 { Some(WheelInputDirection::Down) }
else { None }
}
}; };
if let Some(direction) = vertical_direction {
let input = DigitalInput::Wheel(WheelInput { direction, modifiers: modifiers.clone() }); let input = DigitalInput::Wheel(WheelInput { direction, modifiers: modifiers.clone() });
self.input_events.insert(DigitalInputEvent::Pressed(input.clone())); self.input_events.insert(DigitalInputEvent::Pressed(input.clone()));
self.input_events.insert(DigitalInputEvent::Released(input)); self.input_events.insert(DigitalInputEvent::Released(input));
} }
self.analog_wheel_state = match delta {
MouseScrollDelta::LineDelta(_x, y) => *y * self.config.line_height_px,
MouseScrollDelta::PixelDelta(pixels) => pixels.y as f32,
};
}
pub fn frame_end(self: &mut Self) { pub fn frame_end(self: &mut Self) {
self.analog_wheel_state = 0.0;
self.input_events.clear(); self.input_events.clear();
} }
} }
@@ -257,7 +307,7 @@ pub fn mods_to_string(modifiers: &ModifiersState) -> String {
#[derive(Debug)] #[derive(Debug)]
pub enum AxisInput { pub enum AxisInput {
Analog(AnalogInput), Wheel(ModifiersState),
Digital(VirtualButton, VirtualButton), Digital(VirtualButton, VirtualButton),
} }
@@ -265,34 +315,35 @@ pub enum AxisInput {
pub enum DigitalInput { pub enum DigitalInput {
Keyboard(KeyboardInput), Keyboard(KeyboardInput),
Wheel(WheelInput), Wheel(WheelInput),
Mouse(MouseInput) Mouse(MouseInput),
} }
#[derive(Debug, Eq, PartialEq, Hash, Clone)] #[derive(Debug, Eq, PartialEq, Hash, Clone)]
pub struct KeyboardInput { pub struct KeyboardInput {
scan_code: ScanCode, scan_code: ScanCode,
modifiers: ModifiersState modifiers: ModifiersState,
} }
#[derive(Debug, Eq, PartialEq, Hash, Clone)] #[derive(Debug, Eq, PartialEq, Hash, Clone)]
pub struct MouseInput { pub struct MouseInput {
button: MouseButton, button: MouseButton,
modifiers: ModifiersState modifiers: ModifiersState,
} }
#[derive(Debug, Eq, PartialEq, Hash, Clone)] #[derive(Debug, Eq, PartialEq, Hash, Clone)]
pub struct WheelInput { pub struct WheelInput {
direction: WheelInputDirection, direction: WheelInputDirection,
modifiers: ModifiersState modifiers: ModifiersState,
} }
#[derive(Debug, Eq, PartialEq, Hash, Clone)] #[derive(Debug, Eq, PartialEq, Hash, Clone)]
pub enum WheelInputDirection { pub enum WheelInputDirection {
Up, Up,
Down Down,
} }
#[derive(Debug, Eq, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct AnalogInput { pub struct AnalogWheelInput {
value: f32,
modifiers: ModifiersState,
} }

View File

@@ -27,7 +27,7 @@ impl Game for TestGame {
game_data.recreate_pipeline = true; game_data.recreate_pipeline = true;
} }
self.cam_pos.x += self.input.get_axis("FORWARD_AXIS"); self.cam_pos.x += self.input.get_axis("FORWARD_AXIS") * 0.01;
// Move game objects // Move game objects
game_data.push_constants.time = game_data.start_time.elapsed().unwrap().as_millis() as f32 / 1000.0; game_data.push_constants.time = game_data.start_time.elapsed().unwrap().as_millis() as f32 / 1000.0;