# Portable NavalFighter object

`objects/aircraft/` is a self-contained ES-module object package. It imports only files within that folder and receives the engine API explicitly. Copy the entire aircraft folder together with an independently located copy of `engine/`; the application chooses both import URLs.

```js
import * as api from './engine/index.js';
import {NavalFighter} from './objects/aircraft/index.js';

const fighter = new NavalFighter(api, {gear: false, throttle: 0.65});
scene.add(fighter.root);
fighter.setPosition(0, 1000, 0);
fighter.setFlightState({speed: 140, altitude: 1000, heading: Math.PI / 2,
  pitch: 0.02, roll: -0.1, verticalSpeed: 2, terrainHeight: 250});
fighter.update(dt, elapsedSeconds);
```

The injected API must supply `THREE`, `ObjectState`, and `OBJECT_PROTOCOL: 1`. `consolidate(group)` is used when supplied to batch fixed parts by material; it is optional, but recommended for rendering cost. The local `PortableObject` supplies root/transforms, properties, bounds, serialization and lifecycle. No globals, downloaded images, remote fonts, renderer patches or shared mutable singleton materials are required. All canvas artwork and textures are generated during construction; Node construction has a one-pixel texture fallback for nonvisual checks.

## Reference, scale, orientation and limitations

The reference is a single-seat F/A-18E Super Hornet, using the [US Navy public fact file](https://www.navy.mil/Resources/Fact-Files/Display-FactFiles/Article/2383479/fa-18a-d-hornet-and-fa-18ef-super-hornet-strike-fighter/). The Navy gives 60.3 ft length, 44.9 ft / 13.68 m span and 16 ft / 4.87 m height. The generated exterior measures approximately 18.401 m long, 13.685 m wide and 4.870 m high with the landing gear down. Small discrepancies include modeled lights and edge thickness.

Axes are **-Z forward, +Y up, +X starboard**. Root origin is near the fuselage center. The gear-down model extends to about -1.911 m in local Y; placing its origin at Y = 1.912 on a level surface puts the wheels on that surface. Bounds include the visible scene geometry; `getBounds()` is not an aerodynamic or collision envelope, and the engine's generic bounds include hidden retracted components.

The exterior has lofted fuselage/nacelles, a genuine cockpit opening, swept wings and leading-edge extensions, twin rectangular intake lips with recessed ducts, canted twin vertical tails, separate rudders/flaps/ailerons/stabilators, empty underwing pylons and wingtip rails, twin exhaust collars and petal nozzles, an arresting hook, articulated gear, canopy frames/glass, surface seams, fasteners and locally generated service markings. Markings use fictional `NF / ASTRA 101` identification.

This is a procedural, reference-inspired visual model; it is not manufacturer CAD, an exact block-specific reconstruction, a certified simulator or a complete operational cockpit. Instruments, engine readouts, navigation artwork and systems are representative. Navigation artwork includes a fixed illustrative waypoint route; heading and speed are live, but this package does not integrate real waypoint navigation. No weapons or weapons-system behavior are implemented. It does not simulate aerodynamics, thrust, lift, fuel consumption, electrical buses or engine thermodynamics. The shell owns aircraft motion and feeds state into this object.

## Camera and view

`fighter.cameraMounts.pilot` is an `Object3D` at `(0, 1.28, -3.34)` with local pitch `-0.23` rad. An attached Three.js camera faces forward through the windshield. Its local transform should be identity, or copy the mount's world position and quaternion into an unattached camera. Use a near plane around `0.025 m`; a conventional exterior near plane can cut away controls. A 70–78 degree vertical field of view shows the HUD and upper instrument panel. Looking down exposes the stick, throttles, consoles and pedals. Looking aft exposes the seat and harness. Mouse look belongs in the shell.

`fighter.setView('cockpit' | 'external')` adjusts canopy opacity and a small interior fill light. It does not change camera transforms. A canopy opening exists in the fuselage itself; the eye is not placed inside an opaque hull. The seat, consoles, cockpit sidewalls, coaming, panel and HUD are actual 3D components. `cameraMounts.chase` is a suggested external position reference; the shell may use its existing follow camera instead.

## Controls

`CONTROL_DEFINITIONS` is exported, and also available as `fighter.controlDefinitions`. `setControl(name, value)` returns the fighter. Unknown controls and non-finite numeric values throw. Numeric values are clamped to their documented range. Boolean controls accept booleans or 0/1. `getControl(name)` returns the current command. `activateControl(name)` toggles a boolean or advances a range by its defined step, wrapping at maximum.

| Control | Values / default | Observable behavior |
| --- | --- | --- |
| `masterPower` | boolean / true | Powers displays, avionics readout, cockpit and exterior lights; representative engine RPM spools down when off. |
| `avionics` | boolean / true | Powers the three live displays, HUD and up-front controller; off raises caution with master on. |
| `panelLights` | boolean / true | Enables console label emission and green interior illumination. |
| `panelDimmer` | 0–1 / 0.65 | Scales panel illumination. Click steps by 0.2. |
| `navLights` | boolean / true | Enables port red, starboard green, tail white and flashing red beacon. |
| `landingLights` | boolean / false | Enables forward lamp emission and one non-shadowing spot light. |
| `throttle` | 0–1 / 0.55 | Commands both throttle levers together. Readback is their average. |
| `throttleLeft`, `throttleRight` | 0–1 / 0.55 | Independent physical throttle lever angle, live engine RPM/temperature and exhaust-core brightness. |
| `gear` | boolean / false | Commands an animated deployment or retraction; gear indications follow actual animation position. |
| `flaps` | 0–1 / 0 | Animates trailing-edge flaps and coupled small aileron droop. Click steps by 0.5. |
| `canopy` | boolean / false | Opens or closes the hinged canopy and raises caution when open. |
| `stickPitch`, `stickRoll` | -1–1 / 0 | Moves the physical stick and corresponding stabilator/aileron surfaces. |
| `rudder` | -1–1 / 0 | Moves both rudders and opposing pedals. |

Constructor options can supply these names directly or in a `controls` object. A nested `controls` value overrides its corresponding direct option. Commands are meaningful object state; the shell must separately decide how throttle, stick, flaps or gear affect its flight model.

`fighter.interactiveObjects` contains physical control meshes. Each mesh has `userData.control` and `userData.controlLabel`. Raycast that array, read the name from the closest hit, and call `activateControl(name)`, or use `setControl` for dragging. The click surfaces include master, avionics, panel/navigation/landing lights, gear, flaps, canopy, dimmer and both throttle levers. The representative keypad and MFD bezel buttons are visual detail, not unsupported simulated avionics functions. Pitch/roll/rudder are exposed through the API and animated geometry; the shell supplies input handling.

## Flight state and instruments

`setFlightState` accepts a partial object:

| Field | Units |
| --- | --- |
| `speed` | m/s; clamped to nonnegative |
| `altitude`, `terrainHeight` | metres, using the same vertical datum |
| `heading`, `pitch`, `roll` | radians |
| `verticalSpeed` | m/s; positive climbing |

`getInstrumentState()` returns a fresh snapshot, including flight inputs, knots, feet, heading degrees, ft/min, radar altitude above supplied terrain, display power, panel brightness, throttle positions, representative left/right RPM and EGT, animated gear/flap/canopy positions, and `gearStatus` (`UP`, `TRANSIT`, `DOWN`). It also exposes a representative terrain caution when faster than 45 m/s and less than 45 m above the supplied terrain with gear commanded up. This is visual demonstration logic, not a safety alerting system.

Three 512 × 512 live textures provide an attitude/flight display, compass/navigation display and engine/systems display. A 768 × 640 transparent HUD provides speed, altitude, heading, pitch ladder, roll, vertical speed and radar altitude. Two standby needles follow airspeed and altitude. Electronic display drawing is limited to approximately 10 Hz, independent of render rate. `update(0)` immediately initializes or refreshes dirty display textures. The shell should call `update` every frame for moving controls and lights.

## Lifecycle and verification

`serialize()` extends the common transform/properties snapshot with controls, flight state, mechanism positions, engine RPM and view; `restore(data)` restores those fields. `dispose()` is idempotent and releases the object graph's geometries, materials and textures via the engine's `ObjectState`. Instances do not share owned material or texture resources. Remove/dispose the fighter when its scene is replaced.

`tests/aircraft-object.html` is the standalone visual inspection page. It provides exterior orbit, rear view, a pilot camera, cockpit mouse look, physical control picking, switches/sliders and a `Run object checks` button. It exposes `window.aircraftTest = {fighter, scene, camera, renderer, orbit, setView, runChecks}` for browser verification. Browser rendering evidence must be inspected separately from Node construction results.

Direct Node construction checks verified module loading, finite mesh positions, SI conversion, gear animation, linked throttles and power response, serialization, and idempotent disposal. A forward eye-level ray intersects no opaque airframe mesh within 5 m after the windshield-frame clearance correction. The package currently contains 76,424 geometric triangles, 197 mesh submissions before visibility/frustum culling, 84 material objects and 51 generated textures with injected static consolidation. The inspection page reports actual renderer draw calls/triangles; shadow rendering and host scene content add work. Exact operational visual fidelity and photorealism are not inferred from those counts.

Initial Chrome verification before the detail refinement on 2026-09-07 (authorized extension instance `31c90c85-f2d8-4560-b1da-89548fa371ed`) inspected the actual front-quarter exterior, rear exhaust/tail view, forward pilot view and downward console view. Physical red master-switch picking turned the three screens, HUD, up-front readout and gear lights off. The browser fixture contract checks passed. The fixture reported 205 draw calls / 23,846 triangles externally and approximately 101–138 calls / 13,738–15,882 triangles in tested cockpit views, including the fixture ground and grid. The first-frame negative timestamp delta exposed by that inspection was fixed in the fixture, and startup/JS/shader errors now report visibly. Visual refinement corrected canopy visibility, decal shadow rectangles, fin UV stretching and coaming obstruction of the gear lamps. This is a substantially detailed procedural model, with remaining simplifications in airfoil/fuselage contours, cockpit layout and surface weathering.


## Aircraft-detail5 visual refinement

The refined exterior uses smoothly interpolated longitudinal cross sections for the nose, fuselage and engine housings. Rounded rectangular intake sections transition into the engine bodies, with beveled lips and recessed ducts. Wing, stabilator and vertical-tail geometry now has tapered thickness and curved sections instead of constant-thickness slabs. These are visual sections, not aerodynamic simulation data. The cockpit shoulder skin joins the canopy sill; the internal floor and sidewalls fit inside the forward fuselage without protruding through it or covering the displays.

Painted surfaces use locally generated 2048 × 2048 service-wear/albedo maps, separate roughness and fine bump detail, restrained coat reflections and a modest underside paint variation. Wing seams and markings follow the actual curved surface. Dorsal vents are flush surface details. The exhausts have segmented metal shells and recessed rings/struts. Canopy reflection opacity varies with view angle. The fixed windscreen remains attached to the fuselage while the separate main canopy opens about its rear hinge. No downloaded textures, scanned model, external font, network asset or runtime AI is required.

The cockpit has beveled display housings, keypad/bezel buttons and switch grips; smaller panel legends; fasteners and low-profile fittings; rounded seat cushions; and flat harness ribbons. The public constructor, SI flight-state fields, controls, camera mounts and serialization contract are unchanged. The pilot mount remains `(0, 1.28, -3.34)` with pitch `-0.23` rad. The forward eye-level aperture is clear, and nine rays from the eye to the three live displays independently verify that cockpit geometry does not cover their visible faces.

This revision was inspected in the authorized Chrome instance from front-quarter, side and rear-quarter exterior views, plus the actual pilot and downward console views. Gear retraction, flap movement and canopy opening were visibly exercised. Physical master and avionics switch meshes were clicked: master-off darkened the screens/HUD and electrical annunciators; avionics-off darkened the screens/HUD while gear indications remained lit and caution illuminated. The browser object checks include SI conversion, linked throttles, gear endpoints, fixed-windscreen canopy motion, control surfaces, lighting materials, pickable controls, span, forward aperture and nine display-visibility rays.

The detailed default object contains 76,424 triangles, 197 mesh objects, 84 materials and 51 textures. The standalone fixture measured 219 calls / 82,382 rendered triangles externally and 108 calls / 57,286 triangles in the default pilot view; the fixture includes its sky/ground and transparent-material passes. The extra geometry is the cost of smoother contours and beveled cockpit parts. The fixture now uses engine daylight/environment lighting to inspect painted and metallic response. Do not compare those appearance changes solely as a model change under identical illumination.

Node checks verified finite geometry, wing-facing normals, unchanged camera transform, SI/control behavior, serialization/restoration, per-instance texture isolation and idempotent disposal of all 333 graph resources. The object import-closure audit passes. The model remains procedural and reference-inspired, with representative cockpit layout, simplified gear/detail topology and approximate service markings; these improvements are not a claim of photorealism, manufacturer-CAD accuracy or user visual acceptance.
