impl world methods

This commit is contained in:
2025-10-02 11:51:08 +02:00
parent d4f590b177
commit cd0ba1095d
2 changed files with 87 additions and 83 deletions

View File

@@ -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<Nodes, ManuallyDrop<Pin<Box<SceneNode>>>>,
}
#[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<Nodes, Mesh>,
pub nodes: HashMap<Nodes, ManuallyDrop<Pin<Box<SceneNode>>>>,
}
pub fn load_models() -> HashMap<Nodes, Mesh> {
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<Nodes, Mesh>) -> HashMap<Nodes, ManuallyDrop<Pin<Box<SceneNode>>>> {
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<Nodes, Mesh> {
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<Nodes, Mesh>) -> HashMap<Nodes, ManuallyDrop<Pin<Box<SceneNode>>>> {
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);}
}

View File

@@ -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