Codels
1,4 B üçgen1,80 × 2,40 × 1,71 m
Bağımsız bir ES modülü — yalnızca three paketine bağımlıdır. Fabrika fonksiyonunu çağırıp dönen grubu sahnene ekle.
/**
 * Royal Throne — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,384 · Size (W × H × D): 1.80 × 2.40 × 1.71 m
 *
 * Usage:
 *   import { createThrone } from './throne.js';
 *   
 *   const model = createThrone();
 *   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 createThrone() {
  const root = new THREE.Group();
  root.name = 'Throne';

  // Materials
  const frameMat = new THREE.MeshStandardMaterial({ name: 'frame', color: 0x5e2f1d, roughness: 0.7, flatShading: true });
  const frameDarkMat = new THREE.MeshStandardMaterial({ name: 'frameDark', color: 0x3d1f13, roughness: 0.8, flatShading: true });
  const goldMat = new THREE.MeshStandardMaterial({ name: 'gold', color: 0xe2b346, roughness: 0.3, metalness: 0.6, flatShading: true });
  const velvetMat = new THREE.MeshStandardMaterial({ name: 'velvet', color: 0xa8232e, roughness: 1, flatShading: true });
  const velvetDarkMat = new THREE.MeshStandardMaterial({ name: 'velvetDark', color: 0x761920, roughness: 1, flatShading: true });
  const gemMat = new THREE.MeshStandardMaterial({ name: 'gem', color: 0x3d7be0, roughness: 0.15, metalness: 0.2, emissive: 0x1b3f9a, emissiveIntensity: 0.6, flatShading: true });
  const stoneMat = new THREE.MeshStandardMaterial({ name: 'stone', color: 0x77736d, roughness: 0.95, flatShading: true });
  const stoneDarkMat = new THREE.MeshStandardMaterial({ name: 'stoneDark', color: 0x615d58, roughness: 0.95, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.6, 0.11, 0.006);
  const boxGeo2 = new THREE.BoxGeometry(0.025, 0.008, 0.26);
  const cylinderGeo = new THREE.CylinderGeometry(0.045, 0.06, 0.06, 6);
  const coneGeo = new THREE.ConeGeometry(0.022, 0.08, 6);
  const boxGeo3 = new THREE.BoxGeometry(0.13, 0.62, 0.74);
  const boxGeo4 = new THREE.BoxGeometry(0.012, 0.36, 0.5);
  const octahedronGeo = new THREE.OctahedronGeometry(0.08, 0);
  const boxGeo5 = new THREE.BoxGeometry(0.18, 0.05, 0.82);
  const boxGeo6 = new THREE.BoxGeometry(0.19, 0.02, 0.83);
  const extrudeGeo = extrude([[0.047, 0.235], [0.04, 0.242], [-0.0399, 0.242], [-0.047, 0.235], [-0.047, -0.2349], [-0.0399, -0.242], [0.04, -0.242], [0.047, -0.2349]], 0.009, [], [0.018, 0.018, 1]);
  const cylinderGeo2 = new THREE.CylinderGeometry(0.03, 0.04, 0.04, 6);
  const sphereGeo = new THREE.SphereGeometry(0.05, 6, 4);
  const octahedronGeo2 = new THREE.OctahedronGeometry(0.017, 0);
  const coneGeo2 = new THREE.ConeGeometry(0.022, 0.07, 4);
  const boxGeo7 = new THREE.BoxGeometry(0.09, 1.42, 0.12);
  const boxGeo8 = new THREE.BoxGeometry(0.11, 0.03, 0.14);
  const sphereGeo2 = new THREE.SphereGeometry(0.055, 6, 4);
  const coneGeo3 = new THREE.ConeGeometry(0.025, 0.09, 6);

  // Parts
  const daisLower = new THREE.Mesh(new THREE.BoxGeometry(1.8, 0.11, 1.7), stoneDarkMat);
  daisLower.name = 'daisLower';
  daisLower.position.set(0, 0.055, 0);
  root.add(daisLower);
  const daisUpper = new THREE.Mesh(new THREE.BoxGeometry(1.42, 0.11, 1.3), stoneMat);
  daisUpper.name = 'daisUpper';
  daisUpper.position.set(0, 0.165, -0.05);
  root.add(daisUpper);
  const carpet = new THREE.Mesh(new THREE.BoxGeometry(0.6, 0.006, 0.42), velvetDarkMat);
  carpet.name = 'carpet';
  carpet.position.set(0, 0.223, 0.39);
  root.add(carpet);
  const carpetRiser = new THREE.Mesh(boxGeo, velvetDarkMat);
  carpetRiser.name = 'carpetRiser';
  carpetRiser.position.set(0, 0.165, 0.603);
  root.add(carpetRiser);
  const carpet2 = new THREE.Mesh(new THREE.BoxGeometry(0.6, 0.006, 0.25), velvetDarkMat);
  carpet2.name = 'carpet';
  carpet2.position.set(0, 0.113, 0.725);
  root.add(carpet2);
  const carpetRiser2 = new THREE.Mesh(boxGeo, velvetDarkMat);
  carpetRiser2.name = 'carpetRiser';
  carpetRiser2.position.set(0, 0.055, 0.853);
  root.add(carpetRiser2);
  const carpetTrim = new THREE.Mesh(boxGeo2, goldMat);
  carpetTrim.name = 'carpetTrim';
  carpetTrim.position.set(-0.3, 0.114, 0.725);
  root.add(carpetTrim);
  const carpetTrim2 = new THREE.Mesh(boxGeo2, goldMat);
  carpetTrim2.name = 'carpetTrim';
  carpetTrim2.position.set(0.3, 0.114, 0.725);
  root.add(carpetTrim2);
  const throne = new THREE.Group();
  throne.name = 'throne';
  throne.position.set(0, 0.22, -0.18);
  root.add(throne);
  const foot = new THREE.Mesh(cylinderGeo, goldMat);
  foot.name = 'foot';
  foot.position.set(-0.44, 0.03, -0.31);
  throne.add(foot);
  const foot2 = new THREE.Mesh(cylinderGeo, goldMat);
  foot2.name = 'foot';
  foot2.position.set(-0.44, 0.03, 0.35);
  throne.add(foot2);
  const foot3 = new THREE.Mesh(cylinderGeo, goldMat);
  foot3.name = 'foot';
  foot3.position.set(0.44, 0.03, -0.31);
  throne.add(foot3);
  const foot4 = new THREE.Mesh(cylinderGeo, goldMat);
  foot4.name = 'foot';
  foot4.position.set(0.44, 0.03, 0.35);
  throne.add(foot4);
  const seatBox = new THREE.Mesh(new THREE.BoxGeometry(0.76, 0.38, 0.68), frameMat);
  seatBox.name = 'seatBox';
  seatBox.position.set(0, 0.25, 0.04);
  throne.add(seatBox);
  const seatPanel = new THREE.Mesh(new THREE.BoxGeometry(0.58, 0.22, 0.012), frameDarkMat);
  seatPanel.name = 'seatPanel';
  seatPanel.position.set(0, 0.25, 0.385);
  throne.add(seatPanel);
  const seatMedallion = new THREE.Mesh(new THREE.OctahedronGeometry(0.07, 0), goldMat);
  seatMedallion.name = 'seatMedallion';
  seatMedallion.position.set(0, 0.25, 0.392);
  seatMedallion.scale.set(1, 1, 0.25);
  throne.add(seatMedallion);
  const seatTrim = new THREE.Mesh(new THREE.BoxGeometry(0.78, 0.028, 0.025), goldMat);
  seatTrim.name = 'seatTrim';
  seatTrim.position.set(0, 0.429, 0.375);
  throne.add(seatTrim);
  const seatTrimLow = new THREE.Mesh(new THREE.BoxGeometry(0.78, 0.022, 0.025), goldMat);
  seatTrimLow.name = 'seatTrimLow';
  seatTrimLow.position.set(0, 0.081, 0.375);
  throne.add(seatTrimLow);
  const seatCushion = new THREE.Mesh(extrude([[0.335, 0.2508], [0.2907, 0.295], [-0.2907, 0.295], [-0.335, 0.2508], [-0.335, -0.2508], [-0.2907, -0.295], [0.2907, -0.295], [0.335, -0.2508]], 0.03, [], [0.035, 0.035, 1]), velvetMat);
  seatCushion.name = 'seatCushion';
  seatCushion.position.set(0, 0.49, 0.05);
  seatCushion.rotation.set(deg(-90), 0, 0);
  throne.add(seatCushion);
  const tassel = new THREE.Mesh(coneGeo, goldMat);
  tassel.name = 'tassel';
  tassel.position.set(-0.35, 0.42, 0.38);
  throne.add(tassel);
  const tassel2 = new THREE.Mesh(coneGeo, goldMat);
  tassel2.name = 'tassel';
  tassel2.position.set(0.35, 0.42, 0.38);
  throne.add(tassel2);
  const armPanel = new THREE.Mesh(boxGeo3, frameMat);
  armPanel.name = 'armPanel';
  armPanel.position.set(-0.445, 0.37, 0.02);
  throne.add(armPanel);
  const armInlay = new THREE.Mesh(boxGeo4, frameDarkMat);
  armInlay.name = 'armInlay';
  armInlay.position.set(-0.511, 0.36, 0.03);
  throne.add(armInlay);
  const armMedallion = new THREE.Mesh(octahedronGeo, goldMat);
  armMedallion.name = 'armMedallion';
  armMedallion.position.set(-0.517, 0.36, 0.03);
  armMedallion.scale.set(0.25, 1, 1);
  throne.add(armMedallion);
  const armRest = new THREE.Mesh(boxGeo5, frameMat);
  armRest.name = 'armRest';
  armRest.position.set(-0.445, 0.705, 0.04);
  throne.add(armRest);
  const armTrim = new THREE.Mesh(boxGeo6, goldMat);
  armTrim.name = 'armTrim';
  armTrim.position.set(-0.445, 0.675, 0.04);
  throne.add(armTrim);
  const armPad = new THREE.Mesh(extrudeGeo, velvetMat);
  armPad.name = 'armPad';
  armPad.position.set(-0.445, 0.752, -0.02);
  armPad.rotation.set(deg(-90), 0, 0);
  throne.add(armPad);
  const orbCollar = new THREE.Mesh(cylinderGeo2, goldMat);
  orbCollar.name = 'orbCollar';
  orbCollar.position.set(-0.445, 0.75, 0.38);
  throne.add(orbCollar);
  const armOrb = new THREE.Mesh(sphereGeo, goldMat);
  armOrb.name = 'armOrb';
  armOrb.position.set(-0.445, 0.81, 0.38);
  throne.add(armOrb);
  const armPanel2 = new THREE.Mesh(boxGeo3, frameMat);
  armPanel2.name = 'armPanel';
  armPanel2.position.set(0.445, 0.37, 0.02);
  throne.add(armPanel2);
  const armInlay2 = new THREE.Mesh(boxGeo4, frameDarkMat);
  armInlay2.name = 'armInlay';
  armInlay2.position.set(0.511, 0.36, 0.03);
  throne.add(armInlay2);
  const armMedallion2 = new THREE.Mesh(octahedronGeo, goldMat);
  armMedallion2.name = 'armMedallion';
  armMedallion2.position.set(0.517, 0.36, 0.03);
  armMedallion2.scale.set(0.25, 1, 1);
  throne.add(armMedallion2);
  const armRest2 = new THREE.Mesh(boxGeo5, frameMat);
  armRest2.name = 'armRest';
  armRest2.position.set(0.445, 0.705, 0.04);
  throne.add(armRest2);
  const armTrim2 = new THREE.Mesh(boxGeo6, goldMat);
  armTrim2.name = 'armTrim';
  armTrim2.position.set(0.445, 0.675, 0.04);
  throne.add(armTrim2);
  const armPad2 = new THREE.Mesh(extrudeGeo, velvetMat);
  armPad2.name = 'armPad';
  armPad2.position.set(0.445, 0.752, -0.02);
  armPad2.rotation.set(deg(-90), 0, 0);
  throne.add(armPad2);
  const orbCollar2 = new THREE.Mesh(cylinderGeo2, goldMat);
  orbCollar2.name = 'orbCollar';
  orbCollar2.position.set(0.445, 0.75, 0.38);
  throne.add(orbCollar2);
  const armOrb2 = new THREE.Mesh(sphereGeo, goldMat);
  armOrb2.name = 'armOrb';
  armOrb2.position.set(0.445, 0.81, 0.38);
  throne.add(armOrb2);
  const back = new THREE.Mesh(extrude([[-0.45, 0], [0.45, 0], [0.45, 1.3], [0.436, 1.444], [0.3947, 1.5827], [0.3275, 1.7108], [0.2369, 1.8236], [0.1264, 1.917], [0, 1.9874], [-0.1264, 1.917], [-0.2369, 1.8236], [-0.3275, 1.7108], [-0.3947, 1.5827], [-0.436, 1.444], [-0.45, 1.3]], 0.1), frameMat);
  back.name = 'back';
  back.position.set(0, 0.06, -0.35);
  throne.add(back);
  const backFrame = new THREE.Mesh(extrude([[-0.45, 0], [0.45, 0], [0.45, 1.3], [0.4421, 1.4083], [0.4187, 1.5143], [0.3802, 1.6159], [0.3275, 1.7108], [0.2616, 1.7971], [0.1839, 1.873], [0.0961, 1.9369], [0, 1.9874], [-0.0961, 1.9369], [-0.1839, 1.873], [-0.2616, 1.7971], [-0.3275, 1.7108], [-0.3802, 1.6159], [-0.4187, 1.5143], [-0.4421, 1.4083], [-0.45, 1.3]], 0.024, [[[-0.395, 1.3], [-0.3881, 1.3974], [-0.3677, 1.4928], [-0.3341, 1.5845], [-0.288, 1.6705], [-0.2303, 1.7492], [-0.1621, 1.8191], [-0.0849, 1.8787], [0, 1.9269], [0.0849, 1.8787], [0.1621, 1.8191], [0.2303, 1.7492], [0.288, 1.6705], [0.3341, 1.5845], [0.3677, 1.4928], [0.3881, 1.3974], [0.395, 1.3], [0.395, 0.055], [-0.395, 0.055]]]), goldMat);
  backFrame.name = 'backFrame';
  backFrame.position.set(0, 0.06, -0.288);
  throne.add(backFrame);
  const backCushion = new THREE.Mesh(extrude([[-0.365, 0.445], [0.365, 0.445], [0.365, 1.3], [0.3587, 1.3914], [0.3399, 1.481], [0.3089, 1.5672], [0.2664, 1.6484], [0.2132, 1.7229], [0.1502, 1.7894], [0.0787, 1.8466], [0, 1.8935], [-0.0787, 1.8466], [-0.1502, 1.7894], [-0.2132, 1.7229], [-0.2664, 1.6484], [-0.3089, 1.5672], [-0.3399, 1.481], [-0.3587, 1.3914], [-0.365, 1.3]], 0.03, [], [0.02, 0.02, 1]), velvetMat);
  backCushion.name = 'backCushion';
  backCushion.position.set(0, 0.06, -0.265);
  throne.add(backCushion);
  const button = new THREE.Mesh(octahedronGeo2, goldMat);
  button.name = 'button';
  button.position.set(-0.2, 0.72, -0.229);
  button.scale.set(1, 1, 0.5);
  throne.add(button);
  const button2 = new THREE.Mesh(octahedronGeo2, goldMat);
  button2.name = 'button';
  button2.position.set(0, 0.72, -0.229);
  button2.scale.set(1, 1, 0.5);
  throne.add(button2);
  const button3 = new THREE.Mesh(octahedronGeo2, goldMat);
  button3.name = 'button';
  button3.position.set(0.2, 0.72, -0.229);
  button3.scale.set(1, 1, 0.5);
  throne.add(button3);
  const button4 = new THREE.Mesh(octahedronGeo2, goldMat);
  button4.name = 'button';
  button4.position.set(-0.1, 0.91, -0.229);
  button4.scale.set(1, 1, 0.5);
  throne.add(button4);
  const button5 = new THREE.Mesh(octahedronGeo2, goldMat);
  button5.name = 'button';
  button5.position.set(0.1, 0.91, -0.229);
  button5.scale.set(1, 1, 0.5);
  throne.add(button5);
  const button6 = new THREE.Mesh(octahedronGeo2, goldMat);
  button6.name = 'button';
  button6.position.set(-0.2, 1.1, -0.229);
  button6.scale.set(1, 1, 0.5);
  throne.add(button6);
  const button7 = new THREE.Mesh(octahedronGeo2, goldMat);
  button7.name = 'button';
  button7.position.set(0, 1.1, -0.229);
  button7.scale.set(1, 1, 0.5);
  throne.add(button7);
  const button8 = new THREE.Mesh(octahedronGeo2, goldMat);
  button8.name = 'button';
  button8.position.set(0.2, 1.1, -0.229);
  button8.scale.set(1, 1, 0.5);
  throne.add(button8);
  const button9 = new THREE.Mesh(octahedronGeo2, goldMat);
  button9.name = 'button';
  button9.position.set(-0.1, 1.29, -0.229);
  button9.scale.set(1, 1, 0.5);
  throne.add(button9);
  const button10 = new THREE.Mesh(octahedronGeo2, goldMat);
  button10.name = 'button';
  button10.position.set(0.1, 1.29, -0.229);
  button10.scale.set(1, 1, 0.5);
  throne.add(button10);
  const button11 = new THREE.Mesh(octahedronGeo2, goldMat);
  button11.name = 'button';
  button11.position.set(-0.2, 1.48, -0.229);
  button11.scale.set(1, 1, 0.5);
  throne.add(button11);
  const button12 = new THREE.Mesh(octahedronGeo2, goldMat);
  button12.name = 'button';
  button12.position.set(0, 1.48, -0.229);
  button12.scale.set(1, 1, 0.5);
  throne.add(button12);
  const button13 = new THREE.Mesh(octahedronGeo2, goldMat);
  button13.name = 'button';
  button13.position.set(0.2, 1.48, -0.229);
  button13.scale.set(1, 1, 0.5);
  throne.add(button13);
  const crownBase = new THREE.Mesh(new THREE.OctahedronGeometry(0.06, 0), goldMat);
  crownBase.name = 'crownBase';
  crownBase.position.set(0, 2.0374, -0.35);
  crownBase.scale.set(1.3, 0.6, 1);
  throne.add(crownBase);
  const crownBand = new THREE.Mesh(new THREE.CylinderGeometry(0.085, 0.07, 0.07, 8), goldMat);
  crownBand.name = 'crownBand';
  crownBand.position.set(0, 2.0824, -0.35);
  throne.add(crownBand);
  const crownPoint = new THREE.Mesh(coneGeo2, goldMat);
  crownPoint.name = 'crownPoint';
  crownPoint.position.set(0, 2.1474, -0.278);
  throne.add(crownPoint);
  const crownPoint2 = new THREE.Mesh(coneGeo2, goldMat);
  crownPoint2.name = 'crownPoint';
  crownPoint2.position.set(-0.0685, 2.1474, -0.3278);
  throne.add(crownPoint2);
  const crownPoint3 = new THREE.Mesh(coneGeo2, goldMat);
  crownPoint3.name = 'crownPoint';
  crownPoint3.position.set(-0.0423, 2.1474, -0.4082);
  throne.add(crownPoint3);
  const crownPoint4 = new THREE.Mesh(coneGeo2, goldMat);
  crownPoint4.name = 'crownPoint';
  crownPoint4.position.set(0.0423, 2.1474, -0.4082);
  throne.add(crownPoint4);
  const crownPoint5 = new THREE.Mesh(coneGeo2, goldMat);
  crownPoint5.name = 'crownPoint';
  crownPoint5.position.set(0.0685, 2.1474, -0.3278);
  throne.add(crownPoint5);
  const crownGem = new THREE.Mesh(new THREE.OctahedronGeometry(0.03, 0), gemMat);
  crownGem.name = 'crownGem';
  crownGem.position.set(0, 2.0824, -0.268);
  crownGem.scale.set(1, 1.2, 0.6);
  throne.add(crownGem);
  const backGem = new THREE.Mesh(new THREE.OctahedronGeometry(0.045, 0), gemMat);
  backGem.name = 'backGem';
  backGem.position.set(0, 1.76, -0.226);
  backGem.scale.set(1, 1.25, 0.5);
  throne.add(backGem);
  const backPost = new THREE.Mesh(boxGeo7, frameDarkMat);
  backPost.name = 'backPost';
  backPost.position.set(-0.49, 0.77, -0.35);
  throne.add(backPost);
  const postCap = new THREE.Mesh(boxGeo8, goldMat);
  postCap.name = 'postCap';
  postCap.position.set(-0.49, 1.495, -0.35);
  throne.add(postCap);
  const finial = new THREE.Mesh(sphereGeo2, goldMat);
  finial.name = 'finial';
  finial.position.set(-0.49, 1.565, -0.35);
  throne.add(finial);
  const finialSpike = new THREE.Mesh(coneGeo3, goldMat);
  finialSpike.name = 'finialSpike';
  finialSpike.position.set(-0.49, 1.645, -0.35);
  throne.add(finialSpike);
  const backPost2 = new THREE.Mesh(boxGeo7, frameDarkMat);
  backPost2.name = 'backPost';
  backPost2.position.set(0.49, 0.77, -0.35);
  throne.add(backPost2);
  const postCap2 = new THREE.Mesh(boxGeo8, goldMat);
  postCap2.name = 'postCap';
  postCap2.position.set(0.49, 1.495, -0.35);
  throne.add(postCap2);
  const finial2 = new THREE.Mesh(sphereGeo2, goldMat);
  finial2.name = 'finial';
  finial2.position.set(0.49, 1.565, -0.35);
  throne.add(finial2);
  const finialSpike2 = new THREE.Mesh(coneGeo3, goldMat);
  finialSpike2.name = 'finialSpike';
  finialSpike2.position.set(0.49, 1.645, -0.35);
  throne.add(finialSpike2);

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

export default createThrone;

Puanlar ve yorumlar

—
Henüz puan yok — ilk puanı sen ver.
5
0
4
0
3
0
2
0
1
0

Puan vermek ve yorum yapmak için giriş yap.

0 yorum

Henüz yorum yok. Bu modeli nasıl kullandığını ya da neyin daha iyi olabileceğini paylaş.

Benzer modeller

Aynı kategori ya da benzer etiketler