Codels
1.1K tris0.29 × 0.18 × 0.29 m

Use it in code

Remix in the editor
Self-contained ES module — only depends on three. Call the factory and add the group to your scene.
/**
 * Crown — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the model (it floats — pickups, planets)
 * Triangles: 1,120 · Size (W × H × D): 0.29 × 0.18 × 0.29 m
 *
 * Usage:
 *   import { createCrown } from './crown.js';
 *   
 *   const model = createCrown();
 *   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 createCrown() {
  const root = new THREE.Group();
  root.name = 'Crown';

  // Materials
  const goldMat = new THREE.MeshStandardMaterial({ name: 'gold', color: 0xf2b93b, roughness: 0.32, metalness: 0.8, flatShading: true });
  const gemMat = new THREE.MeshStandardMaterial({ name: 'gem', color: 0xe0314f, roughness: 0.15, emissive: 0xe0314f, emissiveIntensity: 0.25, flatShading: true });
  const gem2Mat = new THREE.MeshStandardMaterial({ name: 'gem2', color: 0x3f86ff, roughness: 0.15, emissive: 0x3f86ff, emissiveIntensity: 0.25, flatShading: true });
  const pearlMat = new THREE.MeshStandardMaterial({ name: 'pearl', color: 0xf6f0e2, roughness: 0.35, flatShading: true });

  // Shared geometries
  const extrudeGeo = extrude([[-0.0497, 0], [0.0497, 0], [0, 0.085]], 0.008, [], [0.003, 0.003, 1]);
  const sphereGeo = new THREE.SphereGeometry(0.014, 6, 4);
  const octahedronGeo = new THREE.OctahedronGeometry(0.019, 0);

  // Parts
  const crown = new THREE.Group();
  crown.name = 'crown';
  crown.position.set(0, -0.0912, 0);
  root.add(crown);
  const band = new THREE.Mesh(lathe([[0.108, 0], [0.12, 0], [0.13, 0.075], [0.118, 0.075], [0.108, 0]], 16), goldMat);
  band.name = 'band';
  crown.add(band);
  const rimBottom = new THREE.Mesh(new THREE.TorusGeometry(0.122, 0.011, 5, 24), goldMat);
  rimBottom.name = 'rimBottom';
  rimBottom.position.set(0, 0.004, 0);
  rimBottom.rotation.set(deg(90), 0, 0);
  crown.add(rimBottom);
  const rimTop = new THREE.Mesh(new THREE.TorusGeometry(0.132, 0.009, 5, 24), goldMat);
  rimTop.name = 'rimTop';
  rimTop.position.set(0, 0.075, 0);
  rimTop.rotation.set(deg(90), 0, 0);
  crown.add(rimTop);
  const tine1 = new THREE.Group();
  tine1.name = 'tine1';
  tine1.position.set(0, 0.071, 0.1201);
  crown.add(tine1);
  const tineBlade1 = new THREE.Mesh(extrudeGeo, goldMat);
  tineBlade1.name = 'tineBlade1';
  tineBlade1.rotation.set(deg(8), 0, 0);
  tine1.add(tineBlade1);
  const pearl1 = new THREE.Mesh(sphereGeo, pearlMat);
  pearl1.name = 'pearl1';
  pearl1.position.set(0, 0.0926, 0.0118);
  tine1.add(pearl1);
  const gemMount1 = new THREE.Group();
  gemMount1.name = 'gemMount1';
  gemMount1.position.set(0, 0.0375, 0.129);
  crown.add(gemMount1);
  const gem1 = new THREE.Mesh(octahedronGeo, gemMat);
  gem1.name = 'gem1';
  gem1.rotation.set(deg(7.6), 0, 0);
  gem1.scale.set(1, 1.25, 0.55);
  gemMount1.add(gem1);
  const tine2 = new THREE.Group();
  tine2.name = 'tine2';
  tine2.position.set(0.0849, 0.071, 0.0849);
  tine2.rotation.set(0, deg(45), 0);
  crown.add(tine2);
  const tineBlade2 = new THREE.Mesh(extrudeGeo, goldMat);
  tineBlade2.name = 'tineBlade2';
  tineBlade2.rotation.set(deg(8), 0, 0);
  tine2.add(tineBlade2);
  const pearl2 = new THREE.Mesh(sphereGeo, pearlMat);
  pearl2.name = 'pearl2';
  pearl2.position.set(0, 0.0926, 0.0118);
  tine2.add(pearl2);
  const gemMount2 = new THREE.Group();
  gemMount2.name = 'gemMount2';
  gemMount2.position.set(0.0912, 0.0375, 0.0912);
  gemMount2.rotation.set(0, deg(45), 0);
  crown.add(gemMount2);
  const gem2 = new THREE.Mesh(octahedronGeo, gem2Mat);
  gem2.name = 'gem2';
  gem2.rotation.set(deg(7.6), 0, 0);
  gem2.scale.set(1, 1.25, 0.55);
  gemMount2.add(gem2);
  const tine3 = new THREE.Group();
  tine3.name = 'tine3';
  tine3.position.set(0.1201, 0.071, 0);
  tine3.rotation.set(0, deg(90), 0);
  crown.add(tine3);
  const tineBlade3 = new THREE.Mesh(extrudeGeo, goldMat);
  tineBlade3.name = 'tineBlade3';
  tineBlade3.rotation.set(deg(8), 0, 0);
  tine3.add(tineBlade3);
  const pearl3 = new THREE.Mesh(sphereGeo, pearlMat);
  pearl3.name = 'pearl3';
  pearl3.position.set(0, 0.0926, 0.0118);
  tine3.add(pearl3);
  const gemMount3 = new THREE.Group();
  gemMount3.name = 'gemMount3';
  gemMount3.position.set(0.129, 0.0375, 0);
  gemMount3.rotation.set(0, deg(90), 0);
  crown.add(gemMount3);
  const gem3 = new THREE.Mesh(octahedronGeo, gemMat);
  gem3.name = 'gem3';
  gem3.rotation.set(deg(7.6), 0, 0);
  gem3.scale.set(1, 1.25, 0.55);
  gemMount3.add(gem3);
  const tine4 = new THREE.Group();
  tine4.name = 'tine4';
  tine4.position.set(0.0849, 0.071, -0.0849);
  tine4.rotation.set(0, deg(135), 0);
  crown.add(tine4);
  const tineBlade4 = new THREE.Mesh(extrudeGeo, goldMat);
  tineBlade4.name = 'tineBlade4';
  tineBlade4.rotation.set(deg(8), 0, 0);
  tine4.add(tineBlade4);
  const pearl4 = new THREE.Mesh(sphereGeo, pearlMat);
  pearl4.name = 'pearl4';
  pearl4.position.set(0, 0.0926, 0.0118);
  tine4.add(pearl4);
  const gemMount4 = new THREE.Group();
  gemMount4.name = 'gemMount4';
  gemMount4.position.set(0.0912, 0.0375, -0.0912);
  gemMount4.rotation.set(0, deg(135), 0);
  crown.add(gemMount4);
  const gem4 = new THREE.Mesh(octahedronGeo, gem2Mat);
  gem4.name = 'gem4';
  gem4.rotation.set(deg(7.6), 0, 0);
  gem4.scale.set(1, 1.25, 0.55);
  gemMount4.add(gem4);
  const tine5 = new THREE.Group();
  tine5.name = 'tine5';
  tine5.position.set(0, 0.071, -0.1201);
  tine5.rotation.set(0, deg(180), 0);
  crown.add(tine5);
  const tineBlade5 = new THREE.Mesh(extrudeGeo, goldMat);
  tineBlade5.name = 'tineBlade5';
  tineBlade5.rotation.set(deg(8), 0, 0);
  tine5.add(tineBlade5);
  const pearl5 = new THREE.Mesh(sphereGeo, pearlMat);
  pearl5.name = 'pearl5';
  pearl5.position.set(0, 0.0926, 0.0118);
  tine5.add(pearl5);
  const gemMount5 = new THREE.Group();
  gemMount5.name = 'gemMount5';
  gemMount5.position.set(0, 0.0375, -0.129);
  gemMount5.rotation.set(0, deg(180), 0);
  crown.add(gemMount5);
  const gem5 = new THREE.Mesh(octahedronGeo, gemMat);
  gem5.name = 'gem5';
  gem5.rotation.set(deg(7.6), 0, 0);
  gem5.scale.set(1, 1.25, 0.55);
  gemMount5.add(gem5);
  const tine6 = new THREE.Group();
  tine6.name = 'tine6';
  tine6.position.set(-0.0849, 0.071, -0.0849);
  tine6.rotation.set(0, deg(225), 0);
  crown.add(tine6);
  const tineBlade6 = new THREE.Mesh(extrudeGeo, goldMat);
  tineBlade6.name = 'tineBlade6';
  tineBlade6.rotation.set(deg(8), 0, 0);
  tine6.add(tineBlade6);
  const pearl6 = new THREE.Mesh(sphereGeo, pearlMat);
  pearl6.name = 'pearl6';
  pearl6.position.set(0, 0.0926, 0.0118);
  tine6.add(pearl6);
  const gemMount6 = new THREE.Group();
  gemMount6.name = 'gemMount6';
  gemMount6.position.set(-0.0912, 0.0375, -0.0912);
  gemMount6.rotation.set(0, deg(225), 0);
  crown.add(gemMount6);
  const gem6 = new THREE.Mesh(octahedronGeo, gem2Mat);
  gem6.name = 'gem6';
  gem6.rotation.set(deg(7.6), 0, 0);
  gem6.scale.set(1, 1.25, 0.55);
  gemMount6.add(gem6);
  const tine7 = new THREE.Group();
  tine7.name = 'tine7';
  tine7.position.set(-0.1201, 0.071, 0);
  tine7.rotation.set(0, deg(270), 0);
  crown.add(tine7);
  const tineBlade7 = new THREE.Mesh(extrudeGeo, goldMat);
  tineBlade7.name = 'tineBlade7';
  tineBlade7.rotation.set(deg(8), 0, 0);
  tine7.add(tineBlade7);
  const pearl7 = new THREE.Mesh(sphereGeo, pearlMat);
  pearl7.name = 'pearl7';
  pearl7.position.set(0, 0.0926, 0.0118);
  tine7.add(pearl7);
  const gemMount7 = new THREE.Group();
  gemMount7.name = 'gemMount7';
  gemMount7.position.set(-0.129, 0.0375, 0);
  gemMount7.rotation.set(0, deg(270), 0);
  crown.add(gemMount7);
  const gem7 = new THREE.Mesh(octahedronGeo, gemMat);
  gem7.name = 'gem7';
  gem7.rotation.set(deg(7.6), 0, 0);
  gem7.scale.set(1, 1.25, 0.55);
  gemMount7.add(gem7);
  const tine8 = new THREE.Group();
  tine8.name = 'tine8';
  tine8.position.set(-0.0849, 0.071, 0.0849);
  tine8.rotation.set(0, deg(315), 0);
  crown.add(tine8);
  const tineBlade8 = new THREE.Mesh(extrudeGeo, goldMat);
  tineBlade8.name = 'tineBlade8';
  tineBlade8.rotation.set(deg(8), 0, 0);
  tine8.add(tineBlade8);
  const pearl8 = new THREE.Mesh(sphereGeo, pearlMat);
  pearl8.name = 'pearl8';
  pearl8.position.set(0, 0.0926, 0.0118);
  tine8.add(pearl8);
  const gemMount8 = new THREE.Group();
  gemMount8.name = 'gemMount8';
  gemMount8.position.set(-0.0912, 0.0375, 0.0912);
  gemMount8.rotation.set(0, deg(315), 0);
  crown.add(gemMount8);
  const gem8 = new THREE.Mesh(octahedronGeo, gem2Mat);
  gem8.name = 'gem8';
  gem8.rotation.set(deg(7.6), 0, 0);
  gem8.scale.set(1, 1.25, 0.55);
  gemMount8.add(gem8);

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

export default createCrown;

Ratings & comments

—
No ratings yet — be the first.
5
0
4
0
3
0
2
0
1
0

Sign in to rate and comment.

0 comments

No comments yet. Share how you used this model or what could be better.

Related models

Same category or similar tags