1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use crate::geometry::proximity_detector::PrimitiveProximityDetectionContext;
use crate::geometry::{sat, Proximity, Shape};
use crate::math::Isometry;
use ncollide::shape::Cuboid;
pub fn detect_proximity_cuboid_cuboid(ctxt: &mut PrimitiveProximityDetectionContext) -> Proximity {
if let (Shape::Cuboid(cube1), Shape::Cuboid(cube2)) = (ctxt.shape1, ctxt.shape2) {
detect_proximity(
ctxt.prediction_distance,
cube1,
ctxt.position1,
cube2,
ctxt.position2,
)
} else {
unreachable!()
}
}
pub fn detect_proximity<'a>(
prediction_distance: f32,
cube1: &'a Cuboid<f32>,
pos1: &'a Isometry<f32>,
cube2: &'a Cuboid<f32>,
pos2: &'a Isometry<f32>,
) -> Proximity {
let pos12 = pos1.inverse() * pos2;
let pos21 = pos12.inverse();
let sep1 =
sat::cuboid_cuboid_find_local_separating_normal_oneway(cube1, cube2, &pos12, &pos21).0;
if sep1 > prediction_distance {
return Proximity::Disjoint;
}
let sep2 =
sat::cuboid_cuboid_find_local_separating_normal_oneway(cube2, cube1, &pos21, &pos12).0;
if sep2 > prediction_distance {
return Proximity::Disjoint;
}
#[cfg(feature = "dim2")]
let sep3 = -f32::MAX;
#[cfg(feature = "dim3")]
let sep3 = sat::cuboid_cuboid_find_local_separating_edge_twoway(cube1, cube2, &pos12, &pos21).0;
if sep3 > prediction_distance {
return Proximity::Disjoint;
}
if sep2 > sep1 && sep2 > sep3 {
if sep2 > 0.0 {
Proximity::WithinMargin
} else {
Proximity::Intersecting
}
} else if sep3 > sep1 {
if sep3 > 0.0 {
Proximity::WithinMargin
} else {
Proximity::Intersecting
}
} else {
if sep1 > 0.0 {
Proximity::WithinMargin
} else {
Proximity::Intersecting
}
}
}