# Wrench

> A low-poly wrench lying flat in two classic designs: a chrome adjustable (crescent) wrench with an angled head, sliding jaw, knurled worm screw and rubber grip, or a heavy pipe wrench with a red I-beam handle, hook jaw, toothed heel jaw and knurled adjusting nut. Set its length and colors for garages, workshops, plumbing jobs and repair-kit pickups.

![Wrench preview](https://codels.download/m/wrench.png)

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

## Facts

- Category: Props › Tools
- Size (W × H × D): 0.26 × 0.02 × 0.18 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 212 · Meshes: 5 · Materials: 3
- License: CC0-1.0 (Codels built-in)
- Tags: mechanic, plumbing, workshop, wrench, low-poly, stylized, construction, industrial, modern, post-apocalyptic, survival, equipment, pickup, prop, tool, metal, rubber, flat, mobile-friendly, parametric, color-gray, color-red, size-tiny, poly-ultra-low
- Page: https://codels.download/models/wrench

## Files

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

## Parameters

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

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `type` | select | adjustable \| pipe | adjustable | adjustable |
| `size` | number | 0.15 – 0.6 | 0.3 | 0.3 |
| `metal` | color | #rrggbb | #a3aab3 | #a3aab3 |
| `grip` | color | #rrggbb | #c43a2f | #c43a2f |

## Parts

- wrench (group)
  - tool (group)
    - handle (extrude · steel)
    - grip (extrude · grip)
    - head (group)
      - headBody (extrude · steel)
      - slidingJaw (extrude · steelDark)
      - wormScrew (cylinder · steelDark)

## How to use

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

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

## Code

```js
/**
 * Wrench — Codels 3D model library (https://codels.download/models/wrench)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 212 · Size (W × H × D): 0.26 × 0.02 × 0.18 m
 *
 * Usage:
 *   import { createWrench } from './wrench.js';
 *   
 *   const model = createWrench();
 *   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 createWrench() {
  const root = new THREE.Group();
  root.name = 'Wrench';

  // Materials
  const steelMat = new THREE.MeshStandardMaterial({ name: 'steel', color: 0xa3aab3, roughness: 0.3, metalness: 0.6, flatShading: true });
  const steelDarkMat = new THREE.MeshStandardMaterial({ name: 'steelDark', color: 0x6a6f74, roughness: 0.45, metalness: 0.5, flatShading: true });
  const gripMat = new THREE.MeshStandardMaterial({ name: 'grip', color: 0xc43a2f, roughness: 0.9, flatShading: true });

  // Parts
  const wrench = new THREE.Group();
  wrench.name = 'wrench';
  wrench.position.set(0, 0.0081, 0);
  wrench.rotation.set(0, deg(30), 0);
  root.add(wrench);
  const tool = new THREE.Group();
  tool.name = 'tool';
  tool.position.set(0.0905, 0, 0);
  tool.rotation.set(deg(-90), 0, 0);
  tool.scale.setScalar(0.9524);
  wrench.add(tool);
  const handle = new THREE.Mesh(extrude([[-0.03, -0.019], [-0.12, -0.0165], [-0.235, -0.017], [-0.2435, -0.0147], [-0.2497, -0.0085], [-0.252, 0], [-0.2497, 0.0085], [-0.2435, 0.0147], [-0.235, 0.017], [-0.12, 0.0165], [-0.03, 0.019]], 0.008, [[[-0.2295, 0], [-0.2327, 0.0056], [-0.2392, 0.0056], [-0.2425, 0], [-0.2392, -0.0056], [-0.2327, -0.0056]]]), steelMat);
  handle.name = 'handle';
  tool.add(handle);
  const grip = new THREE.Mesh(extrude([[-0.21, -0.0185], [-0.085, -0.0175], [-0.08, 0], [-0.085, 0.0175], [-0.21, 0.0185], [-0.215, 0]], 0.008, [], [0.003, 0.002, 1]), gripMat);
  grip.name = 'grip';
  tool.add(grip);
  const head = new THREE.Group();
  head.name = 'head';
  head.position.set(0.004, 0, 0);
  head.rotation.set(0, 0, deg(15));
  tool.add(head);
  const headBody = new THREE.Mesh(extrude([[0.004, 0.011], [0.056, 0.011], [0.059, 0.022], [0.0336, 0.0235], [0.0212, 0.0351], [0.0052, 0.0407], [-0.0118, 0.0393], [-0.0267, 0.0312], [-0.037, 0.0177], [-0.041, 0.0012], [-0.038, -0.0155], [-0.0284, -0.0295], [-0.014, -0.0385], [0.004, -0.036]], 0.012), steelMat);
  headBody.name = 'headBody';
  head.add(headBody);
  const slidingJaw = new THREE.Mesh(extrude([[0.004, -0.036], [0.03, -0.038], [0.05, -0.024], [0.056, -0.009], [0.004, -0.009]], 0.011), steelDarkMat);
  slidingJaw.name = 'slidingJaw';
  head.add(slidingJaw);
  const wormScrew = new THREE.Mesh(new THREE.CylinderGeometry(0.0085, 0.0085, 0.024, 8), steelDarkMat);
  wormScrew.name = 'wormScrew';
  wormScrew.position.set(-0.004, -0.024, 0);
  wormScrew.rotation.set(0, 0, deg(90));
  head.add(wormScrew);

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

export default createWrench;
```

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