diff --git a/src/main.rs b/src/main.rs index bed994f..9b039fc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -129,16 +129,29 @@ unsafe fn create_vao(vertices: &Vec, normals: &Vec, colors: &Vec, // Scene graph drawing function unsafe fn draw_scene(node: &scene_graph::SceneNode, transform_loc: i32, view_projection: &glm::Mat4, transform_so_far: &glm::Mat4) { + // Build model matrix from node transformations + let translation = glm::translation(&node.position); + let rot_x = glm::rotation(node.rotation.x, &glm::vec3(1.0, 0.0, 0.0)); + let rot_y = glm::rotation(node.rotation.y, &glm::vec3(0.0, 1.0, 0.0)); + let rot_z = glm::rotation(node.rotation.z, &glm::vec3(0.0, 0.0, 1.0)); + let rotation = rot_z * rot_y * rot_x; + let scaling = glm::scaling(&node.scale); + let refp = node.reference_point; + let to_ref = glm::translation(&refp); + let from_ref = glm::translation(&-refp); + let model = translation * to_ref * rotation * scaling * from_ref; + let new_transform = *transform_so_far * model; + // Draw this node if drawable if node.index_count > 0 { - let model_transform = view_projection * *transform_so_far; - gl::UniformMatrix4fv(transform_loc, 1, gl::FALSE, model_transform.as_ptr()); + let mvp = view_projection * new_transform; + gl::UniformMatrix4fv(transform_loc, 1, gl::FALSE, mvp.as_ptr()); gl::BindVertexArray(node.vao_id); gl::DrawElements(gl::TRIANGLES, node.index_count, gl::UNSIGNED_INT, ptr::null()); } // Recurse to children for &child in &node.children { - draw_scene(&*child, transform_loc, view_projection, transform_so_far); + draw_scene(&*child, transform_loc, view_projection, &new_transform); } } @@ -232,7 +245,10 @@ fn main() { let body_node = SceneNode::from_vao(heli_body_vao, helicopter.body.index_count); let door_node = SceneNode::from_vao(heli_door_vao, helicopter.door.index_count); let main_rotor_node = SceneNode::from_vao(heli_main_rotor_vao, helicopter.main_rotor.index_count); - let tail_rotor_node = SceneNode::from_vao(heli_tail_rotor_vao, helicopter.tail_rotor.index_count); + let mut tail_rotor_node = SceneNode::from_vao(heli_tail_rotor_vao, helicopter.tail_rotor.index_count); + // Set reference point for tail rotor (pivot around its hub) + let mut tail_rotor_pin = tail_rotor_node.as_mut(); + unsafe { tail_rotor_pin.get_unchecked_mut().reference_point = glm::vec3(0.35, 2.3, 10.4); } heli_root.add_child(&*body_node); heli_root.add_child(&*door_node);