ncollide2d/pipeline/narrow_phase/contact_generator/
composite_shape_composite_shape_manifold_generator.rs1use crate::math::Isometry;
2use crate::pipeline::narrow_phase::{
3 ContactAlgorithm, ContactDispatcher, ContactManifoldGenerator,
4};
5use crate::query::{
6 visitors::AABBSetsInterferencesCollector, ContactManifold, ContactPrediction,
7 ContactPreprocessor,
8};
9use crate::shape::{CompositeShape, Shape};
10use crate::utils::DeterministicState;
11use na::RealField;
12use std::collections::{hash_map::Entry, HashMap};
13
14pub struct CompositeShapeCompositeShapeManifoldGenerator<N> {
16 sub_detectors: HashMap<(usize, usize), (ContactAlgorithm<N>, usize), DeterministicState>,
17 interferences: Vec<(usize, usize)>,
18 timestamp: usize,
19}
20
21impl<N> CompositeShapeCompositeShapeManifoldGenerator<N> {
22 pub fn new() -> CompositeShapeCompositeShapeManifoldGenerator<N> {
24 CompositeShapeCompositeShapeManifoldGenerator {
25 sub_detectors: HashMap::with_hasher(DeterministicState),
26 interferences: Vec::new(),
27 timestamp: 0,
28 }
29 }
30}
31
32impl<N: RealField + Copy> CompositeShapeCompositeShapeManifoldGenerator<N> {
33 fn do_update(
34 &mut self,
35 dispatcher: &dyn ContactDispatcher<N>,
36 m1: &Isometry<N>,
37 g1: &dyn CompositeShape<N>,
38 proc1: Option<&dyn ContactPreprocessor<N>>,
39 m2: &Isometry<N>,
40 g2: &dyn CompositeShape<N>,
41 proc2: Option<&dyn ContactPreprocessor<N>>,
42 prediction: &ContactPrediction<N>,
43 manifold: &mut ContactManifold<N>,
44 ) {
45 self.timestamp += 1;
46
47 let ls_m2 = m1.inverse() * m2;
49 let ls_m2_abs_rot = ls_m2.rotation.to_rotation_matrix().matrix().abs();
51
52 {
53 let mut visitor = AABBSetsInterferencesCollector::new(
54 prediction.linear(),
55 &ls_m2,
56 &ls_m2_abs_rot,
57 &mut self.interferences,
58 );
59 g1.bvh().visit_bvtt(g2.bvh(), &mut visitor);
60 }
61
62 for id in self.interferences.drain(..) {
63 match self.sub_detectors.entry(id) {
64 Entry::Occupied(mut entry) => {
65 entry.get_mut().1 = self.timestamp;
66 }
67 Entry::Vacant(entry) => {
68 let mut new_detector = None;
69
70 g1.map_part_at(id.0, &Isometry::identity(), &mut |_, g1| {
71 g2.map_part_at(id.1, &Isometry::identity(), &mut |_, g2| {
72 new_detector = dispatcher.get_contact_algorithm(g1, g2)
73 });
74 });
75
76 if let Some(new_detector) = new_detector {
77 let _ = entry.insert((new_detector, self.timestamp));
78 }
79 }
80 }
81 }
82
83 let timestamp = self.timestamp;
85 self.sub_detectors.retain(|key, detector| {
86 if detector.1 != timestamp {
87 false
88 } else {
89 let mut keep = false;
90 g1.map_part_and_preprocessor_at(
91 key.0,
92 m1,
93 prediction,
94 &mut |m1, g1, part_proc1| {
95 g2.map_part_and_preprocessor_at(
96 key.1,
97 m2,
98 prediction,
99 &mut |m2, g2, part_proc2| {
100 keep = detector.0.generate_contacts(
102 dispatcher,
103 m1,
104 g1,
105 Some(&(proc1, part_proc1)),
106 m2,
107 g2,
108 Some(&(proc2, part_proc2)),
109 prediction,
110 manifold,
111 );
112 },
113 );
114 },
115 );
116
117 keep
118 }
119 });
120 }
121}
122
123impl<N: RealField + Copy> ContactManifoldGenerator<N>
124 for CompositeShapeCompositeShapeManifoldGenerator<N>
125{
126 fn generate_contacts(
127 &mut self,
128 d: &dyn ContactDispatcher<N>,
129 ma: &Isometry<N>,
130 a: &dyn Shape<N>,
131 proc1: Option<&dyn ContactPreprocessor<N>>,
132 mb: &Isometry<N>,
133 b: &dyn Shape<N>,
134 proc2: Option<&dyn ContactPreprocessor<N>>,
135 prediction: &ContactPrediction<N>,
136 manifold: &mut ContactManifold<N>,
137 ) -> bool {
138 if let (Some(csa), Some(csb)) = (a.as_composite_shape(), b.as_composite_shape()) {
139 self.do_update(d, ma, csa, proc1, mb, csb, proc2, prediction, manifold);
140 true
141 } else {
142 false
143 }
144 }
145}