Skip to main content

bevy_reflect/impls/
glam.rs

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
6/// Reflects the given foreign type as an enum and asserts that the variants/fields match up.
7macro_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 Affine3 {
420        matrix3: Mat3,
421        translation: Vec3,
422    }
423);
424impl_reflect!(
425    #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
426    #[type_path = "glam"]
427    struct Affine3A {
428        matrix3: Mat3A,
429        translation: Vec3A,
430    }
431);
432
433impl_reflect!(
434    #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
435    #[type_path = "glam"]
436    struct DAffine2 {
437        matrix2: DMat2,
438        translation: DVec2,
439    }
440);
441impl_reflect!(
442    #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
443    #[type_path = "glam"]
444    struct DAffine3 {
445        matrix3: DMat3,
446        translation: DVec3,
447    }
448);
449
450impl_reflect!(
451    #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
452    #[type_path = "glam"]
453    struct Quat {
454        x: f32,
455        y: f32,
456        z: f32,
457        w: f32,
458    }
459);
460impl_reflect!(
461    #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
462    #[type_path = "glam"]
463    struct DQuat {
464        x: f64,
465        y: f64,
466        z: f64,
467        w: f64,
468    }
469);
470
471reflect_enum!(
472    #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
473    #[type_path = "glam"]
474    enum EulerRot {
475        ZYX,
476        ZXY,
477        YXZ,
478        YZX,
479        XYZ,
480        XZY,
481        ZYZ,
482        ZXZ,
483        YXY,
484        YZY,
485        XYX,
486        XZX,
487        ZYXEx,
488        ZXYEx,
489        YXZEx,
490        YZXEx,
491        XYZEx,
492        XZYEx,
493        ZYZEx,
494        ZXZEx,
495        YXYEx,
496        YZYEx,
497        XYXEx,
498        XZXEx,
499    }
500);
501
502impl_reflect_opaque!(::glam::BVec3A(
503    Clone,
504    Debug,
505    Default,
506    Deserialize,
507    Serialize
508));
509impl_reflect_opaque!(::glam::BVec4A(
510    Clone,
511    Debug,
512    Default,
513    Deserialize,
514    Serialize
515));
516
517#[cfg(test)]
518mod tests {
519    use alloc::{format, string::String};
520    use ron::{
521        ser::{to_string_pretty, PrettyConfig},
522        Deserializer,
523    };
524    use serde::de::DeserializeSeed;
525    use static_assertions::assert_impl_all;
526
527    use crate::{
528        enums::Enum,
529        prelude::*,
530        serde::{ReflectDeserializer, ReflectSerializer},
531        GetTypeRegistration, TypeRegistry,
532    };
533
534    use super::*;
535
536    assert_impl_all!(EulerRot: Enum);
537
538    #[test]
539    fn euler_rot_serialization() {
540        let v = EulerRot::YXZ;
541
542        let mut registry = TypeRegistry::default();
543        registry.register::<EulerRot>();
544
545        let ser = ReflectSerializer::new(&v, &registry);
546
547        let config = PrettyConfig::default()
548            .new_line(String::from("\n"))
549            .indentor(String::from("    "));
550        let output = to_string_pretty(&ser, config).unwrap();
551        let expected = r#"
552{
553    "glam::EulerRot": YXZ,
554}"#;
555
556        assert_eq!(expected, format!("\n{output}"));
557    }
558
559    #[test]
560    fn euler_rot_deserialization() {
561        let data = r#"
562{
563    "glam::EulerRot": XZY,
564}"#;
565
566        let mut registry = TypeRegistry::default();
567        registry.add_registration(EulerRot::get_type_registration());
568
569        let de = ReflectDeserializer::new(&registry);
570
571        let mut deserializer =
572            Deserializer::from_str(data).expect("Failed to acquire deserializer");
573
574        let dynamic_struct = de
575            .deserialize(&mut deserializer)
576            .expect("Failed to deserialize");
577
578        let mut result = EulerRot::default();
579
580        result.apply(dynamic_struct.as_partial_reflect());
581
582        assert_eq!(result, EulerRot::XZY);
583    }
584}