1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use super::Transform3D;

use crate::datatypes::{
    Rotation3D, RotationAxisAngle, TranslationAndMat3x3, TranslationRotationScale3D, Vec3D,
};

impl Transform3D {
    pub const IDENTITY: Self = Self::TranslationRotationScale(TranslationRotationScale3D::IDENTITY);

    #[inline]
    #[allow(clippy::wrong_self_convention)]
    pub fn from_parent(&self) -> bool {
        match self {
            Self::TranslationAndMat3X3(t) => t.from_parent,
            Self::TranslationRotationScale(t) => t.from_parent,
        }
    }
}

impl Default for Transform3D {
    #[inline]
    fn default() -> Self {
        Self::IDENTITY
    }
}

impl From<TranslationAndMat3x3> for Transform3D {
    #[inline]
    fn from(v: TranslationAndMat3x3) -> Self {
        Self::TranslationAndMat3X3(v)
    }
}

impl From<TranslationRotationScale3D> for Transform3D {
    #[inline]
    fn from(v: TranslationRotationScale3D) -> Self {
        Self::TranslationRotationScale(v)
    }
}

impl From<Vec3D> for Transform3D {
    #[inline]
    fn from(v: Vec3D) -> Self {
        Self::TranslationRotationScale(v.into())
    }
}

#[cfg(feature = "glam")]
impl From<glam::Vec3> for Transform3D {
    #[inline]
    fn from(v: glam::Vec3) -> Self {
        Self::TranslationRotationScale(v.into())
    }
}

impl From<RotationAxisAngle> for Transform3D {
    #[inline]
    fn from(v: RotationAxisAngle) -> Self {
        let rotation = Rotation3D::from(v);
        Self::TranslationRotationScale(rotation.into())
    }
}

#[cfg(feature = "glam")]
impl From<Transform3D> for glam::Affine3A {
    fn from(value: Transform3D) -> Self {
        match value {
            Transform3D::TranslationAndMat3X3(TranslationAndMat3x3 {
                translation,
                matrix,
                from_parent: _,
            }) => glam::Affine3A::from_mat3_translation(
                matrix.unwrap_or_default().into(),
                translation.map_or(glam::Vec3::ZERO, |v| v.into()),
            ),

            Transform3D::TranslationRotationScale(TranslationRotationScale3D {
                translation,
                rotation,
                scale,
                from_parent: _,
            }) => glam::Affine3A::from_scale_rotation_translation(
                scale.map_or(glam::Vec3::ONE, |s| s.into()),
                rotation.map_or(glam::Quat::IDENTITY, |q| q.into()),
                translation.map_or(glam::Vec3::ZERO, |v| v.into()),
            ),
        }
    }
}