# Mine Cart

> A rusty stylized mine cart: a riveted, banded iron tub on a sturdy frame with four flanged wheels (groups wheelFL, wheelFR, wheelRL, wheelRR, axles along X) and couplers at both ends. Toggle a heaped load of gold ore, coal or glowing crystals and an optional rail segment with wooden sleepers. Ideal for mines, caves, dungeons, western towns and minecart ride levels.

![Mine Cart preview](https://codels.download/m/mine-cart.png)

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

## Facts

- Category: Vehicles › Other Vehicles
- Size (W × H × D): 0.95 × 1.19 × 1.90 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 2,484 · Meshes: 100 · Materials: 7
- License: CC0-1.0 (Codels built-in)
- Tags: minecart, rail, low-poly, stylized, mining, western, cave, dungeon, adventure, rpg, survival, container, vehicle, metal, game-ready, parametric, color-brown, color-gray, size-medium, poly-medium
- Page: https://codels.download/models/mine-cart

## Files

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

## Parameters

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

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `ore` | boolean | true \| false | true | true |
| `oreType` | select | gold \| coal \| crystal | gold | gold |
| `rails` | boolean | true \| false | true | true |

## Parts

- body (group)
  - tub (lathe · rust)
  - beamL (box · iron)
  - beamR (box · iron)
  - bumperFront (box · rustDark)
  - couplerFront (torus · iron)
  - bumperRear (box · rustDark)
  - couplerRear (torus · iron)
  - oreHeap (sphere · rock)
- wheels (group)
  - wheelFL (group)
    - tread (cylinder · iron)
    - flange (cylinder · iron)
    - disc (cylinder · rustDark)
    - hub (cylinder · iron)
  - wheelFR (group)
    - tread (cylinder · iron)
    - flange (cylinder · iron)
    - disc (cylinder · rustDark)
    - hub (cylinder · iron)
  - wheelRL (group)
    - tread (cylinder · iron)
    - flange (cylinder · iron)
    - disc (cylinder · rustDark)
    - hub (cylinder · iron)
  - wheelRR (group)
    - tread (cylinder · iron)
    - flange (cylinder · iron)
    - disc (cylinder · rustDark)
    - hub (cylinder · iron)
- rails (group)
  - railL (extrude · steel)
  - railR (extrude · steel)

## How to use

Save the code below as `mine-cart.js`, then:

```js
import { createMineCart } from './mine-cart.js';
const model = createMineCart();
scene.add(model);
```

## Code

```js
/**
 * Mine Cart — Codels 3D model library (https://codels.download/models/mine-cart)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 2,484 · Size (W × H × D): 0.95 × 1.19 × 1.90 m
 *
 * Usage:
 *   import { createMineCart } from './mine-cart.js';
 *   
 *   const model = createMineCart();
 *   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 createMineCart() {
  const root = new THREE.Group();
  root.name = 'MineCart';

  // Materials
  const rustMat = new THREE.MeshStandardMaterial({ name: 'rust', color: 0x8c4f2c, roughness: 0.9, metalness: 0.3, flatShading: true });
  const rustDarkMat = new THREE.MeshStandardMaterial({ name: 'rustDark', color: 0x5b3a28, roughness: 0.85, metalness: 0.35, flatShading: true });
  const ironMat = new THREE.MeshStandardMaterial({ name: 'iron', color: 0x3b3d41, roughness: 0.6, metalness: 0.5, flatShading: true });
  const woodMat = new THREE.MeshStandardMaterial({ name: 'wood', color: 0x7a5634, roughness: 0.95, flatShading: true });
  const steelMat = new THREE.MeshStandardMaterial({ name: 'steel', color: 0xa9adb2, roughness: 0.35, metalness: 0.7, flatShading: true });
  const rockMat = new THREE.MeshStandardMaterial({ name: 'rock', color: 0x57514b, roughness: 0.95, flatShading: true });
  const chunkMat = new THREE.MeshStandardMaterial({ name: 'chunk', color: 0xf2b632, roughness: 0.3, metalness: 0.8, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.014, 0.022, 0.022);
  const boxGeo2 = new THREE.BoxGeometry(0.08, 0.1, 1.08);
  const cylinderGeo = new THREE.CylinderGeometry(0.025, 0.025, 0.64, 6);
  const boxGeo3 = new THREE.BoxGeometry(0.07, 0.086, 0.1);
  const boxGeo4 = new THREE.BoxGeometry(0.52, 0.09, 0.06);
  const boxGeo5 = new THREE.BoxGeometry(0.06, 0.04, 0.1);
  const torusGeo = new THREE.TorusGeometry(0.035, 0.012, 4, 8);
  const cylinderGeo2 = new THREE.CylinderGeometry(0.14, 0.14, 0.055, 12);
  const cylinderGeo3 = new THREE.CylinderGeometry(0.162, 0.162, 0.016, 12);
  const cylinderGeo4 = new THREE.CylinderGeometry(0.1008, 0.1008, 0.012, 10);
  const cylinderGeo5 = new THREE.CylinderGeometry(0.035, 0.045, 0.05, 8);
  const cylinderGeo6 = new THREE.CylinderGeometry(0.022, 0.022, 0.014, 6);
  const boxGeo6 = new THREE.BoxGeometry(0.95, 0.08, 0.14);
  const extrudeGeo = extrude([[-0.035, 0], [0.035, 0], [0.035, 0.012], [0.01, 0.022], [0.01, 0.058], [0.02, 0.064], [0.02, 0.08], [-0.02, 0.08], [-0.02, 0.064], [-0.01, 0.058], [-0.01, 0.022], [-0.035, 0.012]], 1.9);
  const boxGeo7 = new THREE.BoxGeometry(0.1, 0.012, 0.05);

  // Parts
  const body = new THREE.Group();
  body.name = 'body';
  root.add(body);
  const tub = new THREE.Mesh(lathe([[0, 0], [0.4243, 0], [0.5374, 0.5], [0.495, 0.5], [0.3818, 0.0424], [0, 0.0424]], 4, Math.PI / 4, Math.PI * 2), rustMat);
  tub.name = 'tub';
  tub.position.set(0, 0.51, 0);
  tub.scale.set(1, 1, 1.48);
  body.add(tub);
  const lathe3 = new THREE.Mesh(lathe([[0.5317, 0.45], [0.5572, 0.45], [0.5685, 0.5], [0.5431, 0.5], [0.5317, 0.45]], 4, Math.PI / 4, Math.PI * 2), rustDarkMat);
  lathe3.position.set(0, 0.51, 0);
  lathe3.scale.set(1, 1, 1.48);
  body.add(lathe3);
  const lathe4 = new THREE.Mesh(lathe([[0.4808, 0.225], [0.5063, 0.225], [0.5153, 0.265], [0.4899, 0.265], [0.4808, 0.225]], 4, Math.PI / 4, Math.PI * 2), rustDarkMat);
  lathe4.position.set(0, 0.51, 0);
  lathe4.scale.set(1, 1, 1.48);
  body.add(lathe4);
  const lathe5 = new THREE.Mesh(lathe([[0.4299, 0], [0.4554, 0], [0.4644, 0.04], [0.439, 0.04], [0.4299, 0]], 4, Math.PI / 4, Math.PI * 2), rustDarkMat);
  lathe5.position.set(0, 0.51, 0);
  lathe5.scale.set(1, 1, 1.48);
  body.add(lathe5);
  const box6 = new THREE.Mesh(boxGeo, ironMat);
  box6.position.set(0.3616, 0.745, -0.34);
  body.add(box6);
  const box7 = new THREE.Mesh(boxGeo, ironMat);
  box7.position.set(0.4, 0.985, -0.34);
  body.add(box7);
  const box8 = new THREE.Mesh(boxGeo, ironMat);
  box8.position.set(0.3616, 0.745, -0.17);
  body.add(box8);
  const box9 = new THREE.Mesh(boxGeo, ironMat);
  box9.position.set(0.4, 0.985, -0.17);
  body.add(box9);
  const box10 = new THREE.Mesh(boxGeo, ironMat);
  box10.position.set(0.3616, 0.745, 0);
  body.add(box10);
  const box11 = new THREE.Mesh(boxGeo, ironMat);
  box11.position.set(0.4, 0.985, 0);
  body.add(box11);
  const box12 = new THREE.Mesh(boxGeo, ironMat);
  box12.position.set(0.3616, 0.745, 0.17);
  body.add(box12);
  const box13 = new THREE.Mesh(boxGeo, ironMat);
  box13.position.set(0.4, 0.985, 0.17);
  body.add(box13);
  const box14 = new THREE.Mesh(boxGeo, ironMat);
  box14.position.set(0.3616, 0.745, 0.34);
  body.add(box14);
  const box15 = new THREE.Mesh(boxGeo, ironMat);
  box15.position.set(0.4, 0.985, 0.34);
  body.add(box15);
  const box16 = new THREE.Mesh(boxGeo, ironMat);
  box16.position.set(-0.3616, 0.745, -0.34);
  body.add(box16);
  const box17 = new THREE.Mesh(boxGeo, ironMat);
  box17.position.set(-0.4, 0.985, -0.34);
  body.add(box17);
  const box18 = new THREE.Mesh(boxGeo, ironMat);
  box18.position.set(-0.3616, 0.745, -0.17);
  body.add(box18);
  const box19 = new THREE.Mesh(boxGeo, ironMat);
  box19.position.set(-0.4, 0.985, -0.17);
  body.add(box19);
  const box20 = new THREE.Mesh(boxGeo, ironMat);
  box20.position.set(-0.3616, 0.745, 0);
  body.add(box20);
  const box21 = new THREE.Mesh(boxGeo, ironMat);
  box21.position.set(-0.4, 0.985, 0);
  body.add(box21);
  const box22 = new THREE.Mesh(boxGeo, ironMat);
  box22.position.set(-0.3616, 0.745, 0.17);
  body.add(box22);
  const box23 = new THREE.Mesh(boxGeo, ironMat);
  box23.position.set(-0.4, 0.985, 0.17);
  body.add(box23);
  const box24 = new THREE.Mesh(boxGeo, ironMat);
  box24.position.set(-0.3616, 0.745, 0.34);
  body.add(box24);
  const box25 = new THREE.Mesh(boxGeo, ironMat);
  box25.position.set(-0.4, 0.985, 0.34);
  body.add(box25);
  const beamL = new THREE.Mesh(boxGeo2, ironMat);
  beamL.name = 'beamL';
  beamL.position.set(0.2, 0.47, 0);
  body.add(beamL);
  const beamR = new THREE.Mesh(boxGeo2, ironMat);
  beamR.name = 'beamR';
  beamR.position.set(-0.2, 0.47, 0);
  body.add(beamR);
  const cylinder28 = new THREE.Mesh(cylinderGeo, ironMat);
  cylinder28.position.set(0, 0.3, 0.32);
  cylinder28.rotation.set(0, 0, deg(90));
  body.add(cylinder28);
  const box29 = new THREE.Mesh(boxGeo3, ironMat);
  box29.position.set(0.2, 0.313, 0.32);
  body.add(box29);
  const box30 = new THREE.Mesh(boxGeo3, ironMat);
  box30.position.set(-0.2, 0.313, 0.32);
  body.add(box30);
  const cylinder31 = new THREE.Mesh(cylinderGeo, ironMat);
  cylinder31.position.set(0, 0.3, -0.32);
  cylinder31.rotation.set(0, 0, deg(90));
  body.add(cylinder31);
  const box32 = new THREE.Mesh(boxGeo3, ironMat);
  box32.position.set(0.2, 0.313, -0.32);
  body.add(box32);
  const box33 = new THREE.Mesh(boxGeo3, ironMat);
  box33.position.set(-0.2, 0.313, -0.32);
  body.add(box33);
  const bumperFront = new THREE.Mesh(boxGeo4, rustDarkMat);
  bumperFront.name = 'bumperFront';
  bumperFront.position.set(0, 0.49, 0.58);
  body.add(bumperFront);
  const box35 = new THREE.Mesh(boxGeo5, ironMat);
  box35.position.set(0, 0.47, 0.64);
  body.add(box35);
  const couplerFront = new THREE.Mesh(torusGeo, ironMat);
  couplerFront.name = 'couplerFront';
  couplerFront.position.set(0, 0.47, 0.7);
  couplerFront.rotation.set(deg(90), 0, 0);
  body.add(couplerFront);
  const bumperRear = new THREE.Mesh(boxGeo4, rustDarkMat);
  bumperRear.name = 'bumperRear';
  bumperRear.position.set(0, 0.49, -0.58);
  body.add(bumperRear);
  const box38 = new THREE.Mesh(boxGeo5, ironMat);
  box38.position.set(0, 0.47, -0.64);
  body.add(box38);
  const couplerRear = new THREE.Mesh(torusGeo, ironMat);
  couplerRear.name = 'couplerRear';
  couplerRear.position.set(0, 0.47, -0.7);
  couplerRear.rotation.set(deg(90), 0, 0);
  body.add(couplerRear);
  const oreHeap = new THREE.Mesh(new THREE.SphereGeometry(1, 8, 4, 0, Math.PI * 2, 0, Math.PI / 2), rockMat);
  oreHeap.name = 'oreHeap';
  oreHeap.position.set(0, 0.95, 0);
  oreHeap.scale.set(0.36, 0.16, 0.5328);
  body.add(oreHeap);
  const dodecahedron41 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.0682, 0), 0.012, 1), chunkMat);
  dodecahedron41.position.set(0.0057, 1.1184, 0.0735);
  dodecahedron41.rotation.set(deg(19.7787), deg(56.0861), 0);
  body.add(dodecahedron41);
  const dodecahedron42 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.0666, 0), 0.012, 2), rockMat);
  dodecahedron42.position.set(0.0615, 1.0843, 0.3228);
  dodecahedron42.rotation.set(deg(41.2294), deg(81.5059), 0);
  body.add(dodecahedron42);
  const dodecahedron43 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.0672, 0), 0.012, 3), chunkMat);
  dodecahedron43.position.set(0.2015, 1.0705, 0.2441);
  dodecahedron43.rotation.set(deg(59.4504), deg(1.2439), 0);
  body.add(dodecahedron43);
  const dodecahedron44 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.054, 0), 0.012, 4), rockMat);
  dodecahedron44.position.set(0.05, 1.1184, 0.0015);
  dodecahedron44.rotation.set(deg(80.6895), deg(25.9304), 0);
  body.add(dodecahedron44);
  const dodecahedron45 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.0526, 0), 0.012, 5), chunkMat);
  dodecahedron45.position.set(0.1951, 1.075, -0.2319);
  dodecahedron45.rotation.set(deg(1.7117), deg(71.4157), 0);
  body.add(dodecahedron45);
  const dodecahedron46 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.0487, 0), 0.012, 6), rockMat);
  dodecahedron46.position.set(0.1087, 1.1013, -0.1916);
  dodecahedron46.rotation.set(deg(42.307), deg(89.2479), 0);
  body.add(dodecahedron46);
  const dodecahedron47 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.0474, 0), 0.012, 7), chunkMat);
  dodecahedron47.position.set(0.0076, 1.1184, -0.0731);
  dodecahedron47.rotation.set(deg(76.3734), deg(28.5322), 0);
  body.add(dodecahedron47);
  const dodecahedron48 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.0532, 0), 0.012, 8), rockMat);
  dodecahedron48.position.set(-0.1342, 1.0501, -0.3928);
  dodecahedron48.rotation.set(deg(34.7492), deg(19.5533), 0);
  body.add(dodecahedron48);
  const dodecahedron49 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.0714, 0), 0.012, 9), chunkMat);
  dodecahedron49.position.set(-0.2387, 1.0751, -0.1101);
  dodecahedron49.rotation.set(deg(46.0398), deg(72.4562), 0);
  body.add(dodecahedron49);
  const dodecahedron50 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.0492, 0), 0.012, 10), rockMat);
  dodecahedron50.position.set(-0.0498, 1.1184, 0.0066);
  dodecahedron50.rotation.set(deg(57.2443), deg(51.9857), 0);
  body.add(dodecahedron50);
  const dodecahedron51 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.0633, 0), 0.012, 11), chunkMat);
  dodecahedron51.position.set(-0.2384, 1.0706, 0.1545);
  dodecahedron51.rotation.set(deg(0.7314), deg(83.8809), 0);
  body.add(dodecahedron51);
  const dodecahedron52 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.0712, 0), 0.012, 12), rockMat);
  dodecahedron52.position.set(-0.1061, 1.0978, 0.2207);
  dodecahedron52.rotation.set(deg(22.4276), deg(15.7698), 0);
  body.add(dodecahedron52);
  const wheels = new THREE.Group();
  wheels.name = 'wheels';
  root.add(wheels);
  const wheelFL = new THREE.Group();
  wheelFL.name = 'wheelFL';
  wheelFL.position.set(0.3, 0.3, 0.32);
  wheels.add(wheelFL);
  const tread = new THREE.Mesh(cylinderGeo2, ironMat);
  tread.name = 'tread';
  tread.rotation.set(0, 0, deg(90));
  wheelFL.add(tread);
  const flange = new THREE.Mesh(cylinderGeo3, ironMat);
  flange.name = 'flange';
  flange.position.set(-0.0335, 0, 0);
  flange.rotation.set(0, 0, deg(90));
  wheelFL.add(flange);
  const disc = new THREE.Mesh(cylinderGeo4, rustDarkMat);
  disc.name = 'disc';
  disc.position.set(0.0315, 0, 0);
  disc.rotation.set(0, 0, deg(90));
  wheelFL.add(disc);
  const hub = new THREE.Mesh(cylinderGeo5, ironMat);
  hub.name = 'hub';
  hub.position.set(0.0525, 0, 0);
  hub.rotation.set(0, 0, deg(-90));
  wheelFL.add(hub);
  const cylinder59 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder59.position.set(0.0355, 0.0445, 0.0445);
  cylinder59.rotation.set(0, 0, deg(90));
  wheelFL.add(cylinder59);
  const cylinder60 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder60.position.set(0.0355, 0.0445, -0.0445);
  cylinder60.rotation.set(0, 0, deg(90));
  wheelFL.add(cylinder60);
  const cylinder61 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder61.position.set(0.0355, -0.0445, -0.0445);
  cylinder61.rotation.set(0, 0, deg(90));
  wheelFL.add(cylinder61);
  const cylinder62 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder62.position.set(0.0355, -0.0445, 0.0445);
  cylinder62.rotation.set(0, 0, deg(90));
  wheelFL.add(cylinder62);
  const wheelFR = new THREE.Group();
  wheelFR.name = 'wheelFR';
  wheelFR.position.set(-0.3, 0.3, 0.32);
  wheels.add(wheelFR);
  const tread2 = new THREE.Mesh(cylinderGeo2, ironMat);
  tread2.name = 'tread';
  tread2.rotation.set(0, 0, deg(90));
  wheelFR.add(tread2);
  const flange2 = new THREE.Mesh(cylinderGeo3, ironMat);
  flange2.name = 'flange';
  flange2.position.set(0.0335, 0, 0);
  flange2.rotation.set(0, 0, deg(90));
  wheelFR.add(flange2);
  const disc2 = new THREE.Mesh(cylinderGeo4, rustDarkMat);
  disc2.name = 'disc';
  disc2.position.set(-0.0315, 0, 0);
  disc2.rotation.set(0, 0, deg(90));
  wheelFR.add(disc2);
  const hub2 = new THREE.Mesh(cylinderGeo5, ironMat);
  hub2.name = 'hub';
  hub2.position.set(-0.0525, 0, 0);
  hub2.rotation.set(0, 0, deg(90));
  wheelFR.add(hub2);
  const cylinder68 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder68.position.set(-0.0355, 0.0445, 0.0445);
  cylinder68.rotation.set(0, 0, deg(90));
  wheelFR.add(cylinder68);
  const cylinder69 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder69.position.set(-0.0355, 0.0445, -0.0445);
  cylinder69.rotation.set(0, 0, deg(90));
  wheelFR.add(cylinder69);
  const cylinder70 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder70.position.set(-0.0355, -0.0445, -0.0445);
  cylinder70.rotation.set(0, 0, deg(90));
  wheelFR.add(cylinder70);
  const cylinder71 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder71.position.set(-0.0355, -0.0445, 0.0445);
  cylinder71.rotation.set(0, 0, deg(90));
  wheelFR.add(cylinder71);
  const wheelRL = new THREE.Group();
  wheelRL.name = 'wheelRL';
  wheelRL.position.set(0.3, 0.3, -0.32);
  wheels.add(wheelRL);
  const tread3 = new THREE.Mesh(cylinderGeo2, ironMat);
  tread3.name = 'tread';
  tread3.rotation.set(0, 0, deg(90));
  wheelRL.add(tread3);
  const flange3 = new THREE.Mesh(cylinderGeo3, ironMat);
  flange3.name = 'flange';
  flange3.position.set(-0.0335, 0, 0);
  flange3.rotation.set(0, 0, deg(90));
  wheelRL.add(flange3);
  const disc3 = new THREE.Mesh(cylinderGeo4, rustDarkMat);
  disc3.name = 'disc';
  disc3.position.set(0.0315, 0, 0);
  disc3.rotation.set(0, 0, deg(90));
  wheelRL.add(disc3);
  const hub3 = new THREE.Mesh(cylinderGeo5, ironMat);
  hub3.name = 'hub';
  hub3.position.set(0.0525, 0, 0);
  hub3.rotation.set(0, 0, deg(-90));
  wheelRL.add(hub3);
  const cylinder77 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder77.position.set(0.0355, 0.0445, 0.0445);
  cylinder77.rotation.set(0, 0, deg(90));
  wheelRL.add(cylinder77);
  const cylinder78 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder78.position.set(0.0355, 0.0445, -0.0445);
  cylinder78.rotation.set(0, 0, deg(90));
  wheelRL.add(cylinder78);
  const cylinder79 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder79.position.set(0.0355, -0.0445, -0.0445);
  cylinder79.rotation.set(0, 0, deg(90));
  wheelRL.add(cylinder79);
  const cylinder80 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder80.position.set(0.0355, -0.0445, 0.0445);
  cylinder80.rotation.set(0, 0, deg(90));
  wheelRL.add(cylinder80);
  const wheelRR = new THREE.Group();
  wheelRR.name = 'wheelRR';
  wheelRR.position.set(-0.3, 0.3, -0.32);
  wheels.add(wheelRR);
  const tread4 = new THREE.Mesh(cylinderGeo2, ironMat);
  tread4.name = 'tread';
  tread4.rotation.set(0, 0, deg(90));
  wheelRR.add(tread4);
  const flange4 = new THREE.Mesh(cylinderGeo3, ironMat);
  flange4.name = 'flange';
  flange4.position.set(0.0335, 0, 0);
  flange4.rotation.set(0, 0, deg(90));
  wheelRR.add(flange4);
  const disc4 = new THREE.Mesh(cylinderGeo4, rustDarkMat);
  disc4.name = 'disc';
  disc4.position.set(-0.0315, 0, 0);
  disc4.rotation.set(0, 0, deg(90));
  wheelRR.add(disc4);
  const hub4 = new THREE.Mesh(cylinderGeo5, ironMat);
  hub4.name = 'hub';
  hub4.position.set(-0.0525, 0, 0);
  hub4.rotation.set(0, 0, deg(90));
  wheelRR.add(hub4);
  const cylinder86 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder86.position.set(-0.0355, 0.0445, 0.0445);
  cylinder86.rotation.set(0, 0, deg(90));
  wheelRR.add(cylinder86);
  const cylinder87 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder87.position.set(-0.0355, 0.0445, -0.0445);
  cylinder87.rotation.set(0, 0, deg(90));
  wheelRR.add(cylinder87);
  const cylinder88 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder88.position.set(-0.0355, -0.0445, -0.0445);
  cylinder88.rotation.set(0, 0, deg(90));
  wheelRR.add(cylinder88);
  const cylinder89 = new THREE.Mesh(cylinderGeo6, ironMat);
  cylinder89.position.set(-0.0355, -0.0445, 0.0445);
  cylinder89.rotation.set(0, 0, deg(90));
  wheelRR.add(cylinder89);
  const rails = new THREE.Group();
  rails.name = 'rails';
  root.add(rails);
  const box91 = new THREE.Mesh(boxGeo6, woodMat);
  box91.position.set(0, 0.04, -0.78);
  box91.rotation.set(0, deg(-2), 0);
  rails.add(box91);
  const box92 = new THREE.Mesh(boxGeo6, woodMat);
  box92.position.set(0, 0.04, -0.39);
  box92.rotation.set(0, deg(2), 0);
  rails.add(box92);
  const box93 = new THREE.Mesh(boxGeo6, woodMat);
  box93.position.set(0, 0.04, 0);
  box93.rotation.set(0, deg(-2), 0);
  rails.add(box93);
  const box94 = new THREE.Mesh(boxGeo6, woodMat);
  box94.position.set(0, 0.04, 0.39);
  box94.rotation.set(0, deg(2), 0);
  rails.add(box94);
  const box95 = new THREE.Mesh(boxGeo6, woodMat);
  box95.position.set(0, 0.04, 0.78);
  box95.rotation.set(0, deg(-2), 0);
  rails.add(box95);
  const railL = new THREE.Mesh(extrudeGeo, steelMat);
  railL.name = 'railL';
  railL.position.set(0.3, 0.08, 0);
  rails.add(railL);
  const box97 = new THREE.Mesh(boxGeo7, ironMat);
  box97.position.set(0.3, 0.086, -0.78);
  rails.add(box97);
  const box98 = new THREE.Mesh(boxGeo7, ironMat);
  box98.position.set(0.3, 0.086, -0.39);
  rails.add(box98);
  const box99 = new THREE.Mesh(boxGeo7, ironMat);
  box99.position.set(0.3, 0.086, 0);
  rails.add(box99);
  const box100 = new THREE.Mesh(boxGeo7, ironMat);
  box100.position.set(0.3, 0.086, 0.39);
  rails.add(box100);
  const box101 = new THREE.Mesh(boxGeo7, ironMat);
  box101.position.set(0.3, 0.086, 0.78);
  rails.add(box101);
  const railR = new THREE.Mesh(extrudeGeo, steelMat);
  railR.name = 'railR';
  railR.position.set(-0.3, 0.08, 0);
  rails.add(railR);
  const box103 = new THREE.Mesh(boxGeo7, ironMat);
  box103.position.set(-0.3, 0.086, -0.78);
  rails.add(box103);
  const box104 = new THREE.Mesh(boxGeo7, ironMat);
  box104.position.set(-0.3, 0.086, -0.39);
  rails.add(box104);
  const box105 = new THREE.Mesh(boxGeo7, ironMat);
  box105.position.set(-0.3, 0.086, 0);
  rails.add(box105);
  const box106 = new THREE.Mesh(boxGeo7, ironMat);
  box106.position.set(-0.3, 0.086, 0.39);
  rails.add(box106);
  const box107 = new THREE.Mesh(boxGeo7, ironMat);
  box107.position.set(-0.3, 0.086, 0.78);
  rails.add(box107);

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

export default createMineCart;
```

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