# Sedan

> A stylized four-door family sedan with a rounded-boxy body, dark tinted windows, glowing headlights, red taillights, bumpers and four separately named wheels (wheelFL…wheelRR) ready to spin. Pick the paint color and wheel style for city traffic, parking lots or driving games.

![Sedan preview](https://codels.download/m/sedan.png)

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

## Facts

- Category: Vehicles › Cars & Trucks
- Size (W × H × D): 1.86 × 1.44 × 4.46 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 2,108 · Meshes: 48 · Materials: 6
- License: CC0-1.0 (Codels built-in)
- Tags: car, sedan, traffic, low-poly, stylized, modern, city, road, city-builder, racing-game, hero-asset, vehicle, glass, metal, emissive, game-ready, parametric, color-blue, color-gray, size-large, poly-medium
- Page: https://codels.download/models/sedan

## Files

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

## Parameters

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

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `bodyColor` | color | #rrggbb | #3f78c0 | #3f78c0 |
| `wheelStyle` | select | hubcap \| sport \| steel | hubcap | hubcap |
| `lights` | boolean | true \| false | true | true |

## Parts

- body (group)
  - lowerBody (extrude · paint)
  - chassis (box · trim)
  - cabin (extrude · paint)
  - windowFL (extrude · glass)
  - windowRL (extrude · glass)
  - windowFR (extrude · glass)
  - windowRR (extrude · glass)
  - windshield (box · glass)
  - rearWindow (box · glass)
  - headlightL (box · headlight)
  - taillightL (box · taillight)
  - mirrorL (box · paint)
  - skirtL (box · trim)
  - headlightR (box · headlight)
  - taillightR (box · taillight)
  - mirrorR (box · paint)
  - skirtR (box · trim)
  - grille (box · trim)
  - bumperFront (box · trim)
  - bumperRear (box · trim)
  - plateFront (box · chrome)
  - plateRear (box · chrome)
- wheels (group)
  - wheelFL (group)
    - tire (lathe · trim)
    - rim (cylinder · chrome)
    - hubcap (cylinder · chrome)
    - centerCap (cylinder · trim)
  - wheelFR (group)
    - tire (lathe · trim)
    - rim (cylinder · chrome)
    - hubcap (cylinder · chrome)
    - centerCap (cylinder · trim)
  - wheelRL (group)
    - tire (lathe · trim)
    - rim (cylinder · chrome)
    - hubcap (cylinder · chrome)
    - centerCap (cylinder · trim)
  - wheelRR (group)

## How to use

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

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

## Code

```js
/**
 * Sedan — Codels 3D model library (https://codels.download/models/sedan)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 2,108 · Size (W × H × D): 1.86 × 1.44 × 4.46 m
 *
 * Usage:
 *   import { createSedan } from './sedan.js';
 *   
 *   const model = createSedan();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

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

  // Materials
  const paintMat = new THREE.MeshStandardMaterial({ name: 'paint', color: 0x3f78c0, roughness: 0.42, metalness: 0.15, flatShading: true });
  const glassMat = new THREE.MeshStandardMaterial({ name: 'glass', color: 0x2a3644, roughness: 0.2, metalness: 0.3, flatShading: true });
  const trimMat = new THREE.MeshStandardMaterial({ name: 'trim', color: 0x2a2c31, roughness: 0.8, flatShading: true });
  const chromeMat = new THREE.MeshStandardMaterial({ name: 'chrome', color: 0xc9cdd3, roughness: 0.3, metalness: 0.65, flatShading: true });
  const headlightMat = new THREE.MeshStandardMaterial({ name: 'headlight', color: 0xfff4d6, roughness: 0.3, emissive: 0xffe2a0, emissiveIntensity: 0.9, flatShading: true });
  const taillightMat = new THREE.MeshStandardMaterial({ name: 'taillight', color: 0xd81e28, roughness: 0.3, emissive: 0xff2020, emissiveIntensity: 0.7, flatShading: true });

  // Shared geometries
  const extrudeGeo = extrude([[0.8004, 0.99], [0.3225, 1.33], [-0.12, 1.33], [-0.12, 0.99]], 0.02);
  const extrudeGeo2 = extrude([[-0.22, 0.99], [-0.22, 1.33], [-0.6526, 1.33], [-0.9852, 0.99]], 0.02);
  const boxGeo = new THREE.BoxGeometry(0.36, 0.12, 0.06);
  const boxGeo2 = new THREE.BoxGeometry(0.34, 0.11, 0.06);
  const boxGeo3 = new THREE.BoxGeometry(0.13, 0.09, 0.13);
  const boxGeo4 = new THREE.BoxGeometry(0.006, 0.52, 0.014);
  const boxGeo5 = new THREE.BoxGeometry(0.02, 0.03, 0.13);
  const boxGeo6 = new THREE.BoxGeometry(0.05, 0.1, 1.7);
  const boxGeo7 = new THREE.BoxGeometry(1.86, 0.16, 0.24);
  const boxGeo8 = new THREE.BoxGeometry(0.36, 0.11, 0.02);
  const latheGeo = lathe([[0.2139, -0.095], [0.2139, -0.12], [0.3, -0.12], [0.345, -0.07], [0.345, 0.07], [0.3, 0.12], [0.2139, 0.12], [0.2139, 0.095]], 14);
  const cylinderGeo = new THREE.CylinderGeometry(0.2139, 0.2139, 0.19, 14);
  const cylinderGeo2 = new THREE.CylinderGeometry(0.1754, 0.2096, 0.03, 14);
  const cylinderGeo3 = new THREE.CylinderGeometry(0.0535, 0.0684, 0.03, 8);

  // Parts
  const body = new THREE.Group();
  body.name = 'body';
  root.add(body);
  const lowerBody = new THREE.Mesh(extrude([[2.02, 0.24], [2.11, 0.34], [2.12, 0.62], [2, 0.79], [1.5, 0.88], [1, 0.93], [-1.05, 0.935], [-1.88, 0.945], [-2.1, 0.88], [-2.12, 0.44], [-2.02, 0.24], [-1.7773, 0.24], [-1.7802, 0.4376], [-1.6963, 0.6165], [-1.5425, 0.7406], [-1.35, 0.785], [-1.1575, 0.7406], [-1.0037, 0.6165], [-0.9198, 0.4376], [-0.9227, 0.24], [0.9227, 0.24], [0.9198, 0.4376], [1.0037, 0.6165], [1.1575, 0.7406], [1.35, 0.785], [1.5425, 0.7406], [1.6963, 0.6165], [1.7802, 0.4376], [1.7773, 0.24]], 1.73, [], [0.035, 0.035, 2]), paintMat);
  lowerBody.name = 'lowerBody';
  lowerBody.rotation.set(0, deg(-90), 0);
  body.add(lowerBody);
  const chassis = new THREE.Mesh(new THREE.BoxGeometry(1.24, 0.5, 3.9), trimMat);
  chassis.name = 'chassis';
  chassis.position.set(0, 0.55, 0);
  body.add(chassis);
  const cabin = new THREE.Mesh(extrude([[1.12, 0.84], [0.3, 1.4], [-0.66, 1.4], [-1.22, 0.86]], 1.42, [], [0.05, 0.05, 2]), paintMat);
  cabin.name = 'cabin';
  cabin.rotation.set(0, deg(-90), 0);
  body.add(cabin);
  const windowFL = new THREE.Mesh(extrudeGeo, glassMat);
  windowFL.name = 'windowFL';
  windowFL.position.set(0.765, 0, 0);
  windowFL.rotation.set(0, deg(-90), 0);
  body.add(windowFL);
  const windowRL = new THREE.Mesh(extrudeGeo2, glassMat);
  windowRL.name = 'windowRL';
  windowRL.position.set(0.765, 0, 0);
  windowRL.rotation.set(0, deg(-90), 0);
  body.add(windowRL);
  const windowFR = new THREE.Mesh(extrudeGeo, glassMat);
  windowFR.name = 'windowFR';
  windowFR.position.set(-0.765, 0, 0);
  windowFR.rotation.set(0, deg(-90), 0);
  body.add(windowFR);
  const windowRR = new THREE.Mesh(extrudeGeo2, glassMat);
  windowRR.name = 'windowRR';
  windowRR.position.set(-0.765, 0, 0);
  windowRR.rotation.set(0, deg(-90), 0);
  body.add(windowRR);
  const windshield = new THREE.Mesh(new THREE.BoxGeometry(1.3, 0.02, 0.6206), glassMat);
  windshield.name = 'windshield';
  windshield.position.set(0, 1.2079, 0.6948);
  windshield.rotation.set(deg(-145.6698), 0, 0);
  body.add(windshield);
  const rearWindow = new THREE.Mesh(new THREE.BoxGeometry(1.3, 0.02, 0.4898), glassMat);
  rearWindow.name = 'rearWindow';
  rearWindow.position.set(0, 1.2161, -0.9429);
  rearWindow.rotation.set(deg(136.0416), 0, 0);
  body.add(rearWindow);
  const headlightL = new THREE.Mesh(boxGeo, headlightMat);
  headlightL.name = 'headlightL';
  headlightL.position.set(0.57, 0.6, 2.155);
  body.add(headlightL);
  const taillightL = new THREE.Mesh(boxGeo2, taillightMat);
  taillightL.name = 'taillightL';
  taillightL.position.set(0.58, 0.74, -2.155);
  body.add(taillightL);
  const mirrorL = new THREE.Mesh(boxGeo3, paintMat);
  mirrorL.name = 'mirrorL';
  mirrorL.position.set(0.83, 1.03, 0.76);
  body.add(mirrorL);
  const box14 = new THREE.Mesh(boxGeo4, trimMat);
  box14.position.set(0.903, 0.6, 0.86);
  body.add(box14);
  const box15 = new THREE.Mesh(boxGeo4, trimMat);
  box15.position.set(0.903, 0.6, -0.12);
  body.add(box15);
  const box16 = new THREE.Mesh(boxGeo4, trimMat);
  box16.position.set(0.903, 0.6, -0.88);
  body.add(box16);
  const box17 = new THREE.Mesh(boxGeo5, trimMat);
  box17.position.set(0.91, 0.8, 0.36);
  body.add(box17);
  const box18 = new THREE.Mesh(boxGeo5, trimMat);
  box18.position.set(0.91, 0.8, -0.56);
  body.add(box18);
  const skirtL = new THREE.Mesh(boxGeo6, trimMat);
  skirtL.name = 'skirtL';
  skirtL.position.set(0.89, 0.26, 0);
  body.add(skirtL);
  const headlightR = new THREE.Mesh(boxGeo, headlightMat);
  headlightR.name = 'headlightR';
  headlightR.position.set(-0.57, 0.6, 2.155);
  body.add(headlightR);
  const taillightR = new THREE.Mesh(boxGeo2, taillightMat);
  taillightR.name = 'taillightR';
  taillightR.position.set(-0.58, 0.74, -2.155);
  body.add(taillightR);
  const mirrorR = new THREE.Mesh(boxGeo3, paintMat);
  mirrorR.name = 'mirrorR';
  mirrorR.position.set(-0.83, 1.03, 0.76);
  body.add(mirrorR);
  const box23 = new THREE.Mesh(boxGeo4, trimMat);
  box23.position.set(-0.903, 0.6, 0.86);
  body.add(box23);
  const box24 = new THREE.Mesh(boxGeo4, trimMat);
  box24.position.set(-0.903, 0.6, -0.12);
  body.add(box24);
  const box25 = new THREE.Mesh(boxGeo4, trimMat);
  box25.position.set(-0.903, 0.6, -0.88);
  body.add(box25);
  const box26 = new THREE.Mesh(boxGeo5, trimMat);
  box26.position.set(-0.91, 0.8, 0.36);
  body.add(box26);
  const box27 = new THREE.Mesh(boxGeo5, trimMat);
  box27.position.set(-0.91, 0.8, -0.56);
  body.add(box27);
  const skirtR = new THREE.Mesh(boxGeo6, trimMat);
  skirtR.name = 'skirtR';
  skirtR.position.set(-0.89, 0.26, 0);
  body.add(skirtR);
  const grille = new THREE.Mesh(new THREE.BoxGeometry(0.72, 0.13, 0.04), trimMat);
  grille.name = 'grille';
  grille.position.set(0, 0.58, 2.16);
  body.add(grille);
  const bumperFront = new THREE.Mesh(boxGeo7, trimMat);
  bumperFront.name = 'bumperFront';
  bumperFront.position.set(0, 0.33, 2.1);
  body.add(bumperFront);
  const bumperRear = new THREE.Mesh(boxGeo7, trimMat);
  bumperRear.name = 'bumperRear';
  bumperRear.position.set(0, 0.34, -2.1);
  body.add(bumperRear);
  const plateFront = new THREE.Mesh(boxGeo8, chromeMat);
  plateFront.name = 'plateFront';
  plateFront.position.set(0, 0.34, 2.23);
  body.add(plateFront);
  const plateRear = new THREE.Mesh(boxGeo8, chromeMat);
  plateRear.name = 'plateRear';
  plateRear.position.set(0, 0.5, -2.167);
  body.add(plateRear);
  const wheels = new THREE.Group();
  wheels.name = 'wheels';
  root.add(wheels);
  const wheelFL = new THREE.Group();
  wheelFL.name = 'wheelFL';
  wheelFL.position.set(0.765, 0.345, 1.35);
  wheels.add(wheelFL);
  const tire = new THREE.Mesh(latheGeo, trimMat);
  tire.name = 'tire';
  tire.rotation.set(0, 0, deg(90));
  wheelFL.add(tire);
  const rim = new THREE.Mesh(cylinderGeo, chromeMat);
  rim.name = 'rim';
  rim.rotation.set(0, 0, deg(90));
  wheelFL.add(rim);
  const hubcap = new THREE.Mesh(cylinderGeo2, chromeMat);
  hubcap.name = 'hubcap';
  hubcap.position.set(0.11, 0, 0);
  hubcap.rotation.set(0, 0, deg(-90));
  wheelFL.add(hubcap);
  const centerCap = new THREE.Mesh(cylinderGeo3, trimMat);
  centerCap.name = 'centerCap';
  centerCap.position.set(0.135, 0, 0);
  centerCap.rotation.set(0, 0, deg(-90));
  wheelFL.add(centerCap);
  const wheelFR = new THREE.Group();
  wheelFR.name = 'wheelFR';
  wheelFR.position.set(-0.765, 0.345, 1.35);
  wheels.add(wheelFR);
  const tire2 = new THREE.Mesh(latheGeo, trimMat);
  tire2.name = 'tire';
  tire2.rotation.set(0, 0, deg(90));
  wheelFR.add(tire2);
  const rim2 = new THREE.Mesh(cylinderGeo, chromeMat);
  rim2.name = 'rim';
  rim2.rotation.set(0, 0, deg(90));
  wheelFR.add(rim2);
  const hubcap2 = new THREE.Mesh(cylinderGeo2, chromeMat);
  hubcap2.name = 'hubcap';
  hubcap2.position.set(-0.11, 0, 0);
  hubcap2.rotation.set(0, 0, deg(90));
  wheelFR.add(hubcap2);
  const centerCap2 = new THREE.Mesh(cylinderGeo3, trimMat);
  centerCap2.name = 'centerCap';
  centerCap2.position.set(-0.135, 0, 0);
  centerCap2.rotation.set(0, 0, deg(90));
  wheelFR.add(centerCap2);
  const wheelRL = new THREE.Group();
  wheelRL.name = 'wheelRL';
  wheelRL.position.set(0.765, 0.345, -1.35);
  wheels.add(wheelRL);
  const tire3 = new THREE.Mesh(latheGeo, trimMat);
  tire3.name = 'tire';
  tire3.rotation.set(0, 0, deg(90));
  wheelRL.add(tire3);
  const rim3 = new THREE.Mesh(cylinderGeo, chromeMat);
  rim3.name = 'rim';
  rim3.rotation.set(0, 0, deg(90));
  wheelRL.add(rim3);
  const hubcap3 = new THREE.Mesh(cylinderGeo2, chromeMat);
  hubcap3.name = 'hubcap';
  hubcap3.position.set(0.11, 0, 0);
  hubcap3.rotation.set(0, 0, deg(-90));
  wheelRL.add(hubcap3);
  const centerCap3 = new THREE.Mesh(cylinderGeo3, trimMat);
  centerCap3.name = 'centerCap';
  centerCap3.position.set(0.135, 0, 0);
  centerCap3.rotation.set(0, 0, deg(-90));
  wheelRL.add(centerCap3);
  const wheelRR = new THREE.Group();
  wheelRR.name = 'wheelRR';
  wheelRR.position.set(-0.765, 0.345, -1.35);
  wheels.add(wheelRR);
  const tire4 = new THREE.Mesh(latheGeo, trimMat);
  tire4.name = 'tire';
  tire4.rotation.set(0, 0, deg(90));
  wheelRR.add(tire4);
  const rim4 = new THREE.Mesh(cylinderGeo, chromeMat);
  rim4.name = 'rim';
  rim4.rotation.set(0, 0, deg(90));
  wheelRR.add(rim4);
  const hubcap4 = new THREE.Mesh(cylinderGeo2, chromeMat);
  hubcap4.name = 'hubcap';
  hubcap4.position.set(-0.11, 0, 0);
  hubcap4.rotation.set(0, 0, deg(90));
  wheelRR.add(hubcap4);
  const centerCap4 = new THREE.Mesh(cylinderGeo3, trimMat);
  centerCap4.name = 'centerCap';
  centerCap4.position.set(-0.135, 0, 0);
  centerCap4.rotation.set(0, 0, deg(90));
  wheelRR.add(centerCap4);

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

export default createSedan;
```

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