1use crate::{std_traits::ReflectDefault, ReflectDeserialize, ReflectSerialize};
2use assert_type_match::assert_type_match;
3use bevy_reflect_derive::{impl_reflect, impl_reflect_opaque};
4use glam::*;
5
6macro_rules! reflect_enum {
8 ($(#[$meta:meta])* enum $ident:ident { $($ty:tt)* } ) => {
9 impl_reflect!($(#[$meta])* enum $ident { $($ty)* });
10
11 #[assert_type_match($ident, test_only)]
12 #[expect(
13 clippy::upper_case_acronyms,
14 reason = "The variants used are not acronyms."
15 )]
16 enum $ident { $($ty)* }
17 };
18}
19
20impl_reflect!(
21 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
22 #[type_path = "glam"]
23 struct IVec2 {
24 x: i32,
25 y: i32,
26 }
27);
28impl_reflect!(
29 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
30 #[type_path = "glam"]
31 struct IVec3 {
32 x: i32,
33 y: i32,
34 z: i32,
35 }
36);
37impl_reflect!(
38 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
39 #[type_path = "glam"]
40 struct IVec4 {
41 x: i32,
42 y: i32,
43 z: i32,
44 w: i32,
45 }
46);
47
48impl_reflect!(
49 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
50 #[type_path = "glam"]
51 struct I8Vec2 {
52 x: i8,
53 y: i8,
54 }
55);
56
57impl_reflect!(
58 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
59 #[type_path = "glam"]
60 struct I8Vec3 {
61 x: i8,
62 y: i8,
63 z: i8,
64 }
65);
66
67impl_reflect!(
68 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
69 #[type_path = "glam"]
70 struct I8Vec4 {
71 x: i8,
72 y: i8,
73 z: i8,
74 w: i8,
75 }
76);
77
78impl_reflect!(
79 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
80 #[type_path = "glam"]
81 struct I16Vec2 {
82 x: i16,
83 y: i16,
84 }
85);
86
87impl_reflect!(
88 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
89 #[type_path = "glam"]
90 struct I16Vec3 {
91 x: i16,
92 y: i16,
93 z: i16,
94 }
95);
96
97impl_reflect!(
98 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
99 #[type_path = "glam"]
100 struct I16Vec4 {
101 x: i16,
102 y: i16,
103 z: i16,
104 w: i16,
105 }
106);
107
108impl_reflect!(
109 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
110 #[type_path = "glam"]
111 struct I64Vec2 {
112 x: i64,
113 y: i64,
114 }
115);
116
117impl_reflect!(
118 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
119 #[type_path = "glam"]
120 struct I64Vec3 {
121 x: i64,
122 y: i64,
123 z: i64,
124 }
125);
126
127impl_reflect!(
128 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
129 #[type_path = "glam"]
130 struct I64Vec4 {
131 x: i64,
132 y: i64,
133 z: i64,
134 w: i64,
135 }
136);
137
138impl_reflect!(
139 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
140 #[type_path = "glam"]
141 struct UVec2 {
142 x: u32,
143 y: u32,
144 }
145);
146impl_reflect!(
147 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
148 #[type_path = "glam"]
149 struct UVec3 {
150 x: u32,
151 y: u32,
152 z: u32,
153 }
154);
155impl_reflect!(
156 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
157 #[type_path = "glam"]
158 struct UVec4 {
159 x: u32,
160 y: u32,
161 z: u32,
162 w: u32,
163 }
164);
165
166impl_reflect!(
167 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
168 #[type_path = "glam"]
169 struct U8Vec2 {
170 x: u8,
171 y: u8,
172 }
173);
174impl_reflect!(
175 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
176 #[type_path = "glam"]
177 struct U8Vec3 {
178 x: u8,
179 y: u8,
180 z: u8,
181 }
182);
183impl_reflect!(
184 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
185 #[type_path = "glam"]
186 struct U8Vec4 {
187 x: u8,
188 y: u8,
189 z: u8,
190 w: u8,
191 }
192);
193
194impl_reflect!(
195 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
196 #[type_path = "glam"]
197 struct U16Vec2 {
198 x: u16,
199 y: u16,
200 }
201);
202impl_reflect!(
203 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
204 #[type_path = "glam"]
205 struct U16Vec3 {
206 x: u16,
207 y: u16,
208 z: u16,
209 }
210);
211impl_reflect!(
212 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
213 #[type_path = "glam"]
214 struct U16Vec4 {
215 x: u16,
216 y: u16,
217 z: u16,
218 w: u16,
219 }
220);
221
222impl_reflect!(
223 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
224 #[type_path = "glam"]
225 struct U64Vec2 {
226 x: u64,
227 y: u64,
228 }
229);
230impl_reflect!(
231 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
232 #[type_path = "glam"]
233 struct U64Vec3 {
234 x: u64,
235 y: u64,
236 z: u64,
237 }
238);
239impl_reflect!(
240 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
241 #[type_path = "glam"]
242 struct U64Vec4 {
243 x: u64,
244 y: u64,
245 z: u64,
246 w: u64,
247 }
248);
249
250impl_reflect!(
251 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
252 #[type_path = "glam"]
253 struct Vec2 {
254 x: f32,
255 y: f32,
256 }
257);
258impl_reflect!(
259 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
260 #[type_path = "glam"]
261 struct Vec3 {
262 x: f32,
263 y: f32,
264 z: f32,
265 }
266);
267impl_reflect!(
268 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
269 #[type_path = "glam"]
270 struct Vec3A {
271 x: f32,
272 y: f32,
273 z: f32,
274 }
275);
276impl_reflect!(
277 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
278 #[type_path = "glam"]
279 struct Vec4 {
280 x: f32,
281 y: f32,
282 z: f32,
283 w: f32,
284 }
285);
286
287impl_reflect!(
288 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
289 #[type_path = "glam"]
290 struct BVec2 {
291 x: bool,
292 y: bool,
293 }
294);
295impl_reflect!(
296 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
297 #[type_path = "glam"]
298 struct BVec3 {
299 x: bool,
300 y: bool,
301 z: bool,
302 }
303);
304impl_reflect!(
305 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
306 #[type_path = "glam"]
307 struct BVec4 {
308 x: bool,
309 y: bool,
310 z: bool,
311 w: bool,
312 }
313);
314
315impl_reflect!(
316 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
317 #[type_path = "glam"]
318 struct DVec2 {
319 x: f64,
320 y: f64,
321 }
322);
323impl_reflect!(
324 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
325 #[type_path = "glam"]
326 struct DVec3 {
327 x: f64,
328 y: f64,
329 z: f64,
330 }
331);
332impl_reflect!(
333 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
334 #[type_path = "glam"]
335 struct DVec4 {
336 x: f64,
337 y: f64,
338 z: f64,
339 w: f64,
340 }
341);
342
343impl_reflect!(
344 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
345 #[type_path = "glam"]
346 struct Mat2 {
347 x_axis: Vec2,
348 y_axis: Vec2,
349 }
350);
351impl_reflect!(
352 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
353 #[type_path = "glam"]
354 struct Mat3 {
355 x_axis: Vec3,
356 y_axis: Vec3,
357 z_axis: Vec3,
358 }
359);
360impl_reflect!(
361 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
362 #[type_path = "glam"]
363 struct Mat3A {
364 x_axis: Vec3A,
365 y_axis: Vec3A,
366 z_axis: Vec3A,
367 }
368);
369impl_reflect!(
370 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
371 #[type_path = "glam"]
372 struct Mat4 {
373 x_axis: Vec4,
374 y_axis: Vec4,
375 z_axis: Vec4,
376 w_axis: Vec4,
377 }
378);
379
380impl_reflect!(
381 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
382 #[type_path = "glam"]
383 struct DMat2 {
384 x_axis: DVec2,
385 y_axis: DVec2,
386 }
387);
388impl_reflect!(
389 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
390 #[type_path = "glam"]
391 struct DMat3 {
392 x_axis: DVec3,
393 y_axis: DVec3,
394 z_axis: DVec3,
395 }
396);
397impl_reflect!(
398 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
399 #[type_path = "glam"]
400 struct DMat4 {
401 x_axis: DVec4,
402 y_axis: DVec4,
403 z_axis: DVec4,
404 w_axis: DVec4,
405 }
406);
407
408impl_reflect!(
409 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
410 #[type_path = "glam"]
411 struct Affine2 {
412 matrix2: Mat2,
413 translation: Vec2,
414 }
415);
416impl_reflect!(
417 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
418 #[type_path = "glam"]
419 struct Affine3A {
420 matrix3: Mat3A,
421 translation: Vec3A,
422 }
423);
424
425impl_reflect!(
426 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
427 #[type_path = "glam"]
428 struct DAffine2 {
429 matrix2: DMat2,
430 translation: DVec2,
431 }
432);
433impl_reflect!(
434 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
435 #[type_path = "glam"]
436 struct DAffine3 {
437 matrix3: DMat3,
438 translation: DVec3,
439 }
440);
441
442impl_reflect!(
443 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
444 #[type_path = "glam"]
445 struct Quat {
446 x: f32,
447 y: f32,
448 z: f32,
449 w: f32,
450 }
451);
452impl_reflect!(
453 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
454 #[type_path = "glam"]
455 struct DQuat {
456 x: f64,
457 y: f64,
458 z: f64,
459 w: f64,
460 }
461);
462
463reflect_enum!(
464 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
465 #[type_path = "glam"]
466 enum EulerRot {
467 ZYX,
468 ZXY,
469 YXZ,
470 YZX,
471 XYZ,
472 XZY,
473 ZYZ,
474 ZXZ,
475 YXY,
476 YZY,
477 XYX,
478 XZX,
479 ZYXEx,
480 ZXYEx,
481 YXZEx,
482 YZXEx,
483 XYZEx,
484 XZYEx,
485 ZYZEx,
486 ZXZEx,
487 YXYEx,
488 YZYEx,
489 XYXEx,
490 XZXEx,
491 }
492);
493
494impl_reflect_opaque!(::glam::BVec3A(
495 Clone,
496 Debug,
497 Default,
498 Deserialize,
499 Serialize
500));
501impl_reflect_opaque!(::glam::BVec4A(
502 Clone,
503 Debug,
504 Default,
505 Deserialize,
506 Serialize
507));
508
509#[cfg(test)]
510mod tests {
511 use alloc::{format, string::String};
512 use ron::{
513 ser::{to_string_pretty, PrettyConfig},
514 Deserializer,
515 };
516 use serde::de::DeserializeSeed;
517 use static_assertions::assert_impl_all;
518
519 use crate::{
520 prelude::*,
521 serde::{ReflectDeserializer, ReflectSerializer},
522 Enum, GetTypeRegistration, TypeRegistry,
523 };
524
525 use super::*;
526
527 assert_impl_all!(EulerRot: Enum);
528
529 #[test]
530 fn euler_rot_serialization() {
531 let v = EulerRot::YXZ;
532
533 let mut registry = TypeRegistry::default();
534 registry.register::<EulerRot>();
535
536 let ser = ReflectSerializer::new(&v, ®istry);
537
538 let config = PrettyConfig::default()
539 .new_line(String::from("\n"))
540 .indentor(String::from(" "));
541 let output = to_string_pretty(&ser, config).unwrap();
542 let expected = r#"
543{
544 "glam::EulerRot": YXZ,
545}"#;
546
547 assert_eq!(expected, format!("\n{output}"));
548 }
549
550 #[test]
551 fn euler_rot_deserialization() {
552 let data = r#"
553{
554 "glam::EulerRot": XZY,
555}"#;
556
557 let mut registry = TypeRegistry::default();
558 registry.add_registration(EulerRot::get_type_registration());
559
560 let de = ReflectDeserializer::new(®istry);
561
562 let mut deserializer =
563 Deserializer::from_str(data).expect("Failed to acquire deserializer");
564
565 let dynamic_struct = de
566 .deserialize(&mut deserializer)
567 .expect("Failed to deserialize");
568
569 let mut result = EulerRot::default();
570
571 result.apply(dynamic_struct.as_partial_reflect());
572
573 assert_eq!(result, EulerRot::XZY);
574 }
575}