Skip to content

Commit 47c0826

Browse files
committed
Detect coplanar surfaces earlier and allow for wider distance gap to accomodate precision issues
1 parent debb151 commit 47c0826

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

src/bsp.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use {Intersection, Plane, Polygon, Splitter};
2+
use is_zero;
23

34
use binary_space_partition::{BspNode, Plane as BspPlane, PlaneCut};
45
use euclid::{TypedPoint3D, TypedVector3D};
@@ -18,15 +19,29 @@ impl<T, U> BspPlane for Polygon<T, U> where
1819
fn cut(&self, mut poly: Self) -> PlaneCut<Self> {
1920
debug!("\tCutting anchor {} by {}", poly.anchor, self.anchor);
2021
trace!("\t\tbase {:?}", self.plane);
21-
let dist = self.plane.signed_distance_sum_to(&poly);
2222

23-
match self.intersect(&poly) {
24-
Intersection::Coplanar if dist.approx_eq(&T::zero()) => {
25-
debug!("\t\tCoplanar and matching (dist = {:?})", dist);
23+
let (intersection, dist) = if self.plane.normal
24+
.dot(poly.plane.normal)
25+
.approx_eq(&T::one())
26+
{
27+
debug!("\t\tNormals roughly match");
28+
(Intersection::Coplanar, self.plane.offset - poly.plane.offset)
29+
} else {
30+
let is = self.intersect(&poly);
31+
let dist = self.plane.signed_distance_sum_to(&poly);
32+
(is, dist)
33+
};
34+
35+
match intersection {
36+
//Note: we deliberately make the comparison wider than just with T::epsilon().
37+
// This is done to avoid mistakenly ordering items that should be on the same
38+
// plane but end up slightly different due to the floating point precision.
39+
Intersection::Coplanar if is_zero(dist) => {
40+
debug!("\t\tCoplanar at {:?}", dist);
2641
PlaneCut::Sibling(poly)
2742
}
2843
Intersection::Coplanar | Intersection::Outside => {
29-
debug!("\t\tCoplanar at {:?}", dist);
44+
debug!("\t\tOutside at {:?}", dist);
3045
if dist > T::zero() {
3146
PlaneCut::Cut {
3247
front: vec![poly],

0 commit comments

Comments
 (0)