# Horse

> A sturdy, toy-like low-poly horse standing 1.6 m at the withers, with a long blocky head, big friendly eyes, pointy ears, a chunky mane and forelock, a flowing tail and dark hooves. Toggle a full riding set — leather saddle on a red blanket, girth, stirrups, bridle and reins — and a white blaze with socks; recolor the coat and mane for bays, chestnuts, greys and blacks. Head (with the neck, pivoted at the withers), ears, legs and tail are separate groups for walk, gallop and graze animations.

![Horse preview](https://codels.download/m/horse.png)

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

## Facts

- Category: Characters › Animals
- Size (W × H × D): 0.69 × 2.73 × 2.74 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 1,104 · Meshes: 68 · Materials: 10
- License: CC0-1.0 (Codels built-in)
- Tags: horse, livestock, blocky, cartoon, low-poly, farm, medieval, western, grassland, village, farming-sim, rpg, animal, npc, game-ready, mobile-friendly, parametric, color-brown, size-medium, poly-low
- Page: https://codels.download/models/horse

## Files

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

## Parameters

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

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `coat` | color | #rrggbb | #9c5d35 | #9c5d35 |
| `mane` | color | #rrggbb | #2e221d | #2e221d |
| `saddle` | boolean | true \| false | true | true |
| `markings` | boolean | true \| false | true | true |

## Parts

- legFL (group)
  - legFLUpper (box · coat)
  - legFLCannon (box · coat)
  - legFLSock (box · white)
  - legFLHoof (box · hoof)
- legFR (group)
  - legFRUpper (box · coat)
  - legFRCannon (box · coat)
  - legFRHoof (box · hoof)
- legBL (group)
  - legBLThigh (box · coat)
  - legBLCannon (box · coat)
  - legBLHoof (box · hoof)
- legBR (group)
  - legBRThigh (box · coat)
  - legBRCannon (box · coat)
  - legBRSock (box · white)
  - legBRHoof (box · hoof)
- body (group)
  - barrel (box · coat)
  - chest (box · coat)
  - blanketTop (box · blanket)
  - blanketL (box · blanket)
  - blanketTrimL (box · white)
  - girth (box · leather)
  - stirrupLeatherL (box · leather)
  - stirrupL (torus · metal)
  - blanketR (box · blanket)
  - blanketTrimR (box · white)
  - girth (box · leather)
  - stirrupLeatherR (box · leather)
  - stirrupR (torus · metal)
  - girthBelly (box · leather)
  - saddleSeat (box · leather)
  - pommel (box · leather)
  - saddleHorn (cylinder · leather)
  - hornCap (cylinder · leather)
  - cantle (box · leather)
- tail (group)
  - tailDock (box · mane)

## How to use

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

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

## Code

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

const deg = THREE.MathUtils.degToRad;

// Tube along a smooth curve through the given points.
function tube(path, radius, tubularSegments, radialSegments, closed = false) {
  const curve = new THREE.CatmullRomCurve3(path.map(([x, y, z]) => new THREE.Vector3(x, y, z)), closed);
  return new THREE.TubeGeometry(curve, tubularSegments, radius, radialSegments, closed);
}

export function createHorse() {
  const root = new THREE.Group();
  root.name = 'Horse';

  // Materials
  const coatMat = new THREE.MeshStandardMaterial({ name: 'coat', color: 0x9c5d35, roughness: 0.75, flatShading: true });
  const muzzleMat = new THREE.MeshStandardMaterial({ name: 'muzzle', color: 0x653c22, roughness: 0.75, flatShading: true });
  const maneMat = new THREE.MeshStandardMaterial({ name: 'mane', color: 0x2e221d, roughness: 0.9, flatShading: true });
  const whiteMat = new THREE.MeshStandardMaterial({ name: 'white', color: 0xf4efe6, roughness: 0.85, flatShading: true });
  const hoofMat = new THREE.MeshStandardMaterial({ name: 'hoof', color: 0x3b302b, roughness: 0.7, flatShading: true });
  const eyeMat = new THREE.MeshStandardMaterial({ name: 'eye', color: 0x17131a, roughness: 0.3, flatShading: true });
  const shineMat = new THREE.MeshStandardMaterial({ name: 'shine', color: 0xffffff, roughness: 0.3, flatShading: true });
  const leatherMat = new THREE.MeshStandardMaterial({ name: 'leather', color: 0x6a3f22, roughness: 0.6, flatShading: true });
  const blanketMat = new THREE.MeshStandardMaterial({ name: 'blanket', color: 0xb8362f, roughness: 0.9, flatShading: true });
  const metalMat = new THREE.MeshStandardMaterial({ name: 'metal', color: 0xcfd4da, roughness: 0.3, metalness: 0.75, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.2, 0.46, 0.24);
  const boxGeo2 = new THREE.BoxGeometry(0.15, 0.56, 0.16);
  const boxGeo3 = new THREE.BoxGeometry(0.16, 0.2, 0.17);
  const boxGeo4 = new THREE.BoxGeometry(0.19, 0.11, 0.21);
  const boxGeo5 = new THREE.BoxGeometry(0.22, 0.5, 0.32);
  const boxGeo6 = new THREE.BoxGeometry(0.025, 0.26, 0.56);
  const boxGeo7 = new THREE.BoxGeometry(0.03, 0.04, 0.565);
  const boxGeo8 = new THREE.BoxGeometry(0.012, 0.42, 0.09);
  const boxGeo9 = new THREE.BoxGeometry(0.02, 0.42, 0.05);
  const torusGeo = new THREE.TorusGeometry(0.06, 0.016, 4, 8);
  const boxGeo10 = new THREE.BoxGeometry(0.05, 0.03, 0.01);
  const boxGeo11 = new THREE.BoxGeometry(0.075, 0.09, 0.075);
  const boxGeo12 = new THREE.BoxGeometry(0.01, 0.03, 0.03);
  const boxGeo13 = new THREE.BoxGeometry(0.03, 0.03, 0.01);
  const coneGeo = new THREE.ConeGeometry(0.055, 0.15, 4, 1, false, Math.PI / 4);
  const boxGeo14 = new THREE.BoxGeometry(0.012, 0.36, 0.035);
  const boxGeo15 = new THREE.BoxGeometry(0.02, 0.04, 0.04);

  // Parts
  const legFL = new THREE.Group();
  legFL.name = 'legFL';
  legFL.position.set(0.16, 1.06, 0.52);
  root.add(legFL);
  const legFLUpper = new THREE.Mesh(boxGeo, coatMat);
  legFLUpper.name = 'legFLUpper';
  legFLUpper.position.set(0, -0.2, 0);
  legFL.add(legFLUpper);
  const legFLCannon = new THREE.Mesh(boxGeo2, coatMat);
  legFLCannon.name = 'legFLCannon';
  legFLCannon.position.set(0, -0.68, 0);
  legFL.add(legFLCannon);
  const legFLSock = new THREE.Mesh(boxGeo3, whiteMat);
  legFLSock.name = 'legFLSock';
  legFLSock.position.set(0, -0.86, 0);
  legFL.add(legFLSock);
  const legFLHoof = new THREE.Mesh(boxGeo4, hoofMat);
  legFLHoof.name = 'legFLHoof';
  legFLHoof.position.set(0, -1.005, 0.01);
  legFL.add(legFLHoof);
  const legFR = new THREE.Group();
  legFR.name = 'legFR';
  legFR.position.set(-0.16, 1.06, 0.52);
  root.add(legFR);
  const legFRUpper = new THREE.Mesh(boxGeo, coatMat);
  legFRUpper.name = 'legFRUpper';
  legFRUpper.position.set(0, -0.2, 0);
  legFR.add(legFRUpper);
  const legFRCannon = new THREE.Mesh(boxGeo2, coatMat);
  legFRCannon.name = 'legFRCannon';
  legFRCannon.position.set(0, -0.68, 0);
  legFR.add(legFRCannon);
  const legFRHoof = new THREE.Mesh(boxGeo4, hoofMat);
  legFRHoof.name = 'legFRHoof';
  legFRHoof.position.set(0, -1.005, 0.01);
  legFR.add(legFRHoof);
  const legBL = new THREE.Group();
  legBL.name = 'legBL';
  legBL.position.set(0.16, 1.06, -0.52);
  root.add(legBL);
  const legBLThigh = new THREE.Mesh(boxGeo5, coatMat);
  legBLThigh.name = 'legBLThigh';
  legBLThigh.position.set(0, -0.2, -0.02);
  legBL.add(legBLThigh);
  const legBLCannon = new THREE.Mesh(boxGeo2, coatMat);
  legBLCannon.name = 'legBLCannon';
  legBLCannon.position.set(0, -0.68, 0);
  legBL.add(legBLCannon);
  const legBLHoof = new THREE.Mesh(boxGeo4, hoofMat);
  legBLHoof.name = 'legBLHoof';
  legBLHoof.position.set(0, -1.005, 0.01);
  legBL.add(legBLHoof);
  const legBR = new THREE.Group();
  legBR.name = 'legBR';
  legBR.position.set(-0.16, 1.06, -0.52);
  root.add(legBR);
  const legBRThigh = new THREE.Mesh(boxGeo5, coatMat);
  legBRThigh.name = 'legBRThigh';
  legBRThigh.position.set(0, -0.2, -0.02);
  legBR.add(legBRThigh);
  const legBRCannon = new THREE.Mesh(boxGeo2, coatMat);
  legBRCannon.name = 'legBRCannon';
  legBRCannon.position.set(0, -0.68, 0);
  legBR.add(legBRCannon);
  const legBRSock = new THREE.Mesh(boxGeo3, whiteMat);
  legBRSock.name = 'legBRSock';
  legBRSock.position.set(0, -0.86, 0);
  legBR.add(legBRSock);
  const legBRHoof = new THREE.Mesh(boxGeo4, hoofMat);
  legBRHoof.name = 'legBRHoof';
  legBRHoof.position.set(0, -1.005, 0.01);
  legBR.add(legBRHoof);
  const body = new THREE.Group();
  body.name = 'body';
  root.add(body);
  const barrel = new THREE.Mesh(new THREE.BoxGeometry(0.56, 0.62, 1.45), coatMat);
  barrel.name = 'barrel';
  barrel.position.set(0, 1.29, 0);
  body.add(barrel);
  const chest = new THREE.Mesh(new THREE.BoxGeometry(0.46, 0.4, 0.06), coatMat);
  chest.name = 'chest';
  chest.position.set(0, 1.24, 0.745);
  body.add(chest);
  const blanketTop = new THREE.Mesh(new THREE.BoxGeometry(0.61, 0.03, 0.56), blanketMat);
  blanketTop.name = 'blanketTop';
  blanketTop.position.set(0, 1.615, 0.05);
  body.add(blanketTop);
  const blanketL = new THREE.Mesh(boxGeo6, blanketMat);
  blanketL.name = 'blanketL';
  blanketL.position.set(0.2925, 1.485, 0.05);
  body.add(blanketL);
  const blanketTrimL = new THREE.Mesh(boxGeo7, whiteMat);
  blanketTrimL.name = 'blanketTrimL';
  blanketTrimL.position.set(0.295, 1.37, 0.05);
  body.add(blanketTrimL);
  const girth = new THREE.Mesh(boxGeo8, leatherMat);
  girth.name = 'girth';
  girth.position.set(0.311, 1.19, 0.22);
  body.add(girth);
  const stirrupLeatherL = new THREE.Mesh(boxGeo9, leatherMat);
  stirrupLeatherL.name = 'stirrupLeatherL';
  stirrupLeatherL.position.set(0.33, 1.47, 0.08);
  body.add(stirrupLeatherL);
  const stirrupL = new THREE.Mesh(torusGeo, metalMat);
  stirrupL.name = 'stirrupL';
  stirrupL.position.set(0.33, 1.22, 0.08);
  stirrupL.rotation.set(0, deg(90), 0);
  body.add(stirrupL);
  const blanketR = new THREE.Mesh(boxGeo6, blanketMat);
  blanketR.name = 'blanketR';
  blanketR.position.set(-0.2925, 1.485, 0.05);
  body.add(blanketR);
  const blanketTrimR = new THREE.Mesh(boxGeo7, whiteMat);
  blanketTrimR.name = 'blanketTrimR';
  blanketTrimR.position.set(-0.295, 1.37, 0.05);
  body.add(blanketTrimR);
  const girth2 = new THREE.Mesh(boxGeo8, leatherMat);
  girth2.name = 'girth';
  girth2.position.set(-0.311, 1.19, 0.22);
  body.add(girth2);
  const stirrupLeatherR = new THREE.Mesh(boxGeo9, leatherMat);
  stirrupLeatherR.name = 'stirrupLeatherR';
  stirrupLeatherR.position.set(-0.33, 1.47, 0.08);
  body.add(stirrupLeatherR);
  const stirrupR = new THREE.Mesh(torusGeo, metalMat);
  stirrupR.name = 'stirrupR';
  stirrupR.position.set(-0.33, 1.22, 0.08);
  stirrupR.rotation.set(0, deg(90), 0);
  body.add(stirrupR);
  const girthBelly = new THREE.Mesh(new THREE.BoxGeometry(0.52, 0.012, 0.09), leatherMat);
  girthBelly.name = 'girthBelly';
  girthBelly.position.set(0, 0.972, 0.22);
  body.add(girthBelly);
  const saddleSeat = new THREE.Mesh(new THREE.BoxGeometry(0.44, 0.08, 0.46), leatherMat);
  saddleSeat.name = 'saddleSeat';
  saddleSeat.position.set(0, 1.67, 0.05);
  body.add(saddleSeat);
  const pommel = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.13, 0.1), leatherMat);
  pommel.name = 'pommel';
  pommel.position.set(0, 1.73, 0.27);
  body.add(pommel);
  const saddleHorn = new THREE.Mesh(new THREE.CylinderGeometry(0.03, 0.03, 0.1, 6), leatherMat);
  saddleHorn.name = 'saddleHorn';
  saddleHorn.position.set(0, 1.84, 0.29);
  body.add(saddleHorn);
  const hornCap = new THREE.Mesh(new THREE.CylinderGeometry(0.05, 0.05, 0.03, 6), leatherMat);
  hornCap.name = 'hornCap';
  hornCap.position.set(0, 1.9, 0.29);
  body.add(hornCap);
  const cantle = new THREE.Mesh(new THREE.BoxGeometry(0.38, 0.14, 0.09), leatherMat);
  cantle.name = 'cantle';
  cantle.position.set(0, 1.75, -0.16);
  body.add(cantle);
  const tail = new THREE.Group();
  tail.name = 'tail';
  tail.position.set(0, 1.5, -0.725);
  root.add(tail);
  const tailDock = new THREE.Mesh(new THREE.BoxGeometry(0.13, 0.14, 0.2), maneMat);
  tailDock.name = 'tailDock';
  tailDock.position.set(0, 0, -0.08);
  tail.add(tailDock);
  const tailHair = new THREE.Mesh(new THREE.BoxGeometry(0.18, 0.5, 0.16), maneMat);
  tailHair.name = 'tailHair';
  tailHair.position.set(0, -0.26, -0.18);
  tailHair.rotation.set(deg(-14), 0, 0);
  tail.add(tailHair);
  const tailEnd = new THREE.Mesh(new THREE.BoxGeometry(0.15, 0.25, 0.13), maneMat);
  tailEnd.name = 'tailEnd';
  tailEnd.position.set(0, -0.6, -0.26);
  tailEnd.rotation.set(deg(-22), 0, 0);
  tail.add(tailEnd);
  const head = new THREE.Group();
  head.name = 'head';
  head.position.set(0, 1.45, 0.605);
  root.add(head);
  const neck = new THREE.Mesh(new THREE.BoxGeometry(0.32, 0.8, 0.44), coatMat);
  neck.name = 'neck';
  neck.position.set(0, 0.32, 0.12);
  neck.rotation.set(deg(28), 0, 0);
  head.add(neck);
  const mane = new THREE.Group();
  mane.name = 'mane';
  mane.position.set(0, 0.32, 0.12);
  mane.rotation.set(deg(28), 0, 0);
  head.add(mane);
  const maneTuft1 = new THREE.Mesh(new THREE.BoxGeometry(0.1557, 0.21, 0.17), maneMat);
  maneTuft1.name = 'maneTuft1';
  maneTuft1.position.set(0.0055, -0.3, -0.23);
  maneTuft1.rotation.set(deg(-4.4838), 0, 0);
  mane.add(maneTuft1);
  const maneTuft2 = new THREE.Mesh(new THREE.BoxGeometry(0.1537, 0.21, 0.17), maneMat);
  maneTuft2.name = 'maneTuft2';
  maneTuft2.position.set(-0.0083, -0.14, -0.23);
  maneTuft2.rotation.set(deg(1.4746), 0, 0);
  mane.add(maneTuft2);
  const maneTuft3 = new THREE.Mesh(new THREE.BoxGeometry(0.1566, 0.21, 0.17), maneMat);
  maneTuft3.name = 'maneTuft3';
  maneTuft3.position.set(-0.0008, 0.02, -0.23);
  maneTuft3.rotation.set(deg(6.4899), 0, 0);
  mane.add(maneTuft3);
  const maneTuft4 = new THREE.Mesh(new THREE.BoxGeometry(0.1419, 0.21, 0.17), maneMat);
  maneTuft4.name = 'maneTuft4';
  maneTuft4.position.set(0.0056, 0.18, -0.23);
  maneTuft4.rotation.set(deg(3.8498), 0, 0);
  mane.add(maneTuft4);
  const maneTuft5 = new THREE.Mesh(new THREE.BoxGeometry(0.1548, 0.21, 0.17), maneMat);
  maneTuft5.name = 'maneTuft5';
  maneTuft5.position.set(-0.0097, 0.34, -0.23);
  maneTuft5.rotation.set(deg(-0.5536), 0, 0);
  mane.add(maneTuft5);
  const maneBase = new THREE.Mesh(new THREE.BoxGeometry(0.12, 0.74, 0.08), maneMat);
  maneBase.name = 'maneBase';
  maneBase.position.set(0, 0.02, -0.21);
  mane.add(maneBase);
  const skull = new THREE.Group();
  skull.name = 'skull';
  skull.position.set(0, 0.84, 0.38);
  skull.rotation.set(deg(25), 0, 0);
  skull.scale.setScalar(1.22);
  head.add(skull);
  const cranium = new THREE.Mesh(new THREE.BoxGeometry(0.34, 0.36, 0.4), coatMat);
  cranium.name = 'cranium';
  skull.add(cranium);
  const snout = new THREE.Mesh(new THREE.BoxGeometry(0.28, 0.29, 0.36), coatMat);
  snout.name = 'snout';
  snout.position.set(0, -0.035, 0.36);
  skull.add(snout);
  const muzzle = new THREE.Mesh(new THREE.BoxGeometry(0.285, 0.295, 0.12), muzzleMat);
  muzzle.name = 'muzzle';
  muzzle.position.set(0, -0.035, 0.49);
  skull.add(muzzle);
  const nostril = new THREE.Mesh(boxGeo10, eyeMat);
  nostril.name = 'nostril';
  nostril.position.set(0.07, 0.03, 0.552);
  skull.add(nostril);
  const eyeL = new THREE.Mesh(boxGeo11, eyeMat);
  eyeL.name = 'eyeL';
  eyeL.position.set(0.137, 0.07, 0.167);
  skull.add(eyeL);
  const eyeShineL = new THREE.Mesh(boxGeo12, shineMat);
  eyeShineL.name = 'eyeShineL';
  eyeShineL.position.set(0.1775, 0.09, 0.17);
  skull.add(eyeShineL);
  const eyeShineFrontL = new THREE.Mesh(boxGeo13, shineMat);
  eyeShineFrontL.name = 'eyeShineFrontL';
  eyeShineFrontL.position.set(0.15, 0.09, 0.2075);
  skull.add(eyeShineFrontL);
  const nostril2 = new THREE.Mesh(boxGeo10, eyeMat);
  nostril2.name = 'nostril';
  nostril2.position.set(-0.07, 0.03, 0.552);
  skull.add(nostril2);
  const eyeR = new THREE.Mesh(boxGeo11, eyeMat);
  eyeR.name = 'eyeR';
  eyeR.position.set(-0.137, 0.07, 0.167);
  skull.add(eyeR);
  const eyeShineR = new THREE.Mesh(boxGeo12, shineMat);
  eyeShineR.name = 'eyeShineR';
  eyeShineR.position.set(-0.1775, 0.09, 0.17);
  skull.add(eyeShineR);
  const eyeShineFrontR = new THREE.Mesh(boxGeo13, shineMat);
  eyeShineFrontR.name = 'eyeShineFrontR';
  eyeShineFrontR.position.set(-0.15, 0.09, 0.2075);
  skull.add(eyeShineFrontR);
  const mouth = new THREE.Mesh(new THREE.BoxGeometry(0.12, 0.008, 0.01), eyeMat);
  mouth.name = 'mouth';
  mouth.position.set(0, -0.13, 0.552);
  skull.add(mouth);
  const earL = new THREE.Group();
  earL.name = 'earL';
  earL.position.set(0.1, 0.18, -0.12);
  earL.rotation.set(deg(-15), 0, deg(-12));
  skull.add(earL);
  const earOuterL = new THREE.Mesh(coneGeo, coatMat);
  earOuterL.name = 'earOuterL';
  earOuterL.position.set(0, 0.075, 0);
  earOuterL.scale.set(1, 1, 0.6);
  earL.add(earOuterL);
  const earR = new THREE.Group();
  earR.name = 'earR';
  earR.position.set(-0.1, 0.18, -0.12);
  earR.rotation.set(deg(-15), 0, deg(12));
  skull.add(earR);
  const earOuterR = new THREE.Mesh(coneGeo, coatMat);
  earOuterR.name = 'earOuterR';
  earOuterR.position.set(0, 0.075, 0);
  earOuterR.scale.set(1, 1, 0.6);
  earR.add(earOuterR);
  const forelock = new THREE.Mesh(new THREE.BoxGeometry(0.15, 0.13, 0.05), maneMat);
  forelock.name = 'forelock';
  forelock.position.set(0.015, 0.14, 0.21);
  forelock.rotation.set(0, 0, deg(6));
  skull.add(forelock);
  const blazeForehead = new THREE.Mesh(new THREE.BoxGeometry(0.08, 0.12, 0.01), whiteMat);
  blazeForehead.name = 'blazeForehead';
  blazeForehead.position.set(0, -0.02, 0.205);
  skull.add(blazeForehead);
  const blazeNose = new THREE.Mesh(new THREE.BoxGeometry(0.075, 0.01, 0.42), whiteMat);
  blazeNose.name = 'blazeNose';
  blazeNose.position.set(0, 0.115, 0.33);
  skull.add(blazeNose);
  const noseband = new THREE.Mesh(new THREE.BoxGeometry(0.29, 0.3, 0.04), leatherMat);
  noseband.name = 'noseband';
  noseband.position.set(0, -0.035, 0.36);
  skull.add(noseband);
  const cheekStrap = new THREE.Mesh(boxGeo14, leatherMat);
  cheekStrap.name = 'cheekStrap';
  cheekStrap.position.set(0.176, 0, 0.08);
  cheekStrap.rotation.set(deg(-25), 0, 0);
  skull.add(cheekStrap);
  const bitRing = new THREE.Mesh(boxGeo15, metalMat);
  bitRing.name = 'bitRing';
  bitRing.position.set(0.15, -0.13, 0.42);
  skull.add(bitRing);
  const cheekStrap2 = new THREE.Mesh(boxGeo14, leatherMat);
  cheekStrap2.name = 'cheekStrap';
  cheekStrap2.position.set(-0.176, 0, 0.08);
  cheekStrap2.rotation.set(deg(-25), 0, 0);
  skull.add(cheekStrap2);
  const bitRing2 = new THREE.Mesh(boxGeo15, metalMat);
  bitRing2.name = 'bitRing';
  bitRing2.position.set(-0.15, -0.13, 0.42);
  skull.add(bitRing2);
  const browband = new THREE.Mesh(new THREE.BoxGeometry(0.35, 0.035, 0.03), leatherMat);
  browband.name = 'browband';
  browband.position.set(0, 0.1625, 0.12);
  skull.add(browband);
  const reinL = new THREE.Mesh(tube([[0.1952, 0.4797, 0.7774], [0.17, 0.1878, 0.2494], [0.12, 0.1, -0.1]], 0.014, 12, 4), leatherMat);
  reinL.name = 'reinL';
  head.add(reinL);
  const reinR = new THREE.Mesh(tube([[-0.1952, 0.4797, 0.7774], [-0.17, 0.1878, 0.2494], [-0.12, 0.1, -0.1]], 0.014, 12, 4), leatherMat);
  reinR.name = 'reinR';
  head.add(reinR);

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

export default createHorse;
```

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