175 lines
4.8 KiB
Markdown
175 lines
4.8 KiB
Markdown
Here’s a **design plan** for a Bevy-based Solar System sim with **all major planets + major moons** (Earth, Mars, Jupiter, Saturn), no asteroids, stable at **all time scales**, and using a **good fixed timestep** choice for the fastest orbits.
|
||
|
||
---
|
||
|
||
## **1. Simulation Scope**
|
||
|
||
**Bodies included**:
|
||
|
||
* **Planets**: Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
|
||
* **Moons**:
|
||
|
||
* Earth: Moon
|
||
* Mars: Phobos, Deimos
|
||
* Jupiter: Io, Europa, Ganymede, Callisto
|
||
* Saturn: Titan, Rhea, Iapetus, Dione, Tethys, Enceladus, Mimas
|
||
*(Total \~22 bodies)*
|
||
|
||
No asteroids, no small irregular moons — keeps N small enough for **exact N-body**.
|
||
|
||
---
|
||
|
||
## **2. Coordinate & Unit System**
|
||
|
||
**Units**:
|
||
|
||
* Distance: **AU**
|
||
* Time: **days**
|
||
* Mass: **solar masses**
|
||
* Constant: **G = 2.9591220828559093e-4 AU³ / (M☉·day²)**
|
||
|
||
**Precision**:
|
||
|
||
* Simulation: `f64` for all positions/velocities.
|
||
* Rendering: `f32` with **floating origin**.
|
||
|
||
**Reference frame**:
|
||
|
||
* Start in **barycentric J2000 ecliptic frame**.
|
||
* Planets initialized with **orbital elements** from NASA/JPL Horizons.
|
||
* Moons initialized **relative to parent planet**, then converted to barycentric coordinates.
|
||
|
||
---
|
||
|
||
## **3. Time Integration Strategy**
|
||
|
||
### **Base timestep choice**
|
||
|
||
Fastest orbital period in scope:
|
||
|
||
* **Mimas** (moon of Saturn) → \~0.942 days per orbit.
|
||
To get ≥300 steps/orbit for stability:
|
||
* `dt_base = 0.003 days` (\~4.32 minutes per step)
|
||
|
||
This works for:
|
||
|
||
* Mimas: \~314 steps/orbit
|
||
* Mercury: \~29,323 steps/orbit
|
||
* Outer planets: many more → extremely stable.
|
||
|
||
---
|
||
|
||
### **Decoupled simulation loop**
|
||
|
||
* Always integrate at `dt_base = 0.003 days`.
|
||
* Convert **time scale** (days per real second) into **number of steps to take per frame**.
|
||
* At slow speeds: possibly fewer than 1 step/frame (interpolate positions for rendering).
|
||
* At high speeds: multiple steps/frame (batched substepping).
|
||
|
||
---
|
||
|
||
## **4. ECS Structure**
|
||
|
||
**Components**:
|
||
|
||
* `Body`: mass, visual radius, color, parent body index (if a moon)
|
||
* `State`: current position & velocity in AU/day
|
||
* `RenderProxy`: used for floating-origin transforms
|
||
|
||
**Resources**:
|
||
|
||
* `SimParams`: G constant, time scale, base dt, paused flag
|
||
* `FloatingOrigin`: current origin in AU
|
||
|
||
---
|
||
|
||
## **5. Physics Pipeline (per frame)**
|
||
|
||
1. **Determine number of substeps**:
|
||
|
||
* `sim_days_to_advance = time_scale × real_delta_seconds`
|
||
* `steps_needed = sim_days_to_advance / dt_base`
|
||
* Loop substeps until all sim\_days\_to\_advance consumed.
|
||
|
||
2. **N-body force calculation**:
|
||
|
||
* O(N²) summation — still trivial for \~22 bodies.
|
||
* Double precision for all math.
|
||
|
||
3. **Integrator**:
|
||
|
||
* Symplectic leapfrog (kick–drift–kick).
|
||
* Fixed `dt_base` in all cases.
|
||
|
||
4. **Floating origin adjustment**:
|
||
|
||
* Choose tracked target (e.g., Earth or camera target).
|
||
* Subtract target’s AU position from all bodies before converting to f32 for rendering.
|
||
|
||
---
|
||
|
||
## **6. Rendering Pipeline**
|
||
|
||
* **Distance compression**:
|
||
|
||
* Use a scale factor (e.g., `1 AU → 10,000 km visual`) so planets aren’t microscopic.
|
||
* **Planet size exaggeration**:
|
||
|
||
* Apply large visual radius multiplier for visibility.
|
||
* **Orbit trails**:
|
||
|
||
* Store sampled positions in a circular buffer for each body.
|
||
* **Lighting**:
|
||
|
||
* One directional light from Sun position.
|
||
|
||
---
|
||
|
||
## **7. Time Controls**
|
||
|
||
* **Pause/Resume** (spacebar)
|
||
* **Speed up / Slow down** (`[` / `]`) — adjust `time_scale`
|
||
* **Preset speeds**:
|
||
|
||
* 1 min = 1 year
|
||
* 1 sec = 1 day (slow motion)
|
||
* 1 sec = 10 years (fast forward)
|
||
* **Reverse time** (optional) — simply invert `time_scale`
|
||
|
||
---
|
||
|
||
## **8. Initialization Plan**
|
||
|
||
1. **Gather J2000 orbital elements** for all planets and moons (NASA/JPL Horizons).
|
||
2. **For moons**:
|
||
|
||
* Convert orbital elements relative to parent into Cartesian coordinates (AU, AU/day).
|
||
* Add parent planet’s barycentric position/velocity to get barycentric moon state.
|
||
3. **Store** these as starting states in your ECS.
|
||
|
||
---
|
||
|
||
## **9. Performance Considerations**
|
||
|
||
* N=22 bodies → no optimization needed beyond O(N²) CPU.
|
||
* At fastest speed (e.g., 1 sec = 1000 years):
|
||
|
||
* Steps per second = `(1000 × 365.25 days) / 0.003 days` ≈ 121,750 steps/sec
|
||
* Must batch steps in a loop inside one Bevy system per frame.
|
||
* Limit display FPS to avoid CPU overload (physics can run faster than rendering).
|
||
|
||
---
|
||
|
||
## **10. Validation & Testing**
|
||
|
||
* **Check orbital periods**:
|
||
|
||
* Measure period for Mercury, Earth, Moon, Mimas.
|
||
* **Energy drift check**:
|
||
|
||
* Track total system energy & angular momentum over 1,000 years of sim time.
|
||
* **Visual comparison**:
|
||
|
||
* Compare planet positions to JPL Horizons output for 10-year window to confirm accuracy.
|
||
|