diff --git a/crates/bevy_reflect/src/impls/glam.rs b/crates/bevy_reflect/src/impls/glam.rs index 9a20b098cea5a7..64b3a1ea5220a8 100644 --- a/crates/bevy_reflect/src/impls/glam.rs +++ b/crates/bevy_reflect/src/impls/glam.rs @@ -1,6 +1,5 @@ use crate as bevy_reflect; use crate::prelude::ReflectDefault; -use crate::{ReflectDeserialize, ReflectSerialize}; use bevy_reflect_derive::{impl_reflect_struct, impl_reflect_value}; use glam::*; @@ -310,24 +309,26 @@ impl_reflect_struct!( } ); -// Quat fields are read-only (as of now), and reflection is currently missing -// mechanisms for read-only fields. I doubt those mechanisms would be added, -// so for now quaternions will remain as values. They are represented identically -// to Vec4 and DVec4, so you may use those instead and convert between. -impl_reflect_value!(::glam::Quat( - Debug, - PartialEq, - Serialize, - Deserialize, - Default -)); -impl_reflect_value!(::glam::DQuat( - Debug, - PartialEq, - Serialize, - Deserialize, - Default -)); +impl_reflect_struct!( + #[reflect(Debug, PartialEq, Default)] + #[type_path = "glam"] + struct Quat { + x: f32, + y: f32, + z: f32, + w: f32, + } +); +impl_reflect_struct!( + #[reflect(Debug, PartialEq, Default)] + #[type_path = "glam"] + struct DQuat { + x: f64, + y: f64, + z: f64, + w: f64, + } +); impl_reflect_value!(::glam::EulerRot(Debug, Default)); impl_reflect_value!(::glam::BVec3A(Debug, Default)); diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 53304fb65b4285..b01adece410bb5 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -575,7 +575,7 @@ pub mod __macro_exports { #[allow(clippy::disallowed_types, clippy::approx_constant)] mod tests { #[cfg(feature = "glam")] - use ::glam::{vec3, Vec3}; + use ::glam::{quat, vec3, Quat, Vec3}; use ::serde::{de::DeserializeSeed, Deserialize, Serialize}; use bevy_utils::HashMap; use ron::{ @@ -1937,6 +1937,65 @@ bevy_reflect::tests::Test { mod glam { use super::*; + #[test] + fn quat_serialization() { + let q = quat(1.0, 2.0, 3.0, 4.0); + + let mut registry = TypeRegistry::default(); + registry.register::(); + registry.register::(); + + let ser = ReflectSerializer::new(&q, ®istry); + + let config = PrettyConfig::default() + .new_line(String::from("\n")) + .indentor(String::from(" ")); + let output = to_string_pretty(&ser, config).unwrap(); + let expected = r#" +{ + "glam::Quat": ( + x: 1.0, + y: 2.0, + z: 3.0, + w: 4.0, + ), +}"#; + + assert_eq!(expected, format!("\n{output}")); + } + + #[test] + fn quat_deserialization() { + let data = r#" +{ + "glam::Quat": ( + x: 1.0, + y: 2.0, + z: 3.0, + w: 4.0, + ), +}"#; + + let mut registry = TypeRegistry::default(); + registry.register::(); + registry.register::(); + + let de = UntypedReflectDeserializer::new(®istry); + + let mut deserializer = + ron::de::Deserializer::from_str(data).expect("Failed to acquire deserializer"); + + let dynamic_struct = de + .deserialize(&mut deserializer) + .expect("Failed to deserialize"); + + let mut result = Quat::default(); + + result.apply(&*dynamic_struct); + + assert_eq!(result, quat(1.0, 2.0, 3.0, 4.0)); + } + #[test] fn vec3_serialization() { let v = vec3(12.0, 3.0, -6.9);