5
5
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
6
*/
7
7
8
- use crate :: framework:: itest;
9
- use godot:: builtin:: Quaternion ;
8
+ use crate :: framework:: { expect_panic, itest} ;
9
+ use godot:: builtin:: math:: assert_eq_approx;
10
+ use godot:: builtin:: { Quaternion , Vector3 } ;
10
11
11
12
#[ itest]
12
13
fn quaternion_default ( ) {
@@ -28,4 +29,153 @@ fn quaternion_from_xyzw() {
28
29
assert_eq ! ( quat. w, 0.8924 ) ;
29
30
}
30
31
32
+ #[ itest]
33
+ fn quaternion_from_axis_angle ( ) {
34
+ // 1. Should generate quaternion from axis angle.
35
+ let quat = Quaternion :: from_axis_angle ( Vector3 :: BACK , 1.0 ) ;
36
+
37
+ // Taken from doing this in GDScript.
38
+ assert_eq ! ( quat. x, 0.0 ) ;
39
+ assert_eq ! ( quat. y, 0.0 ) ;
40
+ assert_eq_approx ! ( quat. z, 0.479426 ) ;
41
+ assert_eq_approx ! ( quat. w, 0.877583 ) ;
42
+
43
+ // 2. Should panic if axis is not normalized.
44
+ expect_panic ( "Quaternion axis {axis:?} is not normalized." , || {
45
+ Quaternion :: from_axis_angle ( Vector3 :: ZERO , 1.0 ) ;
46
+ } ) ;
47
+
48
+ expect_panic ( "Quaternion axis {axis:?} is not normalized." , || {
49
+ Quaternion :: from_axis_angle ( Vector3 :: UP * 0.7 , 1.0 ) ;
50
+ } ) ;
51
+ }
52
+
53
+ #[ itest]
54
+ fn quaternion_normalization ( ) {
55
+ // 1. Should panic on quaternions with length 0.
56
+ expect_panic ( "Quaternion has length 0" , || {
57
+ Quaternion :: new ( 0.0 , 0.0 , 0.0 , 0.0 ) . normalized ( ) ;
58
+ } ) ;
59
+
60
+ // 2. Should not panic on any other length.
61
+ let quat = Quaternion :: default ( ) . normalized ( ) ;
62
+ assert_eq ! ( quat. length( ) , 1.0 ) ;
63
+ assert ! ( quat. is_normalized( ) ) ;
64
+ }
65
+
66
+ #[ itest]
67
+ fn quaternion_slerp ( ) {
68
+ let a = Quaternion :: new ( -1.0 , -1.0 , -1.0 , 10.0 ) ;
69
+ let b = Quaternion :: new ( 3.0 , 3.0 , 3.0 , 5.0 ) ;
70
+
71
+ // 1. Should perform interpolation.
72
+ let outcome = a. normalized ( ) . slerp ( b. normalized ( ) , 1.0 ) ;
73
+ let expected = Quaternion :: new ( 0.41602516 , 0.41602516 , 0.41602516 , 0.69337523 ) ;
74
+ assert_eq_approx ! ( outcome, expected) ;
75
+
76
+ // 2. Should panic on quaternions that are not normalized.
77
+ expect_panic ( "Slerp requires normalized quaternions" , || {
78
+ a. slerp ( b, 1.9 ) ;
79
+ } ) ;
80
+
81
+ // 3. Should not panic on default values.
82
+ let outcome = Quaternion :: default ( ) . slerp ( Quaternion :: default ( ) , 1.0 ) ;
83
+ assert_eq ! ( outcome, Quaternion :: default ( ) ) ;
84
+ }
85
+
86
+ #[ itest]
87
+ fn quaternion_slerpni ( ) {
88
+ let a = Quaternion :: new ( -1.0 , -1.0 , -1.0 , 10.0 ) ;
89
+ let b = Quaternion :: new ( 3.0 , 3.0 , 3.0 , 6.0 ) ;
90
+
91
+ // 1. Should perform interpolation.
92
+ let outcome = a. normalized ( ) . slerpni ( b. normalized ( ) , 1.0 ) ;
93
+ let expected = Quaternion :: new ( 0.37796447 , 0.37796447 , 0.37796447 , 0.75592893 ) ;
94
+ assert_eq_approx ! ( outcome, expected) ;
95
+
96
+ // 2. Should panic on quaternions that are not normalized.
97
+ expect_panic ( "Slerpni requires normalized quaternions" , || {
98
+ a. slerpni ( b, 1.9 ) ;
99
+ } ) ;
100
+
101
+ // 3. Should not panic on default values.
102
+ let outcome = Quaternion :: default ( ) . slerpni ( Quaternion :: default ( ) , 1.0 ) ;
103
+ assert_eq ! ( outcome, Quaternion :: default ( ) ) ;
104
+ }
105
+
106
+ #[ itest]
107
+ fn quaternion_spherical_cubic_interpolate ( ) {
108
+ let pre_a = Quaternion :: new ( -1.0 , -1.0 , -1.0 , -1.0 ) ;
109
+ let a = Quaternion :: new ( 0.0 , 0.0 , 0.0 , 1.0 ) ;
110
+ let b = Quaternion :: new ( 0.0 , 1.0 , 0.0 , 2.0 ) ;
111
+ let post_b = Quaternion :: new ( 2.0 , 2.0 , 2.0 , 2.0 ) ;
112
+
113
+ // 1. Should perform interpolation.
114
+ let outcome =
115
+ a. spherical_cubic_interpolate ( b. normalized ( ) , pre_a. normalized ( ) , post_b. normalized ( ) , 0.5 ) ;
116
+
117
+ // Taken from doing this in GDScript.
118
+ let expected = Quaternion :: new ( -0.072151 , 0.176298 , -0.072151 , 0.979034 ) ;
119
+ assert_eq_approx ! ( outcome, expected) ;
120
+
121
+ // 2. Should panic on quaternions that are not normalized.
122
+ expect_panic (
123
+ "Spherical cubic interpolation requires normalized quaternions" ,
124
+ || {
125
+ a. spherical_cubic_interpolate ( b, pre_a, post_b, 0.5 ) ;
126
+ } ,
127
+ ) ;
128
+
129
+ // 3. Should not panic on default returns when inputs are normalized.
130
+ let outcome = Quaternion :: default ( ) . spherical_cubic_interpolate (
131
+ Quaternion :: default ( ) ,
132
+ Quaternion :: default ( ) ,
133
+ Quaternion :: default ( ) ,
134
+ 1.0 ,
135
+ ) ;
136
+ assert_eq ! ( outcome, Quaternion :: default ( ) ) ;
137
+ }
138
+
139
+ #[ itest]
140
+ fn quaternion_spherical_cubic_interpolate_in_time ( ) {
141
+ let pre_a = Quaternion :: new ( -1.0 , -1.0 , -1.0 , -1.0 ) ;
142
+ let a = Quaternion :: new ( 0.0 , 0.0 , 0.0 , 1.0 ) ;
143
+ let b = Quaternion :: new ( 0.0 , 1.0 , 0.0 , 2.0 ) ;
144
+ let post_b = Quaternion :: new ( 2.0 , 2.0 , 2.0 , 2.0 ) ;
145
+
146
+ // 1. Should perform interpolation.
147
+ let outcome = a. spherical_cubic_interpolate_in_time (
148
+ b. normalized ( ) ,
149
+ pre_a. normalized ( ) ,
150
+ post_b. normalized ( ) ,
151
+ 0.5 ,
152
+ 0.1 ,
153
+ 0.1 ,
154
+ 0.1 ,
155
+ ) ;
156
+
157
+ // Taken from doing this in GDScript.
158
+ let expected = Quaternion :: new ( 0.280511 , 0.355936 , 0.280511 , 0.84613 ) ;
159
+ assert_eq_approx ! ( outcome, expected) ;
160
+
161
+ // 2. Should panic on quaternions that are not normalized.
162
+ expect_panic (
163
+ "Spherical cubic interpolation in time requires normalized quaternions" ,
164
+ || {
165
+ a. spherical_cubic_interpolate_in_time ( b, pre_a, post_b, 0.5 , 0.1 , 0.1 , 0.1 ) ;
166
+ } ,
167
+ ) ;
168
+
169
+ // 3. Should not panic on default returns when inputs are normalized.
170
+ let outcome = Quaternion :: default ( ) . spherical_cubic_interpolate_in_time (
171
+ Quaternion :: default ( ) ,
172
+ Quaternion :: default ( ) ,
173
+ Quaternion :: default ( ) ,
174
+ 1.0 ,
175
+ 1.0 ,
176
+ 1.0 ,
177
+ 1.0 ,
178
+ ) ;
179
+ assert_eq ! ( outcome, Quaternion :: default ( ) )
180
+ }
31
181
// TODO more tests
0 commit comments