5
5
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
6
*/
7
7
8
+ use core:: cmp:: Ordering ;
8
9
use godot_ffi as sys;
9
10
use sys:: { ffi_methods, GodotFfi } ;
10
11
11
- use crate :: builtin:: inner;
12
12
use crate :: builtin:: math:: { FloatExt , GlamConv , GlamType } ;
13
13
use crate :: builtin:: vectors:: Vector2Axis ;
14
- use crate :: builtin:: { real, RAffine2 , RVec2 , Vector2i } ;
14
+ use crate :: builtin:: { inner , real, RAffine2 , RVec2 , Vector2i } ;
15
15
16
16
use std:: fmt;
17
17
@@ -36,172 +36,100 @@ pub struct Vector2 {
36
36
pub y : real ,
37
37
}
38
38
39
- impl Vector2 {
40
- /// Vector with all components set to `0.0`.
41
- pub const ZERO : Self = Self :: splat ( 0.0 ) ;
42
-
43
- /// Vector with all components set to `1.0`.
44
- pub const ONE : Self = Self :: splat ( 1.0 ) ;
45
-
46
- /// Vector with all components set to `real::INFINITY`.
47
- pub const INF : Self = Self :: splat ( real:: INFINITY ) ;
48
-
49
- /// Unit vector in -X direction (right in 2D coordinate system).
50
- pub const LEFT : Self = Self :: new ( -1.0 , 0.0 ) ;
51
-
52
- /// Unit vector in +X direction (right in 2D coordinate system).
53
- pub const RIGHT : Self = Self :: new ( 1.0 , 0.0 ) ;
54
-
55
- /// Unit vector in -Y direction (up in 2D coordinate system).
56
- pub const UP : Self = Self :: new ( 0.0 , -1.0 ) ;
39
+ impl_vector_operators ! ( Vector2 , real, ( x, y) ) ;
57
40
58
- /// Unit vector in +Y direction (down in 2D coordinate system).
59
- pub const DOWN : Self = Self :: new ( 0.0 , 1.0 ) ;
41
+ impl_vector_consts ! ( Vector2 , real) ;
42
+ impl_float_vector_consts ! ( Vector2 ) ;
43
+ impl_vector2x_consts ! ( Vector2 , real) ;
60
44
61
- /// Constructs a new `Vector2` from the given `x` and `y`.
62
- pub const fn new ( x : real , y : real ) -> Self {
63
- Self { x, y }
64
- }
65
-
66
- /// Constructs a new `Vector2` with both components set to `v`.
67
- pub const fn splat ( v : real ) -> Self {
68
- Self :: new ( v, v)
69
- }
45
+ impl_vector_fns ! ( Vector2 , RVec2 , real, ( x, y) ) ;
46
+ impl_float_vector_fns ! ( Vector2 , ( x, y) ) ;
47
+ impl_vector2x_fns ! ( Vector2 , real) ;
48
+ impl_vector2_vector3_fns ! ( Vector2 , ( x, y) ) ;
70
49
50
+ impl Vector2 {
71
51
/// Constructs a new `Vector2` from a [`Vector2i`].
52
+ #[ inline]
72
53
pub const fn from_vector2i ( v : Vector2i ) -> Self {
73
54
Self {
74
55
x : v. x as real ,
75
56
y : v. y as real ,
76
57
}
77
58
}
78
59
79
- /// Converts the corresponding `glam` type to `Self`.
80
- fn from_glam ( v : RVec2 ) -> Self {
81
- Self :: new ( v. x , v. y )
82
- }
83
-
84
- /// Converts `self` to the corresponding `glam` type.
85
- fn to_glam ( self ) -> RVec2 {
86
- RVec2 :: new ( self . x , self . y )
60
+ #[ doc( hidden) ]
61
+ #[ inline]
62
+ pub fn as_inner ( & self ) -> inner:: InnerVector2 {
63
+ inner:: InnerVector2 :: from_outer ( self )
87
64
}
88
65
66
+ /// Returns this vector's angle with respect to the positive X axis, or `(1.0, 0.0)` vector, in radians.
67
+ ///
68
+ /// For example, `Vector2::RIGHT.angle()` will return zero, `Vector2::DOWN.angle()` will return `PI / 2` (a quarter turn, or 90 degrees),
69
+ /// and `Vector2::new(1.0, -1.0).angle()` will return `-PI / 4` (a negative eighth turn, or -45 degrees).
70
+ ///
71
+ /// [Illustration of the returned angle.](https://raw.githubusercontent.com/godotengine/godot-docs/master/img/vector2_angle.png)
72
+ ///
73
+ /// Equivalent to the result of `y.atan2(x)`.
74
+ #[ inline]
89
75
pub fn angle ( self ) -> real {
90
76
self . y . atan2 ( self . x )
91
77
}
92
78
93
- pub fn angle_to ( self , to : Self ) -> real {
94
- self . to_glam ( ) . angle_between ( to . to_glam ( ) )
95
- }
96
-
79
+ /// Returns the angle to the given vector, in radians.
80
+ ///
81
+ /// [Illustration of the returned angle.](https://raw.githubusercontent.com/godotengine/godot-docs/master/img/vector2_angle_to.png)
82
+ # [ inline ]
97
83
pub fn angle_to_point ( self , to : Self ) -> real {
98
84
( to - self ) . angle ( )
99
85
}
100
86
101
- pub fn aspect ( self ) -> real {
102
- self . x / self . y
103
- }
104
-
105
- pub fn bounce ( self , normal : Self ) -> Self {
106
- -self . reflect ( normal)
107
- }
108
-
109
- pub fn ceil ( self ) -> Self {
110
- Self :: from_glam ( self . to_glam ( ) . ceil ( ) )
111
- }
112
-
113
- pub fn clamp ( self , min : Self , max : Self ) -> Self {
114
- Self :: from_glam ( self . to_glam ( ) . clamp ( min. to_glam ( ) , max. to_glam ( ) ) )
115
- }
116
-
87
+ /// Returns the 2D analog of the cross product for this vector and `with`.
88
+ ///
89
+ /// This is the signed area of the parallelogram formed by the two vectors. If the second vector is clockwise from the first vector,
90
+ /// then the cross product is the positive area. If counter-clockwise, the cross product is the negative area. If the two vectors are
91
+ /// parallel this returns zero, making it useful for testing if two vectors are parallel.
92
+ ///
93
+ /// Note: Cross product is not defined in 2D mathematically. This method embeds the 2D vectors in the XY plane of 3D space and uses
94
+ /// their cross product's Z component as the analog.
95
+ #[ inline]
117
96
pub fn cross ( self , with : Self ) -> real {
118
97
self . to_glam ( ) . perp_dot ( with. to_glam ( ) )
119
98
}
120
99
121
- pub fn direction_to ( self , to : Self ) -> Self {
122
- ( to - self ) . normalized ( )
123
- }
124
-
125
- pub fn distance_squared_to ( self , to : Self ) -> real {
126
- ( to - self ) . length_squared ( )
127
- }
128
-
129
- pub fn distance_to ( self , to : Self ) -> real {
130
- ( to - self ) . length ( )
131
- }
132
-
133
- pub fn dot ( self , other : Self ) -> real {
134
- self . to_glam ( ) . dot ( other. to_glam ( ) )
135
- }
136
-
137
- pub fn floor ( self ) -> Self {
138
- Self :: from_glam ( self . to_glam ( ) . floor ( ) )
139
- }
140
-
100
+ /// Creates a unit Vector2 rotated to the given `angle` in radians. This is equivalent to doing `Vector2::new(angle.cos(), angle.sin())`
101
+ /// or `Vector2::RIGHT.rotated(angle)`.
102
+ ///
103
+ /// ```no_run
104
+ /// use godot::prelude::*;
105
+ ///
106
+ /// let a = Vector2::from_angle(0.0); // (1.0, 0.0)
107
+ /// let b = Vector2::new(1.0, 0.0).angle(); // 0.0
108
+ /// let c = Vector2::from_angle(real_consts::PI / 2.0); // (0.0, 1.0)
109
+ /// ```
110
+ #[ inline]
141
111
pub fn from_angle ( angle : real ) -> Self {
142
112
Self :: from_glam ( RVec2 :: from_angle ( angle) )
143
113
}
144
114
145
- pub fn is_finite ( self ) -> bool {
146
- self . to_glam ( ) . is_finite ( )
147
- }
148
-
149
- pub fn is_normalized ( self ) -> bool {
150
- self . to_glam ( ) . is_normalized ( )
151
- }
152
-
153
- pub fn length_squared ( self ) -> real {
154
- self . to_glam ( ) . length_squared ( )
155
- }
156
-
157
- pub fn limit_length ( self , length : Option < real > ) -> Self {
158
- Self :: from_glam ( self . to_glam ( ) . clamp_length_max ( length. unwrap_or ( 1.0 ) ) )
159
- }
160
-
161
- pub fn max_axis_index ( self ) -> Vector2Axis {
162
- if self . x < self . y {
163
- Vector2Axis :: Y
164
- } else {
165
- Vector2Axis :: X
166
- }
167
- }
168
-
169
- pub fn min_axis_index ( self ) -> Vector2Axis {
170
- if self . x < self . y {
171
- Vector2Axis :: X
172
- } else {
173
- Vector2Axis :: Y
174
- }
175
- }
176
-
177
- pub fn move_toward ( self , to : Self , delta : real ) -> Self {
178
- let vd = to - self ;
179
- let len = vd. length ( ) ;
180
- if len <= delta || len < real:: CMP_EPSILON {
181
- to
182
- } else {
183
- self + vd / len * delta
184
- }
185
- }
186
-
115
+ /// Returns a perpendicular vector rotated 90 degrees counter-clockwise compared to the original, with the same length.
116
+ #[ inline]
187
117
pub fn orthogonal ( self ) -> Self {
188
118
Self :: new ( self . y , -self . x )
189
119
}
190
120
191
- pub fn project ( self , b : Self ) -> Self {
192
- Self :: from_glam ( self . to_glam ( ) . project_onto ( b. to_glam ( ) ) )
193
- }
194
-
195
- pub fn reflect ( self , normal : Self ) -> Self {
196
- 2.0 * normal * self . dot ( normal) - self
197
- }
198
-
199
- pub fn round ( self ) -> Self {
200
- Self :: from_glam ( self . to_glam ( ) . round ( ) )
121
+ /// Returns the result of rotating this vector by `angle` (in radians).
122
+ #[ inline]
123
+ pub fn rotated ( self , angle : real ) -> Self {
124
+ Self :: from_glam ( RAffine2 :: from_angle ( angle) . transform_vector2 ( self . to_glam ( ) ) )
201
125
}
202
126
203
- // TODO compare with gdnative implementation:
204
- // https://github.com/godot-rust/gdnative/blob/master/gdnative-core/src/core_types/vector3.rs#L335-L343
127
+ /// Returns the result of spherical linear interpolation between this vector and `to`, by amount `weight`.
128
+ /// `weight` is on the range of 0.0 to 1.0, representing the amount of interpolation.
129
+ ///
130
+ /// This method also handles interpolating the lengths if the input vectors have different lengths.
131
+ /// For the special case of one or both input vectors having zero length, this method behaves like [`Vector2::lerp`].
132
+ #[ inline]
205
133
pub fn slerp ( self , to : Self , weight : real ) -> Self {
206
134
let start_length_sq = self . length_squared ( ) ;
207
135
let end_length_sq = to. length_squared ( ) ;
@@ -213,24 +141,6 @@ impl Vector2 {
213
141
let angle = self . angle_to ( to) ;
214
142
self . rotated ( angle * weight) * ( result_length / start_length)
215
143
}
216
-
217
- pub fn slide ( self , normal : Self ) -> Self {
218
- self - normal * self . dot ( normal)
219
- }
220
-
221
- /// Returns the result of rotating this vector by `angle` (in radians).
222
- pub fn rotated ( self , angle : real ) -> Self {
223
- Self :: from_glam ( RAffine2 :: from_angle ( angle) . transform_vector2 ( self . to_glam ( ) ) )
224
- }
225
-
226
- #[ doc( hidden) ]
227
- pub fn as_inner ( & self ) -> inner:: InnerVector2 {
228
- inner:: InnerVector2 :: from_outer ( self )
229
- }
230
-
231
- pub fn coords ( & self ) -> ( real , real ) {
232
- ( self . x , self . y )
233
- }
234
144
}
235
145
236
146
/// Formats the vector like Godot: `(x, y)`.
@@ -240,12 +150,6 @@ impl fmt::Display for Vector2 {
240
150
}
241
151
}
242
152
243
- impl_common_vector_fns ! ( Vector2 , real) ;
244
- impl_float_vector_glam_fns ! ( Vector2 , real) ;
245
- impl_float_vector_component_fns ! ( Vector2 , real, ( x, y) ) ;
246
- impl_vector_operators ! ( Vector2 , real, ( x, y) ) ;
247
- impl_swizzle_trait_for_vector2x ! ( Vector2 , real) ;
248
-
249
153
// SAFETY:
250
154
// This type is represented as `Self` in Godot, so `*mut Self` is sound.
251
155
unsafe impl GodotFfi for Vector2 {
0 commit comments