Allow the PhysicsPipeline and CollisionPipeline to update the QueryPipeline incrementally
This commit is contained in:
@@ -20,6 +20,7 @@ mod joint_fixed3;
|
|||||||
mod joint_prismatic3;
|
mod joint_prismatic3;
|
||||||
mod joint_revolute3;
|
mod joint_revolute3;
|
||||||
mod keva3;
|
mod keva3;
|
||||||
|
mod many_static3;
|
||||||
mod pyramid3;
|
mod pyramid3;
|
||||||
mod stacks3;
|
mod stacks3;
|
||||||
mod trimesh3;
|
mod trimesh3;
|
||||||
@@ -54,6 +55,7 @@ pub fn main() {
|
|||||||
("CCD", ccd3::init_world),
|
("CCD", ccd3::init_world),
|
||||||
("Compound", compound3::init_world),
|
("Compound", compound3::init_world),
|
||||||
("Convex polyhedron", convex_polyhedron3::init_world),
|
("Convex polyhedron", convex_polyhedron3::init_world),
|
||||||
|
("Many static", many_static3::init_world),
|
||||||
("Heightfield", heightfield3::init_world),
|
("Heightfield", heightfield3::init_world),
|
||||||
("Stacks", stacks3::init_world),
|
("Stacks", stacks3::init_world),
|
||||||
("Pyramid", pyramid3::init_world),
|
("Pyramid", pyramid3::init_world),
|
||||||
|
|||||||
52
benchmarks3d/many_static3.rs
Normal file
52
benchmarks3d/many_static3.rs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
use rapier3d::prelude::*;
|
||||||
|
use rapier_testbed3d::Testbed;
|
||||||
|
|
||||||
|
pub fn init_world(testbed: &mut Testbed) {
|
||||||
|
/*
|
||||||
|
* World
|
||||||
|
*/
|
||||||
|
let mut bodies = RigidBodySet::new();
|
||||||
|
let mut colliders = ColliderSet::new();
|
||||||
|
let impulse_joints = ImpulseJointSet::new();
|
||||||
|
let multibody_joints = MultibodyJointSet::new();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the balls
|
||||||
|
*/
|
||||||
|
let num = 50;
|
||||||
|
let rad = 1.0;
|
||||||
|
|
||||||
|
let shift = rad * 2.0 + 1.0;
|
||||||
|
let centerx = shift * (num as f32) / 2.0;
|
||||||
|
let centery = shift / 2.0;
|
||||||
|
let centerz = shift * (num as f32) / 2.0;
|
||||||
|
|
||||||
|
for i in 0..num {
|
||||||
|
for j in 0usize..num {
|
||||||
|
for k in 0..num {
|
||||||
|
let x = i as f32 * shift - centerx;
|
||||||
|
let y = j as f32 * shift + centery;
|
||||||
|
let z = k as f32 * shift - centerz;
|
||||||
|
|
||||||
|
let status = if j < num - 1 {
|
||||||
|
RigidBodyType::Fixed
|
||||||
|
} else {
|
||||||
|
RigidBodyType::Dynamic
|
||||||
|
};
|
||||||
|
let density = 0.477;
|
||||||
|
|
||||||
|
// Build the rigid body.
|
||||||
|
let rigid_body = RigidBodyBuilder::new(status).translation(vector![x, y, z]);
|
||||||
|
let handle = bodies.insert(rigid_body);
|
||||||
|
let collider = ColliderBuilder::ball(rad).density(density);
|
||||||
|
colliders.insert_with_parent(collider, handle, &mut bodies);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up the testbed.
|
||||||
|
*/
|
||||||
|
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
|
||||||
|
testbed.look_at(point![100.0, 100.0, 100.0], Point::origin());
|
||||||
|
}
|
||||||
@@ -123,7 +123,6 @@ impl CCDSolver {
|
|||||||
) -> Option<Real> {
|
) -> Option<Real> {
|
||||||
// Update the query pipeline.
|
// Update the query pipeline.
|
||||||
self.query_pipeline.update_with_mode(
|
self.query_pipeline.update_with_mode(
|
||||||
islands,
|
|
||||||
bodies,
|
bodies,
|
||||||
colliders,
|
colliders,
|
||||||
QueryPipelineMode::SweepTestWithPredictedPosition { dt },
|
QueryPipelineMode::SweepTestWithPredictedPosition { dt },
|
||||||
@@ -245,7 +244,6 @@ impl CCDSolver {
|
|||||||
|
|
||||||
// Update the query pipeline.
|
// Update the query pipeline.
|
||||||
self.query_pipeline.update_with_mode(
|
self.query_pipeline.update_with_mode(
|
||||||
islands,
|
|
||||||
bodies,
|
bodies,
|
||||||
colliders,
|
colliders,
|
||||||
QueryPipelineMode::SweepTestWithNextPosition,
|
QueryPipelineMode::SweepTestWithNextPosition,
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ use crate::utils::{WBasis, WReal};
|
|||||||
|
|
||||||
#[cfg(feature = "dim3")]
|
#[cfg(feature = "dim3")]
|
||||||
use crate::dynamics::SphericalJoint;
|
use crate::dynamics::SphericalJoint;
|
||||||
use crate::geometry::ColliderEnabled;
|
|
||||||
|
|
||||||
#[cfg(feature = "dim3")]
|
#[cfg(feature = "dim3")]
|
||||||
bitflags::bitflags! {
|
bitflags::bitflags! {
|
||||||
|
|||||||
88
src/geometry/broad_phase_qbvh.rs
Normal file
88
src/geometry/broad_phase_qbvh.rs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
use crate::geometry::{BroadPhasePairEvent, ColliderHandle, ColliderPair, ColliderSet};
|
||||||
|
use parry::bounding_volume::BoundingVolume;
|
||||||
|
use parry::math::Real;
|
||||||
|
use parry::partitioning::Qbvh;
|
||||||
|
use parry::partitioning::QbvhUpdateWorkspace;
|
||||||
|
use parry::query::visitors::BoundingVolumeIntersectionsSimultaneousVisitor;
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct BroadPhase {
|
||||||
|
qbvh: Qbvh<ColliderHandle>,
|
||||||
|
stack: Vec<(u32, u32)>,
|
||||||
|
#[cfg_attr(feature = "serde-serialize", serde(skip))]
|
||||||
|
workspace: QbvhUpdateWorkspace,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BroadPhase {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BroadPhase {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
qbvh: Qbvh::new(),
|
||||||
|
stack: vec![],
|
||||||
|
workspace: QbvhUpdateWorkspace::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)] // This broad-phase is just experimental right now.
|
||||||
|
pub fn update(
|
||||||
|
&mut self,
|
||||||
|
prediction_distance: Real,
|
||||||
|
colliders: &ColliderSet,
|
||||||
|
modified_colliders: &[ColliderHandle],
|
||||||
|
removed_colliders: &[ColliderHandle],
|
||||||
|
events: &mut Vec<BroadPhasePairEvent>,
|
||||||
|
) {
|
||||||
|
let margin = 0.01;
|
||||||
|
|
||||||
|
if modified_colliders.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Visitor to find collision pairs.
|
||||||
|
let mut visitor = BoundingVolumeIntersectionsSimultaneousVisitor::new(
|
||||||
|
|co1: &ColliderHandle, co2: &ColliderHandle| {
|
||||||
|
events.push(BroadPhasePairEvent::AddPair(ColliderPair::new(*co1, *co2)));
|
||||||
|
true
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let full_rebuild = self.qbvh.raw_nodes().is_empty();
|
||||||
|
|
||||||
|
if full_rebuild {
|
||||||
|
self.qbvh.clear_and_rebuild(
|
||||||
|
colliders.iter().map(|(handle, collider)| {
|
||||||
|
(
|
||||||
|
handle,
|
||||||
|
collider.compute_aabb().loosened(prediction_distance / 2.0),
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
margin,
|
||||||
|
);
|
||||||
|
self.qbvh
|
||||||
|
.traverse_bvtt_with_stack(&self.qbvh, &mut visitor, &mut self.stack);
|
||||||
|
} else {
|
||||||
|
for modified in modified_colliders {
|
||||||
|
self.qbvh.pre_update_or_insert(*modified);
|
||||||
|
}
|
||||||
|
|
||||||
|
for removed in removed_colliders {
|
||||||
|
self.qbvh.remove(*removed);
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = self.qbvh.refit(margin, &mut self.workspace, |handle| {
|
||||||
|
colliders[*handle]
|
||||||
|
.compute_aabb()
|
||||||
|
.loosened(prediction_distance / 2.0)
|
||||||
|
});
|
||||||
|
self.qbvh
|
||||||
|
.traverse_modified_bvtt_with_stack(&self.qbvh, &mut visitor, &mut self.stack);
|
||||||
|
self.qbvh.rebalance(margin, &mut self.workspace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -285,6 +285,7 @@ impl ColliderSet {
|
|||||||
|
|
||||||
// Just a very long name instead of `.get_mut` to make sure
|
// Just a very long name instead of `.get_mut` to make sure
|
||||||
// this is really the method we wanted to use instead of `get_mut_internal`.
|
// this is really the method we wanted to use instead of `get_mut_internal`.
|
||||||
|
#[allow(dead_code)]
|
||||||
pub(crate) fn get_mut_internal_with_modification_tracking(
|
pub(crate) fn get_mut_internal_with_modification_tracking(
|
||||||
&mut self,
|
&mut self,
|
||||||
handle: ColliderHandle,
|
handle: ColliderHandle,
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
//! Structures related to geometry: colliders, shapes, etc.
|
//! Structures related to geometry: colliders, shapes, etc.
|
||||||
|
|
||||||
pub use self::broad_phase_multi_sap::{BroadPhase, BroadPhasePairEvent, ColliderPair};
|
pub use self::broad_phase_multi_sap::{BroadPhasePairEvent, ColliderPair};
|
||||||
|
|
||||||
|
pub use self::broad_phase_multi_sap::BroadPhase;
|
||||||
|
// pub use self::broad_phase_qbvh::BroadPhase;
|
||||||
pub use self::collider_components::*;
|
pub use self::collider_components::*;
|
||||||
pub use self::contact_pair::{
|
pub use self::contact_pair::{
|
||||||
ContactData, ContactManifoldData, ContactPair, IntersectionPair, SolverContact, SolverFlags,
|
ContactData, ContactManifoldData, ContactPair, IntersectionPair, SolverContact, SolverFlags,
|
||||||
@@ -199,5 +202,6 @@ mod interaction_graph;
|
|||||||
mod interaction_groups;
|
mod interaction_groups;
|
||||||
mod narrow_phase;
|
mod narrow_phase;
|
||||||
|
|
||||||
|
mod broad_phase_qbvh;
|
||||||
mod collider;
|
mod collider;
|
||||||
mod collider_set;
|
mod collider_set;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::geometry::{
|
|||||||
BroadPhase, BroadPhasePairEvent, ColliderChanges, ColliderHandle, ColliderPair, NarrowPhase,
|
BroadPhase, BroadPhasePairEvent, ColliderChanges, ColliderHandle, ColliderPair, NarrowPhase,
|
||||||
};
|
};
|
||||||
use crate::math::Real;
|
use crate::math::Real;
|
||||||
use crate::pipeline::{EventHandler, PhysicsHooks};
|
use crate::pipeline::{EventHandler, PhysicsHooks, QueryPipeline};
|
||||||
use crate::{dynamics::RigidBodySet, geometry::ColliderSet};
|
use crate::{dynamics::RigidBodySet, geometry::ColliderSet};
|
||||||
|
|
||||||
/// The collision pipeline, responsible for performing collision detection between colliders.
|
/// The collision pipeline, responsible for performing collision detection between colliders.
|
||||||
@@ -111,6 +111,7 @@ impl CollisionPipeline {
|
|||||||
narrow_phase: &mut NarrowPhase,
|
narrow_phase: &mut NarrowPhase,
|
||||||
bodies: &mut RigidBodySet,
|
bodies: &mut RigidBodySet,
|
||||||
colliders: &mut ColliderSet,
|
colliders: &mut ColliderSet,
|
||||||
|
query_pipeline: Option<&mut QueryPipeline>,
|
||||||
hooks: &dyn PhysicsHooks,
|
hooks: &dyn PhysicsHooks,
|
||||||
events: &dyn EventHandler,
|
events: &dyn EventHandler,
|
||||||
) {
|
) {
|
||||||
@@ -154,6 +155,10 @@ impl CollisionPipeline {
|
|||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if let Some(queries) = query_pipeline {
|
||||||
|
queries.update_incremental(colliders, &modified_colliders, &removed_colliders, true);
|
||||||
|
}
|
||||||
|
|
||||||
self.clear_modified_colliders(colliders, &mut modified_colliders);
|
self.clear_modified_colliders(colliders, &mut modified_colliders);
|
||||||
removed_colliders.clear();
|
removed_colliders.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use crate::geometry::{
|
|||||||
ContactManifoldIndex, NarrowPhase, TemporaryInteractionIndex,
|
ContactManifoldIndex, NarrowPhase, TemporaryInteractionIndex,
|
||||||
};
|
};
|
||||||
use crate::math::{Real, Vector};
|
use crate::math::{Real, Vector};
|
||||||
use crate::pipeline::{EventHandler, PhysicsHooks};
|
use crate::pipeline::{EventHandler, PhysicsHooks, QueryPipeline};
|
||||||
use {crate::dynamics::RigidBodySet, crate::geometry::ColliderSet};
|
use {crate::dynamics::RigidBodySet, crate::geometry::ColliderSet};
|
||||||
|
|
||||||
/// The physics pipeline, responsible for stepping the whole physics simulation.
|
/// The physics pipeline, responsible for stepping the whole physics simulation.
|
||||||
@@ -404,6 +404,7 @@ impl PhysicsPipeline {
|
|||||||
impulse_joints: &mut ImpulseJointSet,
|
impulse_joints: &mut ImpulseJointSet,
|
||||||
multibody_joints: &mut MultibodyJointSet,
|
multibody_joints: &mut MultibodyJointSet,
|
||||||
ccd_solver: &mut CCDSolver,
|
ccd_solver: &mut CCDSolver,
|
||||||
|
mut query_pipeline: Option<&mut QueryPipeline>,
|
||||||
hooks: &dyn PhysicsHooks,
|
hooks: &dyn PhysicsHooks,
|
||||||
events: &dyn EventHandler,
|
events: &dyn EventHandler,
|
||||||
) {
|
) {
|
||||||
@@ -468,13 +469,17 @@ impl PhysicsPipeline {
|
|||||||
colliders,
|
colliders,
|
||||||
impulse_joints,
|
impulse_joints,
|
||||||
multibody_joints,
|
multibody_joints,
|
||||||
&modified_colliders[..],
|
&modified_colliders,
|
||||||
&mut removed_colliders,
|
&removed_colliders,
|
||||||
hooks,
|
hooks,
|
||||||
events,
|
events,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if let Some(queries) = query_pipeline.as_deref_mut() {
|
||||||
|
queries.update_incremental(colliders, &modified_colliders, &removed_colliders, false);
|
||||||
|
}
|
||||||
|
|
||||||
self.clear_modified_colliders(colliders, &mut modified_colliders);
|
self.clear_modified_colliders(colliders, &mut modified_colliders);
|
||||||
removed_colliders.clear();
|
removed_colliders.clear();
|
||||||
|
|
||||||
@@ -595,13 +600,22 @@ impl PhysicsPipeline {
|
|||||||
colliders,
|
colliders,
|
||||||
impulse_joints,
|
impulse_joints,
|
||||||
multibody_joints,
|
multibody_joints,
|
||||||
&mut modified_colliders,
|
&modified_colliders,
|
||||||
&mut removed_colliders,
|
&[],
|
||||||
hooks,
|
hooks,
|
||||||
events,
|
events,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if let Some(queries) = query_pipeline.as_deref_mut() {
|
||||||
|
queries.update_incremental(
|
||||||
|
colliders,
|
||||||
|
&modified_colliders,
|
||||||
|
&[],
|
||||||
|
remaining_substeps == 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.clear_modified_colliders(colliders, &mut modified_colliders);
|
self.clear_modified_colliders(colliders, &mut modified_colliders);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use crate::dynamics::{IslandManager, RigidBodyHandle};
|
use crate::dynamics::RigidBodyHandle;
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
Aabb, Collider, ColliderHandle, InteractionGroups, PointProjection, Qbvh, Ray, RayIntersection,
|
Aabb, Collider, ColliderHandle, InteractionGroups, PointProjection, Qbvh, Ray, RayIntersection,
|
||||||
};
|
};
|
||||||
use crate::math::{Isometry, Point, Real, Vector};
|
use crate::math::{Isometry, Point, Real, Vector};
|
||||||
use crate::{dynamics::RigidBodySet, geometry::ColliderSet};
|
use crate::{dynamics::RigidBodySet, geometry::ColliderSet};
|
||||||
use parry::partitioning::QbvhDataGenerator;
|
use parry::partitioning::{QbvhDataGenerator, QbvhUpdateWorkspace};
|
||||||
use parry::query::details::{
|
use parry::query::details::{
|
||||||
IntersectionCompositeShapeShapeBestFirstVisitor,
|
IntersectionCompositeShapeShapeBestFirstVisitor,
|
||||||
NonlinearTOICompositeShapeShapeBestFirstVisitor, PointCompositeShapeProjBestFirstVisitor,
|
NonlinearTOICompositeShapeShapeBestFirstVisitor, PointCompositeShapeProjBestFirstVisitor,
|
||||||
@@ -30,8 +30,9 @@ pub struct QueryPipeline {
|
|||||||
)]
|
)]
|
||||||
query_dispatcher: Arc<dyn QueryDispatcher>,
|
query_dispatcher: Arc<dyn QueryDispatcher>,
|
||||||
qbvh: Qbvh<ColliderHandle>,
|
qbvh: Qbvh<ColliderHandle>,
|
||||||
tree_built: bool,
|
|
||||||
dilation_factor: Real,
|
dilation_factor: Real,
|
||||||
|
#[cfg_attr(feature = "serde-serialize", serde(skip))]
|
||||||
|
workspace: QbvhUpdateWorkspace,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct QueryPipelineAsCompositeShape<'a> {
|
struct QueryPipelineAsCompositeShape<'a> {
|
||||||
@@ -310,8 +311,8 @@ impl QueryPipeline {
|
|||||||
Self {
|
Self {
|
||||||
query_dispatcher: Arc::new(d),
|
query_dispatcher: Arc::new(d),
|
||||||
qbvh: Qbvh::new(),
|
qbvh: Qbvh::new(),
|
||||||
tree_built: false,
|
|
||||||
dilation_factor: 0.01,
|
dilation_factor: 0.01,
|
||||||
|
workspace: QbvhUpdateWorkspace::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,25 +321,39 @@ impl QueryPipeline {
|
|||||||
&*self.query_dispatcher
|
&*self.query_dispatcher
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the acceleration structure on the query pipeline.
|
/// Update the query pipeline incrementally, avoiding a complete rebuild of its
|
||||||
pub fn update(
|
/// internal data-structure.
|
||||||
|
pub fn update_incremental(
|
||||||
&mut self,
|
&mut self,
|
||||||
islands: &IslandManager,
|
|
||||||
bodies: &RigidBodySet,
|
|
||||||
colliders: &ColliderSet,
|
colliders: &ColliderSet,
|
||||||
|
modified_colliders: &[ColliderHandle],
|
||||||
|
removed_colliders: &[ColliderHandle],
|
||||||
|
refit_and_rebalance: bool,
|
||||||
) {
|
) {
|
||||||
self.update_with_mode(
|
for modified in modified_colliders {
|
||||||
islands,
|
self.qbvh.pre_update_or_insert(*modified);
|
||||||
bodies,
|
}
|
||||||
colliders,
|
|
||||||
QueryPipelineMode::CurrentPosition,
|
for removed in removed_colliders {
|
||||||
)
|
self.qbvh.remove(*removed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if refit_and_rebalance {
|
||||||
|
let _ = self.qbvh.refit(0.0, &mut self.workspace, |handle| {
|
||||||
|
colliders[*handle].compute_aabb()
|
||||||
|
});
|
||||||
|
self.qbvh.rebalance(0.0, &mut self.workspace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Update the acceleration structure on the query pipeline.
|
||||||
|
pub fn update(&mut self, bodies: &RigidBodySet, colliders: &ColliderSet) {
|
||||||
|
self.update_with_mode(bodies, colliders, QueryPipelineMode::CurrentPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the acceleration structure on the query pipeline.
|
/// Update the acceleration structure on the query pipeline.
|
||||||
pub fn update_with_mode(
|
pub fn update_with_mode(
|
||||||
&mut self,
|
&mut self,
|
||||||
islands: &IslandManager,
|
|
||||||
bodies: &RigidBodySet,
|
bodies: &RigidBodySet,
|
||||||
colliders: &ColliderSet,
|
colliders: &ColliderSet,
|
||||||
mode: QueryPipelineMode,
|
mode: QueryPipelineMode,
|
||||||
@@ -392,71 +407,12 @@ impl QueryPipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.tree_built {
|
|
||||||
let generator = DataGenerator {
|
let generator = DataGenerator {
|
||||||
bodies,
|
bodies,
|
||||||
colliders,
|
colliders,
|
||||||
mode,
|
mode,
|
||||||
};
|
};
|
||||||
self.qbvh.clear_and_rebuild(generator, self.dilation_factor);
|
self.qbvh.clear_and_rebuild(generator, self.dilation_factor);
|
||||||
|
|
||||||
// FIXME: uncomment this once we handle insertion/removals properly.
|
|
||||||
// self.tree_built = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for handle in islands.iter_active_bodies() {
|
|
||||||
let rb = &bodies[handle];
|
|
||||||
for handle in &rb.colliders.0 {
|
|
||||||
self.qbvh.pre_update(*handle)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match mode {
|
|
||||||
QueryPipelineMode::CurrentPosition => {
|
|
||||||
self.qbvh.update(
|
|
||||||
|handle| {
|
|
||||||
let co = &colliders[*handle];
|
|
||||||
co.shape.compute_aabb(&co.pos)
|
|
||||||
},
|
|
||||||
self.dilation_factor,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
QueryPipelineMode::SweepTestWithNextPosition => {
|
|
||||||
self.qbvh.update(
|
|
||||||
|handle| {
|
|
||||||
let co = &colliders[*handle];
|
|
||||||
if let Some(parent) = &co.parent {
|
|
||||||
let rb_next_pos = &bodies[parent.handle].pos.next_position;
|
|
||||||
let next_position = rb_next_pos * parent.pos_wrt_parent;
|
|
||||||
co.shape.compute_swept_aabb(&co.pos, &next_position)
|
|
||||||
} else {
|
|
||||||
co.shape.compute_aabb(&co.pos)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
self.dilation_factor,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
QueryPipelineMode::SweepTestWithPredictedPosition { dt } => {
|
|
||||||
self.qbvh.update(
|
|
||||||
|handle| {
|
|
||||||
let co = &colliders[*handle];
|
|
||||||
if let Some(parent) = co.parent {
|
|
||||||
let rb = &bodies[parent.handle];
|
|
||||||
let predicted_pos = rb.pos.integrate_forces_and_velocities(
|
|
||||||
dt, &rb.forces, &rb.vels, &rb.mprops,
|
|
||||||
);
|
|
||||||
|
|
||||||
let next_position = predicted_pos * parent.pos_wrt_parent;
|
|
||||||
co.shape.compute_swept_aabb(&co.pos, &next_position)
|
|
||||||
} else {
|
|
||||||
co.shape.compute_aabb(&co.pos)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
self.dilation_factor,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the closest intersection between a ray and a set of collider.
|
/// Find the closest intersection between a ray and a set of collider.
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ pub(crate) fn handle_user_changes_to_rigid_bodies(
|
|||||||
bodies: &mut RigidBodySet,
|
bodies: &mut RigidBodySet,
|
||||||
colliders: &mut ColliderSet,
|
colliders: &mut ColliderSet,
|
||||||
impulse_joints: &mut ImpulseJointSet,
|
impulse_joints: &mut ImpulseJointSet,
|
||||||
multibody_joints: &mut MultibodyJointSet,
|
_multibody_joints: &mut MultibodyJointSet, // FIXME: propagate disabled state to multibodies
|
||||||
modified_bodies: &[RigidBodyHandle],
|
modified_bodies: &[RigidBodyHandle],
|
||||||
modified_colliders: &mut Vec<ColliderHandle>,
|
modified_colliders: &mut Vec<ColliderHandle>,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -215,6 +215,7 @@ impl Harness {
|
|||||||
&mut physics.impulse_joints,
|
&mut physics.impulse_joints,
|
||||||
&mut physics.multibody_joints,
|
&mut physics.multibody_joints,
|
||||||
&mut physics.ccd_solver,
|
&mut physics.ccd_solver,
|
||||||
|
&mut physics.query_pipeline,
|
||||||
&*physics.hooks,
|
&*physics.hooks,
|
||||||
event_handler,
|
event_handler,
|
||||||
);
|
);
|
||||||
@@ -233,16 +234,11 @@ impl Harness {
|
|||||||
&mut self.physics.impulse_joints,
|
&mut self.physics.impulse_joints,
|
||||||
&mut self.physics.multibody_joints,
|
&mut self.physics.multibody_joints,
|
||||||
&mut self.physics.ccd_solver,
|
&mut self.physics.ccd_solver,
|
||||||
|
Some(&mut self.physics.query_pipeline),
|
||||||
&*self.physics.hooks,
|
&*self.physics.hooks,
|
||||||
&self.event_handler,
|
&self.event_handler,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.physics.query_pipeline.update(
|
|
||||||
&self.physics.islands,
|
|
||||||
&self.physics.bodies,
|
|
||||||
&self.physics.colliders,
|
|
||||||
);
|
|
||||||
|
|
||||||
for plugin in &mut self.plugins {
|
for plugin in &mut self.plugins {
|
||||||
plugin.step(&mut self.physics, &self.state)
|
plugin.step(&mut self.physics, &self.state)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user