Prepare to add a flight mode

main
_ 2020-03-09 01:10:15 +00:00
parent 61a5aae607
commit d39276d93f
1 changed files with 152 additions and 91 deletions

View File

@ -90,7 +90,22 @@ impl EulerAngles {
} }
} }
struct WorldState { enum PlayMode {
WindTunnel,
FreeFlight,
}
#[derive (Copy, Clone, PartialEq, Eq)]
enum UserControl {
Camera,
Wind,
Airplane,
Sunlight,
}
struct WindTunnelState {
user_control: UserControl,
camera: EulerAngles, camera: EulerAngles,
wind: EulerAngles, wind: EulerAngles,
airplane: EulerAngles, airplane: EulerAngles,
@ -98,30 +113,39 @@ struct WorldState {
spin_speed: i32, spin_speed: i32,
} }
impl WorldState { struct WorldState {
pub fn new () -> Self { play_mode: PlayMode,
Self { wind_tunnel: WindTunnelState,
camera: Default::default (), }
wind: Default::default (),
airplane: Default::default (), impl WindTunnelState {
sunlight: EulerAngles { pub fn handle_event (&mut self, event: &sdl2::event::Event) {
altitude: 90.0, match event {
azimuth: 0.0, Event::KeyDown { keycode: Some (Keycode::C), .. } => {
self.user_control = UserControl::Camera;
}, },
spin_speed: 0, Event::KeyDown { keycode: Some (Keycode::W), .. } => {
self.user_control = UserControl::Wind;
},
Event::KeyDown { keycode: Some (Keycode::P), .. } => {
self.user_control = UserControl::Airplane;
},
Event::KeyDown { keycode: Some (Keycode::L), .. } => {
self.user_control = UserControl::Sunlight;
},
_ => (),
} }
} }
pub fn step ( pub fn step (
&mut self, &mut self,
controller: &ControllerState, controller: &ControllerState
user_control: &UserControl
) { ) {
const SPIN_RAMP_TIME: i32 = 30; const SPIN_RAMP_TIME: i32 = 30;
let spin_f = 4.0 * self.spin_speed as f32 / SPIN_RAMP_TIME as f32; let spin_f = 4.0 * self.spin_speed as f32 / SPIN_RAMP_TIME as f32;
let controlled_angle = match user_control { let controlled_angle = match self.user_control {
UserControl::Camera => &mut self.camera, UserControl::Camera => &mut self.camera,
UserControl::Wind => &mut self.wind, UserControl::Wind => &mut self.wind,
UserControl::Airplane => &mut self.airplane, UserControl::Airplane => &mut self.airplane,
@ -150,6 +174,47 @@ impl WorldState {
} }
} }
impl WorldState {
pub fn new () -> Self {
Self {
play_mode: PlayMode::WindTunnel,
wind_tunnel: WindTunnelState {
user_control: UserControl::Camera,
camera: Default::default (),
wind: Default::default (),
airplane: Default::default (),
sunlight: EulerAngles {
altitude: 90.0,
azimuth: 0.0,
},
spin_speed: 0,
},
}
}
pub fn handle_event (&mut self, event: &sdl2::event::Event) {
match event {
Event::KeyDown { keycode: Some (Keycode::T), .. } => {
self.play_mode = PlayMode::WindTunnel;
},
_ => match self.play_mode {
PlayMode::WindTunnel => self.wind_tunnel.handle_event (event),
_ => (),
},
}
}
pub fn step (
&mut self,
controller: &ControllerState
) {
match self.play_mode {
PlayMode::WindTunnel => self.wind_tunnel.step (controller),
_ => (),
}
}
}
mod uniforms { mod uniforms {
use iota::iota; use iota::iota;
iota! { iota! {
@ -866,12 +931,25 @@ impl GameGraphics {
green, green,
]; ];
let longitude = state.camera.azimuth.to_radians ();
let latitude = (state.camera.altitude - 90.0).to_radians ();
let proj_mat = Mat4::perspective_rh_gl (30.0f32.to_radians (), 1280.0 / 720.0, 0.5, 500.0); let proj_mat = Mat4::perspective_rh_gl (30.0f32.to_radians (), 1280.0 / 720.0, 0.5, 500.0);
let light = state.sunlight.to_vec3 (); let view_mat = match state.play_mode {
PlayMode::WindTunnel => {
let state = &state.wind_tunnel;
let longitude = state.camera.azimuth.to_radians ();
let latitude = (state.camera.altitude - 90.0).to_radians ();
proj_mat *
Mat4::from_translation (Vec3::from ((0.0, 0.0, -8.0))) *
Mat4::from_rotation_x (latitude) *
Mat4::from_rotation_z (longitude) *
Mat4::from_translation ((0.0, 0.0, -2.7 * 0.5).into ())
},
_ => proj_mat,
};
let light = state.wind_tunnel.sunlight.to_vec3 ();
let shadow_mat = { let shadow_mat = {
let mut mat = Mat4::identity (); let mut mat = Mat4::identity ();
@ -879,12 +957,7 @@ impl GameGraphics {
mat mat
}; };
let view_mat = proj_mat *
Mat4::from_translation (Vec3::from ((0.0, 0.0, -8.0))) *
Mat4::from_rotation_x (latitude) *
Mat4::from_rotation_z (longitude) *
Mat4::from_translation ((0.0, 0.0, -2.7 * 0.5).into ())
;
let sky_mvp_mat = view_mat * Mat4::from_scale ((16.0, 16.0, 16.0).into ()); let sky_mvp_mat = view_mat * Mat4::from_scale ((16.0, 16.0, 16.0).into ());
@ -897,12 +970,16 @@ impl GameGraphics {
glezz::clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT); glezz::clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT);
}); });
let airplane_model_mat = let airplane_model_mat = match state.play_mode {
Mat4::from_translation ((0.0, 0.0, 2.7 * 0.5).into ()) * PlayMode::WindTunnel => {
Mat4::from_scale ((0.125, 0.125, 0.125).into ()) * let state = &state.wind_tunnel;
Mat4::from_rotation_z (state.airplane.azimuth.to_radians ()) * Mat4::from_translation ((0.0, 0.0, 2.7 * 0.5).into ()) *
Mat4::from_rotation_x (state.airplane.altitude.to_radians ()) Mat4::from_scale ((0.125, 0.125, 0.125).into ()) *
; Mat4::from_rotation_z (state.airplane.azimuth.to_radians ()) *
Mat4::from_rotation_x (state.airplane.altitude.to_radians ())
},
_ => Mat4::identity (),
};
let world_model_mat = Mat4::identity (); let world_model_mat = Mat4::identity ();
let inverse_pumpkin = airplane_model_mat.inverse (); let inverse_pumpkin = airplane_model_mat.inverse ();
@ -1044,14 +1121,6 @@ impl GameGraphics {
} }
} }
#[derive (Copy, Clone, PartialEq, Eq)]
enum UserControl {
Camera,
Wind,
Airplane,
Sunlight,
}
fn main () { fn main () {
let sdl_context = sdl2::init ().unwrap (); let sdl_context = sdl2::init ().unwrap ();
let video_subsystem = sdl_context.video ().unwrap (); let video_subsystem = sdl_context.video ().unwrap ();
@ -1078,7 +1147,6 @@ fn main () {
let graphics = GameGraphics::new (); let graphics = GameGraphics::new ();
let mut gl_state = Default::default (); let mut gl_state = Default::default ();
let mut user_control = UserControl::Camera;
let mut graphics_frames = 0; let mut graphics_frames = 0;
let mut event_pump = sdl_context.event_pump ().unwrap (); let mut event_pump = sdl_context.event_pump ().unwrap ();
@ -1093,37 +1161,16 @@ fn main () {
Event::KeyDown { keycode: Some (Keycode::Escape), .. } => { Event::KeyDown { keycode: Some (Keycode::Escape), .. } => {
break 'running break 'running
}, },
Event::KeyDown { keycode: Some (Keycode::C), .. } => { _ => state.handle_event (&event),
user_control = UserControl::Camera;
},
Event::KeyDown { keycode: Some (Keycode::W), .. } => {
user_control = UserControl::Wind;
},
Event::KeyDown { keycode: Some (Keycode::P), .. } => {
user_control = UserControl::Airplane;
},
Event::KeyDown { keycode: Some (Keycode::L), .. } => {
user_control = UserControl::Sunlight;
},
_ => (),
} }
} }
let controller = ControllerState::from_sdl_keyboard (&event_pump.keyboard_state ()); let controller = ControllerState::from_sdl_keyboard (&event_pump.keyboard_state ());
for _ in 0..frames_to_do { for _ in 0..frames_to_do {
state.step (&controller, &user_control); state.step (&controller);
} }
let purple = (1.0, 0.5, 1.0).into ();
let origin: Vec3 = (0.0, 0.0, 1.35).into ();
let gravity = (0.0, 0.0, -1.0).into ();
let wind = state.wind.to_vec3 () * -1.0;
let wind_force = (wind.x (), 0.125 * wind.y (), wind.z ()).into ();
let control_flash = if graphics_frames % 16 >= 8 { let control_flash = if graphics_frames % 16 >= 8 {
(1.0, 1.0, 1.0).into () (1.0, 1.0, 1.0).into ()
} }
@ -1131,37 +1178,51 @@ fn main () {
(1.0, 0.0, 0.0).into () (1.0, 0.0, 0.0).into ()
}; };
let get_flash = |control_type, default_color| { let arrows = match state.play_mode {
if user_control == control_type { PlayMode::WindTunnel => {
control_flash let state = &state.wind_tunnel;
} let purple = (1.0, 0.5, 1.0).into ();
else {
default_color
}
};
let arrows = vec![ let origin: Vec3 = (0.0, 0.0, 1.35).into ();
Arrow { let gravity = (0.0, 0.0, -1.0).into ();
origin: (0.0, 0.0, 1.35).into (),
direction: gravity, let wind = state.wind.to_vec3 () * -1.0;
color: (1.0, 0.5, 0.5).into (), let wind_force = (wind.x (), 0.125 * wind.y (), wind.z ()).into ();
let get_flash = |control_type, default_color| {
if state.user_control == control_type {
control_flash
}
else {
default_color
}
};
vec![
Arrow {
origin: (0.0, 0.0, 1.35).into (),
direction: gravity,
color: (1.0, 0.5, 0.5).into (),
},
Arrow {
origin: origin + wind * -2.0,
direction: wind,
color: get_flash (UserControl::Wind, purple),
},
Arrow {
origin: origin,
direction: wind_force,
color: purple,
},
Arrow {
origin: origin,
direction: state.airplane.to_vec3 () * 0.5,
color: get_flash (UserControl::Airplane, (0.0, 0.0, 0.0).into ()),
}
]
}, },
Arrow { _ => vec![],
origin: origin + wind * -2.0, };
direction: wind,
color: get_flash (UserControl::Wind, purple),
},
Arrow {
origin: origin,
direction: wind_force,
color: purple,
},
Arrow {
origin: origin,
direction: state.airplane.to_vec3 () * 0.5,
color: get_flash (UserControl::Airplane, (0.0, 0.0, 0.0).into ()),
}
];
let renderable_arrows: Vec <_> = arrows.iter ().map (|arrow| { let renderable_arrows: Vec <_> = arrows.iter ().map (|arrow| {
let dir_len = arrow.direction.length (); let dir_len = arrow.direction.length ();