ncollide3d/pipeline/glue/
update.rs

1use na::RealField;
2
3use crate::bounding_volume::AABB;
4use crate::pipeline::broad_phase::{
5    BroadPhase, BroadPhaseInterferenceHandler, BroadPhasePairFilter,
6};
7use crate::pipeline::narrow_phase::{InteractionGraph, NarrowPhase};
8use crate::pipeline::object::{CollisionGroupsPairFilter, CollisionObjectRef, CollisionObjectSet};
9
10struct CollisionWorldInterferenceHandler<'a, 'b, N, Objects, Filter>
11where
12    N: RealField + Copy,
13    Objects: CollisionObjectSet<N>,
14    Filter: BroadPhasePairFilter<N, Objects> + ?Sized,
15{
16    narrow_phase: &'b mut NarrowPhase<N, Objects::CollisionObjectHandle>,
17    interactions: &'b mut InteractionGraph<N, Objects::CollisionObjectHandle>,
18    objects: &'a Objects,
19    pair_filters: Option<&'a Filter>,
20}
21
22impl<'a, 'b, N: RealField + Copy, Objects, Filter>
23    BroadPhaseInterferenceHandler<Objects::CollisionObjectHandle>
24    for CollisionWorldInterferenceHandler<'a, 'b, N, Objects, Filter>
25where
26    Objects: CollisionObjectSet<N>,
27    Filter: BroadPhasePairFilter<N, Objects> + ?Sized,
28{
29    fn is_interference_allowed(
30        &mut self,
31        b1: &Objects::CollisionObjectHandle,
32        b2: &Objects::CollisionObjectHandle,
33    ) -> bool {
34        let filter_by_groups = CollisionGroupsPairFilter;
35
36        filter_by_groups.is_pair_valid(*b1, *b2, self.objects)
37            && self
38                .pair_filters
39                .map(|f| f.is_pair_valid(*b1, *b2, self.objects))
40                .unwrap_or(true)
41    }
42
43    fn interference_started(
44        &mut self,
45        b1: &Objects::CollisionObjectHandle,
46        b2: &Objects::CollisionObjectHandle,
47    ) {
48        self.narrow_phase
49            .handle_interaction(self.interactions, self.objects, *b1, *b2, true)
50    }
51
52    fn interference_stopped(
53        &mut self,
54        b1: &Objects::CollisionObjectHandle,
55        b2: &Objects::CollisionObjectHandle,
56    ) {
57        self.narrow_phase
58            .handle_interaction(&mut self.interactions, self.objects, *b1, *b2, false)
59    }
60}
61
62/// Performs the broad-phase.
63///
64/// This will update the broad-phase internal structure, and create potential interaction pairs in the interaction graph.
65/// A `pair_filters` can be provided to filter out pairs of object that should not be considered.
66pub fn perform_broad_phase<N: RealField + Copy, Objects>(
67    objects: &Objects,
68    broad_phase: &mut (impl BroadPhase<N, AABB<N>, Objects::CollisionObjectHandle> + ?Sized),
69    narrow_phase: &mut NarrowPhase<N, Objects::CollisionObjectHandle>,
70    interactions: &mut InteractionGraph<N, Objects::CollisionObjectHandle>,
71    pair_filters: Option<&(impl BroadPhasePairFilter<N, Objects> + ?Sized)>,
72) where
73    Objects: CollisionObjectSet<N>,
74{
75    // Take changes into account.
76    objects.foreach(|_, co| {
77        let flags = co.update_flags();
78        let proxy_handle = co.proxy_handle().expect(crate::NOT_REGISTERED_ERROR);
79
80        if flags.needs_bounding_volume_update() {
81            broad_phase.deferred_set_bounding_volume(proxy_handle, co.compute_swept_aabb());
82        }
83
84        if flags.needs_broad_phase_redispatch() {
85            broad_phase.deferred_recompute_all_proximities_with(proxy_handle);
86        }
87    });
88
89    // Update the broad-phase.
90    broad_phase.update(&mut CollisionWorldInterferenceHandler {
91        interactions,
92        narrow_phase,
93        pair_filters,
94        objects,
95    });
96}
97
98/// Performs the narrow-phase.
99///
100/// This will update all interactions in the interaction graph by computing new contacts,
101/// and proximities.
102pub fn perform_narrow_phase<N, Objects>(
103    objects: &Objects,
104    narrow_phase: &mut NarrowPhase<N, Objects::CollisionObjectHandle>,
105    interactions: &mut InteractionGraph<N, Objects::CollisionObjectHandle>,
106) where
107    N: RealField + Copy,
108    Objects: CollisionObjectSet<N>,
109{
110    narrow_phase.update(interactions, objects);
111}
112
113/// Performs the broad-phase and the narrow-phase.
114///
115/// This execute a complete collision detection pipeline by performing the broad-phase first and then
116/// the narrow-phase.
117pub fn perform_all_pipeline<'a, N, Objects>(
118    objects: &Objects,
119    broad_phase: &mut (impl BroadPhase<N, AABB<N>, Objects::CollisionObjectHandle> + ?Sized),
120    narrow_phase: &mut NarrowPhase<N, Objects::CollisionObjectHandle>,
121    interactions: &mut InteractionGraph<N, Objects::CollisionObjectHandle>,
122    pair_filters: Option<&'a (impl BroadPhasePairFilter<N, Objects> + ?Sized)>,
123) where
124    N: RealField + Copy,
125    Objects: CollisionObjectSet<N>,
126{
127    perform_broad_phase(
128        objects,
129        broad_phase,
130        narrow_phase,
131        interactions,
132        pair_filters,
133    );
134    perform_narrow_phase(objects, narrow_phase, interactions);
135}