1use galeon_engine_macros::Component;
4
5use crate::entity::Entity;
6
7#[derive(Component, Debug, Clone, Copy, PartialEq)]
11pub struct Transform {
12 pub position: [f32; 3],
13 pub rotation: [f32; 4],
14 pub scale: [f32; 3],
15}
16
17impl Transform {
18 pub fn identity() -> Self {
20 Self {
21 position: [0.0, 0.0, 0.0],
22 rotation: [0.0, 0.0, 0.0, 1.0],
23 scale: [1.0, 1.0, 1.0],
24 }
25 }
26
27 pub fn from_position(x: f32, y: f32, z: f32) -> Self {
29 Self {
30 position: [x, y, z],
31 ..Self::identity()
32 }
33 }
34}
35
36impl Default for Transform {
37 fn default() -> Self {
38 Self::identity()
39 }
40}
41
42#[derive(Component, Debug, Clone, Copy, PartialEq, Eq)]
44pub struct Visibility {
45 pub visible: bool,
46}
47
48impl Default for Visibility {
49 fn default() -> Self {
50 Self { visible: true }
51 }
52}
53
54#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Hash)]
56pub struct MeshHandle {
57 pub id: u32,
58}
59
60#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Hash)]
62pub struct MaterialHandle {
63 pub id: u32,
64}
65
66#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Hash)]
76pub struct InstanceOf(pub MeshHandle);
77
78#[derive(Component, Debug, Clone, Copy, PartialEq)]
88pub struct Tint(pub [f32; 3]);
89
90#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Hash)]
98pub struct ParentEntity(pub Entity);
99
100#[derive(Component, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
105#[repr(u8)]
106pub enum ObjectType {
107 #[default]
109 Mesh = 0,
110 PointLight = 1,
112 DirectionalLight = 2,
114 LineSegments = 3,
116 Group = 4,
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 fn transform_identity() {
126 let t = Transform::identity();
127 assert_eq!(t.position, [0.0, 0.0, 0.0]);
128 assert_eq!(t.rotation, [0.0, 0.0, 0.0, 1.0]);
129 assert_eq!(t.scale, [1.0, 1.0, 1.0]);
130 }
131
132 #[test]
133 fn transform_from_position() {
134 let t = Transform::from_position(1.0, 2.0, 3.0);
135 assert_eq!(t.position, [1.0, 2.0, 3.0]);
136 assert_eq!(t.scale, [1.0, 1.0, 1.0]);
137 }
138
139 #[test]
140 fn visibility_default_is_visible() {
141 assert!(Visibility::default().visible);
142 }
143
144 #[test]
145 fn parent_entity_stores_entity() {
146 let entity = crate::entity::Entity::from_raw(42, 0);
147 let parent = ParentEntity(entity);
148 assert_eq!(parent.0, entity);
149 }
150
151 #[test]
152 fn object_type_default_is_mesh() {
153 assert_eq!(ObjectType::default(), ObjectType::Mesh);
154 }
155
156 #[test]
157 fn instance_of_wraps_mesh_handle() {
158 let handle = MeshHandle { id: 42 };
159 let tag = InstanceOf(handle);
160 assert_eq!(tag.0, handle);
161 assert_eq!(tag.0.id, 42);
162 }
163
164 #[test]
165 fn instance_of_equality_is_by_mesh_handle() {
166 assert_eq!(
167 InstanceOf(MeshHandle { id: 7 }),
168 InstanceOf(MeshHandle { id: 7 })
169 );
170 assert_ne!(
171 InstanceOf(MeshHandle { id: 7 }),
172 InstanceOf(MeshHandle { id: 8 })
173 );
174 }
175
176 #[test]
177 fn tint_stores_rgb_triple() {
178 let t = Tint([0.25, 0.5, 1.0]);
179 assert_eq!(t.0[0], 0.25);
180 assert_eq!(t.0[1], 0.5);
181 assert_eq!(t.0[2], 1.0);
182 }
183
184 #[test]
185 fn tint_equality() {
186 assert_eq!(Tint([1.0, 0.0, 0.0]), Tint([1.0, 0.0, 0.0]));
187 assert_ne!(Tint([1.0, 0.0, 0.0]), Tint([0.0, 1.0, 0.0]));
188 }
189
190 #[test]
191 fn object_type_as_u8() {
192 assert_eq!(ObjectType::Mesh as u8, 0);
193 assert_eq!(ObjectType::PointLight as u8, 1);
194 assert_eq!(ObjectType::DirectionalLight as u8, 2);
195 assert_eq!(ObjectType::LineSegments as u8, 3);
196 assert_eq!(ObjectType::Group as u8, 4);
197 }
198}