feat: reduce the amount of duplicate work the broad-phase is doing for user changes and CCD + release v0.28.0 (#872)
* feat: reduce the amount of duplicate work the broad-phase is doing for user changes and CCD * Release v0.28.0 * chore: fix warnings * chore: clippy fixes * chore: more clippy fixes
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
use super::TOIEntry;
|
||||
use crate::dynamics::{IslandManager, RigidBodyHandle, RigidBodySet};
|
||||
use crate::geometry::{ColliderParent, ColliderSet, CollisionEvent, NarrowPhase};
|
||||
use crate::dynamics::{IntegrationParameters, IslandManager, RigidBodyHandle, RigidBodySet};
|
||||
use crate::geometry::{BroadPhaseBvh, ColliderParent, ColliderSet, CollisionEvent, NarrowPhase};
|
||||
use crate::math::Real;
|
||||
use crate::parry::utils::SortedPair;
|
||||
use crate::pipeline::{EventHandler, QueryFilter, QueryPipeline};
|
||||
use crate::pipeline::{EventHandler, QueryFilter};
|
||||
use crate::prelude::{ActiveEvents, CollisionEventFlags};
|
||||
use parry::partitioning::{Bvh, BvhBuildStrategy};
|
||||
use parry::utils::hashmap::HashMap;
|
||||
use std::collections::BinaryHeap;
|
||||
|
||||
@@ -16,26 +15,14 @@ pub enum PredictedImpacts {
|
||||
}
|
||||
|
||||
/// Solver responsible for performing motion-clamping on fast-moving bodies.
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Default)]
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
pub struct CCDSolver {
|
||||
// TODO PERF: for now the CCD solver maintains its own bvh for CCD queries.
|
||||
// At each frame it get rebuilt.
|
||||
// We should consider an alternative to directly use the broad-phase’s.
|
||||
#[cfg_attr(feature = "serde-serialize", serde(skip))]
|
||||
bvh: Bvh,
|
||||
}
|
||||
|
||||
impl Default for CCDSolver {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
pub struct CCDSolver;
|
||||
|
||||
impl CCDSolver {
|
||||
/// Initializes a new CCD solver
|
||||
pub fn new() -> Self {
|
||||
Self { bvh: Bvh::new() }
|
||||
Self
|
||||
}
|
||||
|
||||
/// Apply motion-clamping to the bodies affected by the given `impacts`.
|
||||
@@ -101,42 +88,35 @@ impl CCDSolver {
|
||||
#[profiling::function]
|
||||
pub fn find_first_impact(
|
||||
&mut self,
|
||||
dt: Real,
|
||||
dt: Real, // NOTE: this doesn’t necessarily match the `params.dt`.
|
||||
params: &IntegrationParameters,
|
||||
islands: &IslandManager,
|
||||
bodies: &RigidBodySet,
|
||||
colliders: &ColliderSet,
|
||||
broad_phase: &mut BroadPhaseBvh,
|
||||
narrow_phase: &NarrowPhase,
|
||||
) -> Option<Real> {
|
||||
// Update the query pipeline with the colliders’ predicted positions.
|
||||
self.bvh = Bvh::from_iter(
|
||||
BvhBuildStrategy::Binned,
|
||||
colliders.iter_enabled().map(|(co_handle, co)| {
|
||||
let id = co_handle.into_raw_parts().0;
|
||||
if let Some(co_parent) = co.parent {
|
||||
let rb = &bodies[co_parent.handle];
|
||||
for (handle, co) in colliders.iter_enabled() {
|
||||
if let Some(co_parent) = co.parent {
|
||||
let rb = &bodies[co_parent.handle];
|
||||
if rb.is_ccd_active() {
|
||||
let predicted_pos = rb
|
||||
.pos
|
||||
.integrate_forces_and_velocities(dt, &rb.forces, &rb.vels, &rb.mprops);
|
||||
|
||||
let next_position = predicted_pos * co_parent.pos_wrt_parent;
|
||||
(
|
||||
id as usize,
|
||||
co.shape.compute_swept_aabb(&co.pos, &next_position),
|
||||
)
|
||||
} else {
|
||||
(id as usize, co.shape.compute_aabb(&co.pos))
|
||||
let swept_aabb = co.shape.compute_swept_aabb(&co.pos, &next_position);
|
||||
broad_phase.set_aabb(params, handle, swept_aabb);
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let query_pipeline = QueryPipeline {
|
||||
// NOTE: the upcast needs at least rust 1.86
|
||||
dispatcher: narrow_phase.query_dispatcher(),
|
||||
bvh: &self.bvh,
|
||||
let query_pipeline = broad_phase.as_query_pipeline(
|
||||
narrow_phase.query_dispatcher(),
|
||||
bodies,
|
||||
colliders,
|
||||
filter: QueryFilter::default(),
|
||||
};
|
||||
QueryFilter::default(),
|
||||
);
|
||||
|
||||
let mut pairs_seen = HashMap::default();
|
||||
let mut min_toi = dt;
|
||||
@@ -234,43 +214,39 @@ impl CCDSolver {
|
||||
#[profiling::function]
|
||||
pub fn predict_impacts_at_next_positions(
|
||||
&mut self,
|
||||
dt: Real,
|
||||
params: &IntegrationParameters,
|
||||
islands: &IslandManager,
|
||||
bodies: &RigidBodySet,
|
||||
colliders: &ColliderSet,
|
||||
broad_phase: &mut BroadPhaseBvh,
|
||||
narrow_phase: &NarrowPhase,
|
||||
events: &dyn EventHandler,
|
||||
) -> PredictedImpacts {
|
||||
let dt = params.dt;
|
||||
let mut frozen = HashMap::<_, Real>::default();
|
||||
let mut all_toi = BinaryHeap::new();
|
||||
let mut pairs_seen = HashMap::default();
|
||||
let mut min_overstep = dt;
|
||||
|
||||
// Update the query pipeline with the colliders’ `next_position`.
|
||||
self.bvh = Bvh::from_iter(
|
||||
BvhBuildStrategy::Binned,
|
||||
colliders.iter_enabled().map(|(co_handle, co)| {
|
||||
let id = co_handle.into_raw_parts().0;
|
||||
if let Some(co_parent) = co.parent {
|
||||
for (handle, co) in colliders.iter_enabled() {
|
||||
if let Some(co_parent) = co.parent {
|
||||
let rb = &bodies[co_parent.handle];
|
||||
if rb.is_ccd_active() {
|
||||
let rb_next_pos = &bodies[co_parent.handle].pos.next_position;
|
||||
let next_position = rb_next_pos * co_parent.pos_wrt_parent;
|
||||
(
|
||||
id as usize,
|
||||
co.shape.compute_swept_aabb(&co.pos, &next_position),
|
||||
)
|
||||
} else {
|
||||
(id as usize, co.shape.compute_aabb(&co.pos))
|
||||
let swept_aabb = co.shape.compute_swept_aabb(&co.pos, &next_position);
|
||||
broad_phase.set_aabb(params, handle, swept_aabb);
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let query_pipeline = QueryPipeline {
|
||||
dispatcher: narrow_phase.query_dispatcher(),
|
||||
bvh: &self.bvh,
|
||||
let query_pipeline = broad_phase.as_query_pipeline(
|
||||
narrow_phase.query_dispatcher(),
|
||||
bodies,
|
||||
colliders,
|
||||
filter: QueryFilter::default(),
|
||||
};
|
||||
QueryFilter::default(),
|
||||
);
|
||||
|
||||
/*
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user