3
3
* License, v. 2.0. If a copy of the MPL was not distributed with this
4
4
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
5
*/
6
-
7
6
use std:: fmt;
7
+ use std:: ops:: * ;
8
8
9
9
use godot_ffi as sys;
10
10
use sys:: { ffi_methods, GodotFfi } ;
11
11
12
+ use crate :: builtin:: math:: * ;
12
13
use crate :: builtin:: { inner, Vector2i } ;
13
14
14
15
/// Vector used for 2D math using floating point coordinates.
@@ -70,11 +71,6 @@ impl Vector2 {
70
71
}
71
72
}
72
73
73
- /// Returns the result of rotating this vector by `angle` (in radians).
74
- pub fn rotated ( self , angle : f32 ) -> Self {
75
- Self :: from_glam ( glam:: Affine2 :: from_angle ( angle) . transform_vector2 ( self . to_glam ( ) ) )
76
- }
77
-
78
74
/// Converts the corresponding `glam` type to `Self`.
79
75
fn from_glam ( v : glam:: Vec2 ) -> Self {
80
76
Self :: new ( v. x , v. y )
@@ -85,6 +81,206 @@ impl Vector2 {
85
81
glam:: Vec2 :: new ( self . x , self . y )
86
82
}
87
83
84
+ pub fn angle ( self ) -> f32 {
85
+ self . y . atan2 ( self . x )
86
+ }
87
+
88
+ pub fn angle_to ( self , to : Self ) -> f32 {
89
+ self . to_glam ( ) . angle_between ( to. to_glam ( ) )
90
+ }
91
+
92
+ pub fn angle_to_point ( self , to : Self ) -> f32 {
93
+ ( to - self ) . angle ( )
94
+ }
95
+
96
+ pub fn aspect ( self ) -> f32 {
97
+ self . x / self . y
98
+ }
99
+
100
+ pub fn bezier_derivative ( self , control_1 : Self , control_2 : Self , end : Self , t : f32 ) -> Self {
101
+ let x = bezier_derivative ( self . x , control_1. x , control_2. x , end. x , t) ;
102
+ let y = bezier_derivative ( self . y , control_1. y , control_2. y , end. y , t) ;
103
+
104
+ Self :: new ( x, y)
105
+ }
106
+
107
+ pub fn bezier_interpolate ( self , control_1 : Self , control_2 : Self , end : Self , t : f32 ) -> Self {
108
+ let x = bezier_interpolate ( self . x , control_1. x , control_2. x , end. x , t) ;
109
+ let y = bezier_interpolate ( self . y , control_1. y , control_2. y , end. y , t) ;
110
+
111
+ Self :: new ( x, y)
112
+ }
113
+
114
+ pub fn bounce ( self , normal : Self ) -> Self {
115
+ -self . reflect ( normal)
116
+ }
117
+
118
+ pub fn ceil ( self ) -> Self {
119
+ Self :: from_glam ( self . to_glam ( ) . ceil ( ) )
120
+ }
121
+
122
+ pub fn clamp ( self , min : Self , max : Self ) -> Self {
123
+ Self :: from_glam ( self . to_glam ( ) . clamp ( min. to_glam ( ) , max. to_glam ( ) ) )
124
+ }
125
+
126
+ pub fn cross ( self , with : Self ) -> f32 {
127
+ self . to_glam ( ) . perp_dot ( with. to_glam ( ) )
128
+ }
129
+
130
+ pub fn cubic_interpolate ( self , b : Self , pre_a : Self , post_b : Self , weight : f32 ) -> Self {
131
+ let x = cubic_interpolate ( self . x , b. x , pre_a. x , post_b. x , weight) ;
132
+ let y = cubic_interpolate ( self . y , b. y , pre_a. y , post_b. y , weight) ;
133
+
134
+ Self :: new ( x, y)
135
+ }
136
+
137
+ #[ allow( clippy:: too_many_arguments) ]
138
+ pub fn cubic_interpolate_in_time (
139
+ self ,
140
+ b : Self ,
141
+ pre_a : Self ,
142
+ post_b : Self ,
143
+ weight : f32 ,
144
+ b_t : f32 ,
145
+ pre_a_t : f32 ,
146
+ post_b_t : f32 ,
147
+ ) -> Self {
148
+ let x = cubic_interpolate_in_time (
149
+ self . x , b. x , pre_a. x , post_b. x , weight, b_t, pre_a_t, post_b_t,
150
+ ) ;
151
+ let y = cubic_interpolate_in_time (
152
+ self . y , b. y , pre_a. y , post_b. y , weight, b_t, pre_a_t, post_b_t,
153
+ ) ;
154
+
155
+ Self :: new ( x, y)
156
+ }
157
+
158
+ pub fn direction_to ( self , to : Self ) -> Self {
159
+ ( to - self ) . normalized ( )
160
+ }
161
+
162
+ pub fn distance_squared_to ( self , to : Self ) -> f32 {
163
+ self . to_glam ( ) . distance_squared ( to. to_glam ( ) )
164
+ }
165
+
166
+ pub fn distance_to ( self , to : Self ) -> f32 {
167
+ self . to_glam ( ) . distance ( to. to_glam ( ) )
168
+ }
169
+
170
+ pub fn dot ( self , other : Self ) -> f32 {
171
+ self . to_glam ( ) . dot ( other. to_glam ( ) )
172
+ }
173
+
174
+ pub fn floor ( self ) -> Self {
175
+ Self :: from_glam ( self . to_glam ( ) . floor ( ) )
176
+ }
177
+
178
+ pub fn from_angle ( angle : f32 ) -> Self {
179
+ Self :: from_glam ( glam:: Vec2 :: from_angle ( angle) )
180
+ }
181
+
182
+ pub fn is_equal_approx ( self , to : Self ) -> bool {
183
+ is_equal_approx ( self . x , to. x ) && is_equal_approx ( self . y , to. y )
184
+ }
185
+
186
+ pub fn is_finite ( self ) -> bool {
187
+ self . to_glam ( ) . is_finite ( )
188
+ }
189
+
190
+ pub fn is_normalized ( self ) -> bool {
191
+ self . to_glam ( ) . is_normalized ( )
192
+ }
193
+
194
+ pub fn is_zero_approx ( self ) -> bool {
195
+ is_zero_approx ( self . x ) && is_zero_approx ( self . y )
196
+ }
197
+
198
+ pub fn length_squared ( self ) -> f32 {
199
+ self . to_glam ( ) . length_squared ( )
200
+ }
201
+
202
+ pub fn lerp ( self , to : Self , weight : f32 ) -> Self {
203
+ Self :: from_glam ( self . to_glam ( ) . lerp ( to. to_glam ( ) , weight) )
204
+ }
205
+
206
+ pub fn limit_length ( self , length : Option < f32 > ) -> Self {
207
+ Self :: from_glam ( self . to_glam ( ) . clamp_length_max ( length. unwrap_or ( 1.0 ) ) )
208
+ }
209
+
210
+ pub fn max_axis_index ( self ) -> i32 {
211
+ let me = self . to_glam ( ) . max_element ( ) ;
212
+ ( me == self . y ) as i32
213
+ }
214
+
215
+ pub fn min_axis_index ( self ) -> i32 {
216
+ let me = self . to_glam ( ) . min_element ( ) ;
217
+ ( me == self . y ) as i32
218
+ }
219
+
220
+ pub fn move_toward ( self , to : Self , delta : f32 ) -> Self {
221
+ let vd = to - self ;
222
+ let len = vd. length ( ) ;
223
+ if len <= delta || len < CMP_EPSILON {
224
+ to
225
+ } else {
226
+ self + vd / len * delta
227
+ }
228
+ }
229
+
230
+ pub fn orthogonal ( self ) -> Self {
231
+ Self :: new ( self . y , -self . x )
232
+ }
233
+
234
+ pub fn posmod ( self , pmod : f32 ) -> Self {
235
+ Self :: new ( fposmod ( self . x , pmod) , fposmod ( self . y , pmod) )
236
+ }
237
+
238
+ pub fn posmodv ( self , modv : Self ) -> Self {
239
+ Self :: new ( fposmod ( self . x , modv. x ) , fposmod ( self . y , modv. y ) )
240
+ }
241
+
242
+ pub fn project ( self , b : Self ) -> Self {
243
+ Self :: from_glam ( self . to_glam ( ) . project_onto ( b. to_glam ( ) ) )
244
+ }
245
+
246
+ pub fn reflect ( self , normal : Self ) -> Self {
247
+ Self :: from_glam ( self . to_glam ( ) . reject_from ( normal. to_glam ( ) ) )
248
+ }
249
+
250
+ pub fn round ( self ) -> Self {
251
+ Self :: from_glam ( self . to_glam ( ) . round ( ) )
252
+ }
253
+
254
+ pub fn sign ( self ) -> Self {
255
+ -self
256
+ }
257
+
258
+ pub fn slerp ( self , to : Self , weight : f32 ) -> Self {
259
+ let start_length_sq = self . length_squared ( ) ;
260
+ let end_length_sq = to. length_squared ( ) ;
261
+ if start_length_sq == 0.0 || end_length_sq == 0.0 {
262
+ return self . lerp ( to, weight) ;
263
+ }
264
+ let start_length = start_length_sq. sqrt ( ) ;
265
+ let result_length = lerp ( start_length, end_length_sq. sqrt ( ) , weight) ;
266
+ let angle = self . angle_to ( to) ;
267
+ self . rotated ( angle * weight) * ( result_length / start_length)
268
+ }
269
+
270
+ pub fn slide ( self , normal : Self ) -> Self {
271
+ self - normal * self . dot ( normal)
272
+ }
273
+
274
+ pub fn snapped ( self , step : Self ) -> Self {
275
+ Self :: new ( snapped ( self . x , step. x ) , snapped ( self . y , step. y ) )
276
+ }
277
+
278
+ /// Returns the result of rotating this vector by `angle` (in radians).
279
+ pub fn rotated ( self , angle : f32 ) -> Self {
280
+ Self :: from_glam ( glam:: Affine2 :: from_angle ( angle) . transform_vector2 ( self . to_glam ( ) ) )
281
+ }
282
+
283
+ #[ cfg( not( any( gdext_test, doctest) ) ) ]
88
284
#[ doc( hidden) ]
89
285
pub fn as_inner ( & self ) -> inner:: InnerVector2 {
90
286
inner:: InnerVector2 :: from_outer ( self )
0 commit comments