diff --git a/gloom-rs/src/draw.rs b/gloom-rs/src/draw.rs index b73c666..5d0804e 100644 --- a/gloom-rs/src/draw.rs +++ b/gloom-rs/src/draw.rs @@ -43,94 +43,102 @@ unsafe fn draw_scene(node: &SceneNode, draw_scene(&*child, view_projection_matrix, transformation_so_far, shader, elapsed); } } - -pub struct World { - pub nodes: HashMap>>>, -} #[derive(Clone, Copy, Eq, PartialEq, Hash)] pub enum Nodes { - LunarSurface=0, - HeliBody=1, - HeliDoor=2, - HeliMainRotor=3, - HeliTailRotor=4, - HeliRoot=69, - SceneRoot=420, + LunarSurface, + HeliBody, + HeliDoor, + HeliMainRotor, + HeliTailRotor, + HeliRoot, + SceneRoot, +} + +pub struct World { + meshes: HashMap, + pub nodes: HashMap>>>, } -pub fn load_models() -> HashMap { - let helicopter = Helicopter::load(&"resources/helicopter.obj"); - HashMap::from([ - (Nodes::LunarSurface, Terrain::load(&"resources/lunarsurface.obj")), - (Nodes::HeliBody, helicopter.body), - (Nodes::HeliDoor, helicopter.door), - (Nodes::HeliMainRotor, helicopter.main_rotor), - (Nodes::HeliTailRotor, helicopter.tail_rotor), - ]) -} - -pub fn setup_scene_graph(meshes: &HashMap) -> HashMap>>> { - let mut nodes = HashMap::new(); - - // Create all nodes with correct VAO IDs from meshes - for (node, mesh) in meshes { - nodes.insert(*node, SceneNode::from_vao(mesh.vao_id, mesh.index_count)); +impl World { + pub fn new() -> Self { + let meshes = Self::load_models(); + let nodes = Self::setup_scene_graph(&meshes); + World { meshes, nodes } } - nodes.insert(Nodes::HeliRoot, SceneNode::new()); - nodes.insert(Nodes::SceneRoot, SceneNode::new()); + fn load_models() -> HashMap { + let helicopter = Helicopter::load(&"resources/helicopter.obj"); + HashMap::from([ + (Nodes::LunarSurface, Terrain::load(&"resources/lunarsurface.obj")), + (Nodes::HeliBody, helicopter.body), + (Nodes::HeliDoor, helicopter.door), + (Nodes::HeliMainRotor, helicopter.main_rotor), + (Nodes::HeliTailRotor, helicopter.tail_rotor), + ]) + } - // Set reference points and initial state - nodes.get_mut(&Nodes::LunarSurface).unwrap().reference_point = glm::vec3(0.0, 0.0, 0.0); - nodes.get_mut(&Nodes::LunarSurface).unwrap().position.y = -10.0; + fn setup_scene_graph(meshes: &HashMap) -> HashMap>>> { + let mut nodes = HashMap::new(); - nodes.get_mut(&Nodes::HeliRoot).unwrap().reference_point = glm::vec3(0.0, 0.0, 0.0); - nodes.get_mut(&Nodes::HeliBody).unwrap().reference_point = glm::vec3(0.0, 0.0, 0.0); - nodes.get_mut(&Nodes::HeliDoor).unwrap().reference_point = glm::vec3(0.0, 0.0, 0.0); - nodes.get_mut(&Nodes::HeliMainRotor).unwrap().reference_point = glm::vec3(0.0, 2.0, 0.0); - nodes.get_mut(&Nodes::HeliMainRotor).unwrap().rotation = glm::vec3(0.0, 2.0, 0.0); - nodes.get_mut(&Nodes::HeliTailRotor).unwrap().reference_point = glm::vec3(0.35, 2.3, 10.4); - nodes.get_mut(&Nodes::HeliTailRotor).unwrap().rotation = glm::vec3(1.0, 0.0, 0.0); + // Create all nodes with correct VAO IDs from meshes + for (node, mesh) in meshes { + nodes.insert(*node, SceneNode::from_vao(mesh.vao_id, mesh.index_count)); + } - // BUILD THE SCENE GRAPH HIERARCHY - let heli_body_ptr = nodes.get(&Nodes::HeliBody).unwrap().as_ref().get_ref() as *const SceneNode; - let heli_door_ptr = nodes.get(&Nodes::HeliDoor).unwrap().as_ref().get_ref() as *const SceneNode; - let heli_main_rotor_ptr = nodes.get(&Nodes::HeliMainRotor).unwrap().as_ref().get_ref() as *const SceneNode; - let heli_tail_rotor_ptr = nodes.get(&Nodes::HeliTailRotor).unwrap().as_ref().get_ref() as *const SceneNode; - let heli_root_ptr = nodes.get(&Nodes::HeliRoot).unwrap().as_ref().get_ref() as *const SceneNode; - let lunar_ptr = nodes.get(&Nodes::LunarSurface).unwrap().as_ref().get_ref() as *const SceneNode; + nodes.insert(Nodes::HeliRoot, SceneNode::new()); + nodes.insert(Nodes::SceneRoot, SceneNode::new()); - nodes.get_mut(&Nodes::HeliRoot).unwrap().add_child(unsafe { &*heli_body_ptr }); - nodes.get_mut(&Nodes::HeliRoot).unwrap().add_child(unsafe { &*heli_door_ptr }); - nodes.get_mut(&Nodes::HeliRoot).unwrap().add_child(unsafe { &*heli_main_rotor_ptr }); - nodes.get_mut(&Nodes::HeliRoot).unwrap().add_child(unsafe { &*heli_tail_rotor_ptr }); + // Set reference points and initial state + nodes.get_mut(&Nodes::LunarSurface).unwrap().reference_point = glm::vec3(0.0, 0.0, 0.0); + nodes.get_mut(&Nodes::LunarSurface).unwrap().position.y = -10.0; - nodes.get_mut(&Nodes::LunarSurface).unwrap().add_child(unsafe { &*heli_root_ptr }); - nodes.get_mut(&Nodes::SceneRoot).unwrap().add_child(unsafe { &*lunar_ptr }); + nodes.get_mut(&Nodes::HeliRoot).unwrap().reference_point = glm::vec3(0.0, 0.0, 0.0); + nodes.get_mut(&Nodes::HeliBody).unwrap().reference_point = glm::vec3(0.0, 0.0, 0.0); + nodes.get_mut(&Nodes::HeliDoor).unwrap().reference_point = glm::vec3(0.0, 0.0, 0.0); + nodes.get_mut(&Nodes::HeliMainRotor).unwrap().reference_point = glm::vec3(0.0, 2.0, 0.0); + nodes.get_mut(&Nodes::HeliMainRotor).unwrap().rotation = glm::vec3(0.0, 2.0, 0.0); + nodes.get_mut(&Nodes::HeliTailRotor).unwrap().reference_point = glm::vec3(0.35, 2.3, 10.4); + nodes.get_mut(&Nodes::HeliTailRotor).unwrap().rotation = glm::vec3(1.0, 0.0, 0.0); - return nodes; + // BUILD THE SCENE GRAPH HIERARCHY + let heli_body_ptr = nodes.get(&Nodes::HeliBody).unwrap().as_ref().get_ref() as *const SceneNode; + let heli_door_ptr = nodes.get(&Nodes::HeliDoor).unwrap().as_ref().get_ref() as *const SceneNode; + let heli_main_rotor_ptr = nodes.get(&Nodes::HeliMainRotor).unwrap().as_ref().get_ref() as *const SceneNode; + let heli_tail_rotor_ptr = nodes.get(&Nodes::HeliTailRotor).unwrap().as_ref().get_ref() as *const SceneNode; + let heli_root_ptr = nodes.get(&Nodes::HeliRoot).unwrap().as_ref().get_ref() as *const SceneNode; + let lunar_ptr = nodes.get(&Nodes::LunarSurface).unwrap().as_ref().get_ref() as *const SceneNode; + + nodes.get_mut(&Nodes::HeliRoot).unwrap().add_child(unsafe { &*heli_body_ptr }); + nodes.get_mut(&Nodes::HeliRoot).unwrap().add_child(unsafe { &*heli_door_ptr }); + nodes.get_mut(&Nodes::HeliRoot).unwrap().add_child(unsafe { &*heli_main_rotor_ptr }); + nodes.get_mut(&Nodes::HeliRoot).unwrap().add_child(unsafe { &*heli_tail_rotor_ptr }); + + nodes.get_mut(&Nodes::LunarSurface).unwrap().add_child(unsafe { &*heli_root_ptr }); + nodes.get_mut(&Nodes::SceneRoot).unwrap().add_child(unsafe { &*lunar_ptr }); + + return nodes; + } + + pub fn update(&mut self, elapsed: f32, perspective: glm::Mat4, transformation: glm::Mat4, shader: &Shader) { + let transform_thus_far = perspective * transformation; + let rotor_speed = 60.0; + + let iter_heli_heading = toolbox::simple_heading_animation(elapsed); + + let heli_root = self.nodes.get_mut(&Nodes::HeliRoot).unwrap(); + 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; + + self.nodes.get_mut(&Nodes::HeliMainRotor).unwrap().rotation.y = elapsed * rotor_speed; + self.nodes.get_mut(&Nodes::HeliTailRotor).unwrap().rotation.x = elapsed * rotor_speed; + + // Build scene graph on the fly or store scene_root separately + unsafe { + draw_scene(&self.nodes[&Nodes::SceneRoot], &transform_thus_far, glm::identity(), &shader, elapsed); + } + } } - - - -pub fn update(elapsed: f32, world: &mut World, perspective: glm::Mat4, transformation: glm::Mat4, shader: &Shader) { - let transform_thus_far = perspective * transformation; - let rotor_speed = 60.0; - - let iter_heli_heading = toolbox::simple_heading_animation(elapsed); - - let heli_root = world.nodes.get_mut(&Nodes::HeliRoot).unwrap(); - 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; - - world.nodes.get_mut(&Nodes::HeliMainRotor).unwrap().rotation.y = elapsed * rotor_speed; - world.nodes.get_mut(&Nodes::HeliTailRotor).unwrap().rotation.x = elapsed * rotor_speed; - - // Build scene graph on the fly or store scene_root separately - unsafe {draw_scene(&world.nodes[&Nodes::SceneRoot], &transform_thus_far, glm::identity(), &shader, elapsed);} -} - diff --git a/gloom-rs/src/main.rs b/gloom-rs/src/main.rs index e37b1f0..fc2220a 100644 --- a/gloom-rs/src/main.rs +++ b/gloom-rs/src/main.rs @@ -94,11 +94,7 @@ fn main() { 1000.0f32 ); - let meshes = draw::load_models(); - let nodes = draw::setup_scene_graph(&meshes); - let mut world = draw::World { - nodes: nodes - }; + 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; @@ -226,7 +222,7 @@ fn main() { gl::ClearColor(0.40, 0.55, 1.0, 1.0); // night sky gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT); - draw::update(elapsed, &mut world, perspective, transformation, &simple_shader); + world.update(elapsed, perspective, transformation, &simple_shader); // Display the new color buffer on the display context.swap_buffers().unwrap(); // we use "double buffering" to avoid artifacts