use crate::scene::base::PhysicsBinding;
use crate::{
core::{
algebra::{Matrix4, Vector2},
pool::Handle,
visitor::prelude::*,
},
scene2d::{graph::Graph, node::Node, transform::Transform},
};
use std::cell::Cell;
#[derive(Visit)]
pub struct Base {
transform: Transform,
pub(in crate) global_transform: Cell<Matrix4<f32>>,
pub(in crate) visibility: bool,
pub(in crate) global_visibility: Cell<bool>,
pub(in crate) parent: Handle<Node>,
pub(in crate) children: Vec<Handle<Node>>,
pub(in crate) physics_binding: PhysicsBinding,
name: String,
}
impl Default for Base {
fn default() -> Self {
Self {
transform: Default::default(),
global_transform: Cell::new(Matrix4::identity()),
visibility: true,
global_visibility: Cell::new(true),
parent: Default::default(),
children: Default::default(),
physics_binding: Default::default(),
name: Default::default(),
}
}
}
impl Base {
pub fn set_name<S: AsRef<str>>(&mut self, name: S) {
self.name = name.as_ref().to_owned();
}
pub fn name(&self) -> &str {
&self.name
}
pub fn parent(&self) -> Handle<Node> {
self.parent
}
pub fn global_visibility(&self) -> bool {
self.global_visibility.get()
}
pub fn visibility(&self) -> bool {
self.visibility
}
pub fn global_position(&self) -> Vector2<f32> {
let m = self.global_transform.get();
Vector2::new(m[12], m[13])
}
pub fn up(&self) -> Vector2<f32> {
let m = self.global_transform.get();
Vector2::new(m[4], m[5])
}
pub fn right(&self) -> Vector2<f32> {
let m = self.global_transform.get();
Vector2::new(m[0], m[1])
}
pub fn children(&self) -> &[Handle<Node>] {
&self.children
}
pub fn local_transform(&self) -> &Transform {
&self.transform
}
pub fn local_transform_mut(&mut self) -> &mut Transform {
&mut self.transform
}
pub fn global_transform(&self) -> Matrix4<f32> {
self.global_transform.get()
}
pub fn set_physics_binding(&mut self, binding: PhysicsBinding) {
self.physics_binding = binding;
}
pub fn physics_binding(&self) -> PhysicsBinding {
self.physics_binding
}
pub fn raw_copy(&self) -> Self {
Self {
transform: self.transform.clone(),
global_transform: self.global_transform.clone(),
visibility: self.visibility,
global_visibility: self.global_visibility.clone(),
physics_binding: self.physics_binding,
name: self.name.clone(),
parent: Default::default(),
children: Default::default(),
}
}
}
pub struct BaseBuilder {
transform: Transform,
children: Vec<Handle<Node>>,
name: String,
visibility: bool,
physics_binding: PhysicsBinding,
}
impl Default for BaseBuilder {
fn default() -> Self {
Self::new()
}
}
impl BaseBuilder {
pub fn new() -> Self {
Self {
transform: Default::default(),
children: Default::default(),
name: "Base".to_string(),
visibility: true,
physics_binding: Default::default(),
}
}
pub fn with_local_transform(mut self, transform: Transform) -> Self {
self.transform = transform;
self
}
pub fn with_children<'a, I: IntoIterator<Item = &'a Handle<Node>>>(
mut self,
children: I,
) -> Self {
for &child in children.into_iter() {
if child.is_some() {
self.children.push(child)
}
}
self
}
pub fn with_name<N: AsRef<str>>(mut self, name: N) -> Self {
self.name = name.as_ref().to_owned();
self
}
pub fn with_visibility(mut self, visibility: bool) -> Self {
self.visibility = visibility;
self
}
pub fn with_physics_binding(mut self, binding: PhysicsBinding) -> Self {
self.physics_binding = binding;
self
}
pub fn build_base(self) -> Base {
Base {
transform: self.transform,
global_transform: Cell::new(Matrix4::identity()),
visibility: self.visibility,
global_visibility: Cell::new(false),
parent: Default::default(),
children: self.children,
name: self.name,
physics_binding: self.physics_binding,
}
}
pub fn build(self, graph: &mut Graph) -> Handle<Node> {
graph.add_node(Node::Base(self.build_base()))
}
}