Improve distant object panics in broad phase (#128)

Co-authored-by: Thierry Berger <contact@thierryberger.com>
This commit is contained in:
Ben Harper
2024-08-06 01:19:52 +10:00
committed by GitHub
parent 7ff92b1cf5
commit af3a26c99d
6 changed files with 42 additions and 12 deletions

View File

@@ -1,3 +1,9 @@
## Unreleased
### Fix
- The region key has been replaced by an i64 in the f64 version of rapier, increasing the range before panics occur.
## v0.22.0 (20 July 2024) ## v0.22.0 (20 July 2024)
### Fix ### Fix

View File

@@ -1,6 +1,21 @@
[workspace] [workspace]
members = ["crates/rapier2d", "crates/rapier2d-f64", "crates/rapier_testbed2d", "crates/rapier_testbed2d-f64", "examples2d", "benchmarks2d", members = [
"crates/rapier3d", "crates/rapier3d-f64", "crates/rapier_testbed3d", "crates/rapier_testbed3d-f64", "examples3d", "examples3d-f64", "benchmarks3d", "crates/rapier3d-urdf", "crates/rapier3d-stl"] "crates/rapier2d",
"crates/rapier2d-f64",
"crates/rapier_testbed2d",
"crates/rapier_testbed2d-f64",
"examples2d",
"benchmarks2d",
"crates/rapier3d",
"crates/rapier3d-f64",
"crates/rapier_testbed3d",
"crates/rapier_testbed3d-f64",
"examples3d",
"examples3d-f64",
"benchmarks3d",
"crates/rapier3d-urdf",
"crates/rapier3d-stl",
]
resolver = "2" resolver = "2"
[workspace.lints] [workspace.lints]
@@ -44,4 +59,4 @@ opt-level = 1
#opt-level = 3 #opt-level = 3
# #
#[profile.dev.package.kiss3d] #[profile.dev.package.kiss3d]
#opt-level = 3 #opt-level = 3

View File

@@ -42,7 +42,7 @@ rand = "0.8"
rand_pcg = "0.3" rand_pcg = "0.3"
instant = { version = "0.1", features = ["web-sys", "now"] } instant = { version = "0.1", features = ["web-sys", "now"] }
bitflags = "2" bitflags = "2"
glam = { version = "0.24", optional = true } # For Physx glam = { version = "0.24", optional = true } # For Physx
num_cpus = { version = "1", optional = true } num_cpus = { version = "1", optional = true }
physx = { version = "0.19", features = ["glam"], optional = true } physx = { version = "0.19", features = ["glam"], optional = true }
physx-sys = { version = "0.11", optional = true } physx-sys = { version = "0.11", optional = true }

View File

@@ -1,4 +1,4 @@
use super::{SAPProxies, SAPProxy, SAPRegion, SAPRegionPool}; use super::{RegionKey, 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, BroadPhaseProxyIndex}; use crate::geometry::{Aabb, BroadPhaseProxyIndex};
use crate::math::{Point, Real}; use crate::math::{Point, Real};
@@ -13,9 +13,9 @@ 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>, BroadPhaseProxyIndex>, pub regions: HashMap<Point<RegionKey>, 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<RegionKey>>, // Workspace
#[cfg_attr(feature = "serde-serialize", serde(skip))] #[cfg_attr(feature = "serde-serialize", serde(skip))]
pub created_regions: Vec<BroadPhaseProxyIndex>, pub created_regions: Vec<BroadPhaseProxyIndex>,
} }
@@ -188,7 +188,7 @@ impl SAPLayer {
/// of the new region if it did not exist and has been created by this method. /// of the new region if it did not exist and has been created by this method.
pub fn ensure_region_exists( pub fn ensure_region_exists(
&mut self, &mut self,
region_key: Point<i32>, region_key: Point<RegionKey>,
proxies: &mut SAPProxies, proxies: &mut SAPProxies,
pool: &mut SAPRegionPool, pool: &mut SAPRegionPool,
) -> BroadPhaseProxyIndex { ) -> BroadPhaseProxyIndex {

View File

@@ -1,6 +1,11 @@
use crate::math::{Point, Real, Vector}; use crate::math::{Point, Real, Vector};
use parry::bounding_volume::Aabb; use parry::bounding_volume::Aabb;
#[cfg(feature = "f32")]
pub type RegionKey = i32;
#[cfg(feature = "f64")]
pub type RegionKey = i64;
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;
pub(crate) const SENTINEL_VALUE: Real = Real::MAX; pub(crate) const SENTINEL_VALUE: Real = Real::MAX;
@@ -23,14 +28,19 @@ pub(crate) fn clamp_point(point: Point<Real>) -> Point<Real> {
point.map(|e| na::clamp(e, -MAX_AABB_EXTENT, MAX_AABB_EXTENT)) point.map(|e| na::clamp(e, -MAX_AABB_EXTENT, MAX_AABB_EXTENT))
} }
pub(crate) fn point_key(point: Point<Real>, region_width: Real) -> Point<i32> { pub(crate) fn point_key(point: Point<Real>, region_width: Real) -> Point<RegionKey> {
(point / region_width) (point / region_width)
.coords .coords
.map(|e| e.floor() as i32) .map(|e| {
// If the region is outside this range, the region keys will overlap
assert!(e.floor() < RegionKey::MAX as Real);
assert!(e.floor() > RegionKey::MIN as Real);
e.floor() as RegionKey
})
.into() .into()
} }
pub(crate) fn region_aabb(index: Point<i32>, region_width: Real) -> Aabb { pub(crate) fn region_aabb(index: Point<RegionKey>, 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)

View File

@@ -1,5 +1,4 @@
#![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_arguments)]
extern crate nalgebra as na; extern crate nalgebra as na;
pub use crate::graphics::{BevyMaterial, GraphicsManager}; pub use crate::graphics::{BevyMaterial, GraphicsManager};