camera movement
This commit is contained in:
@@ -8,21 +8,38 @@ scan_code = 19
|
|||||||
ctrl = true
|
ctrl = true
|
||||||
|
|
||||||
[[button]]
|
[[button]]
|
||||||
name = "FORWARD"
|
name = "w"
|
||||||
scan_code = 17
|
scan_code = 17
|
||||||
|
|
||||||
[[button]]
|
[[button]]
|
||||||
name = "BACK"
|
name = "s"
|
||||||
scan_code = 31
|
scan_code = 31
|
||||||
|
|
||||||
[[axis]]
|
[[button]]
|
||||||
name = "FORWARD_AXIS"
|
name = "a"
|
||||||
positive_button = "FORWARD"
|
scan_code = 30
|
||||||
negative_button = "BACK"
|
|
||||||
|
[[button]]
|
||||||
|
name = "d"
|
||||||
|
scan_code = 32
|
||||||
|
|
||||||
[[axis]]
|
[[axis]]
|
||||||
name = "FORWARD_AXIS"
|
name = "move_forward"
|
||||||
mouse_wheel = true
|
positive_button = "w"
|
||||||
|
negative_button = "s"
|
||||||
|
|
||||||
|
[[axis]]
|
||||||
|
name = "move_sideways"
|
||||||
|
positive_button = "d"
|
||||||
|
negative_button = "a"
|
||||||
|
|
||||||
|
[[axis]]
|
||||||
|
name = "look_horizontal"
|
||||||
|
mouse_axis = "x"
|
||||||
|
|
||||||
|
[[axis]]
|
||||||
|
name = "look_vertical"
|
||||||
|
mouse_axis = "y"
|
||||||
|
|
||||||
[config]
|
[config]
|
||||||
line_height_px = 16
|
line_height_px = 16
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
input = false
|
input = true
|
||||||
vulkan_validation_layers = true
|
vulkan_validation_layers = true
|
||||||
62
src/input.rs
62
src/input.rs
@@ -52,7 +52,7 @@ struct InputConfigAxis {
|
|||||||
name: String,
|
name: String,
|
||||||
positive_button: Option<String>,
|
positive_button: Option<String>,
|
||||||
negative_button: Option<String>,
|
negative_button: Option<String>,
|
||||||
mouse_wheel: Option<bool>,
|
mouse_axis: Option<String>,
|
||||||
ctrl: Option<bool>,
|
ctrl: Option<bool>,
|
||||||
shift: Option<bool>,
|
shift: Option<bool>,
|
||||||
alt: Option<bool>,
|
alt: Option<bool>,
|
||||||
@@ -63,6 +63,8 @@ struct InputConfigAxis {
|
|||||||
pub struct InputState {
|
pub struct InputState {
|
||||||
pub virtual_buttons: HashMap<String, VirtualButton>,
|
pub virtual_buttons: HashMap<String, VirtualButton>,
|
||||||
pub virtual_axes: HashMap<String, VirtualAxis>,
|
pub virtual_axes: HashMap<String, VirtualAxis>,
|
||||||
|
pub mouse_delta_x: f64,
|
||||||
|
pub mouse_delta_y: f64,
|
||||||
input_events: HashSet<DigitalInputEvent>,
|
input_events: HashSet<DigitalInputEvent>,
|
||||||
pressed_scan_codes: HashSet<ScanCode>,
|
pressed_scan_codes: HashSet<ScanCode>,
|
||||||
pressed_mouse_buttons: HashSet<MouseButton>,
|
pressed_mouse_buttons: HashSet<MouseButton>,
|
||||||
@@ -77,7 +79,7 @@ impl InputState {
|
|||||||
let mut state = InputState { virtual_buttons: HashMap::new(), virtual_axes: HashMap::new(),
|
let mut state = InputState { virtual_buttons: HashMap::new(), virtual_axes: HashMap::new(),
|
||||||
input_events: HashSet::new(), pressed_scan_codes: HashSet::new(),
|
input_events: HashSet::new(), pressed_scan_codes: HashSet::new(),
|
||||||
pressed_mouse_buttons: HashSet::new(), analog_wheel_state: 0.0,
|
pressed_mouse_buttons: HashSet::new(), analog_wheel_state: 0.0,
|
||||||
config: config.config };
|
config: config.config, mouse_delta_x: 0.0, mouse_delta_y: 0.0 };
|
||||||
|
|
||||||
config.button.iter().for_each(|bn| {
|
config.button.iter().for_each(|bn| {
|
||||||
let modifiers = ModifiersState {
|
let modifiers = ModifiersState {
|
||||||
@@ -109,34 +111,39 @@ impl InputState {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
config.axis.iter().for_each(|a| {
|
config.axis.iter().for_each(|axis| {
|
||||||
let axis_input = match a {
|
let axis_input = match axis {
|
||||||
InputConfigAxis { positive_button: Some(pos_button_name), negative_button: Some(neg_button_name), .. } => {
|
InputConfigAxis { positive_button: Some(pos_button_name), negative_button: Some(neg_button_name), .. } => {
|
||||||
let positive_button = state.virtual_buttons.get(pos_button_name)
|
let positive_button = state.virtual_buttons.get(pos_button_name)
|
||||||
.expect(&format!("Button {:?} of axis {:?} not found!", a.positive_button, a.name))
|
.expect(&format!("Button {:?} of axis {:?} not found!", axis.positive_button, axis.name))
|
||||||
.clone();
|
.clone();
|
||||||
let negative_button = state.virtual_buttons.get(neg_button_name)
|
let negative_button = state.virtual_buttons.get(neg_button_name)
|
||||||
.expect(&format!("Button {:?} of axis {:?} not found!", a.positive_button, a.name))
|
.expect(&format!("Button {:?} of axis {:?} not found!", axis.positive_button, axis.name))
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
AxisInput::Digital(positive_button, negative_button)
|
AxisInput::Digital(positive_button, negative_button)
|
||||||
},
|
},
|
||||||
InputConfigAxis { mouse_wheel: Some(true), .. } => {
|
InputConfigAxis { mouse_axis: Some(axis_name), .. } => {
|
||||||
let modifiers = ModifiersState {
|
let modifiers = ModifiersState {
|
||||||
shift: a.shift.is_some(),
|
shift: axis.shift.is_some(),
|
||||||
ctrl: a.ctrl.is_some(),
|
ctrl: axis.ctrl.is_some(),
|
||||||
alt: a.alt.is_some(),
|
alt: axis.alt.is_some(),
|
||||||
logo: a.logo.is_some()
|
logo: axis.logo.is_some(),
|
||||||
};
|
};
|
||||||
AxisInput::Wheel(modifiers)
|
match axis_name.to_lowercase().as_str() {
|
||||||
|
"wheel" => AxisInput::Wheel(modifiers),
|
||||||
|
"x" => AxisInput::MouseMove(MouseMoveDirection::X, modifiers),
|
||||||
|
"y" => AxisInput::MouseMove(MouseMoveDirection::Y, modifiers),
|
||||||
|
other => panic!("Axis {:?} has unknown mouse axis name {:?}!", axis_name, other),
|
||||||
|
}
|
||||||
},
|
},
|
||||||
other => panic!("Axis {:?} needs either positive_button and negative_button or mouse_wheel must be set to true!", other.name)
|
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(&axis.name) {
|
||||||
virtual_axis.axis_inputs.push(axis_input);
|
virtual_axis.axis_inputs.push(axis_input);
|
||||||
} else {
|
} else {
|
||||||
state.virtual_axes.insert(a.name.clone(), VirtualAxis { axis_inputs: vec![axis_input] });
|
state.virtual_axes.insert(axis.name.clone(), VirtualAxis { axis_inputs: vec![axis_input] });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -195,8 +202,22 @@ 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().map(|item| {
|
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 },
|
AxisInput::Wheel(modifiers) => {
|
||||||
AxisInput::Digital(positive_button, negative_button) => self.virtual_button_to_float(positive_button) - self.virtual_button_to_float(negative_button),
|
if self.modifiers_are_pressed(*modifiers) { self.analog_wheel_state } else { 0.0 }
|
||||||
|
},
|
||||||
|
AxisInput::MouseMove(direction, modifiers) => {
|
||||||
|
if self.modifiers_are_pressed(*modifiers) {
|
||||||
|
match direction {
|
||||||
|
MouseMoveDirection::X => self.mouse_delta_x as f32,
|
||||||
|
MouseMoveDirection::Y => self.mouse_delta_y as f32,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
AxisInput::Digital(positive_button, negative_button) => {
|
||||||
|
self.virtual_button_to_float(positive_button) - self.virtual_button_to_float(negative_button)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}).fold(0.0, |fold, it| if f32::abs(it) > f32::abs(fold) { it } else { fold })
|
}).fold(0.0, |fold, it| if f32::abs(it) > f32::abs(fold) { it } else { fold })
|
||||||
} else {
|
} else {
|
||||||
@@ -288,6 +309,8 @@ impl InputState {
|
|||||||
|
|
||||||
pub fn frame_end(self: &mut Self) {
|
pub fn frame_end(self: &mut Self) {
|
||||||
self.analog_wheel_state = 0.0;
|
self.analog_wheel_state = 0.0;
|
||||||
|
self.mouse_delta_x = 0.0;
|
||||||
|
self.mouse_delta_y = 0.0;
|
||||||
self.input_events.clear();
|
self.input_events.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -303,6 +326,7 @@ pub fn mods_to_string(modifiers: &ModifiersState) -> String {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum AxisInput {
|
pub enum AxisInput {
|
||||||
Wheel(ModifiersState),
|
Wheel(ModifiersState),
|
||||||
|
MouseMove(MouseMoveDirection, ModifiersState),
|
||||||
Digital(VirtualButton, VirtualButton),
|
Digital(VirtualButton, VirtualButton),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,6 +361,12 @@ pub enum WheelInputDirection {
|
|||||||
Down,
|
Down,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
|
||||||
|
pub enum MouseMoveDirection {
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct AnalogWheelInput {
|
pub struct AnalogWheelInput {
|
||||||
value: f32,
|
value: f32,
|
||||||
|
|||||||
34
src/main.rs
34
src/main.rs
@@ -1,5 +1,5 @@
|
|||||||
use winit::{Event, WindowEvent};
|
use winit::{Event, WindowEvent, DeviceEvent};
|
||||||
use cgmath::{Matrix4, Rad, Point3, Vector3, Deg};
|
use cgmath::{Matrix4, Rad, Point3, Vector3, Deg, SquareMatrix, Quaternion, Rotation3, One, Rotation};
|
||||||
|
|
||||||
mod vulkan;
|
mod vulkan;
|
||||||
use crate::vulkan::{GameData, Game, LinePoint};
|
use crate::vulkan::{GameData, Game, LinePoint};
|
||||||
@@ -12,7 +12,8 @@ use crate::config::LogConfig;
|
|||||||
|
|
||||||
struct TestGame {
|
struct TestGame {
|
||||||
input: InputState,
|
input: InputState,
|
||||||
cam_pos: Point3<f32>,
|
cam_position: Vector3<f32>,
|
||||||
|
cam_rotation: Quaternion<f32>,
|
||||||
log_config: LogConfig,
|
log_config: LogConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,6 +23,8 @@ impl Game for TestGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn update(self: &mut Self, game_data: &mut GameData) {
|
fn update(self: &mut Self, game_data: &mut GameData) {
|
||||||
|
game_data.push_constants.time = game_data.start_time.elapsed().unwrap().as_millis() as f32 / 1000.0;
|
||||||
|
|
||||||
// User interaction
|
// User interaction
|
||||||
if self.input.button_just_released("QUIT") {
|
if self.input.button_just_released("QUIT") {
|
||||||
game_data.shutdown = true;
|
game_data.shutdown = true;
|
||||||
@@ -31,18 +34,17 @@ impl Game for TestGame {
|
|||||||
game_data.recreate_pipeline = true;
|
game_data.recreate_pipeline = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.cam_pos.x += self.input.get_axis("FORWARD_AXIS") * 0.01;
|
self.cam_rotation = self.cam_rotation * Quaternion::from_angle_z(Deg(self.input.get_axis("look_horizontal") * 0.05));
|
||||||
|
self.cam_rotation = Quaternion::from_angle_x(Deg(self.input.get_axis("look_vertical") * 0.05)) * self.cam_rotation;
|
||||||
|
self.cam_position += self.cam_rotation.invert().rotate_vector(Vector3::new(
|
||||||
|
self.input.get_axis("move_sideways") * -0.05,
|
||||||
|
0.0,
|
||||||
|
self.input.get_axis("move_forward") * 0.05));
|
||||||
|
|
||||||
// Move game objects
|
// Move game objects
|
||||||
game_data.push_constants.time = game_data.start_time.elapsed().unwrap().as_millis() as f32 / 1000.0;
|
|
||||||
|
|
||||||
let model = Matrix4::from_angle_z(Rad::from(Deg(game_data.push_constants.time * 100.0)));
|
let model = Matrix4::from_angle_z(Rad::from(Deg(game_data.push_constants.time * 100.0)));
|
||||||
|
|
||||||
let view = Matrix4::look_at(
|
let view = Matrix4::from(self.cam_rotation) * Matrix4::from_translation(self.cam_position);
|
||||||
self.cam_pos,
|
|
||||||
Point3::new(0.0, 0.0, 0.0),
|
|
||||||
Vector3::new(0.0, 0.0, 1.0)
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut proj = cgmath::perspective(
|
let mut proj = cgmath::perspective(
|
||||||
Rad::from(Deg(45.0)),
|
Rad::from(Deg(45.0)),
|
||||||
@@ -99,6 +101,13 @@ impl Game for TestGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.input.on_mouse_wheel_event(&delta, &modifiers);
|
self.input.on_mouse_wheel_event(&delta, &modifiers);
|
||||||
|
},
|
||||||
|
Event::DeviceEvent { device_id, event: DeviceEvent::MouseMotion { delta: (delta_x, delta_y) } } => {
|
||||||
|
if self.log_config.input {
|
||||||
|
println!("MouseMotion {:?}, ({:?},{:?})", device_id, delta_x, delta_y);
|
||||||
|
}
|
||||||
|
self.input.mouse_delta_x += *delta_x;
|
||||||
|
self.input.mouse_delta_y += *delta_y;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@@ -108,7 +117,8 @@ impl Game for TestGame {
|
|||||||
fn main() {
|
fn main() {
|
||||||
let mut game = TestGame {
|
let mut game = TestGame {
|
||||||
input: InputState::new("config/input.toml"),
|
input: InputState::new("config/input.toml"),
|
||||||
cam_pos: Point3::new(2.0, 2.0, 2.0),
|
cam_rotation: Quaternion::one(),
|
||||||
|
cam_position: Vector3::new(0.0, 0.0, -10.0),
|
||||||
log_config: LogConfig::from_file("config/log.toml"),
|
log_config: LogConfig::from_file("config/log.toml"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user