145 lines
2.8 KiB
Rust
145 lines
2.8 KiB
Rust
use nalgebra_glm as glm;
|
|
|
|
use crate::model::Model;
|
|
|
|
use std::rc::Rc;
|
|
use std::cell::RefCell;
|
|
|
|
pub type NodeRef = Rc<RefCell<Node>>;
|
|
|
|
pub struct Node {
|
|
pub name: String,
|
|
pub gameobject: GameObject,
|
|
pub children: Vec<NodeRef>,
|
|
}
|
|
|
|
pub trait Childbearing<T> { // TODO remove this
|
|
fn add_child(&mut self, name: &str, child: T);
|
|
}
|
|
|
|
impl Node {
|
|
pub fn find_node(&mut self, name: &str) -> Option<NodeRef> {
|
|
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<Camera>),
|
|
Mesh(Box<Mesh>),
|
|
}
|
|
|
|
impl GameObject {
|
|
pub fn get_transform(&self) -> Result<Transform, String> {
|
|
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);
|