prime_forge/
forged_trait.rs

1use std::{
2    cell::RefCell,
3    rc::{Rc, Weak},
4};
5
6use crate::lost_realm::LostRealm;
7
8use super::EtherealFlow;
9
10use nalgebra_glm as glm;
11
12pub trait ForgedTrait: ForgedHierarchy {
13    #[allow(unused_variables)]
14    fn start(&mut self, lost_realm: &mut LostRealm) {}
15    #[allow(unused_variables)]
16    fn update(&mut self, lost_realm: &mut LostRealm, dt: f32) {}
17}
18
19pub trait ForgedHierarchy: EtherealFlow {
20    fn set_father(&mut self, father_id: String);
21    fn get_father(&self) -> Option<String>;
22}
23
24pub struct TransformSpecialTrait {
25    pub position: glm::Vec3,
26    pub rotation: glm::Vec3,
27    pub scale: glm::Vec3,
28    id: uuid::Uuid,
29    parent: Option<Weak<RefCell<TransformSpecialTrait>>>,
30    children: Vec<Rc<RefCell<TransformSpecialTrait>>>,
31    pub model_matrix: glm::Mat4,
32}
33
34impl Default for TransformSpecialTrait {
35    fn default() -> Self {
36        Self {
37            position: glm::vec3(0.0, 0.0, 0.0),
38            rotation: glm::vec3(0.0, 0.0, 0.0),
39            scale: glm::vec3(1.0, 1.0, 1.0),
40            children: Vec::new(),
41            parent: None,
42            model_matrix: glm::Mat4::identity(),
43            id: uuid::Uuid::new_v4(),
44        }
45    }
46}
47
48impl TransformSpecialTrait {
49    pub fn new() -> Self {
50        Self {
51            ..Default::default()
52        }
53    }
54
55    pub fn with_position(mut self, position: glm::Vec3) -> Self {
56        self.position = position;
57        self.update_self_and_children();
58        self
59    }
60
61    pub fn with_rotation(mut self, rotation: glm::Vec3) -> Self {
62        self.rotation = rotation;
63        self.update_self_and_children();
64        self
65    }
66
67    pub fn with_scale(mut self, scale: glm::Vec3) -> Self {
68        self.scale = scale;
69        self.update_self_and_children();
70        self
71    }
72
73    pub(crate) fn set_parent(&mut self, parent: Rc<RefCell<TransformSpecialTrait>>) {
74        if let Some(parent) = self.get_parent() {
75            parent
76                .borrow_mut()
77                .children
78                .retain(|child| child.borrow().id != self.id);
79        }
80        self.parent = Some(Rc::downgrade(&parent));
81    }
82
83    pub(crate) fn set_children(&mut self, children: Vec<Rc<RefCell<TransformSpecialTrait>>>) {
84        if children.len() > 0 {
85            self.children.extend(children.iter().cloned());
86        } else {
87            self.children = children;
88        }
89    }
90
91    pub fn get_parent(&self) -> Option<Rc<RefCell<TransformSpecialTrait>>> {
92        self.parent.as_ref().and_then(|parent| parent.upgrade())
93    }
94
95    pub fn get_children(&self) -> Vec<Rc<RefCell<TransformSpecialTrait>>> {
96        self.children.clone()
97    }
98
99    pub fn get_local_model_matrix(&self) -> glm::Mat4 {
100        let transform_x = glm::rotate(
101            &glm::Mat4::identity(),
102            self.rotation.x.to_radians(),
103            &glm::vec3(1.0, 0.0, 0.0),
104        );
105
106        let transform_y = glm::rotate(
107            &glm::Mat4::identity(),
108            self.rotation.y.to_radians(),
109            &glm::vec3(0.0, 1.0, 0.0),
110        );
111
112        let transform_z = glm::rotate(
113            &glm::Mat4::identity(),
114            self.rotation.z.to_radians(),
115            &glm::vec3(0.0, 0.0, 1.0),
116        );
117
118        let rotation = transform_x * transform_y * transform_z;
119
120        let model = glm::Mat4::identity();
121        let model = glm::translate(&model, &self.position);
122        let model = model * rotation;
123        let model = glm::scale(&model, &self.scale);
124
125        model
126    }
127
128    pub fn update_self_and_children(&mut self) {
129        self.model_matrix = if let Some(parent) = self.get_parent() {
130            let parent = unsafe {
131                let ptr = parent.as_ptr() as *const TransformSpecialTrait;
132                &*ptr
133            };
134            parent.model_matrix * self.get_local_model_matrix()
135        } else {
136            self.get_local_model_matrix()
137        };
138
139        println!("Model Matrix: {:?}", self.model_matrix);
140
141        for child in self.children.iter() {
142            child.borrow_mut().update_self_and_children();
143        }
144    }
145}