3D flight simulator: 6-DOF physics, three.js r160, browser HUD

- Detailed flight dynamics: aero lift/drag/side-force with smooth stall,
  control-surface moments, stability derivatives, engine spool with prop
  torque and gyro precession, inertial coupling, ISA atmosphere, ground
  effect, 3-point gear handling, landing vs crash classification.
- Pure ESM, zero build step; three.js vendored locally. Deterministic
  simulation; physics core is Node-testable (14 node:test cases).
- Procedural 8 km world with runway, water, sky dome, cloud wrap; DOM
  instrument panel (attitude indicator, tapes, VSI, lamps, stall warning).
- Controls: WASD/arrows, Q/E rudder, Shift/Ctrl throttle, F flaps, G gear,
  B brakes, C camera (chase/cockpit/orbit), R reset, P pause, D debug.
This commit is contained in:
Quintine committed 2026-08-24 17:58:58 +10:00
commit 8c19cdaae6
18 files changed
+4499

No files matched your search

+108
View File
@@ -0,0 +1,108 @@
# Flight Sim
A browser 3D flight simulator: a detailed 6-DOF propeller aircraft flown over a
procedural 8 km world, with an instrument HUD, synthesized engine/wind audio and
three camera views (chase / cockpit / orbit). Pure ES modules, zero build step,
no assets, no runtime network — Three.js r160 is vendored locally.
Spawn: on the south end of the runway, engine idling, flaps 25 %, gear down,
brakes on. Throttle up with **Shift**, release brakes with **B**, roll forward
with the stick, and rotate at ~120–140 kts.
## Run it
ES modules must be served over HTTP (opening `index.html` directly on `file://`
is blocked by the browser). From the project root:
```bash
python3 -m http.server 8080
# or
npx serve .
```
Then open <http://localhost:8080>. Fullscreen canvas; **CLICK TO START**
enables audio (the browser requires a user gesture for WebAudio).
## Controls
> Table below mirrors `KEY_BINDINGS` from `src/controls.js` (single source).
| Key | Command |
|----------------|--------------------------------|
| `W` / `S` | Elevator — pitch up / down |
| `A` / `D` | Aileron — bank left / right |
| `↑` / `↓` | Elevator (arrow keys) |
| `←` / `→` | Aileron (arrow keys) |
| `Q` / `E` | Rudder — yaw left / right |
| `Shift`/`Ctrl` | Throttle up / down |
| `F` | Flaps 0 → 25 % → 50 % → 100 % |
| `G` | Gear up / down |
| `B` | Brakes on / off |
| `C` | Camera view (chase/cockpit/orbit) |
| `R` | Reset flight |
| `P` | Pause |
| `D` | Debug overlay |
| `S` / `Enter` | Sound on / off |
Sticks slew smoothly (~1.6 full-range/s), throttle slews slowly (~0.4/s) so
engine response feels realistic; toggle keys ignore auto-repeat.
## Architecture
```
index.html static shell: canvas, #hud, start overlay
css/style.css HUD/instrument glass styles + start overlay (integrator)
src/main.js game loop, fixed-timestep physics driver, cameras,
crash/reset/pause/debug, audio + HUD feed (integrator)
src/config.js SI constants — single source of truth (airframe, atmo)
src/world.js deterministic height field + runway (single ground source)
src/physics.js 6-DOF rigid-body dynamics, ground model, crash logic
src/controls.js keyboard → smoothed inputs + action events
src/aircraft-model.js Three.js visual model (surfaces/prop/gear animate)
src/terrain.js sky, sun, elevation-mapped ground, runway, water, clouds
src/instruments.js DOM instrument overlay (attitude, tapes, lamps, stall)
src/audio.js synthesized engine/wind/stall/touchdown (WebAudio)
vendor/three.module.min.js Three.js r160 (vendored)
```
### Loop
`main.js` runs a fixed-timestep sim: real frame dt is clamped to 0.05 s,
accumulated, and consumed in 1/120 s physics steps (max 8 per frame), so
simulation behaviour is frame-rate independent and deterministic. No
`Math.random()` anywhere in physics; cosmetic randomness is seeded.
### Physics summary
- Body frame **+X forward, +Y right, +Z down**; quaternions `[w,x,y,z]`;
heading 0° = north, +Y world up.
- Forces: stability-axis lift fitted with a smooth stall blend toward the
flat-plate regime, drag `CD0 + k·CL² + flaps/gear + flat-plate`, side force
from β and rudder; moments from static stability, control effectiveness and
rate damping (`Cmq`, `Clp`, `Cnr`).
- Engine: first-order spool to throttle, thrust scaled by `(ρ/ρ0)^0.7`,
prop torque and gyroscopic moment about the thrust axis.
- Inertial coupling with the full symmetric inertia tensor; semi-implicit
Euler integration at 1/240 s substeps, quaternion renormalised per substep.
- Ground: wheel-height contact, crash vs. landing classification by sink rate,
gear state and attitude; rolling friction, ×3 braking, ground steering,
taxi thrust. Fuel burn ∝ rpm·throttle.
- Atmosphere: ISA density lapse with altitude.
### Camera modes (`C`)
1. **Chase** — smooth follow 8 m aft / 2.2 m above the c.g., looking just
ahead of the nose.
2. **Cockpit** — pilot eye at `aircraft-model.cockpitOffset()`, hard-locked to
the aircraft attitude with a subtle g-load sway.
3. **Orbit** — slow auto-spin around the ship; drag with the mouse to steer
the view angle and height.
### Notes
- Shadows are disabled by default (cheap path; flip
`buildEnvironment(scene, { shadows: true })` and enable
`renderer.shadowMap` in `main.js` to test the 4096 px variant).
- Altimeter/airspeed/VS are pitot-static cosmetics: ft, kts, fpm.
- One CSS file owns all HUD look; `instruments.js` only sets per-frame
transforms and class toggles.