# Road Barrier

> A roadworks barricade with one to three boards painted in bold diagonal warning stripes, mounted on splayed A-frame metal legs with heavy feet and an optional amber warning lamp that glows. Set the length, board count and stripe color for road closures, construction sites, detours and racing track blockers.

![Road Barrier preview](https://codels.download/m/road-barrier.png)

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

## Facts

- Category: Urban & Street › Traffic
- Size (W × H × D): 2.00 × 1.49 × 0.92 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 412 · Meshes: 28 · Materials: 5
- License: CC0-1.0 (Codels built-in)
- Tags: barricade, road-barrier, cartoon, low-poly, stylized, construction, modern, city, road, racing-game, obstacle, prop, metal, plastic, emissive, game-ready, instancing-friendly, mobile-friendly, parametric, color-gray, color-orange, color-white, size-medium, poly-low
- Page: https://codels.download/models/road-barrier

## Files

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

## Parameters

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

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `length` | number | 1.2 – 3 | 2 | 2 |
| `boards` | int | 1 – 3 | 2 | 2 |
| `color` | color | #rrggbb | #ea5a1c | #ea5a1c |
| `light` | boolean | true \| false | true | true |

## Parts

- upright (box · metal)
- foot (box · dark)
- brace (box · metal)
- brace (box · metal)
- uprightCap (box · dark)
- upright (box · metal)
- foot (box · dark)
- brace (box · metal)
- brace (box · metal)
- uprightCap (box · dark)
- board (box · board)
- stripe (extrude · stripe)
- stripe (extrude · stripe)
- stripe (extrude · stripe)
- stripe (extrude · stripe)
- stripe (extrude · stripe)
- stripe (extrude · stripe)
- board (box · board)
- stripe (extrude · stripe)
- stripe (extrude · stripe)
- stripe (extrude · stripe)
- stripe (extrude · stripe)
- stripe (extrude · stripe)
- stripe (extrude · stripe)
- lampBracket (box · dark)
- lampHousing (cylinder · dark)
- lampLens (cylinder · lamp)
- lampLensBack (cylinder · lamp)

## How to use

Save the code below as `road-barrier.js`, then:

```js
import { createRoadBarrier } from './road-barrier.js';
const model = createRoadBarrier();
scene.add(model);
```

## Code

```js
/**
 * Road Barrier — Codels 3D model library (https://codels.download/models/road-barrier)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 412 · Size (W × H × D): 2.00 × 1.49 × 0.92 m
 *
 * Usage:
 *   import { createRoadBarrier } from './road-barrier.js';
 *   
 *   const model = createRoadBarrier();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

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

  // Materials
  const boardMat = new THREE.MeshStandardMaterial({ name: 'board', color: 0xf3f1ea, roughness: 0.5, flatShading: true });
  const stripeMat = new THREE.MeshStandardMaterial({ name: 'stripe', color: 0xea5a1c, roughness: 0.5, flatShading: true });
  const metalMat = new THREE.MeshStandardMaterial({ name: 'metal', color: 0x8a9096, roughness: 0.45, metalness: 0.6, flatShading: true });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x2a2d30, roughness: 0.8, flatShading: true });
  const lampMat = new THREE.MeshStandardMaterial({ name: 'lamp', color: 0xffb52e, roughness: 0.3, emissive: 0xff9a1a, emissiveIntensity: 1.2, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.06, 1.06, 0.06);
  const boxGeo2 = new THREE.BoxGeometry(0.11, 0.06, 0.92);
  const boxGeo3 = new THREE.BoxGeometry(0.045, 0.6277, 0.045);
  const boxGeo4 = new THREE.BoxGeometry(0.08, 0.04, 0.08);
  const boxGeo5 = new THREE.BoxGeometry(2, 0.2, 0.03);
  const cylinderGeo = new THREE.CylinderGeometry(0.085, 0.085, 0.03, 10);

  // Parts
  const upright = new THREE.Mesh(boxGeo, metalMat);
  upright.name = 'upright';
  upright.position.set(-0.78, 0.59, 0);
  root.add(upright);
  const foot = new THREE.Mesh(boxGeo2, darkMat);
  foot.name = 'foot';
  foot.position.set(-0.78, 0.03, 0);
  root.add(foot);
  const brace = new THREE.Mesh(boxGeo3, metalMat);
  brace.name = 'brace';
  brace.position.set(-0.78, 0.35, -0.18);
  brace.rotation.set(0, deg(90), deg(30.6507));
  root.add(brace);
  const brace2 = new THREE.Mesh(boxGeo3, metalMat);
  brace2.name = 'brace';
  brace2.position.set(-0.78, 0.35, 0.18);
  brace2.rotation.set(0, deg(-90), deg(30.6507));
  root.add(brace2);
  const uprightCap = new THREE.Mesh(boxGeo4, darkMat);
  uprightCap.name = 'uprightCap';
  uprightCap.position.set(-0.78, 1.14, 0);
  root.add(uprightCap);
  const upright2 = new THREE.Mesh(boxGeo, metalMat);
  upright2.name = 'upright';
  upright2.position.set(0.78, 0.59, 0);
  root.add(upright2);
  const foot2 = new THREE.Mesh(boxGeo2, darkMat);
  foot2.name = 'foot';
  foot2.position.set(0.78, 0.03, 0);
  root.add(foot2);
  const brace3 = new THREE.Mesh(boxGeo3, metalMat);
  brace3.name = 'brace';
  brace3.position.set(0.78, 0.35, -0.18);
  brace3.rotation.set(0, deg(90), deg(30.6507));
  root.add(brace3);
  const brace4 = new THREE.Mesh(boxGeo3, metalMat);
  brace4.name = 'brace';
  brace4.position.set(0.78, 0.35, 0.18);
  brace4.rotation.set(0, deg(-90), deg(30.6507));
  root.add(brace4);
  const uprightCap2 = new THREE.Mesh(boxGeo4, darkMat);
  uprightCap2.name = 'uprightCap';
  uprightCap2.position.set(0.78, 1.14, 0);
  root.add(uprightCap2);
  const board = new THREE.Mesh(boxGeo5, boardMat);
  board.name = 'board';
  board.position.set(0, 0.95, 0.047);
  root.add(board);
  const stripe = new THREE.Mesh(extrude([[-0.998, 0.856], [-0.808, 1.046], [-0.998, 1.046]], 0.04), stripeMat);
  stripe.name = 'stripe';
  stripe.position.set(0, 0, 0.047);
  root.add(stripe);
  const stripe2 = new THREE.Mesh(extrude([[-0.8, 0.854], [-0.6, 0.854], [-0.408, 1.046], [-0.608, 1.046]], 0.04), stripeMat);
  stripe2.name = 'stripe';
  stripe2.position.set(0, 0, 0.047);
  root.add(stripe2);
  const stripe3 = new THREE.Mesh(extrude([[-0.4, 0.854], [-0.2, 0.854], [-0.008, 1.046], [-0.208, 1.046]], 0.04), stripeMat);
  stripe3.name = 'stripe';
  stripe3.position.set(0, 0, 0.047);
  root.add(stripe3);
  const stripe4 = new THREE.Mesh(extrude([[0, 0.854], [0.2, 0.854], [0.392, 1.046], [0.192, 1.046]], 0.04), stripeMat);
  stripe4.name = 'stripe';
  stripe4.position.set(0, 0, 0.047);
  root.add(stripe4);
  const stripe5 = new THREE.Mesh(extrude([[0.4, 0.854], [0.6, 0.854], [0.792, 1.046], [0.592, 1.046]], 0.04), stripeMat);
  stripe5.name = 'stripe';
  stripe5.position.set(0, 0, 0.047);
  root.add(stripe5);
  const stripe6 = new THREE.Mesh(extrude([[0.8, 0.854], [0.998, 0.854], [0.998, 1.046], [0.992, 1.046]], 0.04), stripeMat);
  stripe6.name = 'stripe';
  stripe6.position.set(0, 0, 0.047);
  root.add(stripe6);
  const board2 = new THREE.Mesh(boxGeo5, boardMat);
  board2.name = 'board';
  board2.position.set(0, 0.65, 0.047);
  root.add(board2);
  const stripe7 = new THREE.Mesh(extrude([[-0.998, 0.556], [-0.808, 0.746], [-0.998, 0.746]], 0.04), stripeMat);
  stripe7.name = 'stripe';
  stripe7.position.set(0, 0, 0.047);
  root.add(stripe7);
  const stripe8 = new THREE.Mesh(extrude([[-0.8, 0.554], [-0.6, 0.554], [-0.408, 0.746], [-0.608, 0.746]], 0.04), stripeMat);
  stripe8.name = 'stripe';
  stripe8.position.set(0, 0, 0.047);
  root.add(stripe8);
  const stripe9 = new THREE.Mesh(extrude([[-0.4, 0.554], [-0.2, 0.554], [-0.008, 0.746], [-0.208, 0.746]], 0.04), stripeMat);
  stripe9.name = 'stripe';
  stripe9.position.set(0, 0, 0.047);
  root.add(stripe9);
  const stripe10 = new THREE.Mesh(extrude([[0, 0.554], [0.2, 0.554], [0.392, 0.746], [0.192, 0.746]], 0.04), stripeMat);
  stripe10.name = 'stripe';
  stripe10.position.set(0, 0, 0.047);
  root.add(stripe10);
  const stripe11 = new THREE.Mesh(extrude([[0.4, 0.554], [0.6, 0.554], [0.792, 0.746], [0.592, 0.746]], 0.04), stripeMat);
  stripe11.name = 'stripe';
  stripe11.position.set(0, 0, 0.047);
  root.add(stripe11);
  const stripe12 = new THREE.Mesh(extrude([[0.8, 0.554], [0.998, 0.554], [0.998, 0.746], [0.992, 0.746]], 0.04), stripeMat);
  stripe12.name = 'stripe';
  stripe12.position.set(0, 0, 0.047);
  root.add(stripe12);
  const lampBracket = new THREE.Mesh(new THREE.BoxGeometry(0.05, 0.16, 0.05), darkMat);
  lampBracket.name = 'lampBracket';
  lampBracket.position.set(-0.78, 1.23, 0);
  root.add(lampBracket);
  const lampHousing = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, 0.08, 10), darkMat);
  lampHousing.name = 'lampHousing';
  lampHousing.position.set(-0.78, 1.39, 0);
  lampHousing.rotation.set(deg(90), 0, 0);
  root.add(lampHousing);
  const lampLens = new THREE.Mesh(cylinderGeo, lampMat);
  lampLens.name = 'lampLens';
  lampLens.position.set(-0.78, 1.39, 0.055);
  lampLens.rotation.set(deg(90), 0, 0);
  root.add(lampLens);
  const lampLensBack = new THREE.Mesh(cylinderGeo, lampMat);
  lampLensBack.name = 'lampLensBack';
  lampLensBack.position.set(-0.78, 1.39, -0.055);
  lampLensBack.rotation.set(deg(90), 0, 0);
  root.add(lampLensBack);

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

export default createRoadBarrier;
```

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