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,52 +100,57 @@ 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
 | 
			
		||||
		}
 | 
			
		||||
		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 ()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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