Better encapsulation of nodes

This commit is contained in:
Dane Johnson 2022-04-13 20:21:39 -05:00
parent 4febab44d9
commit 2084d1eddb
2 changed files with 49 additions and 32 deletions

View File

@ -8,6 +8,11 @@ pub struct Node {
pub children: Vec<Node>, pub children: Vec<Node>,
} }
pub trait Childbearing<T> {
fn add_child(&mut self, name: &str, child: T);
fn find_node(&mut self, name: &str) -> Option<&mut Box<T>>;
}
impl Node { impl Node {
pub fn new(name: String, gameobject: GameObject) -> Self { pub fn new(name: String, gameobject: GameObject) -> Self {
Node { Node {
@ -16,12 +21,6 @@ impl Node {
children: Vec::new(), children: Vec::new(),
} }
} }
pub fn add_child(&mut self, child: Node) {
self.children.push(child)
}
pub fn find_node(&mut self, name: &str) -> Option<&mut Node> {
self.children.iter_mut().find(|node| node.name == name)
}
} }
pub enum GameObject { pub enum GameObject {
@ -73,3 +72,22 @@ impl Spatial for Mesh {
self.transform = transform; self.transform = transform;
} }
} }
impl Childbearing<Mesh> for Node {
fn add_child(&mut self, name: &str, child: Mesh) {
self.children.push(Node::new(name.to_string(), GameObject::Mesh(Box::new(child))));
}
fn find_node(&mut self, name: &str) -> Option<&mut Box<Mesh>> {
match self.children.iter_mut().find(|node| node.name == name) {
Some(node) => {
if let GameObject::Mesh(mesh) = &mut node.gameobject {
Some(mesh)
} else {
None
}
},
None => None,
}
}
}

View File

@ -11,7 +11,7 @@ use model::Model;
use scripting::{ ScriptLang, Lua }; use scripting::{ ScriptLang, Lua };
use gameobject::{ Spatial, Mesh, Node, GameObject }; use gameobject::*;
fn main() { fn main() {
use glium::{glutin, Surface}; use glium::{glutin, Surface};
@ -38,7 +38,7 @@ fn main() {
rotation: glm::vec3(0.0, 15.0_f32.to_radians(), 0.0), rotation: glm::vec3(0.0, 15.0_f32.to_radians(), 0.0),
scale: glm::vec3(1.0, 1.0, 1.0), scale: glm::vec3(1.0, 1.0, 1.0),
}); });
root.add_child(Node::new("cube".to_string(), GameObject::Mesh(Box::new(cube)))); root.add_child("cube", cube);
let mut script_lang = Lua::new(); let mut script_lang = Lua::new();
script_lang.init(); script_lang.init();
@ -77,31 +77,30 @@ fn main() {
}; };
target.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0); target.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
let cube: &mut Node = root.find_node("cube").unwrap(); let cube: &mut Box<Mesh> = root.find_node("cube").unwrap();
if let GameObject::Mesh(cube) = &mut cube.gameobject { let mut transform = cube.get_transform();
let mut transform = cube.get_transform(); if device_manager.is_pressed(&device::Key::W) {
if device_manager.is_pressed(&device::Key::W) { transform.position.z += 1.0 * delta;
transform.position.z += 1.0 * delta; } else if device_manager.is_pressed(&device::Key::S) {
} else if device_manager.is_pressed(&device::Key::S) { transform.position.z -= 1.0 * delta;
transform.position.z -= 1.0 * delta;
}
if device_manager.is_pressed(&device::Key::A) {
transform.rotation.x += 1.0 * delta;
} else if device_manager.is_pressed(&device::Key::D) {
transform.rotation.x -= 1.0 * delta;
}
cube.set_transform(transform);
let mvp = glm::perspective::<f32>(4.0/3.0, 45.0_f32.to_radians(), 0.2, 100.0);
let mvp = glm::translate::<f32>(&mvp, &cube.get_transform().position);
let mvp = glm::rotate_x(&mvp, cube.get_transform().rotation.x);
let uniforms = uniform! {
MVP: *mvp.as_ref(),
};
cube.model.draw(&mut target, &program, &uniforms, &params);
} }
if device_manager.is_pressed(&device::Key::A) {
transform.rotation.x += 1.0 * delta;
} else if device_manager.is_pressed(&device::Key::D) {
transform.rotation.x -= 1.0 * delta;
}
cube.set_transform(transform);
let mvp = glm::perspective::<f32>(4.0/3.0, 45.0_f32.to_radians(), 0.2, 100.0);
let mvp = glm::translate::<f32>(&mvp, &cube.get_transform().position);
let mvp = glm::rotate_x(&mvp, cube.get_transform().rotation.x);
let uniforms = uniform! {
MVP: *mvp.as_ref(),
};
cube.model.draw(&mut target, &program, &uniforms, &params);
target.finish().unwrap(); target.finish().unwrap();
} }
_ => (), _ => (),