I implemented a dynamic floating origin solution to address the long-standing distance / precision issues (see #10, #604, #1076, #1321, Creators-of-Aeronautics/Simulated-Project#550, etc.).
Implementation links:
The core changes are concentrated on the Rust / Rapier side. The Java side only periodically requests an origin reset. External APIs and observable behavior remain unchanged (absolute world coordinates are still used everywhere outside the physics pipeline).
Approach
- Maintain a floating origin (
DVec3) per physics scene.
- All coordinates entering/leaving Rapier are converted at the JNI boundary (
world ↔ local).
- Origin is forced to be integer-aligned.
- Static voxel colliders are not shifted (they stay in absolute coordinates). Because Minecraft block positions are integers / half-integers, they remain exactly representable in
f32 after rebasing within a very large range.
- Dynamic rigid bodies and the broadphase are shifted via
shift_world_origin when the origin is reset.
- Java periodically calls
requestOriginReset based on the active region.
This keeps the expensive f32 SIMD path intact while eliminating precision loss for physics.
Results
Physics simulation remains stable roughly within a ±4000 km range from the current floating origin (limited by the fact that world collision queries can still involve large floating-point integers).
Current Limitations
-
Rendering is not addressed
This change only fixes the physics pipeline. Visual jitter / tearing at large distances will still occur until a similar treatment is applied on the rendering side.
-
Multi-player / multi-focus limitation
When two players (or active regions) are very far apart, the origin is currently placed near their midpoint. Both regions can still experience precision issues if the distance between them becomes large.
Happy to open a draft PR if there is interest.
I implemented a dynamic floating origin solution to address the long-standing distance / precision issues (see #10, #604, #1076, #1321, Creators-of-Aeronautics/Simulated-Project#550, etc.).
Implementation links:
The core changes are concentrated on the Rust / Rapier side. The Java side only periodically requests an origin reset. External APIs and observable behavior remain unchanged (absolute world coordinates are still used everywhere outside the physics pipeline).
Approach
DVec3) per physics scene.world ↔ local).f32after rebasing within a very large range.shift_world_originwhen the origin is reset.requestOriginResetbased on the active region.This keeps the expensive f32 SIMD path intact while eliminating precision loss for physics.
Results
Physics simulation remains stable roughly within a ±4000 km range from the current floating origin (limited by the fact that world collision queries can still involve large floating-point integers).
Current Limitations
Rendering is not addressed
This change only fixes the physics pipeline. Visual jitter / tearing at large distances will still occur until a similar treatment is applied on the rendering side.
Multi-player / multi-focus limitation
When two players (or active regions) are very far apart, the origin is currently placed near their midpoint. Both regions can still experience precision issues if the distance between them becomes large.
Happy to open a draft PR if there is interest.