parry3d/query/sat/
sat_cuboid_triangle.rs1#[cfg(feature = "dim3")]
2use crate::approx::AbsDiffEq;
3use crate::math::{Isometry, Real, Vector};
4#[cfg(feature = "dim3")]
5use crate::query::sat;
6#[cfg(feature = "dim2")]
7use crate::query::sat::support_map_support_map_compute_separation;
8use crate::shape::{Cuboid, SupportMap, Triangle};
9
10#[cfg(feature = "dim3")]
15#[inline(always)]
16pub fn cuboid_triangle_find_local_separating_edge_twoway(
17 cube1: &Cuboid,
18 triangle2: &Triangle,
19 pos12: &Isometry<Real>,
20) -> (Real, Vector<Real>) {
21 let a = pos12 * triangle2.a;
26 let b = pos12 * triangle2.b;
27 let c = pos12 * triangle2.c;
28
29 let ab = b - a;
30 let bc = c - b;
31 let ca = a - c;
32
33 let axes = [
35 Vector::new(0.0, -ab.z, ab.y),
37 Vector::new(ab.z, 0.0, -ab.x),
38 Vector::new(-ab.y, ab.x, 0.0),
39 Vector::new(0.0, -bc.z, bc.y),
41 Vector::new(bc.z, 0.0, -bc.x),
42 Vector::new(-bc.y, bc.x, 0.0),
43 Vector::new(0.0, -ca.z, ca.y),
45 Vector::new(ca.z, 0.0, -ca.x),
46 Vector::new(-ca.y, ca.x, 0.0),
47 ];
48
49 let tri_dots = [
50 (axes[0].dot(&a.coords), axes[0].dot(&c.coords)),
51 (axes[1].dot(&a.coords), axes[1].dot(&c.coords)),
52 (axes[2].dot(&a.coords), axes[2].dot(&c.coords)),
53 (axes[3].dot(&a.coords), axes[3].dot(&c.coords)),
54 (axes[4].dot(&a.coords), axes[4].dot(&c.coords)),
55 (axes[5].dot(&a.coords), axes[5].dot(&c.coords)),
56 (axes[6].dot(&a.coords), axes[6].dot(&b.coords)),
57 (axes[7].dot(&a.coords), axes[7].dot(&b.coords)),
58 (axes[8].dot(&a.coords), axes[8].dot(&b.coords)),
59 ];
60
61 let mut best_sep = -Real::MAX;
62 let mut best_axis = axes[0];
63
64 for (i, axis) in axes.iter().enumerate() {
65 let axis_norm_squared = axis.norm_squared();
66
67 if axis_norm_squared > Real::default_epsilon() {
68 let axis_norm = na::ComplexField::sqrt(axis_norm_squared);
69
70 let local_pt1 = cube1.local_support_point(axis);
73 let dot1 = local_pt1.coords.dot(axis) / axis_norm;
74
75 let (dot2_min, dot2_max) = crate::utils::sort2(tri_dots[i].0, tri_dots[i].1);
76
77 let separation_a = dot2_min / axis_norm - dot1; let separation_b = -dot2_max / axis_norm - dot1; if separation_a > best_sep {
81 best_sep = separation_a;
82 best_axis = *axis / axis_norm;
83 }
84
85 if separation_b > best_sep {
86 best_sep = separation_b;
87 best_axis = -*axis / axis_norm;
88 }
89 }
90 }
91
92 (best_sep, best_axis)
93}
94
95#[cfg(feature = "dim2")]
99pub fn triangle_support_map_find_local_separating_normal_oneway(
100 triangle1: &Triangle,
101 shape2: &impl SupportMap,
102 pos12: &Isometry<Real>,
103) -> (Real, Vector<Real>) {
104 let mut best_sep = -Real::MAX;
105 let mut best_normal = Vector::zeros();
106
107 for edge in &triangle1.edges() {
108 if let Some(normal) = edge.normal() {
109 let sep = support_map_support_map_compute_separation(triangle1, shape2, pos12, &normal);
110
111 if sep > best_sep {
112 best_sep = sep;
113 best_normal = *normal;
114 }
115 }
116 }
117
118 (best_sep, best_normal)
119}
120
121#[cfg(feature = "dim2")]
125pub fn triangle_cuboid_find_local_separating_normal_oneway(
126 triangle1: &Triangle,
127 shape2: &Cuboid,
128 pos12: &Isometry<Real>,
129) -> (Real, Vector<Real>) {
130 triangle_support_map_find_local_separating_normal_oneway(triangle1, shape2, pos12)
131}
132
133#[cfg(feature = "dim3")]
137#[inline(always)]
138pub fn triangle_cuboid_find_local_separating_normal_oneway(
139 triangle1: &Triangle,
140 shape2: &Cuboid,
141 pos12: &Isometry<Real>,
142) -> (Real, Vector<Real>) {
143 sat::point_cuboid_find_local_separating_normal_oneway(
144 triangle1.a,
145 triangle1.normal(),
146 shape2,
147 pos12,
148 )
149}