You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
2.1 KiB
Rust
96 lines
2.1 KiB
Rust
use nalgebra_glm::{identity, vec3, Mat4, Vec3, U4};
|
|
use std::cell::{Ref, RefCell};
|
|
use std::rc::Rc;
|
|
|
|
struct Graph {
|
|
root: NodeRef,
|
|
}
|
|
|
|
impl Graph {
|
|
fn new() -> Graph {
|
|
let mut node = Node::new();
|
|
node.is_root = true;
|
|
Graph {
|
|
root: node.into_ref(),
|
|
}
|
|
}
|
|
}
|
|
|
|
type NodeRef = Rc<RefCell<Node>>;
|
|
|
|
trait NodeExt {
|
|
fn append_child(&self, child: &NodeRef);
|
|
fn remove_child(&self, child: &NodeRef);
|
|
}
|
|
|
|
struct Node {
|
|
rotation: Vec3,
|
|
transform: Mat4,
|
|
origin: Vec3,
|
|
absolute_position: Option<Mat4>,
|
|
children: Vec<NodeRef>,
|
|
parent: Option<NodeRef>,
|
|
is_root: bool,
|
|
}
|
|
|
|
impl Node {
|
|
fn new() -> Node {
|
|
Node {
|
|
rotation: vec3(0.0, 0.0, 0.0),
|
|
transform: identity::<_, U4>(),
|
|
origin: vec3(0.0, 0.0, 0.0),
|
|
absolute_position: None,
|
|
children: vec![],
|
|
parent: None,
|
|
is_root: false,
|
|
}
|
|
}
|
|
|
|
fn into_ref(self) -> NodeRef {
|
|
Rc::new(RefCell::new(self))
|
|
}
|
|
}
|
|
|
|
impl NodeExt for NodeRef {
|
|
fn append_child(&self, child: &NodeRef) {
|
|
if Rc::ptr_eq(&self, child) {
|
|
return;
|
|
}
|
|
|
|
if let Some(parent) = child.borrow().parent.clone() {
|
|
parent.remove_child(&self)
|
|
}
|
|
|
|
self.borrow_mut().children.push(child.clone())
|
|
}
|
|
|
|
fn remove_child(&self, child: &NodeRef) {
|
|
let children = &mut self.borrow_mut().children;
|
|
let mut offset: usize = 0;
|
|
for i in 0..childs.len() {
|
|
if Rc::ptr_eq(&childs[i - offset], child) {
|
|
children.remove(i - offset);
|
|
offset += 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
pub mod test {
|
|
use crate::*;
|
|
|
|
#[test]
|
|
pub fn it_works() {
|
|
let node = Node::new().into_ref();
|
|
node.append_child(&node);
|
|
node.remove_child(&node);
|
|
let second_node = Node::new().into_ref();
|
|
node.append_child(&second_node);
|
|
|
|
let graph = Graph::new();
|
|
graph.root.append_child(&node);
|
|
assert_eq!(1, graph.root.borrow().children.len());
|
|
}
|
|
}
|