dimforge / rapier

2D and 3D physics engines focused on performance.
https://rapier.rs
Apache License 2.0
3.97k stars 248 forks source link

Stepping a world with a halfspace collider never terminates #236

Closed Ralith closed 2 years ago

Ralith commented 3 years ago

No progress seems to be made, and memory use grows rapidly (>1GiB/s in release). Perhaps the broadphase needs a special bucket for unbounded colliders?

self-contained repro ```rust use rapier3d_f64::{ dynamics::{CCDSolver, IntegrationParameters, IslandManager, JointSet, RigidBodySet}, geometry::{BroadPhase, ColliderBuilder, ColliderSet, HalfSpace, NarrowPhase, SharedShape}, pipeline::PhysicsPipeline, }; fn main() { let mut islands = IslandManager::new(); let mut bodies = RigidBodySet::new(); let mut colliders = ColliderSet::new(); let mut pipeline = PhysicsPipeline::new(); let integration_parameters = IntegrationParameters::default(); let mut broad_phase = BroadPhase::new(); let mut narrow_phase = NarrowPhase::new(); let mut joints = JointSet::new(); let mut ccd_solver = CCDSolver::new(); // Ground colliders.insert( ColliderBuilder::new(SharedShape::new(HalfSpace { normal: na::Vector3::y_axis(), })) .build(), ); for i in 0..100 { println!("{}", i); pipeline.step( &na::Vector3::new(0.0, -9.81, 0.0), &integration_parameters, &mut islands, &mut broad_phase, &mut narrow_phase, &mut bodies, &mut colliders, &mut joints, &mut ccd_solver, &(), &(), ); } } ```
sebcrozet commented 2 years ago

It looks like this only happen with the f64 version of Rapier.

With the f32 version of Rapier, the largest SAP region size is equal to 5^127 which is much larger than f32::MAX. This implies that the largest layer only really contains unbounded objects, and only contains a single region

With the f64 version of Rapier, the largest region size is still equal to 5^127 which is much smaller than f64::MAX. This means that the unbounded object will be associated to the largest layer and will span all the region of that layer, i.e., about f64::MAX / 5^127 regions.

To deal with this issue, we have two choices:

Ralith commented 2 years ago

allow more than 256 SAP layers

With the ultimate goal of having a layer that's naturally larger than f64::MAX, and therefore catches all unbounded stuff? I assume rapier traverses the tree from the root on a regular basis; might the extra traversals this implies be a performance issue? I suspect unbounded colliders are astronomically more common than colliders with finite dimensions on or above the order of 5e127, so I wonder if intermediate layers there (and even to some extent below) add any value in the common case.

I don't personally have any need for coordinates outside of the range of f32, just better-than-f32 precision at more modest points, so I at least am good regardless.

sebcrozet commented 2 years ago

With the ultimate goal of having a layer that's naturally larger than f64::MAX, and therefore catches all unbounded stuff?

Yes. This basically avoids having to add a special-case for unbounded objects.

I assume rapier traverses the tree from the root on a regular basis; might the extra traversals this implies be a performance issue? I suspect unbounded colliders are astronomically more common than colliders with finite dimensions on or above the order of 5e127, so I wonder if intermediate layers there (and even to some extent below) add any value in the common case.

This will not have any performance impact. If an intermediate layer is empty, it won’t exist (we traverse a linked list containing only populated layers).

Ralith commented 2 years ago

Oh, awesome! That seems very tidy then.

sebcrozet commented 2 years ago

This was fixed in Rapier 0.11.0. Please reopen if the problem persists.