prime_forge/
forged_trait.rs1use 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}