aeronautic

Quick start

Vapor on an aircraft in a few lines.

<WingVapor> is a group where the aircraft's reference point sits, usually its model's origin. Put it inside the model, and give it the airframe, the flight and the day:

import { Canvas } from "@react-three/fiber";
import { WingVapor } from "@aeronautic/wing-vapor/react";
import { webgpu_gl } from "@aeronautic/core/react";

const Jet = () => (
  <group>
    <JetModel />
    <WingVapor
      // The model flies along its local -Z, with +Y up (the defaults)
      forward={[0, 0, -1]}
      airframe={{
        spanM: 14,
        rootChordM: 9.2,
        tipChordM: 1.6,
        leadingEdgeSweepRad: (55 * Math.PI) / 180,
        apexM: -5.66, // the leading edge meets the centreline 5.66 m ahead
      }}
      flight={{ airspeedMPerS: 170, angleOfAttackRad: 0.35 }}
      air={{ altitudeM: 300, relativeHumidity: 0.9 }}
      look={{ sunDirection: [5, 10, 5] }}
    />
  </group>
);

export const App = () => (
  <Canvas gl={webgpu_gl()}>
    <Jet />
  </Canvas>
);

The vapor reads the scene's depth, so it stops at the wing it sits on. Give look.sunDirection the same direction as your scene's sun, so the cloud is lit as the skin is.

Rather than typing the planform

Let the package measure the model from six depth views:

const { scene } = useGLTF("/jet.glb");

<group>
  <primitive object={scene} />
  <WingVapor
    capture={scene}
    // Not the shape the air flies round
    captureFilter={(mesh) => !/Gear|Pylon|Missile/.test(mesh.name)}
    flight={flight}
    air={air}
  />
</group>;

See Any shape.

Every frame

The flight changes every frame in a real scene. Write it through the ref, which costs no React render:

const vapor = useRef<WingVaporHandle>(null);

useFrame(() => {
  vapor.current?.updateFlight({
    airspeedMPerS: airspeed_m_s,
    angleOfAttackRad: angle_of_attack_rad,
  });
});

<WingVapor ref={vapor} airframe={airframe} />;

Next, fly it, or see it on the fighter.

On this page