dimforge / rapier

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

Switch to 64-bit handles #110

Closed emilk closed 3 years ago

emilk commented 3 years ago

I noticed that arena::Index is implemented as usize + u64. This is in contrast with e.g. slotmap which uses 64-bit keys (u32 + u32).

Switching to a smaller index would make for faster lookups, less memory usage etc, but would limit the number of simultaneous bodies/joints/colliders to 2^32 (which like a reasonable limitation). But is there perhaps some subtlety with regard to determinism that I'm missing (e.g. with regards to generation wrapping around after cycling through 2^32 elements)?

sebcrozet commented 3 years ago

Switching to u32+u32 is a possibility, yes. the having the generation cycle through 2^32 elements shouldn't really be an issue as it should happen very rarely, and shouldn't have any grave consequences if it does (it's only there to avoid the ABA problem).

Regarding determinism, the size of the key isn't important. What maters is the deserialization implementation. The arena used by rapier is mostly a copy of generational-arena but with a different serialization/deserialization code. The issue with generational-arena and slotmap is that they don't preserve the order of allocation of new handles after deserialization of the arena. That way they don't have to serialize the free list, but this will cause non-repeatable behavior when restoring the simulation state from an older serialized state.

The slotmap crate looks nice (I tried it a few years ago but I think at that time it required the stored element to implement Copy so I couldn't use it). It even has an equivalent for what Rapier calls Coarena. So using it would mean less code to maintain ourselves, and potentially better performances. We could make a fork of slotmap with a different serialization method, for the sake of determinism, and use that.