Codels
760 三角面1.52 × 3.67 × 1.76 m

在代码中使用

在编辑器中改编
自包含的 ES 模块,仅依赖 three。调用工厂函数,然后把返回的 group 添加到场景中。
/**
 * Energy Pylon — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 760 · Size (W × H × D): 1.52 × 3.67 × 1.76 m
 *
 * Usage:
 *   import { createPylon } from './pylon.js';
 *   
 *   const model = createPylon();
 *   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 createPylon() {
  const root = new THREE.Group();
  root.name = 'Pylon';

  // Materials
  const shellMat = new THREE.MeshStandardMaterial({ name: 'shell', color: 0xd0d6de, roughness: 0.45, metalness: 0.3, flatShading: true });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x2f343c, roughness: 0.6, metalness: 0.4, flatShading: true });
  const metalMat = new THREE.MeshStandardMaterial({ name: 'metal', color: 0x7d858f, roughness: 0.4, metalness: 0.6, flatShading: true });
  const glowMat = new THREE.MeshStandardMaterial({ name: 'glow', color: 0x9b6bff, roughness: 0.4, emissive: 0x9b6bff, emissiveIntensity: 1.3, flatShading: true });
  const crystalMat = new THREE.MeshStandardMaterial({ name: 'crystal', color: 0xb490ff, roughness: 0.15, emissive: 0x9b6bff, emissiveIntensity: 1.3, flatShading: true });
  const auraMat = new THREE.MeshStandardMaterial({ name: 'aura', color: 0x9b6bff, roughness: 0.2, emissive: 0x9b6bff, emissiveIntensity: 0.7, transparent: true, opacity: 0.3, flatShading: true });

  // Shared geometries
  const extrudeGeo = extrude([[0, 0], [0.32, 0], [0.34, 0.3], [0.16, 1.7425], [0, 2.05]], 0.1);
  const extrudeGeo2 = extrude([[0, 0.08], [0.176, 0.08], [0.187, 0.35], [0.088, 1.6482], [0, 1.925]], 0.14);
  const boxGeo = new THREE.BoxGeometry(0.04, 0.9225, 0.05);
  const boxGeo2 = new THREE.BoxGeometry(0.26, 0.42, 0.26);
  const boxGeo3 = new THREE.BoxGeometry(0.04, 0.3, 0.16);
  const boxGeo4 = new THREE.BoxGeometry(0.12, 0.06, 0.3);
  const cylinderGeo = new THREE.CylinderGeometry(0.055, 0.07, 0.3845, 5);
  const cylinderGeo2 = new THREE.CylinderGeometry(0.03, 0.055, 0.6327, 5);
  const sphereGeo = new THREE.SphereGeometry(0.05, 6, 4);

  // Parts
  const baseSlab = new THREE.Mesh(new THREE.CylinderGeometry(0.78, 0.88, 0.2, 6), darkMat);
  baseSlab.name = 'baseSlab';
  baseSlab.position.set(0, 0.1, 0);
  root.add(baseSlab);
  const baseStep = new THREE.Mesh(new THREE.CylinderGeometry(0.6, 0.7, 0.18, 6), shellMat);
  baseStep.name = 'baseStep';
  baseStep.position.set(0, 0.29, 0);
  root.add(baseStep);
  const baseRing = new THREE.Mesh(new THREE.TorusGeometry(0.62, 0.035, 3, 6), glowMat);
  baseRing.name = 'baseRing';
  baseRing.position.set(0, 0.39, 0);
  baseRing.rotation.set(deg(90), 0, deg(30));
  root.add(baseRing);
  const collarLow = new THREE.Mesh(new THREE.CylinderGeometry(0.42, 0.48, 0.14, 6), darkMat);
  collarLow.name = 'collarLow';
  collarLow.position.set(0, 0.45, 0);
  root.add(collarLow);
  const column = new THREE.Mesh(new THREE.CylinderGeometry(0.24, 0.34, 2.05, 6), shellMat);
  column.name = 'column';
  column.position.set(0, 1.525, 0);
  root.add(column);
  const midBand = new THREE.Mesh(new THREE.CylinderGeometry(0.3, 0.3, 0.1, 6), darkMat);
  midBand.name = 'midBand';
  midBand.position.set(0, 1.575, 0);
  root.add(midBand);
  const fin1 = new THREE.Group();
  fin1.name = 'fin1';
  fin1.position.set(0, 0.5, 0);
  fin1.rotation.set(0, deg(90), 0);
  root.add(fin1);
  const finPlate = new THREE.Mesh(extrudeGeo, shellMat);
  finPlate.name = 'finPlate';
  finPlate.position.set(0.2, 0, 0);
  fin1.add(finPlate);
  const finCore = new THREE.Mesh(extrudeGeo2, darkMat);
  finCore.name = 'finCore';
  finCore.position.set(0.2, 0, 0);
  fin1.add(finCore);
  const finLight = new THREE.Mesh(boxGeo, glowMat);
  finLight.name = 'finLight';
  finLight.position.set(0.5, 0.656, 0);
  finLight.rotation.set(0, 0, deg(6));
  fin1.add(finLight);
  const fin2 = new THREE.Group();
  fin2.name = 'fin2';
  fin2.position.set(0, 0.5, 0);
  fin2.rotation.set(0, deg(210), 0);
  root.add(fin2);
  const finPlate2 = new THREE.Mesh(extrudeGeo, shellMat);
  finPlate2.name = 'finPlate';
  finPlate2.position.set(0.2, 0, 0);
  fin2.add(finPlate2);
  const finCore2 = new THREE.Mesh(extrudeGeo2, darkMat);
  finCore2.name = 'finCore';
  finCore2.position.set(0.2, 0, 0);
  fin2.add(finCore2);
  const finLight2 = new THREE.Mesh(boxGeo, glowMat);
  finLight2.name = 'finLight';
  finLight2.position.set(0.5, 0.656, 0);
  finLight2.rotation.set(0, 0, deg(6));
  fin2.add(finLight2);
  const fin3 = new THREE.Group();
  fin3.name = 'fin3';
  fin3.position.set(0, 0.5, 0);
  fin3.rotation.set(0, deg(330), 0);
  root.add(fin3);
  const finPlate3 = new THREE.Mesh(extrudeGeo, shellMat);
  finPlate3.name = 'finPlate';
  finPlate3.position.set(0.2, 0, 0);
  fin3.add(finPlate3);
  const finCore3 = new THREE.Mesh(extrudeGeo2, darkMat);
  finCore3.name = 'finCore';
  finCore3.position.set(0.2, 0, 0);
  fin3.add(finCore3);
  const finLight3 = new THREE.Mesh(boxGeo, glowMat);
  finLight3.name = 'finLight';
  finLight3.position.set(0.5, 0.656, 0);
  finLight3.rotation.set(0, 0, deg(6));
  fin3.add(finLight3);
  const emitterL = new THREE.Group();
  emitterL.name = 'emitterL';
  emitterL.position.set(-0.4, 1.4025, 0);
  root.add(emitterL);
  const emitterBody = new THREE.Mesh(boxGeo2, darkMat);
  emitterBody.name = 'emitterBody';
  emitterL.add(emitterBody);
  const emitterFace = new THREE.Mesh(boxGeo3, glowMat);
  emitterFace.name = 'emitterFace';
  emitterFace.position.set(-0.14, 0, 0);
  emitterL.add(emitterFace);
  const box22 = new THREE.Mesh(boxGeo4, metalMat);
  box22.position.set(0, 0.24, 0);
  emitterL.add(box22);
  const emitterR = new THREE.Group();
  emitterR.name = 'emitterR';
  emitterR.position.set(0.4, 1.4025, 0);
  root.add(emitterR);
  const emitterBody2 = new THREE.Mesh(boxGeo2, darkMat);
  emitterBody2.name = 'emitterBody';
  emitterR.add(emitterBody2);
  const emitterFace2 = new THREE.Mesh(boxGeo3, glowMat);
  emitterFace2.name = 'emitterFace';
  emitterFace2.position.set(0.14, 0, 0);
  emitterR.add(emitterFace2);
  const box26 = new THREE.Mesh(boxGeo4, metalMat);
  box26.position.set(0, 0.24, 0);
  emitterR.add(box26);
  const crownCollar = new THREE.Mesh(new THREE.CylinderGeometry(0.4, 0.26, 0.24, 6), darkMat);
  crownCollar.name = 'crownCollar';
  crownCollar.position.set(0, 2.67, 0);
  root.add(crownCollar);
  const crownSocket = new THREE.Mesh(new THREE.CylinderGeometry(0.12, 0.2, 0.18, 6), metalMat);
  crownSocket.name = 'crownSocket';
  crownSocket.position.set(0, 2.88, 0);
  root.add(crownSocket);
  const claw1 = new THREE.Mesh(cylinderGeo, shellMat);
  claw1.name = 'claw1';
  claw1.position.set(0.205, 2.865, 0.3551);
  claw1.rotation.set(deg(28.7939), deg(-4.1705), deg(-16.146));
  root.add(claw1);
  const clawTip1 = new THREE.Mesh(cylinderGeo2, darkMat);
  clawTip1.name = 'clawTip1';
  clawTip1.position.set(0.19, 3.26, 0.3291);
  clawTip1.rotation.set(deg(-21.2971), deg(-2.2841), deg(12.1045));
  root.add(clawTip1);
  const clawLight1 = new THREE.Mesh(sphereGeo, glowMat);
  clawLight1.name = 'clawLight1';
  clawLight1.position.set(0.13, 3.52, 0.2252);
  root.add(clawLight1);
  const claw2 = new THREE.Mesh(cylinderGeo, shellMat);
  claw2.name = 'claw2';
  claw2.position.set(0.205, 2.865, -0.3551);
  claw2.rotation.set(deg(-28.7939), deg(4.1705), deg(-16.146));
  root.add(claw2);
  const clawTip2 = new THREE.Mesh(cylinderGeo2, darkMat);
  clawTip2.name = 'clawTip2';
  clawTip2.position.set(0.19, 3.26, -0.3291);
  clawTip2.rotation.set(deg(21.2971), deg(2.2841), deg(12.1045));
  root.add(clawTip2);
  const clawLight2 = new THREE.Mesh(sphereGeo, glowMat);
  clawLight2.name = 'clawLight2';
  clawLight2.position.set(0.13, 3.52, -0.2252);
  root.add(clawLight2);
  const claw3 = new THREE.Mesh(cylinderGeo, shellMat);
  claw3.name = 'claw3';
  claw3.position.set(-0.41, 2.865, 0);
  claw3.rotation.set(0, 0, deg(33.6901));
  root.add(claw3);
  const clawTip3 = new THREE.Mesh(cylinderGeo2, darkMat);
  clawTip3.name = 'clawTip3';
  clawTip3.position.set(-0.38, 3.26, 0);
  clawTip3.rotation.set(0, 0, deg(-24.7751));
  root.add(clawTip3);
  const clawLight3 = new THREE.Mesh(sphereGeo, glowMat);
  clawLight3.name = 'clawLight3';
  clawLight3.position.set(-0.26, 3.52, 0);
  root.add(clawLight3);
  const crystal = new THREE.Mesh(new THREE.OctahedronGeometry(0.3, 0), crystalMat);
  crystal.name = 'crystal';
  crystal.position.set(0, 3.1, 0);
  crystal.rotation.set(0, deg(20), 0);
  crystal.scale.set(1, 1.9, 1);
  root.add(crystal);
  const aura = new THREE.Mesh(new THREE.IcosahedronGeometry(0.46, 0), auraMat);
  aura.name = 'aura';
  aura.position.set(0, 3.1, 0);
  aura.scale.set(1, 1.4, 1);
  root.add(aura);
  const haloRing = new THREE.Mesh(new THREE.TorusGeometry(0.62, 0.02, 3, 16), glowMat);
  haloRing.name = 'haloRing';
  haloRing.position.set(0, 3.05, 0);
  haloRing.rotation.set(deg(78), 0, deg(12));
  root.add(haloRing);

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

export default createPylon;

评分与评论

—
暂无评分,快来抢先评分吧。
5
0
4
0
3
0
2
0
1
0

登录后即可评分和评论。

0 条评论

暂无评论。分享一下你是如何使用这个模型的,或者有哪些可以改进的地方。

相关模型

同一分类或相似标签