Skip to content

Commit dfe400d

Browse files
authored
Try #67:
2 parents 4ebdc5e + e826476 commit dfe400d

File tree

4 files changed

+416
-6
lines changed

4 files changed

+416
-6
lines changed

godot-core/src/builtin/math.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ pub fn cubic_interpolate(from: f32, to: f32, pre: f32, post: f32, weight: f32) -
6666
+ (-pre + 3.0 * from - 3.0 * to + post) * (weight * weight * weight))
6767
}
6868

69+
#[allow(clippy::too_many_arguments)]
6970
pub fn cubic_interpolate_in_time(
7071
from: f32,
7172
to: f32,

godot-core/src/builtin/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ mod vector_macros;
3737

3838
mod arrays;
3939
mod color;
40+
mod math;
4041
mod node_path;
4142
mod others;
4243
mod packed_array;
@@ -54,6 +55,7 @@ pub mod meta;
5455

5556
pub use arrays::*;
5657
pub use color::*;
58+
pub use math::*;
5759
pub use node_path::*;
5860
pub use others::*;
5961
pub use packed_array::*;

godot-core/src/builtin/vector2.rs

Lines changed: 202 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
* License, v. 2.0. If a copy of the MPL was not distributed with this
44
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
55
*/
6-
76
use std::fmt;
7+
use std::ops::*;
88

99
use godot_ffi as sys;
1010
use sys::{ffi_methods, GodotFfi};
1111

12+
use crate::builtin::math::*;
1213
use crate::builtin::{inner, Vector2i};
1314

1415
/// Vector used for 2D math using floating point coordinates.
@@ -70,11 +71,6 @@ impl Vector2 {
7071
}
7172
}
7273

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-
7874
/// Converts the corresponding `glam` type to `Self`.
7975
fn from_glam(v: glam::Vec2) -> Self {
8076
Self::new(v.x, v.y)
@@ -85,6 +81,206 @@ impl Vector2 {
8581
glam::Vec2::new(self.x, self.y)
8682
}
8783

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)))]
88284
#[doc(hidden)]
89285
pub fn as_inner(&self) -> inner::InnerVector2 {
90286
inner::InnerVector2::from_outer(self)

0 commit comments

Comments
 (0)