Switch free flight mode to quaternion
parent
3d9f8e1a13
commit
372761c1b2
|
@ -32,6 +32,35 @@ where V: Into <Vec3>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct EulerAngles {
|
||||||
|
pub azimuth: f32,
|
||||||
|
pub altitude: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for EulerAngles {
|
||||||
|
fn default () -> Self {
|
||||||
|
Self {
|
||||||
|
azimuth: 0.0,
|
||||||
|
altitude: 0.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EulerAngles {
|
||||||
|
pub fn to_vec3 (&self) -> Vec3 {
|
||||||
|
let alt = self.altitude.to_radians ();
|
||||||
|
let azi = self.azimuth.to_radians ();
|
||||||
|
|
||||||
|
let z = alt.sin ();
|
||||||
|
let xy_len = alt.cos ();
|
||||||
|
|
||||||
|
let x = xy_len * -azi.sin ();
|
||||||
|
let y = xy_len * azi.cos ();
|
||||||
|
|
||||||
|
(x, y, z).into ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Use iota macro
|
// TODO: Use iota macro
|
||||||
const KEY_LEFT: usize = 0;
|
const KEY_LEFT: usize = 0;
|
||||||
const KEY_RIGHT: usize = KEY_LEFT + 1;
|
const KEY_RIGHT: usize = KEY_LEFT + 1;
|
||||||
|
@ -71,55 +100,60 @@ impl ControllerState {
|
||||||
|
|
||||||
if self.is_pressed (KEY_LEFT) {
|
if self.is_pressed (KEY_LEFT) {
|
||||||
controlled_angle.azimuth += spin_f;
|
controlled_angle.azimuth += spin_f;
|
||||||
std::cmp::min (spin_speed + 1, SPIN_RAMP_TIME)
|
|
||||||
}
|
}
|
||||||
else if self.is_pressed (KEY_RIGHT) {
|
else if self.is_pressed (KEY_RIGHT) {
|
||||||
controlled_angle.azimuth -= spin_f;
|
controlled_angle.azimuth -= spin_f;
|
||||||
std::cmp::min (spin_speed + 1, SPIN_RAMP_TIME)
|
|
||||||
}
|
}
|
||||||
else if self.is_pressed (KEY_UP) {
|
else if self.is_pressed (KEY_UP) {
|
||||||
controlled_angle.altitude = f32::min (90.0, controlled_angle.altitude + spin_f);
|
controlled_angle.altitude = f32::min (90.0, controlled_angle.altitude + spin_f);
|
||||||
std::cmp::min (spin_speed + 1, SPIN_RAMP_TIME)
|
|
||||||
}
|
}
|
||||||
else if self.is_pressed (KEY_DOWN) {
|
else if self.is_pressed (KEY_DOWN) {
|
||||||
controlled_angle.altitude = f32::max (-90.0, controlled_angle.altitude - spin_f);
|
controlled_angle.altitude = f32::max (-90.0, controlled_angle.altitude - spin_f);
|
||||||
std::cmp::min (spin_speed + 1, SPIN_RAMP_TIME)
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cmp::min (spin_speed + 1, SPIN_RAMP_TIME)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn control_quat (
|
||||||
|
&self,
|
||||||
|
controlled_quat: &mut Quat,
|
||||||
|
spin_speed: i32
|
||||||
|
) -> i32
|
||||||
|
{
|
||||||
|
const SPIN_RAMP_TIME: i32 = 30;
|
||||||
|
let spin_f = 4.0 * (spin_speed + 1) as f32 / SPIN_RAMP_TIME as f32;
|
||||||
|
let spin_f = spin_f.to_radians ();
|
||||||
|
|
||||||
|
let mut delta = Quat::default ();
|
||||||
|
|
||||||
|
if self.is_pressed (KEY_LEFT) {
|
||||||
|
delta = delta.mul_quat (Quat::from_rotation_y (-spin_f));
|
||||||
|
}
|
||||||
|
if self.is_pressed (KEY_RIGHT) {
|
||||||
|
delta = delta.mul_quat (Quat::from_rotation_y (spin_f));
|
||||||
|
}
|
||||||
|
if self.is_pressed (KEY_UP) {
|
||||||
|
delta = delta.mul_quat (Quat::from_rotation_x (-spin_f));
|
||||||
|
}
|
||||||
|
if self.is_pressed (KEY_DOWN) {
|
||||||
|
delta = delta.mul_quat (Quat::from_rotation_x (spin_f));
|
||||||
|
}
|
||||||
|
|
||||||
|
//println! ("spin_f {}, Quat {:?}", spin_f, delta);
|
||||||
|
|
||||||
|
if delta == Quat::default () {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
}
|
*controlled_quat = (controlled_quat.mul_quat (delta)).normalize ();
|
||||||
|
std::cmp::min (spin_speed + 1, SPIN_RAMP_TIME)
|
||||||
struct EulerAngles {
|
|
||||||
pub azimuth: f32,
|
|
||||||
pub altitude: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for EulerAngles {
|
|
||||||
fn default () -> Self {
|
|
||||||
Self {
|
|
||||||
azimuth: 0.0,
|
|
||||||
altitude: 0.0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EulerAngles {
|
|
||||||
pub fn to_vec3 (&self) -> Vec3 {
|
|
||||||
let alt = self.altitude.to_radians ();
|
|
||||||
let azi = self.azimuth.to_radians ();
|
|
||||||
|
|
||||||
let z = alt.sin ();
|
|
||||||
let xy_len = alt.cos ();
|
|
||||||
|
|
||||||
let x = xy_len * -azi.sin ();
|
|
||||||
let y = xy_len * azi.cos ();
|
|
||||||
|
|
||||||
(x, y, z).into ()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum PlayMode {
|
enum PlayMode {
|
||||||
WindTunnel,
|
WindTunnel,
|
||||||
FreeFlight,
|
FreeFlight,
|
||||||
|
@ -143,8 +177,13 @@ struct WindTunnelState {
|
||||||
spin_speed: i32,
|
spin_speed: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Airplane {
|
||||||
|
pos: Vec3,
|
||||||
|
ori: Quat,
|
||||||
|
}
|
||||||
|
|
||||||
struct FlightState {
|
struct FlightState {
|
||||||
airplane: EulerAngles,
|
airplane: Airplane,
|
||||||
spin_speed: i32,
|
spin_speed: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +193,7 @@ impl FlightState {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn step (&mut self, controller: &ControllerState) {
|
pub fn step (&mut self, controller: &ControllerState) {
|
||||||
self.spin_speed = controller.control_eulers (&mut self.airplane, self.spin_speed);
|
self.spin_speed = controller.control_quat (&mut self.airplane.ori, self.spin_speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +253,10 @@ impl WorldState {
|
||||||
spin_speed: 0,
|
spin_speed: 0,
|
||||||
},
|
},
|
||||||
flight: FlightState {
|
flight: FlightState {
|
||||||
airplane: Default::default (),
|
airplane: Airplane {
|
||||||
|
pos: (0.0, 0.0, 1.35).into (),
|
||||||
|
ori: Default::default (),
|
||||||
|
},
|
||||||
spin_speed: 0,
|
spin_speed: 0,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -986,10 +1028,9 @@ impl GameGraphics {
|
||||||
Mat4::from_rotation_x (euler.altitude.to_radians ())
|
Mat4::from_rotation_x (euler.altitude.to_radians ())
|
||||||
},
|
},
|
||||||
PlayMode::FreeFlight => {
|
PlayMode::FreeFlight => {
|
||||||
let euler = &state.flight.airplane;
|
let airplane = &state.flight.airplane;
|
||||||
Mat4::from_translation ((0.0, 0.0, 2.7 * 0.5).into ()) *
|
Mat4::from_translation (airplane.pos) *
|
||||||
Mat4::from_rotation_z (euler.azimuth.to_radians ()) *
|
Mat4::from_quat (airplane.ori)
|
||||||
Mat4::from_rotation_x (euler.altitude.to_radians ())
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let inverse_airplane = airplane_model_mat.inverse ();
|
let inverse_airplane = airplane_model_mat.inverse ();
|
||||||
|
|
Loading…
Reference in New Issue