1use std::{fmt, ops};
4
5use glib::translate::*;
6
7use crate::{ffi, Euler, Matrix, Quaternion, Vec3, Vec4};
8
9impl Quaternion {
10    #[doc(alias = "graphene_quaternion_init")]
24    pub fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
25        assert_initialized_main_thread!();
26        unsafe {
27            let mut quat = Self::uninitialized();
28            ffi::graphene_quaternion_init(quat.to_glib_none_mut().0, x, y, z, w);
29            quat
30        }
31    }
32
33    #[doc(alias = "graphene_quaternion_init_from_angle_vec3")]
44    #[doc(alias = "init_from_angle_vec3")]
45    pub fn from_angle_vec3(angle: f32, axis: &Vec3) -> Self {
46        assert_initialized_main_thread!();
47        unsafe {
48            let mut quat = Self::uninitialized();
49            ffi::graphene_quaternion_init_from_angle_vec3(
50                quat.to_glib_none_mut().0,
51                angle,
52                axis.to_glib_none().0,
53            );
54            quat
55        }
56    }
57
58    #[doc(alias = "graphene_quaternion_init_from_angles")]
74    #[doc(alias = "init_from_angles")]
75    pub fn from_angles(deg_x: f32, deg_y: f32, deg_z: f32) -> Self {
76        assert_initialized_main_thread!();
77        unsafe {
78            let mut quat = Self::uninitialized();
79            ffi::graphene_quaternion_init_from_angles(
80                quat.to_glib_none_mut().0,
81                deg_x,
82                deg_y,
83                deg_z,
84            );
85            quat
86        }
87    }
88
89    #[doc(alias = "graphene_quaternion_init_from_euler")]
97    #[doc(alias = "init_from_euler")]
98    pub fn from_euler(e: &Euler) -> Self {
99        assert_initialized_main_thread!();
100        unsafe {
101            let mut quat = Self::uninitialized();
102            ffi::graphene_quaternion_init_from_euler(quat.to_glib_none_mut().0, e.to_glib_none().0);
103            quat
104        }
105    }
106
107    #[doc(alias = "graphene_quaternion_init_from_matrix")]
116    #[doc(alias = "init_from_matrix")]
117    pub fn from_matrix(m: &Matrix) -> Self {
118        assert_initialized_main_thread!();
119        unsafe {
120            let mut quat = Self::uninitialized();
121            ffi::graphene_quaternion_init_from_matrix(
122                quat.to_glib_none_mut().0,
123                m.to_glib_none().0,
124            );
125            quat
126        }
127    }
128
129    #[doc(alias = "graphene_quaternion_init_from_radians")]
145    #[doc(alias = "init_from_radians")]
146    pub fn from_radians(rad_x: f32, rad_y: f32, rad_z: f32) -> Self {
147        assert_initialized_main_thread!();
148        unsafe {
149            let mut quat = Self::uninitialized();
150            ffi::graphene_quaternion_init_from_radians(
151                quat.to_glib_none_mut().0,
152                rad_x,
153                rad_y,
154                rad_z,
155            );
156            quat
157        }
158    }
159
160    #[doc(alias = "graphene_quaternion_init_from_vec4")]
168    #[doc(alias = "init_from_vec4")]
169    pub fn from_vec4(src: &Vec4) -> Self {
170        assert_initialized_main_thread!();
171        unsafe {
172            let mut quat = Self::uninitialized();
173            ffi::graphene_quaternion_init_from_vec4(
174                quat.to_glib_none_mut().0,
175                src.to_glib_none().0,
176            );
177            quat
178        }
179    }
180
181    #[doc(alias = "graphene_quaternion_init_identity")]
188    #[doc(alias = "init_identity")]
189    pub fn new_identity() -> Self {
190        assert_initialized_main_thread!();
191        unsafe {
192            let mut quat = Self::uninitialized();
193            ffi::graphene_quaternion_init_identity(quat.to_glib_none_mut().0);
194            quat
195        }
196    }
197
198    #[inline]
199    pub fn x(&self) -> f32 {
200        self.inner.x
201    }
202
203    #[inline]
204    pub fn y(&self) -> f32 {
205        self.inner.y
206    }
207
208    #[inline]
209    pub fn z(&self) -> f32 {
210        self.inner.z
211    }
212
213    #[inline]
214    pub fn w(&self) -> f32 {
215        self.inner.w
216    }
217}
218
219impl fmt::Debug for Quaternion {
220    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
221        f.debug_struct("Quaternion")
222            .field("x", &self.x())
223            .field("y", &self.y())
224            .field("z", &self.z())
225            .field("w", &self.w())
226            .finish()
227    }
228}
229
230impl ops::Add<Quaternion> for Quaternion {
231    type Output = Quaternion;
232
233    fn add(self, rhs: Quaternion) -> Self::Output {
234        Quaternion::add(&self, &rhs)
235    }
236}
237
238impl ops::AddAssign<Quaternion> for Quaternion {
239    fn add_assign(&mut self, rhs: Quaternion) {
240        *self = *self + rhs;
241    }
242}
243
244impl ops::Mul<Quaternion> for Quaternion {
245    type Output = Quaternion;
246
247    fn mul(self, rhs: Quaternion) -> Self::Output {
248        Quaternion::multiply(&self, &rhs)
249    }
250}
251
252impl ops::MulAssign<Quaternion> for Quaternion {
253    fn mul_assign(&mut self, rhs: Quaternion) {
254        *self = *self * rhs;
255    }
256}