Skip to content

Commit 6608393

Browse files
bors[bot]T4rmyn
andauthored
Merge #295
295: Implementation of Plane integration tests r=Bromeon a=T4rmin Adds integration tests to the re-implemented Plane functions (#268, and fixing a function in it) and should also address the Plane section of issue #209. This PR is also a recreation of #286 since it has the great error of force-pushing after rebasing. Co-authored-by: Aaron Lawrence <[email protected]>
2 parents 57fd56a + 75a81e5 commit 6608393

File tree

3 files changed

+252
-2
lines changed

3 files changed

+252
-2
lines changed

godot-core/src/builtin/plane.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,20 @@ impl Plane {
214214
self.normal.dot(point) > self.d
215215
}
216216

217-
/// Returns a normalized copy of the plane.
217+
/// Returns a copy of the plane with its `normal` and `d` scaled to the unit length.
218+
///
219+
/// A `normal` length of `0.0` would return a plane with its `normal` and `d` being `Vector3::ZERO`
220+
/// and `0.0` respectively.
218221
#[inline]
219222
pub fn normalized(self) -> Self {
220-
Plane::new(self.normal.normalized(), self.d)
223+
let length: real = self.normal.length();
224+
if length == 0.0 {
225+
return Plane {
226+
normal: Vector3::ZERO,
227+
d: 0.0,
228+
};
229+
}
230+
Plane::new(self.normal.normalized(), self.d / length)
221231
}
222232

223233
/// Returns the orthogonal projection of `point` to the plane.

itest/rust/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ mod node_test;
2727
mod object_test;
2828
mod option_ffi_test;
2929
mod packed_array_test;
30+
mod plane_test;
3031
mod projection_test;
3132
mod quaternion_test;
3233
mod rect2i_test;

itest/rust/src/plane_test.rs

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
/*
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
5+
*/
6+
7+
use std::fmt::Debug;
8+
9+
use crate::itest;
10+
use godot::builtin::inner::InnerPlane;
11+
use godot::builtin::{real, Plane, RealConv, ToVariant, Vector3};
12+
use godot::private::class_macros::assert_eq_approx;
13+
14+
fn check_mapping_eq<T>(context: &str, outer: T, inner: T)
15+
where
16+
T: PartialEq + Debug,
17+
{
18+
assert_eq!(
19+
outer, inner,
20+
"{context}: outer != inner ({outer:?} != {inner:?})"
21+
);
22+
}
23+
24+
fn check_mapping_eq_approx_plane(context: &str, outer: Plane, inner: Plane) {
25+
assert_eq_approx!(
26+
outer,
27+
inner,
28+
|a: Plane, b: Plane| a.is_equal_approx(&b),
29+
"{context}: outer != inner ({outer:?} != {inner:?})"
30+
);
31+
}
32+
33+
#[itest]
34+
fn plane_normalized() {
35+
let a = Plane::new(Vector3::new(9.5, 3.3, 2.2).normalized(), -0.1);
36+
let inner_a = InnerPlane::from_outer(&a);
37+
check_mapping_eq_approx_plane("normalized", a.normalized(), inner_a.normalized());
38+
39+
let a = Plane {
40+
normal: Vector3::new(4.2, 2.9, 1.5),
41+
d: 2.4,
42+
};
43+
let inner_a = InnerPlane::from_outer(&a);
44+
check_mapping_eq_approx_plane("normalized", a.normalized(), inner_a.normalized());
45+
}
46+
47+
#[itest]
48+
fn plane_center() {
49+
let a = Plane::new(Vector3::new(0.5, 2.0, 2.5).normalized(), 1.0);
50+
let inner_a = InnerPlane::from_outer(&a);
51+
check_mapping_eq("center", a.center(), inner_a.get_center());
52+
}
53+
54+
#[itest]
55+
fn plane_is_finite() {
56+
let a = Plane::new(Vector3::new(9.4, -1.2, 3.0).normalized(), 1.5);
57+
let inner_a = InnerPlane::from_outer(&a);
58+
check_mapping_eq("is_finite", a.is_finite(), inner_a.is_finite());
59+
60+
let a = Plane {
61+
normal: Vector3::new(real::INFINITY, 2.9, 1.5),
62+
d: 2.4,
63+
};
64+
let inner_a = InnerPlane::from_outer(&a);
65+
check_mapping_eq("is_finite", a.is_finite(), inner_a.is_finite());
66+
}
67+
68+
#[itest]
69+
fn plane_distance_to() {
70+
let a = Plane::new(Vector3::BACK, 0.2);
71+
let inner_a = InnerPlane::from_outer(&a);
72+
let b = Vector3::new(7.0, 9.0, 2.0);
73+
check_mapping_eq(
74+
"distance_to",
75+
a.distance_to(b).as_f64(),
76+
inner_a.distance_to(b),
77+
);
78+
79+
let b = Vector3::new(-7.0, -9.0, -2.0);
80+
check_mapping_eq(
81+
"distance_to",
82+
a.distance_to(b).as_f64(),
83+
inner_a.distance_to(b),
84+
);
85+
}
86+
87+
#[itest]
88+
fn plane_is_point_over() {
89+
let a = Plane::new(Vector3::BACK, 1.1);
90+
let inner_a = InnerPlane::from_outer(&a);
91+
let b = Vector3::new(6.7, 8.4, 8.3);
92+
check_mapping_eq(
93+
"is_point_over",
94+
a.is_point_over(b),
95+
inner_a.is_point_over(b),
96+
);
97+
98+
let b = Vector3::new(-0.5, -1.2, -7.1);
99+
check_mapping_eq(
100+
"is_point_over",
101+
a.is_point_over(b),
102+
inner_a.is_point_over(b),
103+
);
104+
}
105+
106+
#[itest]
107+
fn plane_project() {
108+
let a = Plane::new(Vector3::new(8.6, -1.1, -10.1).normalized(), 3.3);
109+
let inner_a = InnerPlane::from_outer(&a);
110+
let b = Vector3::new(7.2, -3.4, 9.9);
111+
check_mapping_eq("project", a.project(b), inner_a.project(b));
112+
}
113+
114+
#[itest]
115+
fn plane_intersect_segment() {
116+
let a = Plane::new(Vector3::BACK, -0.2);
117+
let inner_a = InnerPlane::from_outer(&a);
118+
let b = Vector3::new(7.2, 10.4, 9.9);
119+
let c = Vector3::new(-9.4, -3.4, -3.1);
120+
check_mapping_eq(
121+
"intersect_segment",
122+
a.intersect_segment(b, c)
123+
.as_ref()
124+
.map(ToVariant::to_variant)
125+
.unwrap_or_default(),
126+
inner_a.intersects_segment(b, c),
127+
);
128+
129+
let a = Plane::new(Vector3::BACK, 0.0);
130+
let inner_a = InnerPlane::from_outer(&a);
131+
let b = Vector3::BACK;
132+
let c = Vector3::new(0.0, 0.0, 0.5);
133+
check_mapping_eq(
134+
"intersect_segment",
135+
a.intersect_segment(b, c)
136+
.as_ref()
137+
.map(ToVariant::to_variant)
138+
.unwrap_or_default(),
139+
inner_a.intersects_segment(b, c),
140+
);
141+
}
142+
143+
#[itest]
144+
fn plane_intersect_ray() {
145+
let a = Plane::new(Vector3::BACK, 0.0);
146+
let inner_a = InnerPlane::from_outer(&a);
147+
let b = Vector3::new(0.1, 9.9, 5.7);
148+
let c = Vector3::new(3.5, 3.2, 0.3);
149+
check_mapping_eq(
150+
"intersect_ray",
151+
a.intersect_ray(b, c)
152+
.as_ref()
153+
.map(ToVariant::to_variant)
154+
.unwrap_or_default(),
155+
inner_a.intersects_ray(b, c),
156+
);
157+
158+
let b = Vector3::BACK;
159+
let c = Vector3::new(1.0, 0.0, 1.0);
160+
check_mapping_eq(
161+
"intersect_ray",
162+
a.intersect_ray(b, c)
163+
.as_ref()
164+
.map(ToVariant::to_variant)
165+
.unwrap_or_default(),
166+
inner_a.intersects_ray(b, c),
167+
);
168+
}
169+
170+
#[itest]
171+
fn plane_contains_point() {
172+
let a = Plane::new(Vector3::new(0.9, 6.6, 0.1).normalized(), 0.0001);
173+
let inner_a = InnerPlane::from_outer(&a);
174+
let b = Vector3::ZERO;
175+
let c: real = 0.01;
176+
check_mapping_eq(
177+
"contains_point",
178+
a.contains_point(b, Some(c)),
179+
inner_a.has_point(b, c.as_f64()),
180+
);
181+
182+
let a = Plane::new(Vector3::new(0.9, 6.6, 0.1).normalized(), 0.1);
183+
let inner_a = InnerPlane::from_outer(&a);
184+
check_mapping_eq(
185+
"contains_point",
186+
a.contains_point(b, Some(c)),
187+
inner_a.has_point(b, c.as_f64()),
188+
);
189+
}
190+
191+
#[itest]
192+
fn plane_is_equal_approx() {
193+
let a = Plane::new(Vector3::new(1.5, 6.3, 2.2).normalized(), 5.2);
194+
let inner_a = InnerPlane::from_outer(&a);
195+
let b = Plane::new(Vector3::new(1.5, 6.3, 2.2).normalized(), 5.2000001);
196+
check_mapping_eq(
197+
"is_equal_approx",
198+
a.is_equal_approx(&b),
199+
inner_a.is_equal_approx(b),
200+
);
201+
202+
let a = Plane::new(Vector3::new(-1.9, 9.0, 2.7).normalized(), 5.4);
203+
let inner_a = InnerPlane::from_outer(&a);
204+
let b = Plane::new(Vector3::new(0.0, 6.2, 2.5).normalized(), 0.4);
205+
check_mapping_eq(
206+
"is_equal_approx",
207+
a.is_equal_approx(&b),
208+
inner_a.is_equal_approx(b),
209+
);
210+
}
211+
212+
#[itest]
213+
fn plane_intersect_3() {
214+
let a = Plane::new(Vector3::new(1.0, 2.0, 0.0).normalized(), 0.0);
215+
let inner_a = InnerPlane::from_outer(&a);
216+
let b = Plane::new(Vector3::new(3.5, 6.0, -3.0).normalized(), 0.0);
217+
let c = Plane::new(Vector3::new(-1.0, 6.0, 0.5).normalized(), 0.0);
218+
check_mapping_eq(
219+
"intersect_3",
220+
a.intersect_3(&b, &c)
221+
.as_ref()
222+
.map(ToVariant::to_variant)
223+
.unwrap_or_default(),
224+
inner_a.intersect_3(b, c),
225+
);
226+
227+
let a = Plane::new(Vector3::new(1.5, 6.3, 2.2).normalized(), 5.2);
228+
let inner_a = InnerPlane::from_outer(&a);
229+
let b = Plane::new(Vector3::new(1.5, 6.3, 2.2).normalized(), 3.2);
230+
let c = Plane::new(Vector3::new(1.5, 6.3, 2.2).normalized(), 9.5);
231+
check_mapping_eq(
232+
"intersect_3",
233+
a.intersect_3(&b, &c)
234+
.as_ref()
235+
.map(ToVariant::to_variant)
236+
.unwrap_or_default(),
237+
inner_a.intersect_3(b, c),
238+
);
239+
}

0 commit comments

Comments
 (0)