#![allow(dead_code)]
use crate::geometry::contact_generator::PrimitiveContactGenerationContext;
use crate::geometry::{sat, Contact, ContactData, ContactManifold, ContactManifoldData, Polygon};
use crate::math::{Pose, Vector, Real};
#[cfg(feature = "dim2")]
use crate::{math::Vector, utils};
use parry::query;
pub fn generate_contacts_polygon_polygon(_ctxt: &mut PrimitiveContactGenerationContext) {
unimplemented!()
}
fn generate_contacts<'a>(
mut p1: &'a Polygon,
mut m1: &'a Pose,
mut p2: &'a Polygon,
mut m2: &'a Pose,
manifold: &'a mut ContactManifold,
) {
let mut m12 = m1.inv_mul(&m2);
let mut m21 = m12.inverse();
if manifold.try_update_contacts(&m12) {
return;
}
let mut sep1 = sat::polygon_polygon_compute_separation_features(p1, p2, &m12);
if sep1.0 > 0.0 {
manifold.points.clear();
return;
}
let mut sep2 = sat::polygon_polygon_compute_separation_features(p2, p1, &m21);
if sep2.0 > 0.0 {
manifold.points.clear();
return;
}
let mut swapped = false;
if sep2.0 > sep1.0 {
core::mem::swap(&mut sep1, &mut sep2);
core::mem::swap(&mut m1, &mut m2);
core::mem::swap(&mut p1, &mut p2);
core::mem::swap(&mut m12, &mut m21);
manifold.swap_identifiers();
swapped = true;
}
let support_face1 = sep1.1;
let local_n1 = p1.normals[support_face1];
let local_n2 = m21.rotation * -local_n1;
let support_face2 = p2.support_face(&local_n2);
let len1 = p1.vertices.len();
let len2 = p2.vertices.len();
let seg1 = (
p1.vertices[support_face1],
p1.vertices[(support_face1 + 1) % len1],
);
let seg2 = (
m12 * p2.vertices[support_face2],
m12 * p2.vertices[(support_face2 + 1) % len2],
);
if let Some((clip_a, clip_b)) = query::details::clip_segment_segment(seg1, seg2) {
let dist_a = (clip_a.1 - clip_a.0).dot(local_n1);
let dist_b = (clip_b.1 - clip_b.0).dot(local_n1);
let mut data_a = ContactData::default();
let mut data_b = ContactData::default();
let fids_a = (
((support_face1 * 2 + clip_a.2) % (len1 * 2)) as u8,
((support_face2 * 2 + clip_a.3) % (len2 * 2)) as u8,
);
let fids_b = (
((support_face1 * 2 + clip_b.2) % (len1 * 2)) as u8,
((support_face2 * 2 + clip_b.3) % (len2 * 2)) as u8,
);
if !manifold.points.is_empty() {
assert_eq!(manifold.points.len(), 2);
let original_fids_a;
let original_fids_b;
if swapped {
original_fids_a = (manifold.points[0].fid1, manifold.points[0].fid2);
original_fids_b = (manifold.points[1].fid1, manifold.points[1].fid2);
} else {
original_fids_a = (manifold.points[0].fid2, manifold.points[0].fid1);
original_fids_b = (manifold.points[1].fid2, manifold.points[1].fid1);
}
if fids_a == original_fids_a {
data_a = manifold.points[0].data;
} else if fids_a == original_fids_b {
data_a = manifold.points[1].data;
}
if fids_b == original_fids_a {
data_b = manifold.points[0].data;
} else if fids_b == original_fids_b {
data_b = manifold.points[1].data;
}
}
manifold.points.clear();
manifold.points.push(Contact {
local_p1: clip_a.0,
local_p2: m21 * clip_a.1,
fid1: fids_a.0,
fid2: fids_a.1,
dist: dist_a,
data: data_a,
});
manifold.points.push(Contact {
local_p1: clip_b.0,
local_p2: m21 * clip_b.1,
fid1: fids_b.0,
fid2: fids_b.1,
dist: dist_b,
data: data_b,
});
manifold.local_n1 = local_n1;
manifold.local_n2 = local_n2;
} else {
manifold.points.clear();
}
}