use nalgebra_glm as glm; use crate::model::Model; use std::rc::Rc; use std::cell::RefCell; pub type NodeRef = Rc>; pub struct Node { pub name: String, pub gameobject: GameObject, pub children: Vec, } pub trait Childbearing { // TODO remove this fn add_child(&mut self, name: &str, child: T); } impl Node { pub fn find_node(&mut self, name: &str) -> Option { self.children .iter() .find(|node| node.borrow().name == name) .map(|node| Rc::clone(node)) } } macro_rules! impl_childbearing { ($t:ty, $e:path) => { impl Childbearing<$t> for Node { fn add_child(&mut self, name: &str, child: $t) { self.children.push(Rc::new(RefCell::new(Node::new(name.to_string(), $e(Box::new(child)))))); } } } } impl Node { pub fn new(name: String, gameobject: GameObject) -> Self { Node { name, gameobject, children: Vec::new(), } } } pub enum GameObject { Null, Camera(Box), Mesh(Box), } impl GameObject { pub fn get_transform(&self) -> Result { use GameObject::*; match self { Camera(camera) => Ok(camera.get_transform()), Mesh(mesh) => Ok(mesh.get_transform()), _ => Err("object does not implement \"get_transform\"".to_string()) } } pub fn set_transform(&mut self, transform: Transform) -> Result<(), String> { use GameObject::*; match self { Camera(camera) => { camera.set_transform(transform); Ok(()) } Mesh(mesh) => { mesh.set_transform(transform); Ok(()) } _ => Err("object does not implement \"set_transform\"".to_string()) } } } #[derive(Clone, Copy)] pub struct Transform { pub position: glm::Vec3, pub rotation: glm::Vec3, pub scale: glm::Vec3, } impl Default for Transform { fn default() -> Self { Transform { position: glm::zero(), rotation: glm::zero(), scale: glm::vec3(1.0, 1.0, 1.0), } } } pub trait Spatial { fn get_transform(&self) -> Transform; fn set_transform(&mut self, transform: Transform); } pub struct Camera { transform: Transform, } impl Camera { pub fn new() -> Self { Camera { transform: Default::default(), } } } impl Spatial for Camera { fn get_transform(&self) -> Transform { self.transform } fn set_transform(&mut self, transform: Transform) { self.transform = transform } } impl_childbearing!(Camera, GameObject::Camera); pub struct Mesh { pub model: Model, transform: Transform, } impl Mesh { pub fn new(model: Model) -> Self { Mesh { model, transform: Default::default(), } } } impl Spatial for Mesh { fn get_transform(&self) -> Transform { self.transform } fn set_transform(&mut self, transform: Transform) { self.transform = transform; } } impl_childbearing!(Mesh, GameObject::Mesh);