Storing Bodies in ECS component performance

Hi, I’m trying to get nphysics working with amethyst, which uses specs. I noticed in https://www.nphysics.org/rigid_body_simulations_with_contacts/ it said that you could provide your own BodySet/ColliderSet/etc implementation for ECS integration. I’ve tried that out by creating a BodySet implementation with Entity (an ECS “handle”) as the handle and is essentially a wrapper around an ECS component that contains a Box<dyn Body<f32>>. The main ECS handles storage of the components, rather than DefaultBodySet. But due to lifetimes each frame ends up constructing its own MechanicalWorld, GeometricalWorld and the wrapper BodySet.

The alternative is to keep the nphysics world and the rest of the world separate. To figure out which specs Entity an nphysics body corresponds to, you would embed an Entity inside the user data for an nphysics body. That’s kind of ugly, and I believe that using Entity as the handle for BodySet is much cleaner. You also need a mapping from an Entity to its corresponding Body by keeping a handle to the Body as a component of the Entity, for example to keep track of what’s been removed.

I’m having trouble getting this working due to lifetimes, but ignoring that fact, are there significant performance downsides of creating a new MechanicalWorld and GeometricalWorld every frame as opposed to keeping one around between frames (is there any sort of caching)? Intuitively, any idea as to CPU and memory tradeoffs between constantly translating between the nphysics world and the rest of the world versus creating a brand new MechanicalWorld and GeometricalWorld on every frame?

Hi!

A very recent change should make this integration much easier. It will be released within the next days. You may want to look at what is done in specs-physics.

Yes, this would have a very terrible performance impact, as well as introduce stability problems because of all the caches lost.

I had looked at specs-physics but saw that it was copying the ECS physics components to the nphysics world and back, and was hoping the copying back and forth wasn’t necessary.

But maybe it’s better to just go with specs-physics and hope that copying data back and forth between worlds isn’t the bottleneck. Based on your comment that probably has a much lower impact on performance than creating new nphysics worlds every frame.

Thanks!

This copying is no longer performed in the 0.4.0 branch which is based on my BodySet PR. Instead, BodySet and ColliderSet are simply Storages, and soon this will also be true of JointConstraints as well I believe. The biggest performance issue with the 0.4.0 version of the code is a general issue with Specs which is a lack of linearity in iteration over physics bodies. While my branch introduces an indirection with the trait objects of bodies, I don’t believe there’s much to be gained from concrete storages for each type since join-based iteration in Specs tends to jump around in memory a lot anyways. My current implementation upcoming in 0.4.0 is probably best-case for Specs.

Good to hear! Looking forward to it getting merged!

DefaultBodySet already boxes everything, so yeah it’s probably fine.