# Fighter Jet

> A stylized twin-engine fighter jet with a faceted fuselage, dark radome, bubble canopy (hinged canopy group), boxy side intakes, swept delta wings with wingtip and underwing missiles, canted twin tails and glowing afterburner groups. The nose and main landing gear are pivoting groups that can be shown down or tucked away. Choose body and accent colors for air combat, military and flight games.

![Fighter Jet preview](https://codels.download/m/jet.png)

Multi-view sheet (3/4, front, side, top): https://codels.download/m/jet.sheet.png

## Facts

- Category: Vehicles › Aircraft
- Size (W × H × D): 10.39 × 4.57 × 16.55 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 1,836 · Meshes: 70 · Materials: 8
- License: CC0-1.0 (Codels built-in)
- Tags: aircraft, airfield, jet, plane, low-poly, stylized, military, modern, sky, shooter, hero-asset, vehicle, metal, emissive, game-ready, parametric, color-gray, size-huge, poly-medium
- Page: https://codels.download/models/jet

## Files

| Format | URL |
|---|---|
| three.js ES module (`createJet()`) | https://codels.download/m/jet.js |
| React Three Fiber component (`<Jet />`) | https://codels.download/m/jet.jsx |
| Instancing module (`createJetInstances(count, place)`, one draw call per material) | https://codels.download/m/jet.instanced.js |
| Standalone HTML demo | https://codels.download/m/jet.html |
| glTF binary | https://codels.download/m/jet.glb |
| glTF binary, Meshopt-compressed (2–3× smaller; GLTFLoader needs `setMeshoptDecoder(MeshoptDecoder)`) | https://codels.download/m/jet.glb?compress=meshopt |
| glTF JSON | https://codels.download/m/jet.gltf |
| OBJ (vertex colors) + MTL | https://codels.download/m/jet.obj · https://codels.download/m/jet.mtl |
| STL | https://codels.download/m/jet.stl |
| CodelSpec JSON | https://codels.download/m/jet.json |

## Parameters

Append them as query parameters to any URL above to get a customized variant (e.g. `?bodyColor=...`).

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `bodyColor` | color | #rrggbb | #808d9c | #808d9c |
| `accentColor` | color | #rrggbb | #d24d38 | #d24d38 |
| `afterburner` | boolean | true \| false | true | true |
| `gear` | boolean | true \| false | true | true |

## Parts

- airframe (group)
  - fuselage (lathe · paint)
  - radome (lathe · radome)
  - pitotProbe (cylinder · metal)
  - antiGlare (box · dark)
  - spine (box · paint)
  - canopy (group)
    - canopyGlass (sphere · glass)
    - canopyFrame (torus · dark)
  - canopyHinge (box · dark)
  - intakeL (box · paint)
  - intakeMouthL (box · dark)
  - intakeLipL (box · accent)
  - nacelleL (cylinder · paint)
  - nozzleL (cylinder · dark)
  - afterburnerL (group)
    - nozzleGlow (cylinder · core)
    - plume (cone · glow)
    - plumeCore (cone · core)
  - intakeR (box · paint)
  - intakeMouthR (box · dark)
  - intakeLipR (box · accent)
  - nacelleR (cylinder · paint)
  - nozzleR (cylinder · dark)
  - afterburnerR (group)
    - nozzleGlow (cylinder · core)
    - plume (cone · glow)
    - plumeCore (cone · core)
  - wingL (group)
    - wingPanel (extrude · paint)
    - wingTip (extrude · accent)
    - tipRail (box · dark)
    - tipMissile (group)
      - body (cylinder · metal)
      - seeker (cone · accent)
    - pylon (box · dark)
    - wingMissile (group)
      - body (cylinder · metal)
      - seeker (cone · accent)
  - wingR (group)

## How to use

Save the code below as `jet.js`, then:

```js
import { createJet } from './jet.js';
const model = createJet();
scene.add(model);
```

## Code

```js
/**
 * Fighter Jet — Codels 3D model library (https://codels.download/models/jet)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,836 · Size (W × H × D): 10.39 × 4.57 × 16.55 m
 *
 * Usage:
 *   import { createJet } from './jet.js';
 *   
 *   const model = createJet();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

// Revolve a 2D profile [[radius, y], ...] around the Y axis.
function lathe(points, segments, phiStart = 0, phiLength = Math.PI * 2) {
  return new THREE.LatheGeometry(points.map(([x, y]) => new THREE.Vector2(x, y)), segments, phiStart, phiLength);
}

// Extrude a 2D outline along Z (centered). bevel = [thickness, size, segments].
function extrude(outline, depth, holes = [], bevel = null) {
  const shape = new THREE.Shape(outline.map(([x, y]) => new THREE.Vector2(x, y)));
  for (const hole of holes) shape.holes.push(new THREE.Path(hole.map(([x, y]) => new THREE.Vector2(x, y))));
  const options = bevel
    ? { depth, bevelEnabled: true, bevelThickness: bevel[0], bevelSize: bevel[1], bevelSegments: bevel[2] }
    : { depth, bevelEnabled: false };
  return new THREE.ExtrudeGeometry(shape, options).translate(0, 0, -depth / 2);
}

export function createJet() {
  const root = new THREE.Group();
  root.name = 'Jet';

  // Materials
  const paintMat = new THREE.MeshStandardMaterial({ name: 'paint', color: 0x808d9c, roughness: 0.5, metalness: 0.25, flatShading: true });
  const accentMat = new THREE.MeshStandardMaterial({ name: 'accent', color: 0xd24d38, roughness: 0.45, metalness: 0.15, flatShading: true });
  const radomeMat = new THREE.MeshStandardMaterial({ name: 'radome', color: 0x464e56, roughness: 0.55, metalness: 0.2, flatShading: true });
  const glassMat = new THREE.MeshStandardMaterial({ name: 'glass', color: 0x25313e, roughness: 0.2, metalness: 0.35 });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x2b2f36, roughness: 0.6, metalness: 0.35, flatShading: true });
  const metalMat = new THREE.MeshStandardMaterial({ name: 'metal', color: 0xc3c8cf, roughness: 0.35, metalness: 0.6, flatShading: true });
  const glowMat = new THREE.MeshStandardMaterial({ name: 'glow', color: 0xff7a2a, roughness: 0.5, emissive: 0xff5212, emissiveIntensity: 1.5, flatShading: true });
  const coreMat = new THREE.MeshStandardMaterial({ name: 'core', color: 0xfff1bf, roughness: 0.5, emissive: 0xffd77a, emissiveIntensity: 1.6, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.66, 0.96, 2.5);
  const boxGeo2 = new THREE.BoxGeometry(0.54, 0.82, 0.04);
  const boxGeo3 = new THREE.BoxGeometry(0.7, 0.07, 0.4);
  const cylinderGeo = new THREE.CylinderGeometry(0.55, 0.55, 6.7, 10);
  const cylinderGeo2 = new THREE.CylinderGeometry(0.5, 0.55, 0.55, 10);
  const cylinderGeo3 = new THREE.CylinderGeometry(0.44, 0.44, 0.03, 10);
  const coneGeo = new THREE.ConeGeometry(0.42, 1.6, 10);
  const coneGeo2 = new THREE.ConeGeometry(0.27, 1, 8);
  const boxGeo4 = new THREE.BoxGeometry(0.08, 0.1, 2);
  const cylinderGeo4 = new THREE.CylinderGeometry(0.075, 0.075, 2.4, 6);
  const coneGeo3 = new THREE.ConeGeometry(0.075, 0.3, 6);
  const boxGeo5 = new THREE.BoxGeometry(0.36, 0.02, 0.2);
  const boxGeo6 = new THREE.BoxGeometry(0.02, 0.36, 0.2);
  const boxGeo7 = new THREE.BoxGeometry(0.08, 0.3, 1.2);
  const cylinderGeo5 = new THREE.CylinderGeometry(0.1, 0.1, 2.9, 6);
  const coneGeo4 = new THREE.ConeGeometry(0.1, 0.4, 6);
  const boxGeo8 = new THREE.BoxGeometry(0.46, 0.02, 0.26);
  const boxGeo9 = new THREE.BoxGeometry(0.02, 0.46, 0.26);
  const boxGeo10 = new THREE.BoxGeometry(0.32, 0.02, 0.2);
  const extrudeGeo = extrude([[-3.4, -0.15], [-5.25, 2.3], [-6.2, 2.36], [-6.7, -0.15]], 0.09, [], [0.03, 0.04, 1]);
  const extrudeGeo2 = extrude([[-4.97, 1.93], [-5.25, 2.3], [-6.2, 2.36], [-6.27, 1.93]], 0.12, [], [0.03, 0.04, 1]);
  const boxGeo11 = new THREE.BoxGeometry(0.1, 0.4, 0.05);
  const cylinderGeo6 = new THREE.CylinderGeometry(0.07, 0.08, 0.9, 6);
  const boxGeo12 = new THREE.BoxGeometry(0.04, 0.72, 0.6);
  const cylinderGeo7 = new THREE.CylinderGeometry(0.4, 0.4, 0.26, 12);
  const cylinderGeo8 = new THREE.CylinderGeometry(0.2, 0.2, 0.28, 8);

  // Parts
  const airframe = new THREE.Group();
  airframe.name = 'airframe';
  airframe.position.set(0, 1.95, 0);
  root.add(airframe);
  const fuselage = new THREE.Mesh(lathe([[0, -6.05], [0.46, -6.05], [0.7, -4.6], [0.82, -2], [0.86, 0.6], [0.8, 2.6], [0.68, 4.3], [0.52, 5.55]], 10, 0.3142, Math.PI * 2), paintMat);
  fuselage.name = 'fuselage';
  fuselage.rotation.set(deg(90), 0, 0);
  fuselage.scale.set(1, 1, 0.78);
  airframe.add(fuselage);
  const radome = new THREE.Mesh(lathe([[0.52, 5.55], [0.4, 6.35], [0.22, 7.1], [0.06, 7.5], [0, 7.55]], 10, 0.3142, Math.PI * 2), radomeMat);
  radome.name = 'radome';
  radome.rotation.set(deg(90), 0, 0);
  radome.scale.set(1, 1, 0.78);
  airframe.add(radome);
  const pitotProbe = new THREE.Mesh(new THREE.CylinderGeometry(0.025, 0.025, 0.6, 5), metalMat);
  pitotProbe.name = 'pitotProbe';
  pitotProbe.position.set(0, 0, 7.75);
  pitotProbe.rotation.set(deg(90), 0, 0);
  airframe.add(pitotProbe);
  const antiGlare = new THREE.Mesh(new THREE.BoxGeometry(0.5, 0.04, 1), darkMat);
  antiGlare.name = 'antiGlare';
  antiGlare.position.set(0, 0.6, 5);
  antiGlare.rotation.set(deg(-6), 0, 0);
  airframe.add(antiGlare);
  const spine = new THREE.Mesh(new THREE.BoxGeometry(0.36, 0.3, 4.6), paintMat);
  spine.name = 'spine';
  spine.position.set(0, 0.55, -0.6);
  airframe.add(spine);
  const canopy = new THREE.Group();
  canopy.name = 'canopy';
  canopy.position.set(0, 0.38, 2.3);
  airframe.add(canopy);
  const canopyGlass = new THREE.Mesh(new THREE.SphereGeometry(0.5, 12, 5, 0, Math.PI * 2, 0, Math.PI / 2), glassMat);
  canopyGlass.name = 'canopyGlass';
  canopyGlass.position.set(0, -0.02, 1.25);
  canopyGlass.scale.set(0.8, 0.9, 2.5);
  canopy.add(canopyGlass);
  const canopyFrame = new THREE.Mesh(new THREE.TorusGeometry(1, 0.05, 4, 12, Math.PI), darkMat);
  canopyFrame.name = 'canopyFrame';
  canopyFrame.position.set(0, -0.02, 1.62);
  canopyFrame.scale.set(0.37, 0.42, 1);
  canopy.add(canopyFrame);
  const canopyHinge = new THREE.Mesh(new THREE.BoxGeometry(0.62, 0.12, 0.3), darkMat);
  canopyHinge.name = 'canopyHinge';
  canopyHinge.position.set(0, 0.36, 2.25);
  airframe.add(canopyHinge);
  const intakeL = new THREE.Mesh(boxGeo, paintMat);
  intakeL.name = 'intakeL';
  intakeL.position.set(1.06, -0.15, 1.15);
  airframe.add(intakeL);
  const intakeMouthL = new THREE.Mesh(boxGeo2, darkMat);
  intakeMouthL.name = 'intakeMouthL';
  intakeMouthL.position.set(1.06, -0.15, 2.41);
  airframe.add(intakeMouthL);
  const intakeLipL = new THREE.Mesh(boxGeo3, accentMat);
  intakeLipL.name = 'intakeLipL';
  intakeLipL.position.set(1.06, 0.36, 2.15);
  airframe.add(intakeLipL);
  const nacelleL = new THREE.Mesh(cylinderGeo, paintMat);
  nacelleL.name = 'nacelleL';
  nacelleL.position.set(0.86, -0.2, -3);
  nacelleL.rotation.set(deg(90), 0, 0);
  airframe.add(nacelleL);
  const nozzleL = new THREE.Mesh(cylinderGeo2, darkMat);
  nozzleL.name = 'nozzleL';
  nozzleL.position.set(0.86, -0.2, -6.62);
  nozzleL.rotation.set(deg(90), 0, 0);
  airframe.add(nozzleL);
  const afterburnerL = new THREE.Group();
  afterburnerL.name = 'afterburnerL';
  afterburnerL.position.set(0.86, -0.2, -6.9);
  airframe.add(afterburnerL);
  const nozzleGlow = new THREE.Mesh(cylinderGeo3, coreMat);
  nozzleGlow.name = 'nozzleGlow';
  nozzleGlow.position.set(0, 0, 0.02);
  nozzleGlow.rotation.set(deg(90), 0, 0);
  afterburnerL.add(nozzleGlow);
  const plume = new THREE.Mesh(coneGeo, glowMat);
  plume.name = 'plume';
  plume.position.set(0, 0, -0.8);
  plume.rotation.set(deg(-90), 0, 0);
  afterburnerL.add(plume);
  const plumeCore = new THREE.Mesh(coneGeo2, coreMat);
  plumeCore.name = 'plumeCore';
  plumeCore.position.set(0, 0, -0.51);
  plumeCore.rotation.set(deg(-90), 0, 0);
  afterburnerL.add(plumeCore);
  const intakeR = new THREE.Mesh(boxGeo, paintMat);
  intakeR.name = 'intakeR';
  intakeR.position.set(-1.06, -0.15, 1.15);
  airframe.add(intakeR);
  const intakeMouthR = new THREE.Mesh(boxGeo2, darkMat);
  intakeMouthR.name = 'intakeMouthR';
  intakeMouthR.position.set(-1.06, -0.15, 2.41);
  airframe.add(intakeMouthR);
  const intakeLipR = new THREE.Mesh(boxGeo3, accentMat);
  intakeLipR.name = 'intakeLipR';
  intakeLipR.position.set(-1.06, 0.36, 2.15);
  airframe.add(intakeLipR);
  const nacelleR = new THREE.Mesh(cylinderGeo, paintMat);
  nacelleR.name = 'nacelleR';
  nacelleR.position.set(-0.86, -0.2, -3);
  nacelleR.rotation.set(deg(90), 0, 0);
  airframe.add(nacelleR);
  const nozzleR = new THREE.Mesh(cylinderGeo2, darkMat);
  nozzleR.name = 'nozzleR';
  nozzleR.position.set(-0.86, -0.2, -6.62);
  nozzleR.rotation.set(deg(90), 0, 0);
  airframe.add(nozzleR);
  const afterburnerR = new THREE.Group();
  afterburnerR.name = 'afterburnerR';
  afterburnerR.position.set(-0.86, -0.2, -6.9);
  airframe.add(afterburnerR);
  const nozzleGlow2 = new THREE.Mesh(cylinderGeo3, coreMat);
  nozzleGlow2.name = 'nozzleGlow';
  nozzleGlow2.position.set(0, 0, 0.02);
  nozzleGlow2.rotation.set(deg(90), 0, 0);
  afterburnerR.add(nozzleGlow2);
  const plume2 = new THREE.Mesh(coneGeo, glowMat);
  plume2.name = 'plume';
  plume2.position.set(0, 0, -0.8);
  plume2.rotation.set(deg(-90), 0, 0);
  afterburnerR.add(plume2);
  const plumeCore2 = new THREE.Mesh(coneGeo2, coreMat);
  plumeCore2.name = 'plumeCore';
  plumeCore2.position.set(0, 0, -0.51);
  plumeCore2.rotation.set(deg(-90), 0, 0);
  afterburnerR.add(plumeCore2);
  const wingL = new THREE.Group();
  wingL.name = 'wingL';
  wingL.position.set(0, -0.08, 0);
  wingL.rotation.set(0, 0, deg(-2));
  airframe.add(wingL);
  const wingPanel = new THREE.Mesh(extrude([[0.5, 2.4], [1.4, 1], [4.75, -2.5], [4.85, -3.45], [0.5, -4.1]], 0.1, [], [0.03, 0.04, 1]), paintMat);
  wingPanel.name = 'wingPanel';
  wingPanel.rotation.set(deg(90), 0, 0);
  wingL.add(wingPanel);
  const wingTip = new THREE.Mesh(extrude([[4.1, -1.82], [4.75, -2.5], [4.85, -3.45], [4.1, -3.53]], 0.12, [], [0.03, 0.04, 1]), accentMat);
  wingTip.name = 'wingTip';
  wingTip.rotation.set(deg(90), 0, 0);
  wingL.add(wingTip);
  const tipRail = new THREE.Mesh(boxGeo4, darkMat);
  tipRail.name = 'tipRail';
  tipRail.position.set(4.93, 0, -2.75);
  wingL.add(tipRail);
  const tipMissile = new THREE.Group();
  tipMissile.name = 'tipMissile';
  tipMissile.position.set(5.02, 0, -2.55);
  wingL.add(tipMissile);
  const body = new THREE.Mesh(cylinderGeo4, metalMat);
  body.name = 'body';
  body.rotation.set(deg(90), 0, 0);
  tipMissile.add(body);
  const seeker = new THREE.Mesh(coneGeo3, accentMat);
  seeker.name = 'seeker';
  seeker.position.set(0, 0, 1.35);
  seeker.rotation.set(deg(90), 0, 0);
  tipMissile.add(seeker);
  const box36 = new THREE.Mesh(boxGeo5, darkMat);
  box36.position.set(0, 0, -1);
  tipMissile.add(box36);
  const box37 = new THREE.Mesh(boxGeo6, darkMat);
  box37.position.set(0, 0, -1);
  tipMissile.add(box37);
  const pylon = new THREE.Mesh(boxGeo7, darkMat);
  pylon.name = 'pylon';
  pylon.position.set(2.7, -0.2, -1.9);
  wingL.add(pylon);
  const wingMissile = new THREE.Group();
  wingMissile.name = 'wingMissile';
  wingMissile.position.set(2.7, -0.45, -1.75);
  wingL.add(wingMissile);
  const body2 = new THREE.Mesh(cylinderGeo5, metalMat);
  body2.name = 'body';
  body2.rotation.set(deg(90), 0, 0);
  wingMissile.add(body2);
  const seeker2 = new THREE.Mesh(coneGeo4, accentMat);
  seeker2.name = 'seeker';
  seeker2.position.set(0, 0, 1.65);
  seeker2.rotation.set(deg(90), 0, 0);
  wingMissile.add(seeker2);
  const box42 = new THREE.Mesh(boxGeo8, darkMat);
  box42.position.set(0, 0, -1.25);
  wingMissile.add(box42);
  const box43 = new THREE.Mesh(boxGeo9, darkMat);
  box43.position.set(0, 0, -1.25);
  wingMissile.add(box43);
  const box44 = new THREE.Mesh(boxGeo10, darkMat);
  box44.position.set(0, 0, 0.7);
  wingMissile.add(box44);
  const wingR = new THREE.Group();
  wingR.name = 'wingR';
  wingR.position.set(0, -0.08, 0);
  wingR.rotation.set(0, 0, deg(2));
  airframe.add(wingR);
  const wingPanel2 = new THREE.Mesh(extrude([[-0.5, 2.4], [-1.4, 1], [-4.75, -2.5], [-4.85, -3.45], [-0.5, -4.1]], 0.1, [], [0.03, 0.04, 1]), paintMat);
  wingPanel2.name = 'wingPanel';
  wingPanel2.rotation.set(deg(90), 0, 0);
  wingR.add(wingPanel2);
  const wingTip2 = new THREE.Mesh(extrude([[-4.1, -1.82], [-4.75, -2.5], [-4.85, -3.45], [-4.1, -3.53]], 0.12, [], [0.03, 0.04, 1]), accentMat);
  wingTip2.name = 'wingTip';
  wingTip2.rotation.set(deg(90), 0, 0);
  wingR.add(wingTip2);
  const tipRail2 = new THREE.Mesh(boxGeo4, darkMat);
  tipRail2.name = 'tipRail';
  tipRail2.position.set(-4.93, 0, -2.75);
  wingR.add(tipRail2);
  const tipMissile2 = new THREE.Group();
  tipMissile2.name = 'tipMissile';
  tipMissile2.position.set(-5.02, 0, -2.55);
  wingR.add(tipMissile2);
  const body3 = new THREE.Mesh(cylinderGeo4, metalMat);
  body3.name = 'body';
  body3.rotation.set(deg(90), 0, 0);
  tipMissile2.add(body3);
  const seeker3 = new THREE.Mesh(coneGeo3, accentMat);
  seeker3.name = 'seeker';
  seeker3.position.set(0, 0, 1.35);
  seeker3.rotation.set(deg(90), 0, 0);
  tipMissile2.add(seeker3);
  const box52 = new THREE.Mesh(boxGeo5, darkMat);
  box52.position.set(0, 0, -1);
  tipMissile2.add(box52);
  const box53 = new THREE.Mesh(boxGeo6, darkMat);
  box53.position.set(0, 0, -1);
  tipMissile2.add(box53);
  const pylon2 = new THREE.Mesh(boxGeo7, darkMat);
  pylon2.name = 'pylon';
  pylon2.position.set(-2.7, -0.2, -1.9);
  wingR.add(pylon2);
  const wingMissile2 = new THREE.Group();
  wingMissile2.name = 'wingMissile';
  wingMissile2.position.set(-2.7, -0.45, -1.75);
  wingR.add(wingMissile2);
  const body4 = new THREE.Mesh(cylinderGeo5, metalMat);
  body4.name = 'body';
  body4.rotation.set(deg(90), 0, 0);
  wingMissile2.add(body4);
  const seeker4 = new THREE.Mesh(coneGeo4, accentMat);
  seeker4.name = 'seeker';
  seeker4.position.set(0, 0, 1.65);
  seeker4.rotation.set(deg(90), 0, 0);
  wingMissile2.add(seeker4);
  const box58 = new THREE.Mesh(boxGeo8, darkMat);
  box58.position.set(0, 0, -1.25);
  wingMissile2.add(box58);
  const box59 = new THREE.Mesh(boxGeo9, darkMat);
  box59.position.set(0, 0, -1.25);
  wingMissile2.add(box59);
  const box60 = new THREE.Mesh(boxGeo10, darkMat);
  box60.position.set(0, 0, 0.7);
  wingMissile2.add(box60);
  const stabilizerL = new THREE.Mesh(extrude([[1, -4.6], [3.05, -6.15], [3.15, -6.95], [1, -6.85]], 0.08, [], [0.03, 0.04, 1]), paintMat);
  stabilizerL.name = 'stabilizerL';
  stabilizerL.position.set(0, -0.2, 0);
  stabilizerL.rotation.set(deg(90), 0, 0);
  airframe.add(stabilizerL);
  const stabilizerR = new THREE.Mesh(extrude([[-1, -4.6], [-3.05, -6.15], [-3.15, -6.95], [-1, -6.85]], 0.08, [], [0.03, 0.04, 1]), paintMat);
  stabilizerR.name = 'stabilizerR';
  stabilizerR.position.set(0, -0.2, 0);
  stabilizerR.rotation.set(deg(90), 0, 0);
  airframe.add(stabilizerR);
  const tailFinL = new THREE.Group();
  tailFinL.name = 'tailFinL';
  tailFinL.position.set(1.2, 0.27, 0);
  tailFinL.rotation.set(0, 0, deg(-14));
  airframe.add(tailFinL);
  const fin = new THREE.Mesh(extrudeGeo, paintMat);
  fin.name = 'fin';
  fin.rotation.set(0, deg(-90), 0);
  tailFinL.add(fin);
  const finTip = new THREE.Mesh(extrudeGeo2, accentMat);
  finTip.name = 'finTip';
  finTip.rotation.set(0, deg(-90), 0);
  tailFinL.add(finTip);
  const finLight = new THREE.Mesh(boxGeo11, darkMat);
  finLight.name = 'finLight';
  finLight.position.set(0, 1.1, -5.9);
  tailFinL.add(finLight);
  const tailFinR = new THREE.Group();
  tailFinR.name = 'tailFinR';
  tailFinR.position.set(-1.2, 0.27, 0);
  tailFinR.rotation.set(0, 0, deg(14));
  airframe.add(tailFinR);
  const fin2 = new THREE.Mesh(extrudeGeo, paintMat);
  fin2.name = 'fin';
  fin2.rotation.set(0, deg(-90), 0);
  tailFinR.add(fin2);
  const finTip2 = new THREE.Mesh(extrudeGeo2, accentMat);
  finTip2.name = 'finTip';
  finTip2.rotation.set(0, deg(-90), 0);
  tailFinR.add(finTip2);
  const finLight2 = new THREE.Mesh(boxGeo11, darkMat);
  finLight2.name = 'finLight';
  finLight2.position.set(0, 1.1, -5.9);
  tailFinR.add(finLight2);
  const mainGearL = new THREE.Group();
  mainGearL.name = 'mainGearL';
  mainGearL.position.set(1.32, -0.65, -1.1);
  airframe.add(mainGearL);
  const strut = new THREE.Mesh(cylinderGeo6, metalMat);
  strut.name = 'strut';
  strut.position.set(0, -0.45, 0);
  mainGearL.add(strut);
  const gearDoor = new THREE.Mesh(boxGeo12, paintMat);
  gearDoor.name = 'gearDoor';
  gearDoor.position.set(0.16, -0.405, 0.05);
  mainGearL.add(gearDoor);
  const wheel = new THREE.Group();
  wheel.name = 'wheel';
  wheel.position.set(0, -0.9, 0);
  mainGearL.add(wheel);
  const tire = new THREE.Mesh(cylinderGeo7, darkMat);
  tire.name = 'tire';
  tire.rotation.set(0, 0, deg(90));
  wheel.add(tire);
  const hub = new THREE.Mesh(cylinderGeo8, metalMat);
  hub.name = 'hub';
  hub.rotation.set(0, 0, deg(90));
  wheel.add(hub);
  const mainGearR = new THREE.Group();
  mainGearR.name = 'mainGearR';
  mainGearR.position.set(-1.32, -0.65, -1.1);
  airframe.add(mainGearR);
  const strut2 = new THREE.Mesh(cylinderGeo6, metalMat);
  strut2.name = 'strut';
  strut2.position.set(0, -0.45, 0);
  mainGearR.add(strut2);
  const gearDoor2 = new THREE.Mesh(boxGeo12, paintMat);
  gearDoor2.name = 'gearDoor';
  gearDoor2.position.set(-0.16, -0.405, 0.05);
  mainGearR.add(gearDoor2);
  const wheel2 = new THREE.Group();
  wheel2.name = 'wheel';
  wheel2.position.set(0, -0.9, 0);
  mainGearR.add(wheel2);
  const tire2 = new THREE.Mesh(cylinderGeo7, darkMat);
  tire2.name = 'tire';
  tire2.rotation.set(0, 0, deg(90));
  wheel2.add(tire2);
  const hub2 = new THREE.Mesh(cylinderGeo8, metalMat);
  hub2.name = 'hub';
  hub2.rotation.set(0, 0, deg(90));
  wheel2.add(hub2);
  const noseGear = new THREE.Group();
  noseGear.name = 'noseGear';
  noseGear.position.set(0, -0.45, 4.65);
  airframe.add(noseGear);
  const strut3 = new THREE.Mesh(new THREE.CylinderGeometry(0.06, 0.07, 1.2, 6), metalMat);
  strut3.name = 'strut';
  strut3.position.set(0, -0.6, 0);
  noseGear.add(strut3);
  const torqueLink = new THREE.Mesh(new THREE.BoxGeometry(0.08, 0.08, 0.5), metalMat);
  torqueLink.name = 'torqueLink';
  torqueLink.position.set(0, -0.88, -0.2);
  torqueLink.rotation.set(deg(-30), 0, 0);
  noseGear.add(torqueLink);
  const wheel3 = new THREE.Group();
  wheel3.name = 'wheel';
  wheel3.position.set(0, -1.2, 0);
  noseGear.add(wheel3);
  const tire3 = new THREE.Mesh(new THREE.CylinderGeometry(0.3, 0.3, 0.2, 10), darkMat);
  tire3.name = 'tire';
  tire3.rotation.set(0, 0, deg(90));
  wheel3.add(tire3);
  const hub3 = new THREE.Mesh(new THREE.CylinderGeometry(0.15, 0.15, 0.22, 8), metalMat);
  hub3.name = 'hub';
  hub3.rotation.set(0, 0, deg(90));
  wheel3.add(hub3);

  root.traverse((o) => {
    if (o.isMesh) {
      o.castShadow = true;
      o.receiveShadow = true;
    }
  });
  return root;
}

export default createJet;
```

---
Codels — 3D models as code for three.js. Search more: https://codels.download/api/v1/models?q=<query> · Guide: https://codels.download/llms.txt
