Merge branch 'main' of https://github.com/ScorpionX90/TDT4195
This commit is contained in:
@@ -57,17 +57,42 @@ pub enum Nodes {
|
||||
SceneRoot,
|
||||
}
|
||||
|
||||
pub struct ChaseCamera {
|
||||
pub position: glm::Vec3,
|
||||
pub target: glm::Vec3,
|
||||
pub radius: f32, // set to big number to get normal camera
|
||||
pub perspective: glm::Mat4,
|
||||
pitch: f32,
|
||||
yaw: f32
|
||||
}
|
||||
|
||||
impl ChaseCamera {
|
||||
pub fn new(radius: f32, perspective: glm::Mat4) -> Self {
|
||||
ChaseCamera {
|
||||
position: glm::vec3(100.0, 35.0, 0.0),
|
||||
target: glm::vec3(0.0, 0.0, 0.0),
|
||||
radius,
|
||||
perspective,
|
||||
pitch: 0.0,
|
||||
yaw: 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct World {
|
||||
pub nodes: HashMap<Nodes, Vec<ManuallyDrop<Pin<Box<SceneNode>>>>>,
|
||||
pub anim_ctxs: Vec<AnimCTX>
|
||||
pub anim_ctxs: Vec<AnimCTX>,
|
||||
pub camera: ChaseCamera,
|
||||
pub model_transformation: glm::Mat4
|
||||
}
|
||||
|
||||
impl World {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(radius: f32, perspective: glm::Mat4) -> Self {
|
||||
let meshes = Self::load_models();
|
||||
let nodes = Self::setup_scene_graph(&meshes);
|
||||
let anim_ctxs:Vec<AnimCTX> = Vec::new();
|
||||
World { nodes, anim_ctxs }
|
||||
let camera = ChaseCamera::new(radius, perspective);
|
||||
World { nodes, anim_ctxs, camera, model_transformation: glm::identity() }
|
||||
}
|
||||
|
||||
fn load_models() -> HashMap<Nodes, Mesh> {
|
||||
@@ -146,23 +171,49 @@ impl World {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
pub fn update(&mut self, elapsed: f32, perspective: glm::Mat4, transformation: glm::Mat4, shader: &Shader) {
|
||||
let transform_thus_far = perspective * transformation;
|
||||
fn view_matrix(&self) -> glm::Mat4 {
|
||||
glm::look_at(
|
||||
&self.camera.position,
|
||||
&self.camera.target,
|
||||
&glm::vec3(0.0, 1.0, 0.0)
|
||||
)
|
||||
}
|
||||
|
||||
pub fn update(&mut self, elapsed: f32, shader: &Shader) {
|
||||
let rotor_speed = 60.0;
|
||||
|
||||
// update all helicopter positions
|
||||
for i in 0..self.nodes[&Nodes::HeliRoot].len() {
|
||||
// let iter_heli_heading = toolbox::simple_heading_animation(elapsed + i as f32 * 1.6f32);
|
||||
// let heli_root = &mut self.nodes.get_mut(&Nodes::HeliRoot).unwrap()[i];
|
||||
// heli_root.position.x = iter_heli_heading.x;
|
||||
// heli_root.position.z = iter_heli_heading.z;
|
||||
// heli_root.rotation.z = iter_heli_heading.roll;
|
||||
// heli_root.rotation.y = iter_heli_heading.yaw;
|
||||
// heli_root.rotation.x = iter_heli_heading.pitch;
|
||||
let iter_heli_heading = toolbox::simple_heading_animation(elapsed + i as f32 * 1.6f32);
|
||||
let heli_root = &mut self.nodes.get_mut(&Nodes::HeliRoot).unwrap()[i];
|
||||
heli_root.position.x = iter_heli_heading.x;
|
||||
heli_root.position.y = 15.0;
|
||||
heli_root.position.z = iter_heli_heading.z;
|
||||
heli_root.rotation.z = iter_heli_heading.roll;
|
||||
heli_root.rotation.y = iter_heli_heading.yaw;
|
||||
heli_root.rotation.x = iter_heli_heading.pitch;
|
||||
|
||||
self.nodes.get_mut(&Nodes::HeliMainRotor).unwrap()[i].rotation.y = elapsed * rotor_speed;
|
||||
self.nodes.get_mut(&Nodes::HeliTailRotor).unwrap()[i].rotation.x = elapsed * rotor_speed;
|
||||
}
|
||||
|
||||
// camera chase after target
|
||||
let camera_target = &self.nodes[&Nodes::HeliRoot][0];
|
||||
self.camera.target = camera_target.position;
|
||||
let distance = glm::distance(&self.camera.position, &self.camera.target);
|
||||
let direction = glm::normalize(&(self.camera.target - self.camera.position));
|
||||
if distance > self.camera.radius {
|
||||
self.camera.position += direction * (distance - self.camera.radius);
|
||||
}
|
||||
|
||||
// update camera angles
|
||||
self.camera.yaw = direction.z.atan2(direction.x) + glm::half_pi::<f32>();
|
||||
let horizontal_distance = (direction.x * direction.x + direction.z * direction.z).sqrt();
|
||||
self.camera.pitch = direction.y.atan2(horizontal_distance);
|
||||
|
||||
|
||||
let transform_thus_far = self.camera.perspective * self.view_matrix();
|
||||
|
||||
// Build scene graph on the fly or store scene_root separately
|
||||
unsafe {
|
||||
draw_scene(&self.nodes[&Nodes::SceneRoot][0], &transform_thus_far, glm::identity(), &shader, elapsed);
|
||||
|
||||
@@ -91,22 +91,12 @@ fn main() {
|
||||
println!("GLSL\t: {}", util::get_gl_string(gl::SHADING_LANGUAGE_VERSION));
|
||||
}
|
||||
|
||||
let mut transformation: glm::Mat4;
|
||||
let perspective: glm::Mat4 = glm::perspective(
|
||||
let mut world = draw::World::new(30.0, glm::perspective(
|
||||
window_aspect_ratio,
|
||||
120.0f32,
|
||||
1.0f32,
|
||||
1000.0f32
|
||||
);
|
||||
|
||||
let mut world = draw::World::new();
|
||||
|
||||
let mut camera_position: glm::Vec3 = glm::vec3(0.0, 0.0, 0.0);
|
||||
let translation_speed = 30.0f32;
|
||||
let rotation_speed = 1.5f32;
|
||||
|
||||
let mut yaw = 0.0f32;
|
||||
let mut pitch = 0.0f32;
|
||||
));
|
||||
|
||||
// == // Set up your shaders here
|
||||
|
||||
@@ -135,9 +125,6 @@ fn main() {
|
||||
let delta_time = now.duration_since(previous_frame_time).as_secs_f32();
|
||||
previous_frame_time = now;
|
||||
|
||||
let angle_speed = rotation_speed * delta_time;
|
||||
let trans_speed: f32 = translation_speed * delta_time;
|
||||
|
||||
// Handle resize events
|
||||
if let Ok(mut new_size) = window_size.lock() {
|
||||
if new_size.2 {
|
||||
@@ -149,34 +136,10 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate forward vector, and right vector in x-z plane for relative yaw based translation.
|
||||
let f_xz = glm::vec3(-yaw.sin(), yaw.cos(), 0.0);
|
||||
let r_xz = glm::rotation2d(glm::half_pi()) * f_xz;
|
||||
|
||||
let forward = glm::vec3(f_xz.x, f_xz.z, f_xz.y);
|
||||
let right = glm::vec3(r_xz.x, r_xz.z, r_xz.y);
|
||||
// Handle keyboard input
|
||||
if let Ok(keys) = pressed_keys.lock() {
|
||||
for key in keys.iter() {
|
||||
match key {
|
||||
VirtualKeyCode::W => {
|
||||
camera_position += forward * trans_speed;
|
||||
}
|
||||
VirtualKeyCode::A => {
|
||||
camera_position -= right * trans_speed;
|
||||
}
|
||||
VirtualKeyCode::S => {
|
||||
camera_position -= forward * trans_speed;
|
||||
}
|
||||
VirtualKeyCode::D => {
|
||||
camera_position += right * trans_speed;
|
||||
}
|
||||
VirtualKeyCode::Space => {
|
||||
camera_position.y -= trans_speed;
|
||||
}
|
||||
VirtualKeyCode::LShift => {
|
||||
camera_position.y += trans_speed;
|
||||
}
|
||||
VirtualKeyCode::E => {
|
||||
|
||||
let ptr = &world.nodes[&Nodes::HeliDoor][0];
|
||||
@@ -196,27 +159,6 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
VirtualKeyCode::Down => {
|
||||
pitch += angle_speed;
|
||||
pitch = pitch.clamp(
|
||||
-std::f32::consts::FRAC_PI_2,
|
||||
std::f32::consts::FRAC_PI_2
|
||||
);
|
||||
}
|
||||
VirtualKeyCode::Up => {
|
||||
pitch -= angle_speed;
|
||||
pitch = pitch.clamp(
|
||||
-std::f32::consts::FRAC_PI_2,
|
||||
std::f32::consts::FRAC_PI_2
|
||||
);
|
||||
}
|
||||
VirtualKeyCode::Right => {
|
||||
yaw += angle_speed;
|
||||
}
|
||||
VirtualKeyCode::Left => {
|
||||
yaw -= angle_speed;
|
||||
}
|
||||
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
@@ -230,14 +172,6 @@ fn main() {
|
||||
*delta = (0.0, 0.0); // reset when done
|
||||
}
|
||||
|
||||
let yaw_matrix = glm::rotation(yaw, &glm::vec3(0.0, 1.0, 0.0));
|
||||
let pitch_matrix = glm::rotation(pitch, &glm::vec3(1.0, 0.0, 0.0));
|
||||
let translation_matrix = glm::translation(&(camera_position));
|
||||
|
||||
// apply yaw dependent pitch first.
|
||||
let rotation_matrix = pitch_matrix * yaw_matrix;
|
||||
transformation = rotation_matrix * translation_matrix;
|
||||
|
||||
unsafe {
|
||||
simple_shader.activate();
|
||||
|
||||
@@ -245,7 +179,7 @@ fn main() {
|
||||
gl::ClearColor(40.0f32 / 256.0f32, 42.0f32 / 256.0f32, 54.0f32 / 256.0f32, 1.0); // night sky
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
|
||||
|
||||
world.update(elapsed, perspective, transformation, &simple_shader);
|
||||
world.update(elapsed, &simple_shader);
|
||||
|
||||
// Display the new color buffer on the display
|
||||
context.swap_buffers().unwrap(); // we use "double buffering" to avoid artifacts
|
||||
|
||||
Reference in New Issue
Block a user