Skip to content

Commit bba75b8

Browse files
authored
Try #295:
2 parents 7573721 + 7fd0b89 commit bba75b8

File tree

3 files changed

+175
-1
lines changed

3 files changed

+175
-1
lines changed

godot-core/src/builtin/plane.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,14 @@ impl Plane {
217217
/// Returns a normalized copy of the plane.
218218
#[inline]
219219
pub fn normalized(self) -> Self {
220-
Plane::new(self.normal.normalized(), self.d)
220+
let length: real = self.normal.length();
221+
if length == 0.0 {
222+
return Plane {
223+
normal: Vector3::ZERO,
224+
d: 0.0,
225+
};
226+
}
227+
Plane::new(self.normal.normalized(), self.d / length)
221228
}
222229

223230
/// 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: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
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::{
11+
prelude::{inner::InnerPlane, real, Plane, RealConv, ToVariant, Vector3},
12+
private::class_macros::assert_eq_approx,
13+
};
14+
15+
#[itest]
16+
fn plane_equiv() {
17+
let test_planes = [
18+
Plane::new(Vector3::UP.normalized(), 0.0),
19+
Plane::new(Vector3::BACK.normalized(), 0.0),
20+
Plane::new(Vector3::new(1.5, 3.0, 0.0).normalized(), 2.0),
21+
Plane::new(Vector3::new(0.5, 2.0, 2.5).normalized(), 1.0),
22+
Plane::new(Vector3::new(-3.0, 5.0, 0.1).normalized(), -0.2),
23+
Plane::new(Vector3::new(1.82, 5.32, -6.1).normalized(), 6.0),
24+
Plane::new(Vector3::new(1.82, 5.32, -6.000001).normalized(), 6.0),
25+
];
26+
let unnormalized_planes = [
27+
Plane {
28+
normal: Vector3::new(4.2, 2.9, 1.5),
29+
d: 2.4,
30+
},
31+
Plane {
32+
normal: Vector3::new(-7.4, 10.5, -1.5),
33+
d: 6.0,
34+
},
35+
Plane {
36+
normal: Vector3::new(-3.1, 0.0, 1.4),
37+
d: 6.1,
38+
},
39+
Plane {
40+
normal: Vector3::new(-5.0, 12.0, 9.1),
41+
d: -2.4,
42+
},
43+
Plane {
44+
normal: Vector3::new(0.0, 0.0, 0.0),
45+
d: 6.0,
46+
},
47+
];
48+
let test_vectors = [
49+
Vector3::ZERO,
50+
Vector3::new(0.0, 3.0, 2.0),
51+
Vector3::new(6.1, 8.0, 9.0),
52+
Vector3::new(2.0, 1.0, -2.0),
53+
Vector3::new(5.2, 2.0, -1.0),
54+
Vector3::new(7.0, -3.0, -0.15),
55+
Vector3::new(0.0, 0.0, 0.0001),
56+
Vector3::new(0.0, 0.0, 0.000001),
57+
];
58+
let test_reals: [real; 5] = [1.0, 0.0005, 0.000005, 0.0000001, 0.0];
59+
let test_inf_planes = [
60+
Plane {
61+
normal: Vector3::new(real::INFINITY, 0.0, 0.0),
62+
d: 10.0,
63+
},
64+
Plane {
65+
normal: Vector3::new(real::NAN, real::INFINITY, real::NEG_INFINITY),
66+
d: real::NAN,
67+
},
68+
Plane {
69+
normal: Vector3::new(0.8, real::INFINITY, -1.2),
70+
d: 3.5,
71+
},
72+
];
73+
74+
fn check_mapping_eq<T>(context: &str, outer: T, inner: T)
75+
where
76+
T: PartialEq + Debug,
77+
{
78+
assert_eq!(
79+
outer, inner,
80+
"{context}: outer != inner ({outer:?} != {inner:?})"
81+
);
82+
}
83+
84+
fn check_mapping_eq_approx_plane(context: &str, outer: Plane, inner: Plane) {
85+
assert_eq_approx!(
86+
outer,
87+
inner,
88+
|a: Plane, b: Plane| a.is_equal_approx(&b),
89+
"{context}: outer != inner ({outer:?} != {inner:?})"
90+
);
91+
}
92+
93+
for a in unnormalized_planes {
94+
let inner_a = InnerPlane::from_outer(&a);
95+
check_mapping_eq_approx_plane("normalized", a.normalized(), inner_a.normalized());
96+
}
97+
98+
for a in test_planes {
99+
let inner_a = InnerPlane::from_outer(&a);
100+
101+
check_mapping_eq("center", a.center(), inner_a.get_center());
102+
check_mapping_eq("is_finite", a.is_finite(), inner_a.is_finite());
103+
104+
for b in test_inf_planes {
105+
let inner_b = InnerPlane::from_outer(&b);
106+
check_mapping_eq("is_finite", b.is_finite(), inner_b.is_finite());
107+
}
108+
109+
for b in test_vectors {
110+
check_mapping_eq(
111+
"distance_to",
112+
a.distance_to(b).as_f64(),
113+
inner_a.distance_to(b),
114+
);
115+
check_mapping_eq(
116+
"is_point_over",
117+
a.is_point_over(b),
118+
inner_a.is_point_over(b),
119+
);
120+
check_mapping_eq("project", a.project(b), inner_a.project(b));
121+
for c in test_vectors {
122+
check_mapping_eq(
123+
"intersect_segment",
124+
a.intersect_segment(b, c)
125+
.as_ref()
126+
.map(ToVariant::to_variant)
127+
.unwrap_or_default(),
128+
inner_a.intersects_segment(b, c),
129+
);
130+
check_mapping_eq(
131+
"intersect_ray",
132+
a.intersect_ray(b, c)
133+
.as_ref()
134+
.map(ToVariant::to_variant)
135+
.unwrap_or_default(),
136+
inner_a.intersects_ray(b, c),
137+
);
138+
}
139+
for c in test_reals {
140+
check_mapping_eq(
141+
"contains_point",
142+
a.contains_point(b, Some(c)),
143+
inner_a.has_point(b, c.as_f64()),
144+
);
145+
}
146+
}
147+
148+
for b in test_planes {
149+
check_mapping_eq(
150+
"is_equal_approx",
151+
a.is_equal_approx(&b),
152+
inner_a.is_equal_approx(b),
153+
);
154+
for c in test_planes {
155+
check_mapping_eq(
156+
"intersect_3",
157+
a.intersect_3(&b, &c)
158+
.as_ref()
159+
.map(ToVariant::to_variant)
160+
.unwrap_or_default(),
161+
inner_a.intersect_3(b, c),
162+
);
163+
}
164+
}
165+
}
166+
}

0 commit comments

Comments
 (0)