aeronautic

Driving from code

The nozzle handle and the batch ref, and which to use for what.

There are two refs. Each value lives on one of them:

what changeswhere it liveshow to change it per frame
throttlethe nozzlehandle.throttle = …
where it sits, which way it pointsthe nozzlehandle.setOffset, setDirection
the engine (radius, Mach, soot…)the nozzle's paramshandle.updateParams (not every frame)
altitude, airspeed, the day, exposurethe batch's profilebatch.updateProfile
step countsthe batch's qualitybatch.setQuality

The nozzle handle

import {
  Afterburner,
  type AfterburnerHandle,
} from "@aeronautic/afterburner/react";

const engine = useRef<AfterburnerHandle>(null);

<Afterburner ref={engine} preset="afterburner" />;
memberwhat it does
throttleRead or write, 0 to 1 dry, to 1.1 with reheat. Cheap enough to write every frame.
updateParams(partial)Merges into the current params. Rewrites this one instance.
setParams(params)Replaces the params over the preset.
setOffset(offset)Moves or turns the nozzle in the frame it sits in.
setDirection([x,y,z])Points the exhaust.
paramsThe resolved params, or null before the nozzle is in a batch.
objectThe nozzle's Group.
nozzleThe core AfterburnerNozzle, for anything else.
batchThe AfterburnerBatchHandle it draws with.

The handle is stable for the component's life. It's safe to use before the nozzle has joined a batch.

The plume doesn't jump to a throttle you write: it eases toward it over the batch's responseS, a quarter of a second by default, as a real engine spools and a burner lights. handle.nozzle.drawnThrottle is where it has got to. Set responseS={0} on <AfterburnerBatch> to follow at once.

throttle-ref.tsx
Starting…

The batch ref

<AfterburnerBatch ref> is the AfterburnerBatchHandle itself:

import {
  AfterburnerBatch,
  type AfterburnerBatchHandle,
} from "@aeronautic/afterburner/react";

const batch = useRef<AfterburnerBatchHandle>(null);

useFrame(() => {
  batch.current?.updateProfile({ altitudeM: aircraft.position.y });
});

<AfterburnerBatch ref={batch} preset="afterburner">
  <Afterburner />
  <Afterburner position={[0, 0, 1.2]} />
</AfterburnerBatch>;

updateProfile merges the fields you give and only writes uniforms. Calling it every frame is fine. batch.stats() returns { nozzles, near, mid, far, culled }, handy for an overlay.

Without an <AfterburnerBatch> you can still reach the shared batch through any nozzle's handle.batch. Inside one, useAfterburnerBatch() returns the nearest.

Props versus refs

A prop is applied when it changes, and wins when it does. If something writes updateParams({ sootPerM }) and the params prop later changes, the prop's value replaces it. The same goes for profile and updateProfile. Let one owner set each field: props for settings, refs for what a simulation drives.

On this page