# Fire Trap

> A floor flame-jet trap: a hazard-striped steel vent plate with a grille and a glowing nozzle that blasts a tall column of layered low-poly fire with flying embers. Toggle the flame to show the idle and firing states (the jets live in the 'flames' group, origin on the plate, ready to scale or hide in code); 1 m and 2 m plates with one or four nozzles. For dungeons, platformers and obstacle courses.

![Fire Trap preview](https://codels.download/m/fire-trap.png)

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

## Facts

- Category: Game Kit › Hazards
- Size (W × H × D): 1.03 × 2.04 × 1.03 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 1,376 · Meshes: 66 · Materials: 9
- License: CC0-1.0 (Codels built-in)
- Tags: fire, flamethrower, vent, cartoon, low-poly, stylized, industrial, dungeon, volcanic, adventure, party-game, platformer, roguelike, hazard, modular, obstacle, energy, metal, emissive, game-ready, mobile-friendly, parametric, color-blue, color-orange, size-medium, poly-low
- Page: https://codels.download/models/fire-trap

## Files

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

## Parameters

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

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `flame` | boolean | true \| false | true | true |
| `height` | number | 0.8 – 3 | 1.8 | 1.8 |
| `size` | int | 1 – 2 | 1 | 1 |
| `color` | color | #rrggbb | #ff6a1a | #ff6a1a |

## Parts

- band (box · hazard)
- stripesFront (group)
- stripesRight (group)
- stripesBack (group)
- stripesLeft (group)
- plate (box · plate)
- ventGlow (box · vent)
- nozzle1 (cylinder · steel)
- nozzleGlow1 (cylinder · vent)
- flames (group)
  - flame1 (group)
    - core (lathe · core)

## How to use

Save the code below as `fire-trap.js`, then:

```js
import { createFireTrap } from './fire-trap.js';
const model = createFireTrap();
scene.add(model);
```

## Code

```js
/**
 * Fire Trap — Codels 3D model library (https://codels.download/models/fire-trap)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,376 · Size (W × H × D): 1.03 × 2.04 × 1.03 m
 *
 * Usage:
 *   import { createFireTrap } from './fire-trap.js';
 *   
 *   const model = createFireTrap();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

// Deterministic vertex displacement (organic low-poly look).
function jitter(geometry, amount, seed) {
  const pos = geometry.attributes.position;
  const h = (a, b, c, s) => {
    let x = Math.imul(a, 73856093) ^ Math.imul(b, 19349663) ^ Math.imul(c, 83492791) ^ Math.imul(s, 2654435761);
    x = Math.imul(x ^ (x >>> 16), 2246822507);
    x = Math.imul(x ^ (x >>> 13), 3266489909);
    return ((x ^ (x >>> 16)) >>> 0) / 4294967295 - 0.5;
  };
  for (let i = 0; i < pos.count; i++) {
    const x = pos.getX(i), y = pos.getY(i), z = pos.getZ(i);
    const qx = Math.round(x * 1000), qy = Math.round(y * 1000), qz = Math.round(z * 1000);
    pos.setXYZ(i, x + h(qx, qy, qz, seed) * 2 * amount, y + h(qx, qy, qz, seed + 1) * 2 * amount, z + h(qx, qy, qz, seed + 2) * 2 * amount);
  }
  pos.needsUpdate = true;
  geometry.computeVertexNormals();
  return geometry;
}

// 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 createFireTrap() {
  const root = new THREE.Group();
  root.name = 'FireTrap';

  // Materials
  const plateMat = new THREE.MeshStandardMaterial({ name: 'plate', color: 0x3a4252, roughness: 0.6, metalness: 0.35, flatShading: true });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x1c1f26, roughness: 0.8, metalness: 0.2, flatShading: true });
  const hazardMat = new THREE.MeshStandardMaterial({ name: 'hazard', color: 0xf5c02a, roughness: 0.55, flatShading: true });
  const stripeMat = new THREE.MeshStandardMaterial({ name: 'stripe', color: 0x1d1f25, roughness: 0.7, flatShading: true });
  const steelMat = new THREE.MeshStandardMaterial({ name: 'steel', color: 0xaeb6c2, roughness: 0.3, metalness: 0.75, flatShading: true });
  const ventMat = new THREE.MeshStandardMaterial({ name: 'vent', color: 0xff5a12, roughness: 0.6, emissive: 0xff5a12, emissiveIntensity: 0.9, flatShading: true });
  const outerMat = new THREE.MeshStandardMaterial({ name: 'outer', color: 0xf54b14, roughness: 0.6, emissive: 0xf54b14, emissiveIntensity: 0.9, flatShading: true });
  const midMat = new THREE.MeshStandardMaterial({ name: 'mid', color: 0xff6a1a, roughness: 0.5, emissive: 0xff6a1a, flatShading: true });
  const coreMat = new THREE.MeshStandardMaterial({ name: 'core', color: 0xffd38b, roughness: 0.4, emissive: 0xffc161, emissiveIntensity: 1.1, flatShading: true });

  // Shared geometries
  const extrudeGeo = extrude([[-0.51, 0.025], [-0.51, -0.025], [-0.49, -0.025], [-0.44, 0.025]], 0.006);
  const extrudeGeo2 = extrude([[-0.42, -0.025], [-0.35, -0.025], [-0.3, 0.025], [-0.37, 0.025]], 0.006);
  const extrudeGeo3 = extrude([[-0.28, -0.025], [-0.21, -0.025], [-0.16, 0.025], [-0.23, 0.025]], 0.006);
  const extrudeGeo4 = extrude([[-0.14, -0.025], [-0.07, -0.025], [-0.02, 0.025], [-0.09, 0.025]], 0.006);
  const extrudeGeo5 = extrude([[0, -0.025], [0.07, -0.025], [0.12, 0.025], [0.05, 0.025]], 0.006);
  const extrudeGeo6 = extrude([[0.14, -0.025], [0.21, -0.025], [0.26, 0.025], [0.19, 0.025]], 0.006);
  const extrudeGeo7 = extrude([[0.28, -0.025], [0.35, -0.025], [0.4, 0.025], [0.33, 0.025]], 0.006);
  const extrudeGeo8 = extrude([[0.42, -0.025], [0.49, -0.025], [0.51, -0.005], [0.51, 0.025], [0.47, 0.025]], 0.006);
  const boxGeo = new THREE.BoxGeometry(1, 0.035, 0.09);
  const boxGeo2 = new THREE.BoxGeometry(0.09, 0.035, 0.82);
  const cylinderGeo = new THREE.CylinderGeometry(0.025, 0.025, 0.02, 6);
  const boxGeo3 = new THREE.BoxGeometry(0.82, 0.03, 0.045);

  // Parts
  const band = new THREE.Mesh(new THREE.BoxGeometry(1.02, 0.05, 1.02), hazardMat);
  band.name = 'band';
  band.position.set(0, 0.025, 0);
  root.add(band);
  const stripesFront = new THREE.Group();
  stripesFront.name = 'stripesFront';
  stripesFront.position.set(0, 0.025, 0.51);
  root.add(stripesFront);
  const extrude3 = new THREE.Mesh(extrudeGeo, stripeMat);
  extrude3.position.set(0, 0, 0.003);
  stripesFront.add(extrude3);
  const extrude4 = new THREE.Mesh(extrudeGeo2, stripeMat);
  extrude4.position.set(0, 0, 0.003);
  stripesFront.add(extrude4);
  const extrude5 = new THREE.Mesh(extrudeGeo3, stripeMat);
  extrude5.position.set(0, 0, 0.003);
  stripesFront.add(extrude5);
  const extrude6 = new THREE.Mesh(extrudeGeo4, stripeMat);
  extrude6.position.set(0, 0, 0.003);
  stripesFront.add(extrude6);
  const extrude7 = new THREE.Mesh(extrudeGeo5, stripeMat);
  extrude7.position.set(0, 0, 0.003);
  stripesFront.add(extrude7);
  const extrude8 = new THREE.Mesh(extrudeGeo6, stripeMat);
  extrude8.position.set(0, 0, 0.003);
  stripesFront.add(extrude8);
  const extrude9 = new THREE.Mesh(extrudeGeo7, stripeMat);
  extrude9.position.set(0, 0, 0.003);
  stripesFront.add(extrude9);
  const extrude10 = new THREE.Mesh(extrudeGeo8, stripeMat);
  extrude10.position.set(0, 0, 0.003);
  stripesFront.add(extrude10);
  const stripesRight = new THREE.Group();
  stripesRight.name = 'stripesRight';
  stripesRight.position.set(0.51, 0.025, 0);
  stripesRight.rotation.set(0, deg(90), 0);
  root.add(stripesRight);
  const extrude12 = new THREE.Mesh(extrudeGeo, stripeMat);
  extrude12.position.set(0, 0, 0.003);
  stripesRight.add(extrude12);
  const extrude13 = new THREE.Mesh(extrudeGeo2, stripeMat);
  extrude13.position.set(0, 0, 0.003);
  stripesRight.add(extrude13);
  const extrude14 = new THREE.Mesh(extrudeGeo3, stripeMat);
  extrude14.position.set(0, 0, 0.003);
  stripesRight.add(extrude14);
  const extrude15 = new THREE.Mesh(extrudeGeo4, stripeMat);
  extrude15.position.set(0, 0, 0.003);
  stripesRight.add(extrude15);
  const extrude16 = new THREE.Mesh(extrudeGeo5, stripeMat);
  extrude16.position.set(0, 0, 0.003);
  stripesRight.add(extrude16);
  const extrude17 = new THREE.Mesh(extrudeGeo6, stripeMat);
  extrude17.position.set(0, 0, 0.003);
  stripesRight.add(extrude17);
  const extrude18 = new THREE.Mesh(extrudeGeo7, stripeMat);
  extrude18.position.set(0, 0, 0.003);
  stripesRight.add(extrude18);
  const extrude19 = new THREE.Mesh(extrudeGeo8, stripeMat);
  extrude19.position.set(0, 0, 0.003);
  stripesRight.add(extrude19);
  const stripesBack = new THREE.Group();
  stripesBack.name = 'stripesBack';
  stripesBack.position.set(0, 0.025, -0.51);
  stripesBack.rotation.set(0, deg(180), 0);
  root.add(stripesBack);
  const extrude21 = new THREE.Mesh(extrudeGeo, stripeMat);
  extrude21.position.set(0, 0, 0.003);
  stripesBack.add(extrude21);
  const extrude22 = new THREE.Mesh(extrudeGeo2, stripeMat);
  extrude22.position.set(0, 0, 0.003);
  stripesBack.add(extrude22);
  const extrude23 = new THREE.Mesh(extrudeGeo3, stripeMat);
  extrude23.position.set(0, 0, 0.003);
  stripesBack.add(extrude23);
  const extrude24 = new THREE.Mesh(extrudeGeo4, stripeMat);
  extrude24.position.set(0, 0, 0.003);
  stripesBack.add(extrude24);
  const extrude25 = new THREE.Mesh(extrudeGeo5, stripeMat);
  extrude25.position.set(0, 0, 0.003);
  stripesBack.add(extrude25);
  const extrude26 = new THREE.Mesh(extrudeGeo6, stripeMat);
  extrude26.position.set(0, 0, 0.003);
  stripesBack.add(extrude26);
  const extrude27 = new THREE.Mesh(extrudeGeo7, stripeMat);
  extrude27.position.set(0, 0, 0.003);
  stripesBack.add(extrude27);
  const extrude28 = new THREE.Mesh(extrudeGeo8, stripeMat);
  extrude28.position.set(0, 0, 0.003);
  stripesBack.add(extrude28);
  const stripesLeft = new THREE.Group();
  stripesLeft.name = 'stripesLeft';
  stripesLeft.position.set(-0.51, 0.025, 0);
  stripesLeft.rotation.set(0, deg(-90), 0);
  root.add(stripesLeft);
  const extrude30 = new THREE.Mesh(extrudeGeo, stripeMat);
  extrude30.position.set(0, 0, 0.003);
  stripesLeft.add(extrude30);
  const extrude31 = new THREE.Mesh(extrudeGeo2, stripeMat);
  extrude31.position.set(0, 0, 0.003);
  stripesLeft.add(extrude31);
  const extrude32 = new THREE.Mesh(extrudeGeo3, stripeMat);
  extrude32.position.set(0, 0, 0.003);
  stripesLeft.add(extrude32);
  const extrude33 = new THREE.Mesh(extrudeGeo4, stripeMat);
  extrude33.position.set(0, 0, 0.003);
  stripesLeft.add(extrude33);
  const extrude34 = new THREE.Mesh(extrudeGeo5, stripeMat);
  extrude34.position.set(0, 0, 0.003);
  stripesLeft.add(extrude34);
  const extrude35 = new THREE.Mesh(extrudeGeo6, stripeMat);
  extrude35.position.set(0, 0, 0.003);
  stripesLeft.add(extrude35);
  const extrude36 = new THREE.Mesh(extrudeGeo7, stripeMat);
  extrude36.position.set(0, 0, 0.003);
  stripesLeft.add(extrude36);
  const extrude37 = new THREE.Mesh(extrudeGeo8, stripeMat);
  extrude37.position.set(0, 0, 0.003);
  stripesLeft.add(extrude37);
  const plate = new THREE.Mesh(new THREE.BoxGeometry(1, 0.07, 1), plateMat);
  plate.name = 'plate';
  plate.position.set(0, 0.085, 0);
  root.add(plate);
  const box39 = new THREE.Mesh(boxGeo, plateMat);
  box39.position.set(0, 0.1375, -0.455);
  root.add(box39);
  const box40 = new THREE.Mesh(boxGeo2, plateMat);
  box40.position.set(-0.455, 0.1375, 0);
  root.add(box40);
  const box41 = new THREE.Mesh(boxGeo, plateMat);
  box41.position.set(0, 0.1375, 0.455);
  root.add(box41);
  const box42 = new THREE.Mesh(boxGeo2, plateMat);
  box42.position.set(0.455, 0.1375, 0);
  root.add(box42);
  const cylinder43 = new THREE.Mesh(cylinderGeo, steelMat);
  cylinder43.position.set(-0.455, 0.165, -0.455);
  root.add(cylinder43);
  const cylinder44 = new THREE.Mesh(cylinderGeo, steelMat);
  cylinder44.position.set(0.455, 0.165, -0.455);
  root.add(cylinder44);
  const cylinder45 = new THREE.Mesh(cylinderGeo, steelMat);
  cylinder45.position.set(0.455, 0.165, 0.455);
  root.add(cylinder45);
  const cylinder46 = new THREE.Mesh(cylinderGeo, steelMat);
  cylinder46.position.set(-0.455, 0.165, 0.455);
  root.add(cylinder46);
  const ventGlow = new THREE.Mesh(new THREE.BoxGeometry(0.82, 0.012, 0.82), ventMat);
  ventGlow.name = 'ventGlow';
  ventGlow.position.set(0, 0.126, 0);
  root.add(ventGlow);
  const box48 = new THREE.Mesh(boxGeo3, darkMat);
  box48.position.set(0, 0.14, -0.3514);
  root.add(box48);
  const box49 = new THREE.Mesh(boxGeo3, darkMat);
  box49.position.set(0, 0.14, -0.2343);
  root.add(box49);
  const box50 = new THREE.Mesh(boxGeo3, darkMat);
  box50.position.set(0, 0.14, -0.1171);
  root.add(box50);
  const box51 = new THREE.Mesh(boxGeo3, darkMat);
  box51.position.set(0, 0.14, 0);
  root.add(box51);
  const box52 = new THREE.Mesh(boxGeo3, darkMat);
  box52.position.set(0, 0.14, 0.1171);
  root.add(box52);
  const box53 = new THREE.Mesh(boxGeo3, darkMat);
  box53.position.set(0, 0.14, 0.2343);
  root.add(box53);
  const box54 = new THREE.Mesh(boxGeo3, darkMat);
  box54.position.set(0, 0.14, 0.3514);
  root.add(box54);
  const nozzle1 = new THREE.Mesh(new THREE.CylinderGeometry(0.11, 0.13, 0.07, 10), steelMat);
  nozzle1.name = 'nozzle1';
  nozzle1.position.set(0, 0.155, 0);
  root.add(nozzle1);
  const nozzleGlow1 = new THREE.Mesh(new THREE.CylinderGeometry(0.07, 0.07, 0.012, 10), ventMat);
  nozzleGlow1.name = 'nozzleGlow1';
  nozzleGlow1.position.set(0, 0.192, 0);
  root.add(nozzleGlow1);
  const flames = new THREE.Group();
  flames.name = 'flames';
  root.add(flames);
  const flame1 = new THREE.Group();
  flame1.name = 'flame1';
  flame1.position.set(0, 0.19, 0);
  flames.add(flame1);
  const lathe59 = new THREE.Mesh(jitter(lathe([[0, 0], [0.105, 0.0376], [0.15, 0.1631], [0.1275, 0.3137], [0.0675, 0.4894], [0, 0.6274]], 6), 0.015, 30), outerMat);
  lathe59.position.set(0.0597, 0, 0.006);
  lathe59.rotation.set(deg(1.1002), deg(-0.1069), deg(-11.104));
  flame1.add(lathe59);
  const lathe60 = new THREE.Mesh(jitter(lathe([[0, 0], [0.105, 0.0429], [0.15, 0.1858], [0.1275, 0.3573], [0.0675, 0.5574], [0, 0.7146]], 6), 0.015, 31), outerMat);
  lathe60.position.set(0.0266, 0, 0.0538);
  lathe60.rotation.set(deg(6.5614), deg(-0.1857), deg(-3.2381));
  flame1.add(lathe60);
  const lathe61 = new THREE.Mesh(jitter(lathe([[0, 0], [0.105, 0.0473], [0.15, 0.2049], [0.1275, 0.394], [0.0675, 0.6146], [0, 0.7879]], 6), 0.015, 32), outerMat);
  lathe61.position.set(-0.0358, 0, 0.0482);
  lathe61.rotation.set(deg(7.5459), deg(0.3694), deg(5.5974));
  flame1.add(lathe61);
  const lathe62 = new THREE.Mesh(jitter(lathe([[0, 0], [0.105, 0.045], [0.15, 0.1948], [0.1275, 0.3747], [0.0675, 0.5845], [0, 0.7493]], 6), 0.015, 33), outerMat);
  lathe62.position.set(-0.0594, 0, 0.0085);
  lathe62.rotation.set(deg(1.5714), deg(0.1525), deg(11.0854));
  flame1.add(lathe62);
  const lathe63 = new THREE.Mesh(jitter(lathe([[0, 0], [0.105, 0.0411], [0.15, 0.1781], [0.1275, 0.3425], [0.0675, 0.5342], [0, 0.6849]], 6), 0.015, 34), outerMat);
  lathe63.position.set(-0.0255, 0, -0.0543);
  lathe63.rotation.set(deg(-6.2603), deg(-0.1608), deg(2.9391));
  flame1.add(lathe63);
  const lathe64 = new THREE.Mesh(jitter(lathe([[0, 0], [0.105, 0.0386], [0.15, 0.1673], [0.1275, 0.3217], [0.0675, 0.5019], [0, 0.6434]], 6), 0.015, 35), outerMat);
  lathe64.position.set(0.0244, 0, -0.0548);
  lathe64.rotation.set(deg(-10.8034), deg(0.4532), deg(-4.7902));
  flame1.add(lathe64);
  const lathe65 = new THREE.Mesh(jitter(lathe([[0, 0], [0.126, 0.0827], [0.18, 0.3584], [0.153, 0.6892], [0.081, 1.0751], [0, 1.3783]], 6), 0.02, 40), midMat);
  lathe65.position.set(0.0306, 0.02, 0.0257);
  lathe65.rotation.set(deg(2.2063), deg(-0.0506), deg(-2.6297));
  flame1.add(lathe65);
  const lathe66 = new THREE.Mesh(jitter(lathe([[0, 0], [0.126, 0.0822], [0.18, 0.3563], [0.153, 0.6852], [0.081, 1.0688], [0, 1.3703]], 6), 0.02, 41), midMat);
  lathe66.position.set(-0.0376, 0.02, 0.0137);
  lathe66.rotation.set(deg(1.1738), deg(0.0331), deg(3.2263));
  flame1.add(lathe66);
  const lathe67 = new THREE.Mesh(jitter(lathe([[0, 0], [0.126, 0.0751], [0.18, 0.3255], [0.153, 0.626], [0.081, 0.9765], [0, 1.2519]], 6), 0.02, 42), midMat);
  lathe67.position.set(0.0069, 0.02, -0.0394);
  lathe67.rotation.set(deg(-3.3814), deg(0.0176), deg(-0.5959));
  flame1.add(lathe67);
  const core = new THREE.Mesh(jitter(lathe([[0, 0], [0.084, 0.108], [0.12, 0.468], [0.102, 0.9], [0.054, 1.404], [0, 1.8]], 6), 0.015, 50), coreMat);
  core.name = 'core';
  core.position.set(0, 0.04, 0);
  flame1.add(core);
  const octahedron69 = new THREE.Mesh(new THREE.OctahedronGeometry(0.0205, 0), midMat);
  octahedron69.position.set(0.2294, 1.2354, 0.0275);
  octahedron69.rotation.set(deg(11.0936), deg(42.307), 0);
  flame1.add(octahedron69);
  const octahedron70 = new THREE.Mesh(new THREE.OctahedronGeometry(0.019, 0), coreMat);
  octahedron70.position.set(0.1542, 1.7537, -0.0081);
  octahedron70.rotation.set(deg(28.5322), deg(36.6806), 0);
  flame1.add(octahedron70);
  const octahedron71 = new THREE.Mesh(new THREE.OctahedronGeometry(0.0226, 0), midMat);
  octahedron71.position.set(0.1574, 1.1855, -0.0141);
  octahedron71.rotation.set(deg(78.2302), deg(65.0125), 0);
  flame1.add(octahedron71);
  const octahedron72 = new THREE.Mesh(new THREE.OctahedronGeometry(0.0277, 0), coreMat);
  octahedron72.position.set(0.1387, 1.5742, -0.1322);
  octahedron72.rotation.set(deg(12.5667), deg(57.2443), 0);
  flame1.add(octahedron72);

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

export default createFireTrap;
```

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