havok_types/math/
quaternion.rs

1use parse_display::Display;
2
3/// # Quaternion
4///
5/// # C++ Info
6/// - name: `hkQuaternion`
7/// - type_size: ` 16`(x86)/` 16`(x86_64)
8///
9/// # XML representation
10/// ```xml
11/// <hkparam>(0.000000 0.000000 0.000000 1.000000)</hkparam>
12/// ```
13#[repr(C, align(16))]
14#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16#[derive(Debug, Clone, Default, PartialEq, PartialOrd, Display)]
17#[display("({x:.06} {y:.06} {z:.06} {scaler:.06})")]
18pub struct Quaternion {
19    /// # C++ Info
20    /// - name: `x`(ctype: `hkReal`)
21    /// - offset: `  0`(x86)/`  0`(x86_64)
22    /// - type_size: ` 4`(x86)/` 4`(x86_64)
23    pub x: f32,
24    /// # C++ Info
25    /// - name: `y`(ctype: `hkReal`)
26    /// - offset: `  4`(x86)/`  4`(x86_64)
27    /// - type_size: ` 4`(x86)/` 4`(x86_64)
28    pub y: f32,
29    /// # C++ Info
30    /// - name: `z`(ctype: `hkReal`)
31    /// - offset: `  8`(x86)/`  8`(x86_64)
32    /// - type_size: ` 4`(x86)/` 4`(x86_64)
33    pub z: f32,
34    /// # C++ Info
35    /// - name: `scaler`(ctype: `hkReal`)
36    /// - offset: ` 12`(x86)/` 12`(x86_64)
37    /// - type_size: ` 4`(x86)/` 4`(x86_64)
38    pub scaler: f32,
39}
40
41static_assertions::assert_eq_size!(Quaternion, [u8; 16]);
42
43impl Quaternion {
44    /// Creates a new `Quaternion`
45    pub const fn new(x: f32, y: f32, z: f32, scaler: f32) -> Self {
46        Self { x, y, z, scaler }
47    }
48
49    #[inline]
50    pub fn to_le_bytes(&self) -> [u8; 16] {
51        let mut bytes = [0; 16];
52        bytes[0..4].copy_from_slice(&self.x.to_le_bytes());
53        bytes[4..8].copy_from_slice(&self.y.to_le_bytes());
54        bytes[8..12].copy_from_slice(&self.z.to_le_bytes());
55        bytes[12..16].copy_from_slice(&self.scaler.to_le_bytes());
56        bytes
57    }
58
59    #[inline]
60    pub fn to_be_bytes(&self) -> [u8; 16] {
61        let mut bytes = [0; 16];
62        bytes[0..4].copy_from_slice(&self.x.to_be_bytes());
63        bytes[4..8].copy_from_slice(&self.y.to_be_bytes());
64        bytes[8..12].copy_from_slice(&self.z.to_be_bytes());
65        bytes[12..16].copy_from_slice(&self.scaler.to_be_bytes());
66        bytes
67    }
68
69    /// Create a [`Quaternion`] value from its representation as a byte array in little endian.
70    #[inline]
71    pub const fn from_le_bytes(bytes: &[u8; 16]) -> Self {
72        Self {
73            x: f32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]),
74            y: f32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]),
75            z: f32::from_le_bytes([bytes[8], bytes[9], bytes[10], bytes[11]]),
76            scaler: f32::from_le_bytes([bytes[12], bytes[13], bytes[14], bytes[15]]),
77        }
78    }
79
80    /// Create a [`Quaternion`] value from its representation as a byte array in big endian.
81    #[inline]
82    pub const fn from_be_bytes(bytes: &[u8; 16]) -> Self {
83        Self {
84            x: f32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]),
85            y: f32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]),
86            z: f32::from_be_bytes([bytes[8], bytes[9], bytes[10], bytes[11]]),
87            scaler: f32::from_be_bytes([bytes[12], bytes[13], bytes[14], bytes[15]]),
88        }
89    }
90}