Skip to content

Commit 5601237

Browse files
RealAstolfottencate
RealAstolfo
andcommitted
Use of vector macro to create vector types
Co-Authored-By: Thomas ten Cate <[email protected]>
1 parent edf2fe5 commit 5601237

File tree

3 files changed

+602
-145
lines changed

3 files changed

+602
-145
lines changed

godot-core/src/builtin/vector2.rs

Lines changed: 277 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3,81 +3,306 @@
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+
use std::ops::*;
67

7-
use godot_ffi as sys;
8-
use sys::{ffi_methods, GodotFfi};
8+
use crate::builtin::math::*;
9+
use crate::builtin::real::Real;
910

10-
type Inner = glam::f32::Vec2;
11-
//type Inner = glam::f64::DVec2;
11+
impl_vector!(Vector2, crate::builtin::real::Vec2, Real, (x, y));
12+
impl_float_vector!(Vector2, Real);
13+
impl_vector_from!(Vector2, Vector2i, Real, (x, y));
1214

13-
#[derive(Default, Copy, Clone, Debug, PartialEq)]
14-
#[repr(C)]
15-
pub struct Vector2 {
16-
inner: Inner,
17-
}
15+
type Inner = crate::builtin::real::Vec2;
1816

1917
impl Vector2 {
20-
pub fn new(x: f32, y: f32) -> Self {
21-
Self {
22-
inner: Inner::new(x, y),
18+
19+
/// Left unit vector. Represents the direction of left.
20+
pub const LEFT: Self = Self::new(-1.0, 0.0);
21+
22+
/// Right unit vector. Represents the direction of right.
23+
pub const RIGHT: Self = Self::new(1.0, 0.0);
24+
25+
/// Up unit vector. Y is down in 2D, so this vector points -Y.
26+
pub const UP: Self = Self::new(0.0, -1.0);
27+
28+
/// Down unit vector. Y is down in 2D, so this vector points +Y.
29+
pub const DOWN: Self = Self::new(0.0, 1.0);
30+
31+
pub fn abs(self) -> Self {
32+
Self(self.0.abs())
33+
}
34+
35+
pub fn angle(self) -> Real {
36+
self.y().atan2(self.x())
37+
}
38+
39+
pub fn angle_to(self, to: Self) -> Real {
40+
self.0.angle_between(to.0)
41+
}
42+
43+
pub fn angle_to_point(self, to: Self) -> Real {
44+
(to - self).angle()
45+
}
46+
47+
pub fn aspect(self) -> Real {
48+
self.x() / self.y()
49+
}
50+
51+
pub fn bezier_derivative(
52+
self,
53+
control_1: Self,
54+
control_2: Self,
55+
end: Self,
56+
t: Real,
57+
) -> Self {
58+
let x = bezier_derivative(
59+
self.x(),
60+
control_1.x(),
61+
control_2.x(),
62+
end.x(),
63+
t,
64+
);
65+
let y = bezier_derivative(
66+
self.y(),
67+
control_1.y(),
68+
control_2.y(),
69+
end.y(),
70+
t,
71+
);
72+
73+
Self::new(x, y)
74+
}
75+
76+
pub fn bezier_interpolate(
77+
self,
78+
control_1: Self,
79+
control_2: Self,
80+
end: Self,
81+
t: Real,
82+
) -> Self {
83+
let x = bezier_interpolate(
84+
self.x(),
85+
control_1.x(),
86+
control_2.x(),
87+
end.x(),
88+
t,
89+
);
90+
let y = bezier_interpolate(
91+
self.y(),
92+
control_1.y(),
93+
control_2.y(),
94+
end.y(),
95+
t,
96+
);
97+
98+
Self::new(x, y)
99+
}
100+
101+
pub fn bounce(self, normal: Self) -> Self {
102+
-self.reflect(normal)
103+
}
104+
105+
pub fn ceil(self) -> Self {
106+
Self(self.0.ceil())
107+
}
108+
109+
pub fn clamp(self, min: Self, max: Self) -> Self {
110+
Self(self.0.clamp(min.0, max.0))
111+
}
112+
113+
pub fn cross(self, with: Self) -> Real {
114+
self.0.perp_dot(with.0)
115+
}
116+
117+
pub fn cubic_interpolate(self, b: Self, pre_a: Self, post_b: Self, weight: Real) -> Self {
118+
let x = cubic_interpolate(
119+
self.x(),
120+
b.x(),
121+
pre_a.x(),
122+
post_b.x(),
123+
weight,
124+
);
125+
let y = cubic_interpolate(
126+
self.y(),
127+
b.y(),
128+
pre_a.y(),
129+
post_b.y(),
130+
weight,
131+
);
132+
133+
Self::new(x, y)
134+
}
135+
136+
pub fn cubic_interpolate_in_time(
137+
self,
138+
b: Self,
139+
pre_a: Self,
140+
post_b: Self,
141+
weight: Real,
142+
b_t: Real,
143+
pre_a_t: Real,
144+
post_b_t: Real,
145+
) -> Self {
146+
let x = cubic_interpolate_in_time(
147+
self.x(),
148+
b.x(),
149+
pre_a.x(),
150+
post_b.x(),
151+
weight,
152+
b_t,
153+
pre_a_t,
154+
post_b_t,
155+
);
156+
let y = cubic_interpolate_in_time(
157+
self.y(),
158+
b.y(),
159+
pre_a.y(),
160+
post_b.y(),
161+
weight,
162+
b_t,
163+
pre_a_t,
164+
post_b_t,
165+
);
166+
167+
Self::new(x, y)
168+
}
169+
170+
pub fn direction_to(self, to: Self) -> Self {
171+
(to - self).normalized()
172+
}
173+
174+
pub fn distance_squared_to(self, to: Self) -> Real {
175+
self.0.distance_squared(to.0)
176+
}
177+
178+
pub fn distance_to(self, to: Self) -> Real {
179+
self.0.distance(to.0)
180+
}
181+
182+
pub fn dot(self, other: Self) -> Real {
183+
self.0.dot(other.0)
184+
}
185+
186+
pub fn floor(self) -> Self {
187+
Self(self.0.floor())
188+
}
189+
190+
pub fn from_angle(angle: Real) -> Self {
191+
Self(Inner::from_angle(angle))
192+
}
193+
194+
pub fn is_equal_approx(self, to: Self) -> bool {
195+
is_equal_approx(self.x(), to.x()) && is_equal_approx(self.y(), to.y())
196+
}
197+
198+
pub fn is_finite(self) -> bool {
199+
self.0.is_finite()
200+
}
201+
202+
pub fn is_normalized(self) -> bool {
203+
self.0.is_normalized()
204+
}
205+
206+
pub fn is_zero_approx(self) -> bool {
207+
is_zero_approx(self.x()) && is_zero_approx(self.y())
208+
}
209+
210+
pub fn length_squared(self) -> Real {
211+
self.0.length_squared()
212+
}
213+
214+
pub fn lerp(self, to: Self, weight: Real) -> Self {
215+
Self(self.0.lerp(to.0, weight))
216+
}
217+
218+
pub fn limit_length(self, length: Option<Real>) -> Self {
219+
Self(self.0.clamp_length_max(length.unwrap_or(1.0)))
220+
}
221+
222+
pub fn max_axis_index(self) -> i32 {
223+
if self.0.max_element() == self.x() {
224+
0
225+
} else {
226+
1
23227
}
24228
}
25229

26-
pub fn from_inner(inner: Inner) -> Self {
27-
Self { inner }
230+
pub fn min_axis_index(self) -> i32 {
231+
if self.0.min_element() == self.x() {
232+
0
233+
} else {
234+
1
235+
}
28236
}
29237

30-
/// only for testing
31-
pub fn inner(self) -> Inner {
32-
self.inner
238+
pub fn move_toward(self, to: Self, delta: Real) -> Self {
239+
let vd = to - self;
240+
let len = vd.length();
241+
if len <= delta || len < CMP_EPSILON {
242+
return to;
243+
} else {
244+
return self + vd / len * delta;
245+
};
33246
}
34247

35-
// Hacks for example
36-
// pub fn length(self) -> f32 {
37-
// self.inner.length()
38-
// }
39-
// pub fn normalized(self) -> Vector2 {
40-
// Self::from_inner(self.inner.normalize())
41-
// }
42-
pub fn rotated(self, angle: f32) -> Self {
43-
Self::from_inner(glam::Affine2::from_angle(angle).transform_vector2(self.inner))
248+
pub fn orthogonal(self) -> Self {
249+
Self::new(self.y(), -self.x())
44250
}
45-
}
46251

47-
impl GodotFfi for Vector2 {
48-
ffi_methods! { type sys::GDExtensionTypePtr = *mut Self; .. }
49-
}
252+
pub fn posmod(self, pmod: Real) -> Self {
253+
Self::new(fposmod(self.x(), pmod), fposmod(self.y(), pmod))
254+
}
50255

51-
impl std::fmt::Display for Vector2 {
52-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53-
self.inner.fmt(f)
256+
pub fn posmodv(self, modv: Self) -> Self {
257+
Self::new(
258+
fposmod(self.x(), modv.x()),
259+
fposmod(self.y(), modv.y()),
260+
)
54261
}
55-
}
56262

57-
// ----------------------------------------------------------------------------------------------------------------------------------------------
263+
pub fn project(self, b: Self) -> Self {
264+
Self(self.0.project_onto(b.0))
265+
}
58266

59-
type IInner = glam::IVec2;
267+
pub fn reflect(self, normal: Self) -> Self {
268+
Self(self.0.reject_from(normal.0))
269+
}
60270

61-
#[derive(Default, Copy, Clone, Debug, Eq, PartialEq)]
62-
#[repr(C)]
63-
pub struct Vector2i {
64-
inner: IInner,
65-
}
271+
pub fn round(self) -> Self {
272+
Self(self.0.round())
273+
}
274+
275+
pub fn sign(self) -> Self {
276+
-self
277+
}
66278

67-
impl Vector2i {
68-
pub fn new(x: i32, y: i32) -> Self {
69-
Self {
70-
inner: IInner::new(x, y),
279+
pub fn slerp(self, to: Self, weight: Real) -> Self {
280+
let start_length_sq = self.length_squared();
281+
let end_length_sq = to.length_squared();
282+
if start_length_sq == 0.0 || end_length_sq == 0.0 {
283+
return self.lerp(to, weight);
71284
}
285+
let start_length = start_length_sq.sqrt();
286+
let result_length = lerp(start_length, end_length_sq.sqrt(), weight);
287+
let angle = self.angle_to(to);
288+
self.rotated(angle * weight) * (result_length / start_length)
72289
}
73-
}
74290

75-
impl GodotFfi for Vector2i {
76-
ffi_methods! { type sys::GDExtensionTypePtr = *mut Self; .. }
77-
}
291+
pub fn slide(self, normal: Self) -> Self {
292+
self - normal * self.dot(normal)
293+
}
294+
295+
pub fn snapped(self, step: Self) -> Self {
296+
Self::new(
297+
snapped(self.x(), step.x()),
298+
snapped(self.y(), step.y()),
299+
)
300+
}
78301

79-
impl std::fmt::Display for Vector2i {
80-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81-
self.inner.fmt(f)
302+
pub fn rotated(self, angle: Real) -> Self {
303+
glam::Affine2::from_angle(angle).transform_vector2(self.into()).into()
82304
}
83305
}
306+
307+
impl_vector!(Vector2i, glam::IVec2, i32, (x, y));
308+
impl_vector_from!(Vector2i, Vector2, i32, (x, y));

0 commit comments

Comments
 (0)