havok_types/math/
qs_transform.rs

1use crate::{Quaternion, Vector4};
2use parse_display::Display;
3
4/// # QsTransform
5///
6/// # C++ Info
7/// - name: `hkQsTransform`
8/// - type_size: ` 48`(x86)/` 48`(x86_64)
9/// - align: ` 16`(x86)/` 16`(x86_64)
10///
11/// # XML representation
12/// - [`Vector4::w`] (4th) of `transition` & `scale` isn't used.
13/// ```xml
14/// <!--  transition: Vector4 --><!--     rotation: Quaternion      --><!--   scale: Vector4    -->
15/// (0.000000 0.000000 0.000000)(-0.000000 0.000000 -0.000000 1.000000)(1.000000 1.000000 1.000000)
16/// ```
17///
18/// [`Vector4::w`](Vector4)
19#[repr(C, align(16))]
20#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22#[derive(Debug, Clone, Default, PartialEq, PartialOrd, Display)]
23#[display("{transition}{quaternion}{scale}")]
24pub struct QsTransform {
25    /// # C++ Info
26    /// - name: `transition`(ctype: `hkVector4`)
27    /// - offset: `  0`(x86)/`  0`(x86_64)
28    /// - type_size: ` 16`(x86)/` 16`(x86_64)
29    ///
30    /// # NOTE
31    /// - `Vector4::w`(4th) isn't used(always 0.0).
32    #[display("({x:.06} {y:.06} {z:.06})")]
33    pub transition: Vector4,
34    /// # C++ Info
35    /// - name: `quaternion`(ctype: `hkQuaternion`)
36    /// - offset: ` 16`(x86)/` 16`(x86_64)
37    /// - type_size: ` 16`(x86)/` 16`(x86_64)
38    pub quaternion: Quaternion,
39    /// # C++ Info
40    /// - name: `scale`(ctype: `hkVector4`)
41    /// - offset: ` 32`(x86)/` 32`(x86_64)
42    /// - type_size: ` 16`(x86)/` 16`(x86_64)
43    /// - `scale`: `Vector4`
44    ///
45    /// # NOTE
46    /// - `Vector4::w`(4th) isn't used(always 0.0).
47    #[display("({x:.06} {y:.06} {z:.06})")]
48    pub scale: Vector4,
49}
50
51impl QsTransform {
52    /// Creates a new `QsTransform`
53    #[inline]
54    pub const fn new(transition: Vector4, quaternion: Quaternion, scale: Vector4) -> Self {
55        Self {
56            transition,
57            quaternion,
58            scale,
59        }
60    }
61
62    pub fn to_le_bytes(&self) -> [u8; 48] {
63        let mut bytes = [0; 48];
64        bytes[0..16].copy_from_slice(&self.transition.to_le_bytes());
65        bytes[16..32].copy_from_slice(&self.quaternion.to_le_bytes());
66        bytes[32..48].copy_from_slice(&self.scale.to_le_bytes());
67        bytes
68    }
69
70    pub fn to_be_bytes(&self) -> [u8; 48] {
71        let mut bytes = [0; 48];
72        bytes[0..16].copy_from_slice(&self.transition.to_le_bytes());
73        bytes[16..32].copy_from_slice(&self.quaternion.to_le_bytes());
74        bytes[32..48].copy_from_slice(&self.scale.to_le_bytes());
75        bytes
76    }
77}
78
79#[test]
80fn should_write_bytes() {
81    assert_eq!(
82        QsTransform {
83            transition: Vector4::default(),
84            quaternion: Quaternion {
85                x: 0.0,
86                y: -0.0,
87                z: -0.0,
88                scaler: -1.0
89            },
90            scale: Vector4 {
91                x: 1.0,
92                y: 1.0,
93                z: 1.0,
94                w: 0.0
95            }
96        }
97        .to_le_bytes(),
98        [
99            0, 0, 0, 0, //
100            0, 0, 0, 0, //
101            0, 0, 0, 0, //
102            0, 0, 0, 0, //
103            //
104            0, 0, 0, 0, //
105            0, 0, 0, 128, //
106            0, 0, 0, 128, //
107            0, 0, 128, 191, //
108            //
109            0, 0, 128, 63, //
110            0, 0, 128, 63, //
111            0, 0, 128, 63, //
112            0, 0, 0, 0, //
113        ]
114    );
115}