Skip to content

Commit

Permalink
Remove dynamic flipping from heightfield and plane vs. ball tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralith committed Jun 15, 2020
1 parent bb52d08 commit f1da60b
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ impl<N: RealField> ContactDispatcher<N> for DefaultContactDispatcher {

if a_is_heightfield || b_is_heightfield {
return Some(wrap(
flip,
HeightFieldShapeManifoldGenerator::<N>::new(b_is_heightfield),
flip ^ b_is_heightfield,
HeightFieldShapeManifoldGenerator::<N>::new(),
));
} else if a_is_capsule && b_is_capsule {
Some(wrap(flip, CapsuleCapsuleManifoldGenerator::<N>::new()))
Expand All @@ -64,9 +64,9 @@ impl<N: RealField> ContactDispatcher<N> for DefaultContactDispatcher {
} else if a_is_ball && b_is_ball {
Some(wrap(flip, BallBallManifoldGenerator::<N>::new()))
} else if a_is_plane && b_is_ball {
Some(wrap(flip, PlaneBallManifoldGenerator::<N>::new(false)))
Some(wrap(flip, PlaneBallManifoldGenerator::<N>::new()))
} else if a_is_ball && b_is_plane {
Some(wrap(flip, PlaneBallManifoldGenerator::<N>::new(true)))
Some(wrap(!flip, PlaneBallManifoldGenerator::<N>::new()))
} else if a_is_plane && b.is_support_map() {
let gen = PlaneConvexPolyhedronManifoldGenerator::<N>::new(false);
Some(wrap(flip, gen))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@ use std::collections::{hash_map::Entry, HashMap};
/// Collision detector between an heightfield and another shape.
pub struct HeightFieldShapeManifoldGenerator<N: RealField> {
sub_detectors: HashMap<usize, (ContactAlgorithm<N>, usize), DeterministicState>,
flip: bool,
timestamp: usize,
}

impl<N: RealField> HeightFieldShapeManifoldGenerator<N> {
/// Creates a new collision detector between an heightfield and another shape.
pub fn new(flip: bool) -> HeightFieldShapeManifoldGenerator<N> {
pub fn new() -> HeightFieldShapeManifoldGenerator<N> {
HeightFieldShapeManifoldGenerator {
sub_detectors: HashMap::with_hasher(DeterministicState),
flip,
timestamp: 0,
}
}
Expand Down Expand Up @@ -47,20 +45,27 @@ impl<N: RealField> HeightFieldShapeManifoldGenerator<N> {
.entry(i)
{
Entry::Occupied(mut entry) => {
let ok = if self.flip {
entry.get_mut().0.generate_contacts(
dispatcher,
m2,
g2,
proc2,
m1,
elt1,
Some(&(proc1, part_proc1)),
prediction,
manifold,
)
} else {
entry.get_mut().0.generate_contacts(
let ok = entry.get_mut().0.generate_contacts(
dispatcher,
m1,
elt1,
Some(&(proc1, part_proc1)),
m2,
g2,
proc2,
prediction,
manifold,
);

if ok {
entry.get_mut().1 = self.timestamp;
}
}
Entry::Vacant(entry) => {
let new_detector = dispatcher.get_contact_algorithm(elt1, g2);

if let Some(mut new_detector) = new_detector {
let _ = new_detector.generate_contacts(
dispatcher,
m1,
elt1,
Expand All @@ -70,46 +75,7 @@ impl<N: RealField> HeightFieldShapeManifoldGenerator<N> {
proc2,
prediction,
manifold,
)
};

if ok {
entry.get_mut().1 = self.timestamp;
}
}
Entry::Vacant(entry) => {
let new_detector = if self.flip {
dispatcher.get_contact_algorithm(g2, elt1)
} else {
dispatcher.get_contact_algorithm(elt1, g2)
};

if let Some(mut new_detector) = new_detector {
if self.flip {
let _ = new_detector.generate_contacts(
dispatcher,
m2,
g2,
proc2,
m1,
elt1,
Some(&(proc1, part_proc1)),
prediction,
manifold,
);
} else {
let _ = new_detector.generate_contacts(
dispatcher,
m1,
elt1,
Some(&(proc1, part_proc1)),
m2,
g2,
proc2,
prediction,
manifold,
);
}
);
let _ = entry.insert((new_detector, self.timestamp));
}
}
Expand All @@ -135,16 +101,9 @@ impl<N: RealField> ContactManifoldGenerator<N> for HeightFieldShapeManifoldGener
prediction: &ContactPrediction<N>,
manifold: &mut ContactManifold<N>,
) -> bool {
if !self.flip {
if let Some(hf) = a.as_shape::<HeightField<N>>() {
self.do_update(d, ma, hf, proc1, mb, b, proc2, prediction, manifold);
return true;
}
} else {
if let Some(hf) = b.as_shape::<HeightField<N>>() {
self.do_update(d, mb, hf, proc2, ma, a, proc1, prediction, manifold);
return true;
}
if let Some(hf) = a.as_shape::<HeightField<N>>() {
self.do_update(d, ma, hf, proc1, mb, b, proc2, prediction, manifold);
return true;
}

return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,15 @@ use std::marker::PhantomData;
/// Collision detector between g1 plane and g1 shape implementing the `SupportMap` trait.
#[derive(Clone)]
pub struct PlaneBallManifoldGenerator<N: RealField> {
flip: bool,
phantom: PhantomData<N>,
}

impl<N: RealField> PlaneBallManifoldGenerator<N> {
/// Creates g1 new persistent collision detector between g1 plane and g1 shape with g1 support
/// mapping function.
#[inline]
pub fn new(flip: bool) -> PlaneBallManifoldGenerator<N> {
pub fn new() -> PlaneBallManifoldGenerator<N> {
PlaneBallManifoldGenerator {
flip,
phantom: PhantomData,
}
}
Expand All @@ -36,7 +34,6 @@ impl<N: RealField> PlaneBallManifoldGenerator<N> {
proc2: Option<&dyn ContactPreprocessor<N>>,
prediction: &ContactPrediction<N>,
manifold: &mut ContactManifold<N>,
flip: bool,
) -> bool {
if let (Some(plane), Some(ball)) = (g1.as_shape::<Plane<N>>(), g2.as_shape::<Ball<N>>()) {
let plane_normal = m1 * plane.normal();
Expand All @@ -61,19 +58,11 @@ impl<N: RealField> PlaneBallManifoldGenerator<N> {
let approx_ball = NeighborhoodGeometry::Point;
let approx_plane = NeighborhoodGeometry::Plane(*plane.normal());

if !flip {
contact = Contact::new(world1, world2, plane_normal, depth);
kinematic.set_approx1(f1, local1, approx_plane);
kinematic.set_approx2(f2, local2, approx_ball);
kinematic.set_dilation2(ball.radius());
let _ = manifold.push(contact, kinematic, Point::origin(), proc1, proc2);
} else {
contact = Contact::new(world2, world1, -plane_normal, depth);
kinematic.set_approx1(f2, local2, approx_ball);
kinematic.set_dilation1(ball.radius());
kinematic.set_approx2(f1, local1, approx_plane);
let _ = manifold.push(contact, kinematic, Point::origin(), proc2, proc1);
}
contact = Contact::new(world1, world2, plane_normal, depth);
kinematic.set_approx1(f1, local1, approx_plane);
kinematic.set_approx2(f2, local2, approx_ball);
kinematic.set_dilation2(ball.radius());
let _ = manifold.push(contact, kinematic, Point::origin(), proc1, proc2);
}

true
Expand All @@ -97,10 +86,6 @@ impl<N: RealField> ContactManifoldGenerator<N> for PlaneBallManifoldGenerator<N>
prediction: &ContactPrediction<N>,
manifold: &mut ContactManifold<N>,
) -> bool {
if !self.flip {
Self::do_update_to(m1, g1, proc1, m2, g2, proc2, prediction, manifold, false)
} else {
Self::do_update_to(m2, g2, proc2, m1, g1, proc1, prediction, manifold, true)
}
Self::do_update_to(m1, g1, proc1, m2, g2, proc2, prediction, manifold)
}
}

0 comments on commit f1da60b

Please sign in to comment.