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
|
||||
const KEY_LEFT: usize = 0;
|
||||
const KEY_RIGHT: usize = KEY_LEFT + 1;
|
||||
|
@ -71,55 +100,60 @@ impl ControllerState {
|
|||
|
||||
if self.is_pressed (KEY_LEFT) {
|
||||
controlled_angle.azimuth += spin_f;
|
||||
std::cmp::min (spin_speed + 1, SPIN_RAMP_TIME)
|
||||
}
|
||||
else if self.is_pressed (KEY_RIGHT) {
|
||||
controlled_angle.azimuth -= spin_f;
|
||||
std::cmp::min (spin_speed + 1, SPIN_RAMP_TIME)
|
||||
}
|
||||
else if self.is_pressed (KEY_UP) {
|
||||
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) {
|
||||
controlled_angle.altitude = f32::max (-90.0, controlled_angle.altitude - spin_f);
|
||||
std::cmp::min (spin_speed + 1, SPIN_RAMP_TIME)
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct EulerAngles {
|
||||
pub azimuth: f32,
|
||||
pub altitude: f32,
|
||||
}
|
||||
|
||||
impl Default for EulerAngles {
|
||||
fn default () -> Self {
|
||||
Self {
|
||||
azimuth: 0.0,
|
||||
altitude: 0.0,
|
||||
else {
|
||||
*controlled_quat = (controlled_quat.mul_quat (delta)).normalize ();
|
||||
std::cmp::min (spin_speed + 1, SPIN_RAMP_TIME)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
WindTunnel,
|
||||
FreeFlight,
|
||||
|
@ -143,8 +177,13 @@ struct WindTunnelState {
|
|||
spin_speed: i32,
|
||||
}
|
||||
|
||||
struct Airplane {
|
||||
pos: Vec3,
|
||||
ori: Quat,
|
||||
}
|
||||
|
||||
struct FlightState {
|
||||
airplane: EulerAngles,
|
||||
airplane: Airplane,
|
||||
spin_speed: i32,
|
||||
}
|
||||
|
||||
|
@ -154,7 +193,7 @@ impl FlightState {
|
|||
}
|
||||
|
||||
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,
|
||||
},
|
||||
flight: FlightState {
|
||||
airplane: Default::default (),
|
||||
airplane: Airplane {
|
||||
pos: (0.0, 0.0, 1.35).into (),
|
||||
ori: Default::default (),
|
||||
},
|
||||
spin_speed: 0,
|
||||
},
|
||||
}
|
||||
|
@ -986,10 +1028,9 @@ impl GameGraphics {
|
|||
Mat4::from_rotation_x (euler.altitude.to_radians ())
|
||||
},
|
||||
PlayMode::FreeFlight => {
|
||||
let euler = &state.flight.airplane;
|
||||
Mat4::from_translation ((0.0, 0.0, 2.7 * 0.5).into ()) *
|
||||
Mat4::from_rotation_z (euler.azimuth.to_radians ()) *
|
||||
Mat4::from_rotation_x (euler.altitude.to_radians ())
|
||||
let airplane = &state.flight.airplane;
|
||||
Mat4::from_translation (airplane.pos) *
|
||||
Mat4::from_quat (airplane.ori)
|
||||
},
|
||||
};
|
||||
let inverse_airplane = airplane_model_mat.inverse ();
|
||||
|
|
Loading…
Reference in New Issue