feat: add a BroadPhaseTrait for allowing custom broad-phases
This commit is contained in:
committed by
Sébastien Crozet
parent
cfb2c2c93e
commit
3d112287b9
@@ -11,6 +11,12 @@
|
|||||||
based only on its current velocity.
|
based only on its current velocity.
|
||||||
- Add `Collider::copy_from` to copy most collider attributes to an existing collider.
|
- Add `Collider::copy_from` to copy most collider attributes to an existing collider.
|
||||||
- Add `RigidBody::copy_from` to copy most rigid-body attributes to an existing rigid-body.
|
- Add `RigidBody::copy_from` to copy most rigid-body attributes to an existing rigid-body.
|
||||||
|
- Add the `BroadPhase` trait and expect an implementor of this trait as input to `PhysicsPipeline::step`.
|
||||||
|
|
||||||
|
### Modified
|
||||||
|
|
||||||
|
- Renamed `BroadPhase` to `BroadPhaseMultiSap`. The `BroadPhase` is no a trait that can be
|
||||||
|
implemented for providing a custom broad-phase to rapier.
|
||||||
|
|
||||||
## v0.18.0 (24 Jan. 2024)
|
## v0.18.0 (24 Jan. 2024)
|
||||||
|
|
||||||
|
|||||||
47
src/geometry/broad_phase.rs
Normal file
47
src/geometry/broad_phase.rs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
use crate::geometry::{BroadPhasePairEvent, ColliderHandle, ColliderSet};
|
||||||
|
use parry::math::Real;
|
||||||
|
|
||||||
|
/// An internal index stored in colliders by some broad-phase algorithms.
|
||||||
|
pub type BroadPhaseProxyIndex = u32;
|
||||||
|
|
||||||
|
/// Trait implemented by broad-phase algorithms supported by Rapier.
|
||||||
|
///
|
||||||
|
/// The task of a broad-phase algorithm is to detect potential collision pairs, usually based on
|
||||||
|
/// bounding volumes. The pairs must be concervative: it is OK to create a collision pair if
|
||||||
|
/// two objects don’t actually touch, but it is incorrect to remove a pair between two objects
|
||||||
|
/// that are still touching. In other words, it can have false-positive (though these induce
|
||||||
|
/// some computational overhead on the narrow-phase), but cannot have false-negative.
|
||||||
|
pub trait BroadPhase {
|
||||||
|
/// Updates the broad-phase.
|
||||||
|
///
|
||||||
|
/// The results must be output through the `events` struct. The broad-phase algorithm is only
|
||||||
|
/// required to generate new events (i.e. no need to re-send an `AddPair` event if it was already
|
||||||
|
/// sent previously and no `RemovePair` happened since then). Sending redundant events is allowed
|
||||||
|
/// but can result in a slight computational overhead.
|
||||||
|
///
|
||||||
|
/// The `colliders` set is mutable only to provide access to
|
||||||
|
/// [`collider.set_internal_broad_phase_proxy_index`]. Other properties of the collider should
|
||||||
|
/// **not** be modified during the broad-phase update.
|
||||||
|
///
|
||||||
|
/// # Parameters
|
||||||
|
/// - `prediction_distance`: colliders that are not exactly touching, but closer to this
|
||||||
|
/// distance must form a collision pair.
|
||||||
|
/// - `colliders`: the set of colliders. Change detection with `collider.needs_broad_phase_update()`
|
||||||
|
/// can be relied on at this stage.
|
||||||
|
/// - `modified_colliders`: colliders that are know to be modified since the last update.
|
||||||
|
/// - `removed_colliders`: colliders that got removed since the last update. Any associated data
|
||||||
|
/// in the broad-phase should be removed by this call to `update`.
|
||||||
|
/// - `events`: the broad-phase’s output. They indicate what collision pairs need to be created
|
||||||
|
/// and what pairs need to be removed. It is OK to create pairs for colliders that don’t
|
||||||
|
/// actually collide (though this can increase computational overhead in the narrow-phase)
|
||||||
|
/// but it is important not to indicate removal of a collision pair if the underlying colliders
|
||||||
|
/// are still touching or closer than `prediction_distance`.
|
||||||
|
fn update(
|
||||||
|
&mut self,
|
||||||
|
prediction_distance: Real,
|
||||||
|
colliders: &mut ColliderSet,
|
||||||
|
modified_colliders: &[ColliderHandle],
|
||||||
|
removed_colliders: &[ColliderHandle],
|
||||||
|
events: &mut Vec<BroadPhasePairEvent>,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
use super::{
|
use super::{
|
||||||
BroadPhasePairEvent, ColliderPair, SAPLayer, SAPProxies, SAPProxy, SAPProxyData, SAPRegionPool,
|
BroadPhasePairEvent, ColliderPair, SAPLayer, SAPProxies, SAPProxy, SAPProxyData, SAPRegionPool,
|
||||||
};
|
};
|
||||||
use crate::geometry::broad_phase_multi_sap::SAPProxyIndex;
|
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
ColliderBroadPhaseData, ColliderChanges, ColliderHandle, ColliderPosition, ColliderSet,
|
BroadPhaseProxyIndex, ColliderBroadPhaseData, ColliderChanges, ColliderHandle,
|
||||||
ColliderShape,
|
ColliderPosition, ColliderSet, ColliderShape,
|
||||||
};
|
};
|
||||||
use crate::math::Real;
|
use crate::math::Real;
|
||||||
|
use crate::prelude::BroadPhase;
|
||||||
use crate::utils::IndexMut2;
|
use crate::utils::IndexMut2;
|
||||||
use parry::bounding_volume::BoundingVolume;
|
use parry::bounding_volume::BoundingVolume;
|
||||||
use parry::utils::hashmap::HashMap;
|
use parry::utils::hashmap::HashMap;
|
||||||
@@ -90,7 +90,7 @@ pub struct BroadPhaseMultiSap {
|
|||||||
// Another alternative would be to remove ColliderProxyId and
|
// Another alternative would be to remove ColliderProxyId and
|
||||||
// just use a Coarena. But this seems like it could use too
|
// just use a Coarena. But this seems like it could use too
|
||||||
// much memory.
|
// much memory.
|
||||||
colliders_proxy_ids: HashMap<ColliderHandle, SAPProxyIndex>,
|
colliders_proxy_ids: HashMap<ColliderHandle, BroadPhaseProxyIndex>,
|
||||||
#[cfg_attr(feature = "serde-serialize", serde(skip))]
|
#[cfg_attr(feature = "serde-serialize", serde(skip))]
|
||||||
region_pool: SAPRegionPool, // To avoid repeated allocations.
|
region_pool: SAPRegionPool, // To avoid repeated allocations.
|
||||||
// We could think serializing this workspace is useless.
|
// We could think serializing this workspace is useless.
|
||||||
@@ -156,7 +156,7 @@ impl BroadPhaseMultiSap {
|
|||||||
/// remove, the `complete_removal` method MUST be called to
|
/// remove, the `complete_removal` method MUST be called to
|
||||||
/// complete the removal of these proxies, by actually removing them
|
/// complete the removal of these proxies, by actually removing them
|
||||||
/// from all the relevant layers/regions/axes.
|
/// from all the relevant layers/regions/axes.
|
||||||
fn predelete_proxy(&mut self, proxy_index: SAPProxyIndex) {
|
fn predelete_proxy(&mut self, proxy_index: BroadPhaseProxyIndex) {
|
||||||
if proxy_index == crate::INVALID_U32 {
|
if proxy_index == crate::INVALID_U32 {
|
||||||
// This collider has not been added to the broad-phase yet.
|
// This collider has not been added to the broad-phase yet.
|
||||||
return;
|
return;
|
||||||
@@ -449,65 +449,6 @@ impl BroadPhaseMultiSap {
|
|||||||
!layer.created_regions.is_empty()
|
!layer.created_regions.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the broad-phase, taking into account the new collider positions.
|
|
||||||
pub fn update(
|
|
||||||
&mut self,
|
|
||||||
prediction_distance: Real,
|
|
||||||
colliders: &mut ColliderSet,
|
|
||||||
modified_colliders: &[ColliderHandle],
|
|
||||||
removed_colliders: &[ColliderHandle],
|
|
||||||
events: &mut Vec<BroadPhasePairEvent>,
|
|
||||||
) {
|
|
||||||
// Phase 1: pre-delete the collisions that have been deleted.
|
|
||||||
self.handle_removed_colliders(removed_colliders);
|
|
||||||
|
|
||||||
let mut need_region_propagation = false;
|
|
||||||
|
|
||||||
// Phase 2: pre-delete the collisions that have been deleted.
|
|
||||||
for handle in modified_colliders {
|
|
||||||
// NOTE: we use `get` because the collider may no longer
|
|
||||||
// exist if it has been removed.
|
|
||||||
if let Some(co) = colliders.get_mut_internal(*handle) {
|
|
||||||
if !co.is_enabled() || !co.changes.needs_broad_phase_update() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut new_proxy_id = co.bf_data.proxy_index;
|
|
||||||
|
|
||||||
if self.handle_modified_collider(
|
|
||||||
prediction_distance,
|
|
||||||
*handle,
|
|
||||||
&mut new_proxy_id,
|
|
||||||
(&co.pos, &co.shape, &co.changes),
|
|
||||||
) {
|
|
||||||
need_region_propagation = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if co.bf_data.proxy_index != new_proxy_id {
|
|
||||||
self.colliders_proxy_ids.insert(*handle, new_proxy_id);
|
|
||||||
|
|
||||||
// Make sure we have the new proxy index in case
|
|
||||||
// the collider was added for the first time.
|
|
||||||
co.bf_data = ColliderBroadPhaseData {
|
|
||||||
proxy_index: new_proxy_id,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phase 3: bottom-up pass to propagate new regions from smaller layers to larger layers.
|
|
||||||
if need_region_propagation {
|
|
||||||
self.propagate_created_regions();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phase 4: top-down pass to propagate proxies from larger layers to smaller layers.
|
|
||||||
self.update_layers_and_find_pairs(events);
|
|
||||||
|
|
||||||
// Phase 5: bottom-up pass to remove proxies, and propagate region removed from smaller
|
|
||||||
// layers to possible remove regions from larger layers that would become empty that way.
|
|
||||||
self.complete_removals(colliders, removed_colliders);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Propagate regions from the smallest layers up to the larger layers.
|
/// Propagate regions from the smallest layers up to the larger layers.
|
||||||
///
|
///
|
||||||
/// Whenever a region is created on a layer `n`, then its Aabb must be
|
/// Whenever a region is created on a layer `n`, then its Aabb must be
|
||||||
@@ -618,6 +559,67 @@ impl BroadPhaseMultiSap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BroadPhase for BroadPhaseMultiSap {
|
||||||
|
/// Updates the broad-phase, taking into account the new collider positions.
|
||||||
|
fn update(
|
||||||
|
&mut self,
|
||||||
|
prediction_distance: Real,
|
||||||
|
colliders: &mut ColliderSet,
|
||||||
|
modified_colliders: &[ColliderHandle],
|
||||||
|
removed_colliders: &[ColliderHandle],
|
||||||
|
events: &mut Vec<BroadPhasePairEvent>,
|
||||||
|
) {
|
||||||
|
// Phase 1: pre-delete the collisions that have been deleted.
|
||||||
|
self.handle_removed_colliders(removed_colliders);
|
||||||
|
|
||||||
|
let mut need_region_propagation = false;
|
||||||
|
|
||||||
|
// Phase 2: pre-delete the collisions that have been deleted.
|
||||||
|
for handle in modified_colliders {
|
||||||
|
// NOTE: we use `get` because the collider may no longer
|
||||||
|
// exist if it has been removed.
|
||||||
|
if let Some(co) = colliders.get_mut_internal(*handle) {
|
||||||
|
if !co.is_enabled() || !co.changes.needs_broad_phase_update() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut new_proxy_id = co.bf_data.proxy_index;
|
||||||
|
|
||||||
|
if self.handle_modified_collider(
|
||||||
|
prediction_distance,
|
||||||
|
*handle,
|
||||||
|
&mut new_proxy_id,
|
||||||
|
(&co.pos, &co.shape, &co.changes),
|
||||||
|
) {
|
||||||
|
need_region_propagation = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if co.bf_data.proxy_index != new_proxy_id {
|
||||||
|
self.colliders_proxy_ids.insert(*handle, new_proxy_id);
|
||||||
|
|
||||||
|
// Make sure we have the new proxy index in case
|
||||||
|
// the collider was added for the first time.
|
||||||
|
co.bf_data = ColliderBroadPhaseData {
|
||||||
|
proxy_index: new_proxy_id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Phase 3: bottom-up pass to propagate new regions from smaller layers to larger layers.
|
||||||
|
if need_region_propagation {
|
||||||
|
self.propagate_created_regions();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Phase 4: top-down pass to propagate proxies from larger layers to smaller layers.
|
||||||
|
self.update_layers_and_find_pairs(events);
|
||||||
|
|
||||||
|
// Phase 5: bottom-up pass to remove proxies, and propagate region removed from smaller
|
||||||
|
// layers to possible remove regions from larger layers that would become empty that way.
|
||||||
|
self.complete_removals(colliders, removed_colliders);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::dynamics::{
|
use crate::dynamics::{
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
pub use self::broad_phase_multi_sap::BroadPhaseMultiSap;
|
pub use self::broad_phase_multi_sap::BroadPhaseMultiSap;
|
||||||
pub use self::broad_phase_pair_event::{BroadPhasePairEvent, ColliderPair};
|
pub use self::broad_phase_pair_event::{BroadPhasePairEvent, ColliderPair};
|
||||||
pub use self::sap_proxy::SAPProxyIndex;
|
|
||||||
|
|
||||||
use self::sap_axis::*;
|
use self::sap_axis::*;
|
||||||
use self::sap_endpoint::*;
|
use self::sap_endpoint::*;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use super::{SAPEndpoint, SAPProxies, NUM_SENTINELS};
|
use super::{SAPEndpoint, SAPProxies, NUM_SENTINELS};
|
||||||
use crate::geometry::broad_phase_multi_sap::DELETED_AABB_VALUE;
|
use crate::geometry::broad_phase_multi_sap::DELETED_AABB_VALUE;
|
||||||
use crate::geometry::SAPProxyIndex;
|
use crate::geometry::BroadPhaseProxyIndex;
|
||||||
use crate::math::Real;
|
use crate::math::Real;
|
||||||
use bit_vec::BitVec;
|
use bit_vec::BitVec;
|
||||||
use parry::bounding_volume::BoundingVolume;
|
use parry::bounding_volume::BoundingVolume;
|
||||||
@@ -39,7 +39,7 @@ impl SAPAxis {
|
|||||||
pub fn batch_insert(
|
pub fn batch_insert(
|
||||||
&mut self,
|
&mut self,
|
||||||
dim: usize,
|
dim: usize,
|
||||||
new_proxies: &[SAPProxyIndex],
|
new_proxies: &[BroadPhaseProxyIndex],
|
||||||
proxies: &SAPProxies,
|
proxies: &SAPProxies,
|
||||||
reporting: Option<&mut HashMap<(u32, u32), bool>>,
|
reporting: Option<&mut HashMap<(u32, u32), bool>>,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use super::{SAPProxies, SAPProxy, SAPRegion, SAPRegionPool};
|
use super::{SAPProxies, SAPProxy, SAPRegion, SAPRegionPool};
|
||||||
use crate::geometry::broad_phase_multi_sap::DELETED_AABB_VALUE;
|
use crate::geometry::broad_phase_multi_sap::DELETED_AABB_VALUE;
|
||||||
use crate::geometry::{Aabb, SAPProxyIndex};
|
use crate::geometry::{Aabb, BroadPhaseProxyIndex};
|
||||||
use crate::math::{Point, Real};
|
use crate::math::{Point, Real};
|
||||||
use parry::bounding_volume::BoundingVolume;
|
use parry::bounding_volume::BoundingVolume;
|
||||||
use parry::utils::hashmap::{Entry, HashMap};
|
use parry::utils::hashmap::{Entry, HashMap};
|
||||||
@@ -13,11 +13,11 @@ pub(crate) struct SAPLayer {
|
|||||||
pub smaller_layer: Option<u8>,
|
pub smaller_layer: Option<u8>,
|
||||||
pub larger_layer: Option<u8>,
|
pub larger_layer: Option<u8>,
|
||||||
region_width: Real,
|
region_width: Real,
|
||||||
pub regions: HashMap<Point<i32>, SAPProxyIndex>,
|
pub regions: HashMap<Point<i32>, BroadPhaseProxyIndex>,
|
||||||
#[cfg_attr(feature = "serde-serialize", serde(skip))]
|
#[cfg_attr(feature = "serde-serialize", serde(skip))]
|
||||||
regions_to_potentially_remove: Vec<Point<i32>>, // Workspace
|
regions_to_potentially_remove: Vec<Point<i32>>, // Workspace
|
||||||
#[cfg_attr(feature = "serde-serialize", serde(skip))]
|
#[cfg_attr(feature = "serde-serialize", serde(skip))]
|
||||||
pub created_regions: Vec<SAPProxyIndex>,
|
pub created_regions: Vec<BroadPhaseProxyIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SAPLayer {
|
impl SAPLayer {
|
||||||
@@ -103,7 +103,7 @@ impl SAPLayer {
|
|||||||
/// one region on its parent "larger" layer.
|
/// one region on its parent "larger" layer.
|
||||||
fn register_subregion(
|
fn register_subregion(
|
||||||
&mut self,
|
&mut self,
|
||||||
proxy_id: SAPProxyIndex,
|
proxy_id: BroadPhaseProxyIndex,
|
||||||
proxies: &mut SAPProxies,
|
proxies: &mut SAPProxies,
|
||||||
pool: &mut SAPRegionPool,
|
pool: &mut SAPRegionPool,
|
||||||
) {
|
) {
|
||||||
@@ -140,7 +140,7 @@ impl SAPLayer {
|
|||||||
|
|
||||||
fn unregister_subregion(
|
fn unregister_subregion(
|
||||||
&mut self,
|
&mut self,
|
||||||
proxy_id: SAPProxyIndex,
|
proxy_id: BroadPhaseProxyIndex,
|
||||||
proxy_region: &SAPRegion,
|
proxy_region: &SAPRegion,
|
||||||
proxies: &mut SAPProxies,
|
proxies: &mut SAPProxies,
|
||||||
) {
|
) {
|
||||||
@@ -191,7 +191,7 @@ impl SAPLayer {
|
|||||||
region_key: Point<i32>,
|
region_key: Point<i32>,
|
||||||
proxies: &mut SAPProxies,
|
proxies: &mut SAPProxies,
|
||||||
pool: &mut SAPRegionPool,
|
pool: &mut SAPRegionPool,
|
||||||
) -> SAPProxyIndex {
|
) -> BroadPhaseProxyIndex {
|
||||||
match self.regions.entry(region_key) {
|
match self.regions.entry(region_key) {
|
||||||
// Yay, the region already exists!
|
// Yay, the region already exists!
|
||||||
Entry::Occupied(occupied) => *occupied.get(),
|
Entry::Occupied(occupied) => *occupied.get(),
|
||||||
@@ -266,7 +266,7 @@ impl SAPLayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn predelete_proxy(&mut self, proxies: &mut SAPProxies, proxy_index: SAPProxyIndex) {
|
pub fn predelete_proxy(&mut self, proxies: &mut SAPProxies, proxy_index: BroadPhaseProxyIndex) {
|
||||||
// Discretize the Aabb to find the regions that need to be invalidated.
|
// Discretize the Aabb to find the regions that need to be invalidated.
|
||||||
let proxy_aabb = &mut proxies[proxy_index].aabb;
|
let proxy_aabb = &mut proxies[proxy_index].aabb;
|
||||||
let start = super::point_key(proxy_aabb.mins, self.region_width);
|
let start = super::point_key(proxy_aabb.mins, self.region_width);
|
||||||
@@ -379,7 +379,7 @@ impl SAPLayer {
|
|||||||
pub fn proper_proxy_moved_to_bigger_layer(
|
pub fn proper_proxy_moved_to_bigger_layer(
|
||||||
&mut self,
|
&mut self,
|
||||||
proxies: &mut SAPProxies,
|
proxies: &mut SAPProxies,
|
||||||
proxy_id: SAPProxyIndex,
|
proxy_id: BroadPhaseProxyIndex,
|
||||||
) {
|
) {
|
||||||
for (point, region_id) in &self.regions {
|
for (point, region_id) in &self.regions {
|
||||||
let region = &mut proxies[*region_id].data.as_region_mut();
|
let region = &mut proxies[*region_id].data.as_region_mut();
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
use super::NEXT_FREE_SENTINEL;
|
use super::NEXT_FREE_SENTINEL;
|
||||||
use crate::geometry::broad_phase_multi_sap::SAPRegion;
|
use crate::geometry::broad_phase_multi_sap::SAPRegion;
|
||||||
use crate::geometry::ColliderHandle;
|
use crate::geometry::{BroadPhaseProxyIndex, ColliderHandle};
|
||||||
use parry::bounding_volume::Aabb;
|
use parry::bounding_volume::Aabb;
|
||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
|
|
||||||
pub type SAPProxyIndex = u32;
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum SAPProxyData {
|
pub enum SAPProxyData {
|
||||||
@@ -49,7 +47,7 @@ impl SAPProxyData {
|
|||||||
pub struct SAPProxy {
|
pub struct SAPProxy {
|
||||||
pub data: SAPProxyData,
|
pub data: SAPProxyData,
|
||||||
pub aabb: Aabb,
|
pub aabb: Aabb,
|
||||||
pub next_free: SAPProxyIndex,
|
pub next_free: BroadPhaseProxyIndex,
|
||||||
// TODO: pack the layer_id and layer_depth into a single u16?
|
// TODO: pack the layer_id and layer_depth into a single u16?
|
||||||
pub layer_id: u8,
|
pub layer_id: u8,
|
||||||
pub layer_depth: i8,
|
pub layer_depth: i8,
|
||||||
@@ -81,7 +79,7 @@ impl SAPProxy {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SAPProxies {
|
pub struct SAPProxies {
|
||||||
pub elements: Vec<SAPProxy>,
|
pub elements: Vec<SAPProxy>,
|
||||||
pub first_free: SAPProxyIndex,
|
pub first_free: BroadPhaseProxyIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SAPProxies {
|
impl Default for SAPProxies {
|
||||||
@@ -98,7 +96,7 @@ impl SAPProxies {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, proxy: SAPProxy) -> SAPProxyIndex {
|
pub fn insert(&mut self, proxy: SAPProxy) -> BroadPhaseProxyIndex {
|
||||||
if self.first_free != NEXT_FREE_SENTINEL {
|
if self.first_free != NEXT_FREE_SENTINEL {
|
||||||
let proxy_id = self.first_free;
|
let proxy_id = self.first_free;
|
||||||
self.first_free = self.elements[proxy_id as usize].next_free;
|
self.first_free = self.elements[proxy_id as usize].next_free;
|
||||||
@@ -110,31 +108,31 @@ impl SAPProxies {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove(&mut self, proxy_id: SAPProxyIndex) {
|
pub fn remove(&mut self, proxy_id: BroadPhaseProxyIndex) {
|
||||||
let proxy = &mut self.elements[proxy_id as usize];
|
let proxy = &mut self.elements[proxy_id as usize];
|
||||||
proxy.next_free = self.first_free;
|
proxy.next_free = self.first_free;
|
||||||
self.first_free = proxy_id;
|
self.first_free = proxy_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: this must not take holes into account.
|
// NOTE: this must not take holes into account.
|
||||||
pub fn get_mut(&mut self, i: SAPProxyIndex) -> Option<&mut SAPProxy> {
|
pub fn get_mut(&mut self, i: BroadPhaseProxyIndex) -> Option<&mut SAPProxy> {
|
||||||
self.elements.get_mut(i as usize)
|
self.elements.get_mut(i as usize)
|
||||||
}
|
}
|
||||||
// NOTE: this must not take holes into account.
|
// NOTE: this must not take holes into account.
|
||||||
pub fn get(&self, i: SAPProxyIndex) -> Option<&SAPProxy> {
|
pub fn get(&self, i: BroadPhaseProxyIndex) -> Option<&SAPProxy> {
|
||||||
self.elements.get(i as usize)
|
self.elements.get(i as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index<SAPProxyIndex> for SAPProxies {
|
impl Index<BroadPhaseProxyIndex> for SAPProxies {
|
||||||
type Output = SAPProxy;
|
type Output = SAPProxy;
|
||||||
fn index(&self, i: SAPProxyIndex) -> &SAPProxy {
|
fn index(&self, i: BroadPhaseProxyIndex) -> &SAPProxy {
|
||||||
self.elements.index(i as usize)
|
self.elements.index(i as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IndexMut<SAPProxyIndex> for SAPProxies {
|
impl IndexMut<BroadPhaseProxyIndex> for SAPProxies {
|
||||||
fn index_mut(&mut self, i: SAPProxyIndex) -> &mut SAPProxy {
|
fn index_mut(&mut self, i: BroadPhaseProxyIndex) -> &mut SAPProxy {
|
||||||
self.elements.index_mut(i as usize)
|
self.elements.index_mut(i as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use super::{SAPAxis, SAPProxies};
|
use super::{SAPAxis, SAPProxies};
|
||||||
use crate::geometry::SAPProxyIndex;
|
use crate::geometry::BroadPhaseProxyIndex;
|
||||||
use crate::math::DIM;
|
use crate::math::DIM;
|
||||||
use bit_vec::BitVec;
|
use bit_vec::BitVec;
|
||||||
use parry::bounding_volume::Aabb;
|
use parry::bounding_volume::Aabb;
|
||||||
@@ -13,8 +13,8 @@ pub struct SAPRegion {
|
|||||||
pub axes: [SAPAxis; DIM],
|
pub axes: [SAPAxis; DIM],
|
||||||
pub existing_proxies: BitVec,
|
pub existing_proxies: BitVec,
|
||||||
#[cfg_attr(feature = "serde-serialize", serde(skip))]
|
#[cfg_attr(feature = "serde-serialize", serde(skip))]
|
||||||
pub to_insert: Vec<SAPProxyIndex>, // Workspace
|
pub to_insert: Vec<BroadPhaseProxyIndex>, // Workspace
|
||||||
pub subregions: Vec<SAPProxyIndex>,
|
pub subregions: Vec<BroadPhaseProxyIndex>,
|
||||||
pub id_in_parent_subregion: u32,
|
pub id_in_parent_subregion: u32,
|
||||||
pub update_count: u8,
|
pub update_count: u8,
|
||||||
pub needs_update_after_subregion_removal: bool,
|
pub needs_update_after_subregion_removal: bool,
|
||||||
@@ -90,7 +90,7 @@ impl SAPRegion {
|
|||||||
/// If this region contains the given proxy, this will decrement this region's proxy count.
|
/// If this region contains the given proxy, this will decrement this region's proxy count.
|
||||||
///
|
///
|
||||||
/// Returns `true` if this region contained the proxy. Returns `false` otherwise.
|
/// Returns `true` if this region contained the proxy. Returns `false` otherwise.
|
||||||
pub fn proper_proxy_moved_to_a_bigger_layer(&mut self, proxy_id: SAPProxyIndex) -> bool {
|
pub fn proper_proxy_moved_to_a_bigger_layer(&mut self, proxy_id: BroadPhaseProxyIndex) -> bool {
|
||||||
if self.existing_proxies.get(proxy_id as usize) == Some(true) {
|
if self.existing_proxies.get(proxy_id as usize) == Some(true) {
|
||||||
// NOTE: we are just registering the fact that that proxy isn't a
|
// NOTE: we are just registering the fact that that proxy isn't a
|
||||||
// subproper proxy anymore. But it is still part of this region
|
// subproper proxy anymore. But it is still part of this region
|
||||||
@@ -142,7 +142,7 @@ impl SAPRegion {
|
|||||||
self.subproper_proxy_count -= num_deleted_subregion_endpoints[0] / 2;
|
self.subproper_proxy_count -= num_deleted_subregion_endpoints[0] / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn predelete_proxy(&mut self, _proxy_id: SAPProxyIndex) {
|
pub fn predelete_proxy(&mut self, _proxy_id: BroadPhaseProxyIndex) {
|
||||||
// We keep the proxy_id as argument for uniformity with the "preupdate"
|
// We keep the proxy_id as argument for uniformity with the "preupdate"
|
||||||
// method. However we don't actually need it because the deletion will be
|
// method. However we don't actually need it because the deletion will be
|
||||||
// handled transparently during the next update.
|
// handled transparently during the next update.
|
||||||
@@ -153,14 +153,18 @@ impl SAPRegion {
|
|||||||
self.update_count = self.update_count.max(1);
|
self.update_count = self.update_count.max(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_subregion(&mut self, proxy_id: SAPProxyIndex) -> usize {
|
pub fn register_subregion(&mut self, proxy_id: BroadPhaseProxyIndex) -> usize {
|
||||||
let subregion_index = self.subregions.len();
|
let subregion_index = self.subregions.len();
|
||||||
self.subregions.push(proxy_id);
|
self.subregions.push(proxy_id);
|
||||||
self.preupdate_proxy(proxy_id, true);
|
self.preupdate_proxy(proxy_id, true);
|
||||||
subregion_index
|
subregion_index
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn preupdate_proxy(&mut self, proxy_id: SAPProxyIndex, is_subproper_proxy: bool) -> bool {
|
pub fn preupdate_proxy(
|
||||||
|
&mut self,
|
||||||
|
proxy_id: BroadPhaseProxyIndex,
|
||||||
|
is_subproper_proxy: bool,
|
||||||
|
) -> bool {
|
||||||
let mask_len = self.existing_proxies.len();
|
let mask_len = self.existing_proxies.len();
|
||||||
if proxy_id as usize >= mask_len {
|
if proxy_id as usize >= mask_len {
|
||||||
self.existing_proxies
|
self.existing_proxies
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle};
|
use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle};
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
ActiveCollisionTypes, ColliderBroadPhaseData, ColliderChanges, ColliderFlags,
|
ActiveCollisionTypes, BroadPhaseProxyIndex, ColliderBroadPhaseData, ColliderChanges,
|
||||||
ColliderMassProps, ColliderMaterial, ColliderParent, ColliderPosition, ColliderShape,
|
ColliderFlags, ColliderMassProps, ColliderMaterial, ColliderParent, ColliderPosition,
|
||||||
ColliderType, InteractionGroups, SharedShape,
|
ColliderShape, ColliderType, InteractionGroups, SharedShape,
|
||||||
};
|
};
|
||||||
use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector, DIM};
|
use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector, DIM};
|
||||||
use crate::parry::transformation::vhacd::VHACDParameters;
|
use crate::parry::transformation::vhacd::VHACDParameters;
|
||||||
@@ -50,6 +50,21 @@ impl Collider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An internal index associated to this collider by the broad-phase algorithm.
|
||||||
|
pub fn internal_broad_phase_proxy_index(&self) -> BroadPhaseProxyIndex {
|
||||||
|
self.bf_data.proxy_index
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the internal index associated to this collider by the broad-phase algorithm.
|
||||||
|
///
|
||||||
|
/// This must **not** be called, unless you are implementing your own custom broad-phase
|
||||||
|
/// that require storing an index in the collider struct.
|
||||||
|
/// Modifying that index outside of a custom broad-phase code will most certainly break
|
||||||
|
/// the physics engine.
|
||||||
|
pub fn set_internal_broad_phase_proxy_index(&mut self, id: BroadPhaseProxyIndex) {
|
||||||
|
self.bf_data.proxy_index = id;
|
||||||
|
}
|
||||||
|
|
||||||
/// The rigid body this collider is attached to.
|
/// The rigid body this collider is attached to.
|
||||||
pub fn parent(&self) -> Option<RigidBodyHandle> {
|
pub fn parent(&self) -> Option<RigidBodyHandle> {
|
||||||
self.parent.map(|parent| parent.handle)
|
self.parent.map(|parent| parent.handle)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle, RigidBodyType};
|
use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle, RigidBodyType};
|
||||||
use crate::geometry::{InteractionGroups, SAPProxyIndex, Shape, SharedShape};
|
use crate::geometry::{BroadPhaseProxyIndex, InteractionGroups, Shape, SharedShape};
|
||||||
use crate::math::{Isometry, Real};
|
use crate::math::{Isometry, Real};
|
||||||
use crate::parry::partitioning::IndexedData;
|
use crate::parry::partitioning::IndexedData;
|
||||||
use crate::pipeline::{ActiveEvents, ActiveHooks};
|
use crate::pipeline::{ActiveEvents, ActiveHooks};
|
||||||
@@ -118,7 +118,7 @@ impl ColliderType {
|
|||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
/// Data associated to a collider that takes part to a broad-phase algorithm.
|
/// Data associated to a collider that takes part to a broad-phase algorithm.
|
||||||
pub struct ColliderBroadPhaseData {
|
pub struct ColliderBroadPhaseData {
|
||||||
pub(crate) proxy_index: SAPProxyIndex,
|
pub(crate) proxy_index: BroadPhaseProxyIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ColliderBroadPhaseData {
|
impl Default for ColliderBroadPhaseData {
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
//! Structures related to geometry: colliders, shapes, etc.
|
//! Structures related to geometry: colliders, shapes, etc.
|
||||||
|
|
||||||
pub use self::broad_phase_multi_sap::{BroadPhasePairEvent, ColliderPair};
|
pub use self::broad_phase::BroadPhase;
|
||||||
|
pub use self::broad_phase_multi_sap::{BroadPhaseMultiSap, BroadPhasePairEvent, ColliderPair};
|
||||||
pub use self::broad_phase_multi_sap::BroadPhaseMultiSap;
|
|
||||||
// pub use self::broad_phase_qbvh::BroadPhaseMultiSap;
|
|
||||||
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,
|
||||||
@@ -180,7 +178,7 @@ impl ContactForceEvent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) use self::broad_phase_multi_sap::SAPProxyIndex;
|
pub(crate) use self::broad_phase::BroadPhaseProxyIndex;
|
||||||
pub(crate) use self::narrow_phase::ContactManifoldIndex;
|
pub(crate) use self::narrow_phase::ContactManifoldIndex;
|
||||||
pub(crate) use parry::partitioning::Qbvh;
|
pub(crate) use parry::partitioning::Qbvh;
|
||||||
pub use parry::shape::*;
|
pub use parry::shape::*;
|
||||||
@@ -203,6 +201,7 @@ mod interaction_graph;
|
|||||||
mod interaction_groups;
|
mod interaction_groups;
|
||||||
mod narrow_phase;
|
mod narrow_phase;
|
||||||
|
|
||||||
|
mod broad_phase;
|
||||||
mod broad_phase_qbvh;
|
mod broad_phase_qbvh;
|
||||||
mod collider;
|
mod collider;
|
||||||
mod collider_set;
|
mod collider_set;
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
use crate::dynamics::{ImpulseJointSet, MultibodyJointSet};
|
use crate::dynamics::{ImpulseJointSet, MultibodyJointSet};
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
BroadPhaseMultiSap, BroadPhasePairEvent, ColliderChanges, ColliderHandle, ColliderPair,
|
BroadPhase, BroadPhaseMultiSap, BroadPhasePairEvent, ColliderChanges, ColliderHandle,
|
||||||
NarrowPhase,
|
ColliderPair, NarrowPhase,
|
||||||
};
|
};
|
||||||
use crate::math::Real;
|
use crate::math::Real;
|
||||||
use crate::pipeline::{EventHandler, PhysicsHooks, QueryPipeline};
|
use crate::pipeline::{EventHandler, PhysicsHooks, QueryPipeline};
|
||||||
@@ -44,7 +44,7 @@ impl CollisionPipeline {
|
|||||||
fn detect_collisions(
|
fn detect_collisions(
|
||||||
&mut self,
|
&mut self,
|
||||||
prediction_distance: Real,
|
prediction_distance: Real,
|
||||||
broad_phase: &mut BroadPhaseMultiSap,
|
broad_phase: &mut dyn BroadPhase,
|
||||||
narrow_phase: &mut NarrowPhase,
|
narrow_phase: &mut NarrowPhase,
|
||||||
bodies: &mut RigidBodySet,
|
bodies: &mut RigidBodySet,
|
||||||
colliders: &mut ColliderSet,
|
colliders: &mut ColliderSet,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::dynamics::{
|
|||||||
RigidBodyChanges, RigidBodyHandle, RigidBodyPosition, RigidBodyType,
|
RigidBodyChanges, RigidBodyHandle, RigidBodyPosition, RigidBodyType,
|
||||||
};
|
};
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
BroadPhaseMultiSap, BroadPhasePairEvent, ColliderChanges, ColliderHandle, ColliderPair,
|
BroadPhase, BroadPhasePairEvent, ColliderChanges, ColliderHandle, ColliderPair,
|
||||||
ContactManifoldIndex, NarrowPhase, TemporaryInteractionIndex,
|
ContactManifoldIndex, NarrowPhase, TemporaryInteractionIndex,
|
||||||
};
|
};
|
||||||
use crate::math::{Real, Vector};
|
use crate::math::{Real, Vector};
|
||||||
@@ -93,7 +93,7 @@ impl PhysicsPipeline {
|
|||||||
&mut self,
|
&mut self,
|
||||||
integration_parameters: &IntegrationParameters,
|
integration_parameters: &IntegrationParameters,
|
||||||
islands: &mut IslandManager,
|
islands: &mut IslandManager,
|
||||||
broad_phase: &mut BroadPhaseMultiSap,
|
broad_phase: &mut dyn BroadPhase,
|
||||||
narrow_phase: &mut NarrowPhase,
|
narrow_phase: &mut NarrowPhase,
|
||||||
bodies: &mut RigidBodySet,
|
bodies: &mut RigidBodySet,
|
||||||
colliders: &mut ColliderSet,
|
colliders: &mut ColliderSet,
|
||||||
@@ -406,7 +406,7 @@ impl PhysicsPipeline {
|
|||||||
gravity: &Vector<Real>,
|
gravity: &Vector<Real>,
|
||||||
integration_parameters: &IntegrationParameters,
|
integration_parameters: &IntegrationParameters,
|
||||||
islands: &mut IslandManager,
|
islands: &mut IslandManager,
|
||||||
broad_phase: &mut BroadPhaseMultiSap,
|
broad_phase: &mut dyn BroadPhase,
|
||||||
narrow_phase: &mut NarrowPhase,
|
narrow_phase: &mut NarrowPhase,
|
||||||
bodies: &mut RigidBodySet,
|
bodies: &mut RigidBodySet,
|
||||||
colliders: &mut ColliderSet,
|
colliders: &mut ColliderSet,
|
||||||
|
|||||||
Reference in New Issue
Block a user