1
+ use std:: ops:: Mul ;
2
+
1
3
use crate :: core_types:: { Basis , Vector3 } ;
2
4
3
5
/// 3D Transformation (3x4 matrix) Using basis + origin representation.
@@ -13,6 +15,13 @@ pub struct Transform {
13
15
pub origin : Vector3 ,
14
16
}
15
17
18
+ impl Default for Transform {
19
+ #[ inline]
20
+ fn default ( ) -> Self {
21
+ Self :: IDENTITY
22
+ }
23
+ }
24
+
16
25
impl Transform {
17
26
#[ doc( hidden) ]
18
27
#[ inline]
@@ -28,11 +37,102 @@ impl Transform {
28
37
unsafe { std:: mem:: transmute :: < sys:: godot_transform , Self > ( c) }
29
38
}
30
39
40
+ pub const IDENTITY : Transform = Transform {
41
+ basis : Basis :: identity ( ) ,
42
+ origin : Vector3 :: ZERO ,
43
+ } ;
44
+
45
+ /// Creates a new transform from its three basis vectors and origin.
31
46
#[ inline]
32
- pub fn translate ( origin : Vector3 ) -> Transform {
33
- Transform {
34
- basis : Basis :: identity ( ) ,
47
+ pub fn from_axis_origin (
48
+ x_axis : Vector3 ,
49
+ y_axis : Vector3 ,
50
+ z_axis : Vector3 ,
51
+ origin : Vector3 ,
52
+ ) -> Self {
53
+ Self {
35
54
origin,
55
+ basis : Basis :: from_elements ( [ x_axis, y_axis, z_axis] ) ,
56
+ }
57
+ }
58
+
59
+ /// Returns this transform, with its origin moved by a certain `translation`
60
+ #[ inline]
61
+ pub fn translated ( & self , translation : Vector3 ) -> Transform {
62
+ Self {
63
+ origin : self . origin + translation,
64
+ basis : self . basis ,
65
+ }
66
+ }
67
+
68
+ /// Returns a vector transformed (multiplied) by the matrix.
69
+ #[ inline]
70
+ pub fn xform ( & self , v : Vector3 ) -> Vector3 {
71
+ self . basis . xform ( v) + self . origin
72
+ }
73
+
74
+ /// Returns a vector transformed (multiplied) by the transposed basis
75
+ /// matrix.
76
+ ///
77
+ /// **Note:** This results in a multiplication by the inverse of the matrix
78
+ /// only if it represents a rotation-reflection.
79
+ #[ inline]
80
+ pub fn xform_inv ( & self , v : Vector3 ) -> Vector3 {
81
+ self . basis . xform_inv ( v - self . origin )
82
+ }
83
+
84
+ /// Returns the inverse of the transform, under the assumption that the
85
+ /// transformation is composed of rotation and translation (no scaling, use
86
+ /// affine_inverse for transforms with scaling).
87
+ #[ inline]
88
+ pub fn inverse ( & self ) -> Transform {
89
+ let basis_inv = self . basis . transposed ( ) ;
90
+ let origin_inv = basis_inv. xform ( -self . origin ) ;
91
+ Transform {
92
+ origin : origin_inv,
93
+ basis : basis_inv,
94
+ }
95
+ }
96
+
97
+ /// Returns the inverse of the transform, under the assumption that the
98
+ /// transformation is composed of rotation, scaling and translation.
99
+ #[ inline]
100
+ pub fn affine_inverse ( & self ) -> Transform {
101
+ let basis_inv = self . basis . inverted ( ) ;
102
+ let origin_inv = basis_inv. xform ( -self . origin ) ;
103
+ Transform {
104
+ origin : origin_inv,
105
+ basis : basis_inv,
36
106
}
37
107
}
108
+
109
+ /// Returns a copy of the transform rotated such that its -Z axis points
110
+ /// towards the target position.
111
+ ///
112
+ /// The transform will first be rotated around the given up vector, and then
113
+ /// fully aligned to the target by a further rotation around an axis
114
+ /// perpendicular to both the target and up vectors.
115
+ #[ inline]
116
+ pub fn looking_at ( & self , target : Vector3 , up : Vector3 ) -> Transform {
117
+ let up = up. normalized ( ) ;
118
+ let v_z = ( self . origin - target) . normalized ( ) ;
119
+ let v_x = up. cross ( v_z) ;
120
+ let v_y = v_z. cross ( v_x) ;
121
+
122
+ Transform {
123
+ basis : Basis :: from_elements ( [ v_x, v_y, v_z] ) . transposed ( ) ,
124
+ origin : self . origin ,
125
+ }
126
+ }
127
+ }
128
+
129
+ impl Mul < Transform > for Transform {
130
+ type Output = Transform ;
131
+
132
+ #[ inline]
133
+ fn mul ( self , rhs : Transform ) -> Self :: Output {
134
+ let origin = self . xform ( rhs. origin ) ;
135
+ let basis = self . basis * rhs. basis ;
136
+ Transform { origin, basis }
137
+ }
38
138
}
0 commit comments