Switch to the published parry 0.11
This commit is contained in:
@@ -88,7 +88,7 @@
|
|||||||
by default.
|
by default.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Debug-renderer: add rendering of contacts, solver contacts, and collider AABBs
|
- Debug-renderer: add rendering of contacts, solver contacts, and collider Aabbs
|
||||||
- Add `MultibodyJointSet::attached_joints` to return all the multibody joints attached to a given rigid-body.
|
- Add `MultibodyJointSet::attached_joints` to return all the multibody joints attached to a given rigid-body.
|
||||||
|
|
||||||
## v0.12.0 (30 Apr. 2022)
|
## v0.12.0 (30 Apr. 2022)
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ vec_map = { version = "0.8", optional = true }
|
|||||||
instant = { version = "0.1", features = [ "now" ], optional = true }
|
instant = { version = "0.1", features = [ "now" ], optional = true }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
nalgebra = "0.31"
|
nalgebra = "0.31"
|
||||||
parry2d-f64 = "0.10"
|
parry2d-f64 = "0.11"
|
||||||
simba = "0.7"
|
simba = "0.7"
|
||||||
approx = "0.5"
|
approx = "0.5"
|
||||||
rayon = { version = "1", optional = true }
|
rayon = { version = "1", optional = true }
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ vec_map = { version = "0.8", optional = true }
|
|||||||
instant = { version = "0.1", features = [ "now" ], optional = true }
|
instant = { version = "0.1", features = [ "now" ], optional = true }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
nalgebra = "0.31"
|
nalgebra = "0.31"
|
||||||
parry2d = "0.10"
|
parry2d = "0.11"
|
||||||
simba = "0.7"
|
simba = "0.7"
|
||||||
approx = "0.5"
|
approx = "0.5"
|
||||||
rayon = { version = "1", optional = true }
|
rayon = { version = "1", optional = true }
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ vec_map = { version = "0.8", optional = true }
|
|||||||
instant = { version = "0.1", features = [ "now" ], optional = true }
|
instant = { version = "0.1", features = [ "now" ], optional = true }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
nalgebra = "0.31"
|
nalgebra = "0.31"
|
||||||
parry3d-f64 = "0.10"
|
parry3d-f64 = "0.11"
|
||||||
simba = "0.7"
|
simba = "0.7"
|
||||||
approx = "0.5"
|
approx = "0.5"
|
||||||
rayon = { version = "1", optional = true }
|
rayon = { version = "1", optional = true }
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ vec_map = { version = "0.8", optional = true }
|
|||||||
instant = { version = "0.1", features = [ "now" ], optional = true }
|
instant = { version = "0.1", features = [ "now" ], optional = true }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
nalgebra = "0.31"
|
nalgebra = "0.31"
|
||||||
parry3d = "0.10"
|
parry3d = "0.11"
|
||||||
simba = "0.7"
|
simba = "0.7"
|
||||||
approx = "0.5"
|
approx = "0.5"
|
||||||
rayon = { version = "1", optional = true }
|
rayon = { version = "1", optional = true }
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use parry::utils::hashmap::HashMap;
|
|||||||
/// the interactions between far-away objects. This means that objects
|
/// the interactions between far-away objects. This means that objects
|
||||||
/// that are very far away will still have some of their endpoints swapped
|
/// that are very far away will still have some of their endpoints swapped
|
||||||
/// within the SAP data-structure. This results in poor scaling because this
|
/// within the SAP data-structure. This results in poor scaling because this
|
||||||
/// results in lots of swapping between endpoints of AABBs that won't ever
|
/// results in lots of swapping between endpoints of Aabbs that won't ever
|
||||||
/// actually interact.
|
/// actually interact.
|
||||||
///
|
///
|
||||||
/// The first optimization to address this problem is to use the Multi-SAP
|
/// The first optimization to address this problem is to use the Multi-SAP
|
||||||
@@ -25,7 +25,7 @@ use parry::utils::hashmap::HashMap;
|
|||||||
/// the spaces into equally-sized subspaces (grid cells). Each subspace, which we call
|
/// the spaces into equally-sized subspaces (grid cells). Each subspace, which we call
|
||||||
/// a "region" contains an SAP instance (i.e. there SAP axes responsible for
|
/// a "region" contains an SAP instance (i.e. there SAP axes responsible for
|
||||||
/// collecting endpoints and swapping them when they move to detect interaction pairs).
|
/// collecting endpoints and swapping them when they move to detect interaction pairs).
|
||||||
/// Each AABB is inserted in all the regions it intersects.
|
/// Each Aabb is inserted in all the regions it intersects.
|
||||||
/// This prevents the far-away problem because two objects that are far away will
|
/// This prevents the far-away problem because two objects that are far away will
|
||||||
/// be located on different regions. So their endpoints will never meet.
|
/// be located on different regions. So their endpoints will never meet.
|
||||||
///
|
///
|
||||||
@@ -39,10 +39,10 @@ use parry::utils::hashmap::HashMap;
|
|||||||
/// replace the grid by a hierarchical grid. A hierarchical grid is composed of
|
/// replace the grid by a hierarchical grid. A hierarchical grid is composed of
|
||||||
/// several layers. And each layer have different region sizes. For example all
|
/// several layers. And each layer have different region sizes. For example all
|
||||||
/// the regions on layer 0 will have the size 1x1x1. All the regions on the layer
|
/// the regions on layer 0 will have the size 1x1x1. All the regions on the layer
|
||||||
/// 1 will have the size 10x10x10, etc. That way, a given AABB will be inserted
|
/// 1 will have the size 10x10x10, etc. That way, a given Aabb will be inserted
|
||||||
/// on the layer that has regions big enough to avoid the large-object problem.
|
/// on the layer that has regions big enough to avoid the large-object problem.
|
||||||
/// For example a 20x20x20 object will be inserted in the layer with region
|
/// For example a 20x20x20 object will be inserted in the layer with region
|
||||||
/// of size 10x10x10, resulting in only 8 regions being intersect by the AABB.
|
/// of size 10x10x10, resulting in only 8 regions being intersect by the Aabb.
|
||||||
/// (If it was inserted in the layer with regions of size 1x1x1, it would have intersected
|
/// (If it was inserted in the layer with regions of size 1x1x1, it would have intersected
|
||||||
/// 8000 regions, which is a problem performancewise.)
|
/// 8000 regions, which is a problem performancewise.)
|
||||||
///
|
///
|
||||||
@@ -53,14 +53,14 @@ use parry::utils::hashmap::HashMap;
|
|||||||
/// way. So we need a way to do inter-layer interference detection. There is a lot ways of doing
|
/// way. So we need a way to do inter-layer interference detection. There is a lot ways of doing
|
||||||
/// this: performing inter-layer Multi-Box-Pruning passes is one example (but this is not what we do).
|
/// this: performing inter-layer Multi-Box-Pruning passes is one example (but this is not what we do).
|
||||||
/// In our implementation, we do the following:
|
/// In our implementation, we do the following:
|
||||||
/// - The AABB bounds of each region of the layer `n` are inserted into the corresponding larger region
|
/// - The Aabb bounds of each region of the layer `n` are inserted into the corresponding larger region
|
||||||
/// of the layer `n + 1`.
|
/// of the layer `n + 1`.
|
||||||
/// - When an AABB in the region of the layer `n + 1` intersects the AABB corresponding to one of the
|
/// - When an Aabb in the region of the layer `n + 1` intersects the Aabb corresponding to one of the
|
||||||
/// regions at the smaller layer `n`, we add that AABB to that smaller region.
|
/// regions at the smaller layer `n`, we add that Aabb to that smaller region.
|
||||||
/// So in the end it means that a given AABB will be inserted into all the region it intersects at
|
/// So in the end it means that a given Aabb will be inserted into all the region it intersects at
|
||||||
/// the layer `n`. And it will also be inserted into all the regions it intersects at the smaller layers
|
/// the layer `n`. And it will also be inserted into all the regions it intersects at the smaller layers
|
||||||
/// (the layers `< n`), but only for the regions that already exist (so we don't have to discretize
|
/// (the layers `< n`), but only for the regions that already exist (so we don't have to discretize
|
||||||
/// our AABB into the layers `< n`). This involves a fair amount of bookkeeping unfortunately, but
|
/// our Aabb into the layers `< n`). This involves a fair amount of bookkeeping unfortunately, but
|
||||||
/// this has the benefit of keep the overall complexity of the algorithm O(1) in the typical specially
|
/// this has the benefit of keep the overall complexity of the algorithm O(1) in the typical specially
|
||||||
/// coherent scenario.
|
/// coherent scenario.
|
||||||
///
|
///
|
||||||
@@ -68,10 +68,10 @@ use parry::utils::hashmap::HashMap;
|
|||||||
/// - There is one `SAPLayer` per layer of the hierarchical grid.
|
/// - There is one `SAPLayer` per layer of the hierarchical grid.
|
||||||
/// - Each `SAPLayer` contains multiple `SAPRegion` (each being a region of the grid represented by that layer).
|
/// - Each `SAPLayer` contains multiple `SAPRegion` (each being a region of the grid represented by that layer).
|
||||||
/// - Each `SAPRegion` contains three `SAPAxis`, representing the "classical" SAP algorithm running on this region.
|
/// - Each `SAPRegion` contains three `SAPAxis`, representing the "classical" SAP algorithm running on this region.
|
||||||
/// - Each `SAPAxis` maintains a sorted list of `SAPEndpoints` representing the endpoints of the AABBs intersecting
|
/// - Each `SAPAxis` maintains a sorted list of `SAPEndpoints` representing the endpoints of the Aabbs intersecting
|
||||||
/// the bounds on the `SAPRegion` containing this `SAPAxis`.
|
/// the bounds on the `SAPRegion` containing this `SAPAxis`.
|
||||||
/// - A set of `SAPProxy` are maintained separately. It contains the AABBs of all the colliders managed by this
|
/// - A set of `SAPProxy` are maintained separately. It contains the Aabbs of all the colliders managed by this
|
||||||
/// broad-phase, as well as the AABBs of all the regions part of this broad-phase.
|
/// broad-phase, as well as the Aabbs of all the regions part of this broad-phase.
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct BroadPhase {
|
pub struct BroadPhase {
|
||||||
@@ -151,7 +151,7 @@ impl BroadPhase {
|
|||||||
/// Pre-deletes a proxy from this broad-phase.
|
/// Pre-deletes a proxy from this broad-phase.
|
||||||
///
|
///
|
||||||
/// The removal of a proxy is a semi-lazy process. It will mark
|
/// The removal of a proxy is a semi-lazy process. It will mark
|
||||||
/// the proxy as predeleted, and will set its AABB as +infinity.
|
/// the proxy as predeleted, and will set its Aabb as +infinity.
|
||||||
/// After this method has been called with all the proxies to
|
/// After this method has been called with all the proxies to
|
||||||
/// 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
|
||||||
@@ -355,7 +355,7 @@ impl BroadPhase {
|
|||||||
if aabb.mins.coords.iter().any(|e| !e.is_finite())
|
if aabb.mins.coords.iter().any(|e| !e.is_finite())
|
||||||
|| aabb.maxs.coords.iter().any(|e| !e.is_finite())
|
|| aabb.maxs.coords.iter().any(|e| !e.is_finite())
|
||||||
{
|
{
|
||||||
// Reject AABBs with non-finite values.
|
// Reject Aabbs with non-finite values.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,11 +401,11 @@ impl BroadPhase {
|
|||||||
let layer = &mut self.layers[layer_id as usize];
|
let layer = &mut self.layers[layer_id as usize];
|
||||||
|
|
||||||
// Preupdate the collider in the layer.
|
// Preupdate the collider in the layer.
|
||||||
// We need to use both the prev AABB and the new AABB for this update, to
|
// We need to use both the prev Aabb and the new Aabb for this update, to
|
||||||
// handle special cases where one AABB has left a region that doesn’t contain
|
// handle special cases where one Aabb has left a region that doesn’t contain
|
||||||
// any other modified AABBs.
|
// any other modified Aabbs.
|
||||||
// If the combination of both previous and new aabbs isn’t more than 25% bigger
|
// If the combination of both previous and new aabbs isn’t more than 25% bigger
|
||||||
// than the new AABB, we just merge them to save some computation times (to avoid
|
// than the new Aabb, we just merge them to save some computation times (to avoid
|
||||||
// discretizing twice the area at their intersection. If it’s bigger than 25% then
|
// discretizing twice the area at their intersection. If it’s bigger than 25% then
|
||||||
// we discretize both aabbs individually.
|
// we discretize both aabbs individually.
|
||||||
let merged_aabbs = prev_aabb.merged(&aabb);
|
let merged_aabbs = prev_aabb.merged(&aabb);
|
||||||
@@ -501,7 +501,7 @@ impl BroadPhase {
|
|||||||
|
|
||||||
/// 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
|
||||||
/// added to its larger layer so we can detect when an object
|
/// added to its larger layer so we can detect when an object
|
||||||
/// in a larger layer may start interacting with objects in a smaller
|
/// in a larger layer may start interacting with objects in a smaller
|
||||||
/// layer.
|
/// layer.
|
||||||
@@ -551,7 +551,7 @@ impl BroadPhase {
|
|||||||
// order to account for the fact that a big proxy moved.
|
// order to account for the fact that a big proxy moved.
|
||||||
// NOTE: this 2nd point could probably be improved: instead of updating
|
// NOTE: this 2nd point could probably be improved: instead of updating
|
||||||
// all the subregions, we could perhaps just update the subregions
|
// all the subregions, we could perhaps just update the subregions
|
||||||
// that crosses the boundary of the AABB of the big proxies that
|
// that crosses the boundary of the Aabb of the big proxies that
|
||||||
// moved in they layer `n`.
|
// moved in they layer `n`.
|
||||||
let mut layer_id = Some(self.largest_layer);
|
let mut layer_id = Some(self.largest_layer);
|
||||||
|
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ impl SAPAxis {
|
|||||||
.retain(|endpt| endpt.is_sentinel() || existing_proxies[endpt.proxy() as usize])
|
.retain(|endpt| endpt.is_sentinel() || existing_proxies[endpt.proxy() as usize])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes from this axis all the endpoints corresponding to a proxy with an AABB mins/maxs values
|
/// Removes from this axis all the endpoints corresponding to a proxy with an Aabb mins/maxs values
|
||||||
/// equal to DELETED_AABB_VALUE, indicating that the endpoints should be deleted.
|
/// equal to DELETED_AABB_VALUE, indicating that the endpoints should be deleted.
|
||||||
///
|
///
|
||||||
/// Returns the number of deleted proxies such that `proxy.layer_depth <= layer_depth`.
|
/// Returns the number of deleted proxies such that `proxy.layer_depth <= layer_depth`.
|
||||||
|
|||||||
@@ -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::{SAPProxyIndex, AABB};
|
use crate::geometry::{Aabb, SAPProxyIndex};
|
||||||
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};
|
||||||
@@ -215,8 +215,8 @@ impl SAPLayer {
|
|||||||
pub fn preupdate_collider(
|
pub fn preupdate_collider(
|
||||||
&mut self,
|
&mut self,
|
||||||
proxy_id: u32,
|
proxy_id: u32,
|
||||||
aabb_to_discretize: &AABB,
|
aabb_to_discretize: &Aabb,
|
||||||
actual_aabb: Option<&AABB>,
|
actual_aabb: Option<&Aabb>,
|
||||||
proxies: &mut SAPProxies,
|
proxies: &mut SAPProxies,
|
||||||
pool: &mut SAPRegionPool,
|
pool: &mut SAPRegionPool,
|
||||||
) {
|
) {
|
||||||
@@ -241,15 +241,15 @@ impl SAPLayer {
|
|||||||
let region = region_proxy.data.as_region_mut();
|
let region = region_proxy.data.as_region_mut();
|
||||||
|
|
||||||
// NOTE: sometimes, rounding errors will generate start/end indices
|
// NOTE: sometimes, rounding errors will generate start/end indices
|
||||||
// that lie outside of the actual region’s AABB.
|
// that lie outside of the actual region’s Aabb.
|
||||||
// TODO: is there a smarter, more efficient way of dealing with this?
|
// TODO: is there a smarter, more efficient way of dealing with this?
|
||||||
if !region_proxy.aabb.intersects(aabb_to_discretize) {
|
if !region_proxy.aabb.intersects(aabb_to_discretize) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(actual_aabb) = actual_aabb {
|
if let Some(actual_aabb) = actual_aabb {
|
||||||
// NOTE: if the actual AABB doesn't intersect the
|
// NOTE: if the actual Aabb doesn't intersect the
|
||||||
// region’s AABB, then we need to delete the
|
// region’s Aabb, then we need to delete the
|
||||||
// proxy from that region because it means that
|
// proxy from that region because it means that
|
||||||
// during the last update the proxy intersected
|
// during the last update the proxy intersected
|
||||||
// that region, but it doesn't intersect it any
|
// that region, but it doesn't intersect it any
|
||||||
@@ -267,12 +267,12 @@ 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: SAPProxyIndex) {
|
||||||
// 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);
|
||||||
let end = super::point_key(proxy_aabb.maxs, self.region_width);
|
let end = super::point_key(proxy_aabb.maxs, self.region_width);
|
||||||
|
|
||||||
// Set the AABB of the proxy to a very large value.
|
// Set the Aabb of the proxy to a very large value.
|
||||||
proxy_aabb.mins.coords.fill(DELETED_AABB_VALUE);
|
proxy_aabb.mins.coords.fill(DELETED_AABB_VALUE);
|
||||||
proxy_aabb.maxs.coords.fill(DELETED_AABB_VALUE);
|
proxy_aabb.maxs.coords.fill(DELETED_AABB_VALUE);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
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::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;
|
pub type SAPProxyIndex = u32;
|
||||||
@@ -51,7 +51,7 @@ impl SAPProxyData {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
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: SAPProxyIndex,
|
||||||
// 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,
|
||||||
@@ -59,7 +59,7 @@ pub struct SAPProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SAPProxy {
|
impl SAPProxy {
|
||||||
pub fn collider(handle: ColliderHandle, aabb: AABB, layer_id: u8, layer_depth: i8) -> Self {
|
pub fn collider(handle: ColliderHandle, aabb: Aabb, layer_id: u8, layer_depth: i8) -> Self {
|
||||||
Self {
|
Self {
|
||||||
data: SAPProxyData::Collider(handle),
|
data: SAPProxyData::Collider(handle),
|
||||||
aabb,
|
aabb,
|
||||||
@@ -69,7 +69,7 @@ impl SAPProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn subregion(subregion: Box<SAPRegion>, aabb: AABB, layer_id: u8, layer_depth: i8) -> Self {
|
pub fn subregion(subregion: Box<SAPRegion>, aabb: Aabb, layer_id: u8, layer_depth: i8) -> Self {
|
||||||
Self {
|
Self {
|
||||||
data: SAPProxyData::Region(Some(subregion)),
|
data: SAPProxyData::Region(Some(subregion)),
|
||||||
aabb,
|
aabb,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use super::{SAPAxis, SAPProxies};
|
|||||||
use crate::geometry::SAPProxyIndex;
|
use crate::geometry::SAPProxyIndex;
|
||||||
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;
|
||||||
use parry::utils::hashmap::HashMap;
|
use parry::utils::hashmap::HashMap;
|
||||||
|
|
||||||
pub type SAPRegionPool = Vec<Box<SAPRegion>>;
|
pub type SAPRegionPool = Vec<Box<SAPRegion>>;
|
||||||
@@ -25,7 +25,7 @@ pub struct SAPRegion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SAPRegion {
|
impl SAPRegion {
|
||||||
pub fn new(bounds: AABB) -> Self {
|
pub fn new(bounds: Aabb) -> Self {
|
||||||
let axes = [
|
let axes = [
|
||||||
SAPAxis::new(bounds.mins.x, bounds.maxs.x),
|
SAPAxis::new(bounds.mins.x, bounds.maxs.x),
|
||||||
SAPAxis::new(bounds.mins.y, bounds.maxs.y),
|
SAPAxis::new(bounds.mins.y, bounds.maxs.y),
|
||||||
@@ -44,7 +44,7 @@ impl SAPRegion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recycle(bounds: AABB, mut old: Box<Self>) -> Box<Self> {
|
pub fn recycle(bounds: Aabb, mut old: Box<Self>) -> Box<Self> {
|
||||||
// Correct the bounds
|
// Correct the bounds
|
||||||
for i in 0..DIM {
|
for i in 0..DIM {
|
||||||
// Make sure the axis is empty (it may still contain
|
// Make sure the axis is empty (it may still contain
|
||||||
@@ -73,7 +73,7 @@ impl SAPRegion {
|
|||||||
old
|
old
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recycle_or_new(bounds: AABB, pool: &mut Vec<Box<Self>>) -> Box<Self> {
|
pub fn recycle_or_new(bounds: Aabb, pool: &mut Vec<Box<Self>>) -> Box<Self> {
|
||||||
if let Some(old) = pool.pop() {
|
if let Some(old) = pool.pop() {
|
||||||
Self::recycle(bounds, old)
|
Self::recycle(bounds, old)
|
||||||
} else {
|
} else {
|
||||||
@@ -177,7 +177,7 @@ impl SAPRegion {
|
|||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
// Here we need a second update if all proxies exit this region. In this case, we need
|
// Here we need a second update if all proxies exit this region. In this case, we need
|
||||||
// to delete the final proxy, but the region may not have AABBs overlapping it, so it
|
// to delete the final proxy, but the region may not have Aabbs overlapping it, so it
|
||||||
// wouldn't get an update otherwise.
|
// wouldn't get an update otherwise.
|
||||||
self.update_count = 2;
|
self.update_count = 2;
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::math::{Point, Real, Vector};
|
use crate::math::{Point, Real, Vector};
|
||||||
use parry::bounding_volume::AABB;
|
use parry::bounding_volume::Aabb;
|
||||||
|
|
||||||
pub(crate) const NUM_SENTINELS: usize = 1;
|
pub(crate) const NUM_SENTINELS: usize = 1;
|
||||||
pub(crate) const NEXT_FREE_SENTINEL: u32 = u32::MAX;
|
pub(crate) const NEXT_FREE_SENTINEL: u32 = u32::MAX;
|
||||||
@@ -30,26 +30,26 @@ pub(crate) fn point_key(point: Point<Real>, region_width: Real) -> Point<i32> {
|
|||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn region_aabb(index: Point<i32>, region_width: Real) -> AABB {
|
pub(crate) fn region_aabb(index: Point<i32>, region_width: Real) -> Aabb {
|
||||||
let mins = index.coords.map(|i| i as Real * region_width).into();
|
let mins = index.coords.map(|i| i as Real * region_width).into();
|
||||||
let maxs = mins + Vector::repeat(region_width);
|
let maxs = mins + Vector::repeat(region_width);
|
||||||
AABB::new(mins, maxs)
|
Aabb::new(mins, maxs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn region_width(depth: i8) -> Real {
|
pub(crate) fn region_width(depth: i8) -> Real {
|
||||||
(REGION_WIDTH_BASE * REGION_WIDTH_POWER_BASIS.powi(depth as i32)).min(MAX_AABB_EXTENT)
|
(REGION_WIDTH_BASE * REGION_WIDTH_POWER_BASIS.powi(depth as i32)).min(MAX_AABB_EXTENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the depth of the layer the given AABB should be part of.
|
/// Computes the depth of the layer the given Aabb should be part of.
|
||||||
///
|
///
|
||||||
/// The idea here is that an AABB should be part of a layer which has
|
/// The idea here is that an Aabb should be part of a layer which has
|
||||||
/// regions large enough so that one AABB doesn't crosses too many
|
/// regions large enough so that one Aabb doesn't crosses too many
|
||||||
/// regions. But the regions must also not be too large, otherwise
|
/// regions. But the regions must also not be too large, otherwise
|
||||||
/// we are loosing the benefits of Multi-SAP.
|
/// we are loosing the benefits of Multi-SAP.
|
||||||
///
|
///
|
||||||
/// If the code bellow, we select a layer such that each region can
|
/// If the code bellow, we select a layer such that each region can
|
||||||
/// contain at least a chain of 10 contiguous objects with that AABB.
|
/// contain at least a chain of 10 contiguous objects with that Aabb.
|
||||||
pub(crate) fn layer_containing_aabb(aabb: &AABB) -> i8 {
|
pub(crate) fn layer_containing_aabb(aabb: &Aabb) -> i8 {
|
||||||
// Max number of elements of this size we would like one region to be able to contain.
|
// Max number of elements of this size we would like one region to be able to contain.
|
||||||
const NUM_ELEMENTS_PER_DIMENSION: Real = 10.0;
|
const NUM_ELEMENTS_PER_DIMENSION: Real = 10.0;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector, DIM};
|
|||||||
use crate::parry::transformation::vhacd::VHACDParameters;
|
use crate::parry::transformation::vhacd::VHACDParameters;
|
||||||
use crate::pipeline::{ActiveEvents, ActiveHooks};
|
use crate::pipeline::{ActiveEvents, ActiveHooks};
|
||||||
use na::Unit;
|
use na::Unit;
|
||||||
use parry::bounding_volume::AABB;
|
use parry::bounding_volume::Aabb;
|
||||||
use parry::shape::Shape;
|
use parry::shape::Shape;
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
@@ -348,13 +348,13 @@ impl Collider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the axis-aligned bounding box of this collider.
|
/// Compute the axis-aligned bounding box of this collider.
|
||||||
pub fn compute_aabb(&self) -> AABB {
|
pub fn compute_aabb(&self) -> Aabb {
|
||||||
self.shape.compute_aabb(&self.pos)
|
self.shape.compute_aabb(&self.pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the axis-aligned bounding box of this collider moving from its current position
|
/// Compute the axis-aligned bounding box of this collider moving from its current position
|
||||||
/// to the given `next_position`
|
/// to the given `next_position`
|
||||||
pub fn compute_swept_aabb(&self, next_position: &Isometry<Real>) -> AABB {
|
pub fn compute_swept_aabb(&self, next_position: &Isometry<Real>) -> Aabb {
|
||||||
self.shape.compute_swept_aabb(&self.pos, next_position)
|
self.shape.compute_swept_aabb(&self.pos, next_position)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ pub type Cylinder = parry::shape::Cylinder;
|
|||||||
#[cfg(feature = "dim3")]
|
#[cfg(feature = "dim3")]
|
||||||
pub type Cone = parry::shape::Cone;
|
pub type Cone = parry::shape::Cone;
|
||||||
/// An axis-aligned bounding box.
|
/// An axis-aligned bounding box.
|
||||||
pub type AABB = parry::bounding_volume::AABB;
|
pub type Aabb = parry::bounding_volume::Aabb;
|
||||||
/// A ray that can be cast against colliders.
|
/// A ray that can be cast against colliders.
|
||||||
pub type Ray = parry::query::Ray;
|
pub type Ray = parry::query::Ray;
|
||||||
/// The intersection between a ray and a collider.
|
/// The intersection between a ray and a collider.
|
||||||
@@ -178,7 +178,7 @@ impl ContactForceEvent {
|
|||||||
|
|
||||||
pub(crate) use self::broad_phase_multi_sap::SAPProxyIndex;
|
pub(crate) use self::broad_phase_multi_sap::SAPProxyIndex;
|
||||||
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::*;
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ bitflags::bitflags! {
|
|||||||
const SOLVER_CONTACTS = 1 << 4;
|
const SOLVER_CONTACTS = 1 << 4;
|
||||||
/// If this flag is set, the geometric contacts will be rendered.
|
/// If this flag is set, the geometric contacts will be rendered.
|
||||||
const CONTACTS = 1 << 5;
|
const CONTACTS = 1 << 5;
|
||||||
/// If this flag is set, the AABBs of colliders will be rendered.
|
/// If this flag is set, the Aabbs of colliders will be rendered.
|
||||||
const COLLIDER_AABBS = 1 << 6;
|
const COLLIDER_AABBS = 1 << 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ pub struct DebugRenderStyle {
|
|||||||
pub contact_normal_color: DebugColor,
|
pub contact_normal_color: DebugColor,
|
||||||
/// The length of the contact normals.
|
/// The length of the contact normals.
|
||||||
pub contact_normal_length: Real,
|
pub contact_normal_length: Real,
|
||||||
/// The color of the colliders AABBs.
|
/// The color of the colliders Aabbs.
|
||||||
pub collider_aabb_color: DebugColor,
|
pub collider_aabb_color: DebugColor,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use crate::dynamics::{IslandManager, RigidBodyHandle};
|
use crate::dynamics::{IslandManager, RigidBodyHandle};
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
Collider, ColliderHandle, InteractionGroups, PointProjection, Ray, RayIntersection, AABB, QBVH,
|
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;
|
||||||
use parry::query::details::{
|
use parry::query::details::{
|
||||||
IntersectionCompositeShapeShapeBestFirstVisitor,
|
IntersectionCompositeShapeShapeBestFirstVisitor,
|
||||||
NonlinearTOICompositeShapeShapeBestFirstVisitor, PointCompositeShapeProjBestFirstVisitor,
|
NonlinearTOICompositeShapeShapeBestFirstVisitor, PointCompositeShapeProjBestFirstVisitor,
|
||||||
@@ -12,12 +12,12 @@ use parry::query::details::{
|
|||||||
RayCompositeShapeToiAndNormalBestFirstVisitor, RayCompositeShapeToiBestFirstVisitor,
|
RayCompositeShapeToiAndNormalBestFirstVisitor, RayCompositeShapeToiBestFirstVisitor,
|
||||||
TOICompositeShapeShapeBestFirstVisitor,
|
TOICompositeShapeShapeBestFirstVisitor,
|
||||||
};
|
};
|
||||||
use parry::utils::DefaultStorage;
|
|
||||||
use parry::query::visitors::{
|
use parry::query::visitors::{
|
||||||
BoundingVolumeIntersectionsVisitor, PointIntersectionsVisitor, RayIntersectionsVisitor,
|
BoundingVolumeIntersectionsVisitor, PointIntersectionsVisitor, RayIntersectionsVisitor,
|
||||||
};
|
};
|
||||||
use parry::query::{DefaultQueryDispatcher, NonlinearRigidMotion, QueryDispatcher, TOI};
|
use parry::query::{DefaultQueryDispatcher, NonlinearRigidMotion, QueryDispatcher, TOI};
|
||||||
use parry::shape::{FeatureId, Shape, TypedSimdCompositeShape};
|
use parry::shape::{FeatureId, Shape, TypedSimdCompositeShape};
|
||||||
|
use parry::utils::DefaultStorage;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// A pipeline for performing queries on all the colliders of a scene.
|
/// A pipeline for performing queries on all the colliders of a scene.
|
||||||
@@ -29,7 +29,7 @@ pub struct QueryPipeline {
|
|||||||
serde(skip, default = "crate::geometry::default_query_dispatcher")
|
serde(skip, default = "crate::geometry::default_query_dispatcher")
|
||||||
)]
|
)]
|
||||||
query_dispatcher: Arc<dyn QueryDispatcher>,
|
query_dispatcher: Arc<dyn QueryDispatcher>,
|
||||||
qbvh: QBVH<ColliderHandle>,
|
qbvh: Qbvh<ColliderHandle>,
|
||||||
tree_built: bool,
|
tree_built: bool,
|
||||||
dilation_factor: Real,
|
dilation_factor: Real,
|
||||||
}
|
}
|
||||||
@@ -246,7 +246,7 @@ pub enum QueryPipelineMode {
|
|||||||
impl<'a> TypedSimdCompositeShape for QueryPipelineAsCompositeShape<'a> {
|
impl<'a> TypedSimdCompositeShape for QueryPipelineAsCompositeShape<'a> {
|
||||||
type PartShape = dyn Shape;
|
type PartShape = dyn Shape;
|
||||||
type PartId = ColliderHandle;
|
type PartId = ColliderHandle;
|
||||||
type QBVHStorage = DefaultStorage;
|
type QbvhStorage = DefaultStorage;
|
||||||
|
|
||||||
fn map_typed_part_at(
|
fn map_typed_part_at(
|
||||||
&self,
|
&self,
|
||||||
@@ -268,7 +268,7 @@ impl<'a> TypedSimdCompositeShape for QueryPipelineAsCompositeShape<'a> {
|
|||||||
self.map_typed_part_at(shape_id, f);
|
self.map_typed_part_at(shape_id, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn typed_qbvh(&self) -> &QBVH<ColliderHandle> {
|
fn typed_qbvh(&self) -> &Qbvh<ColliderHandle> {
|
||||||
&self.query_pipeline.qbvh
|
&self.query_pipeline.qbvh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -309,7 +309,7 @@ impl QueryPipeline {
|
|||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
query_dispatcher: Arc::new(d),
|
query_dispatcher: Arc::new(d),
|
||||||
qbvh: QBVH::new(),
|
qbvh: Qbvh::new(),
|
||||||
tree_built: false,
|
tree_built: false,
|
||||||
dilation_factor: 0.01,
|
dilation_factor: 0.01,
|
||||||
}
|
}
|
||||||
@@ -349,13 +349,13 @@ impl QueryPipeline {
|
|||||||
mode: QueryPipelineMode,
|
mode: QueryPipelineMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> QBVHDataGenerator<ColliderHandle> for DataGenerator<'a> {
|
impl<'a> QbvhDataGenerator<ColliderHandle> for DataGenerator<'a> {
|
||||||
fn size_hint(&self) -> usize {
|
fn size_hint(&self) -> usize {
|
||||||
self.colliders.len()
|
self.colliders.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn for_each(&mut self, mut f: impl FnMut(ColliderHandle, AABB)) {
|
fn for_each(&mut self, mut f: impl FnMut(ColliderHandle, Aabb)) {
|
||||||
match self.mode {
|
match self.mode {
|
||||||
QueryPipelineMode::CurrentPosition => {
|
QueryPipelineMode::CurrentPosition => {
|
||||||
for (h, co) in self.colliders.iter() {
|
for (h, co) in self.colliders.iter() {
|
||||||
@@ -675,10 +675,10 @@ impl QueryPipeline {
|
|||||||
.map(|h| (h.1 .1 .0, h.1 .0, h.1 .1 .1))
|
.map(|h| (h.1 .1 .0, h.1 .0, h.1 .1 .1))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds all handles of all the colliders with an AABB intersecting the given AABB.
|
/// Finds all handles of all the colliders with an Aabb intersecting the given Aabb.
|
||||||
pub fn colliders_with_aabb_intersecting_aabb(
|
pub fn colliders_with_aabb_intersecting_aabb(
|
||||||
&self,
|
&self,
|
||||||
aabb: &AABB,
|
aabb: &Aabb,
|
||||||
mut callback: impl FnMut(&ColliderHandle) -> bool,
|
mut callback: impl FnMut(&ColliderHandle) -> bool,
|
||||||
) {
|
) {
|
||||||
let mut visitor = BoundingVolumeIntersectionsVisitor::new(aabb, &mut callback);
|
let mut visitor = BoundingVolumeIntersectionsVisitor::new(aabb, &mut callback);
|
||||||
|
|||||||
Reference in New Issue
Block a user