Skip to content

Commit 72870d1

Browse files
bors[bot]lilizoey
andauthored
Merge #124
124: Implement the matrix types r=Bromeon a=sayaks Implement the four matrix types godot has: `Basis`, `Transform2D`, `Transform3D`, `Projection`. `Transform2D` in godot consists of an array of 3 `Vector2`s, where the first two are the basis. This means godot has some methods named `Transform2D::basis_<something>()`. I decided to instead make a struct `Basis2D`. so now any method like the above would be called `trans.basis.<something>()` instead. `Projection` has a lot of intricate math for many of its functions so it is largely a wrapper around `InnerProjection`, except for some methods that were easy to reimplement. Depends on #128 Co-authored-by: Lili Zoey <[email protected]>
2 parents e573ba8 + 8232785 commit 72870d1

File tree

14 files changed

+2771
-26
lines changed

14 files changed

+2771
-26
lines changed

godot-core/src/builtin/basis.rs

Lines changed: 840 additions & 0 deletions
Large diffs are not rendered by default.

godot-core/src/builtin/math.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
use std::f32::consts::TAU;
88

9+
use super::Vector2;
10+
911
pub const CMP_EPSILON: f32 = 0.00001;
1012

1113
pub fn lerp(a: f32, b: f32, t: f32) -> f32 {
@@ -23,6 +25,18 @@ pub fn is_equal_approx(a: f32, b: f32) -> bool {
2325
(a - b).abs() < tolerance
2426
}
2527

28+
/// Check if two angles are approximately equal, by comparing the distance
29+
/// between the points on the unit circle with 0 using [`is_equal_approx`].
30+
pub fn is_angle_equal_approx(a: f32, b: f32) -> bool {
31+
let (x1, y1) = a.sin_cos();
32+
let (x2, y2) = b.sin_cos();
33+
34+
is_equal_approx(
35+
Vector2::distance_to(Vector2::new(x1, y1), Vector2::new(x2, y2)),
36+
0.0,
37+
)
38+
}
39+
2640
pub fn is_zero_approx(s: f32) -> bool {
2741
s.abs() < CMP_EPSILON
2842
}
@@ -190,6 +204,15 @@ mod test {
190204
assert_ne_approx!(1.0, 2.0, is_equal_approx, "Message {}", "formatted");
191205
}
192206

207+
#[test]
208+
fn angle_equal_approx() {
209+
assert_eq_approx!(1.0, 1.000001, is_angle_equal_approx);
210+
assert_eq_approx!(0.0, TAU, is_angle_equal_approx);
211+
assert_eq_approx!(PI, -PI, is_angle_equal_approx);
212+
assert_eq_approx!(4.45783, -(TAU - 4.45783), is_angle_equal_approx);
213+
assert_eq_approx!(31.0 * PI, -13.0 * PI, is_angle_equal_approx);
214+
}
215+
193216
#[test]
194217
#[should_panic(expected = "I am inside format")]
195218
fn eq_approx_fail_with_message() {
@@ -198,22 +221,17 @@ mod test {
198221

199222
#[test]
200223
fn lerp_angle_test() {
201-
assert_eq_approx!(lerp_angle(0.0, PI, 0.5), -FRAC_PI_2, is_equal_approx);
224+
assert_eq_approx!(lerp_angle(0.0, PI, 0.5), -FRAC_PI_2, is_angle_equal_approx);
202225
assert_eq_approx!(
203226
lerp_angle(0.0, PI + 3.0 * TAU, 0.5),
204227
FRAC_PI_2,
205-
is_equal_approx
228+
is_angle_equal_approx
206229
);
207230
let angle = PI * 2.0 / 3.0;
208231
assert_eq_approx!(
209-
lerp_angle(-5.0 * TAU, angle + 3.0 * TAU, 0.5).sin(),
210-
(angle / 2.0).sin(),
211-
is_equal_approx
212-
);
213-
assert_eq_approx!(
214-
lerp_angle(-5.0 * TAU, angle + 3.0 * TAU, 0.5).cos(),
215-
(angle / 2.0).cos(),
216-
is_equal_approx
232+
lerp_angle(-5.0 * TAU, angle + 3.0 * TAU, 0.5),
233+
(angle / 2.0),
234+
is_angle_equal_approx
217235
);
218236
}
219237
}

godot-core/src/builtin/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,19 @@
3636
pub use crate::{array, dict, varray};
3737

3838
pub use array_inner::{Array, TypedArray};
39+
pub use basis::*;
3940
pub use color::*;
4041
pub use dictionary_inner::Dictionary;
4142
pub use math::*;
4243
pub use node_path::*;
4344
pub use others::*;
4445
pub use packed_array::*;
46+
pub use projection::*;
4547
pub use quaternion::*;
4648
pub use string::*;
4749
pub use string_name::*;
50+
pub use transform2d::*;
51+
pub use transform3d::*;
4852
pub use variant::*;
4953
pub use vector2::*;
5054
pub use vector2i::*;
@@ -79,15 +83,19 @@ mod array_inner;
7983
#[path = "dictionary.rs"]
8084
mod dictionary_inner;
8185

86+
mod basis;
8287
mod color;
8388
mod glam_helpers;
8489
mod math;
8590
mod node_path;
8691
mod others;
8792
mod packed_array;
93+
mod projection;
8894
mod quaternion;
8995
mod string;
9096
mod string_name;
97+
mod transform2d;
98+
mod transform3d;
9199
mod variant;
92100
mod vector2;
93101
mod vector2i;

godot-core/src/builtin/others.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ impl_builtin_stub!(Rect2, OpaqueRect2);
1717
impl_builtin_stub!(Rect2i, OpaqueRect2i);
1818
impl_builtin_stub!(Plane, OpaquePlane);
1919
impl_builtin_stub!(Aabb, OpaqueAabb);
20-
impl_builtin_stub!(Basis, OpaqueBasis);
21-
impl_builtin_stub!(Transform2D, OpaqueTransform2D);
22-
impl_builtin_stub!(Transform3D, OpaqueTransform3D);
23-
impl_builtin_stub!(Projection, OpaqueProjection);
2420
impl_builtin_stub!(Rid, OpaqueRid);
2521
impl_builtin_stub!(Callable, OpaqueCallable);
2622
impl_builtin_stub!(Signal, OpaqueSignal);

0 commit comments

Comments
 (0)