Codels
1124 三角面1.00 × 4.00 × 1.00 m

在代码中使用

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

export function createPillar() {
  const root = new THREE.Group();
  root.name = 'Pillar';

  // Materials
  const stoneMat = new THREE.MeshStandardMaterial({ name: 'stone', color: 0xc8bfae, roughness: 0.9, flatShading: true });
  const stone2Mat = new THREE.MeshStandardMaterial({ name: 'stone2', color: 0xb0a899, roughness: 0.92, flatShading: true });
  const stone3Mat = new THREE.MeshStandardMaterial({ name: 'stone3', color: 0x8c867a, roughness: 1, flatShading: true });

  // Shared geometries
  const cylinderGeo = new THREE.CylinderGeometry(0.13, 0.13, 0.66, 10);
  const cylinderGeo2 = new THREE.CylinderGeometry(0.11, 0.11, 0.5, 10);
  const torusGeo = new THREE.TorusGeometry(0.075, 0.025, 3, 8);
  const cylinderGeo3 = new THREE.CylinderGeometry(0.03, 0.03, 0.02, 6);

  // Parts
  const plinth = new THREE.Mesh(new THREE.BoxGeometry(1, 0.2, 1), stone2Mat);
  plinth.name = 'plinth';
  plinth.position.set(0, 0.1, 0);
  root.add(plinth);
  const baseDisc = new THREE.Mesh(new THREE.CylinderGeometry(0.43, 0.45, 0.08, 16), stoneMat);
  baseDisc.name = 'baseDisc';
  baseDisc.position.set(0, 0.24, 0);
  root.add(baseDisc);
  const lowerTorus = new THREE.Mesh(new THREE.TorusGeometry(0.38, 0.075, 4, 16), stoneMat);
  lowerTorus.name = 'lowerTorus';
  lowerTorus.position.set(0, 0.32, 0);
  lowerTorus.rotation.set(deg(90), 0, 0);
  root.add(lowerTorus);
  const scotia = new THREE.Mesh(new THREE.CylinderGeometry(0.33, 0.35, 0.08, 16), stone2Mat);
  scotia.name = 'scotia';
  scotia.position.set(0, 0.4, 0);
  root.add(scotia);
  const upperTorus = new THREE.Mesh(new THREE.TorusGeometry(0.34, 0.05, 4, 16), stoneMat);
  upperTorus.name = 'upperTorus';
  upperTorus.position.set(0, 0.46, 0);
  upperTorus.rotation.set(deg(90), 0, 0);
  root.add(upperTorus);
  const shaft = new THREE.Mesh(lathe([[0.33, 0], [0.3298, 0.9966], [0.313, 1.9932], [0.28, 3.02]], 16), stoneMat);
  shaft.name = 'shaft';
  shaft.position.set(0, 0.48, 0);
  root.add(shaft);
  const necking = new THREE.Mesh(new THREE.TorusGeometry(0.29, 0.035, 3, 16), stone2Mat);
  necking.name = 'necking';
  necking.position.set(0, 3.44, 0);
  necking.rotation.set(deg(90), 0, 0);
  root.add(necking);
  const echinus = new THREE.Mesh(new THREE.CylinderGeometry(0.4, 0.29, 0.16, 16), stoneMat);
  echinus.name = 'echinus';
  echinus.position.set(0, 3.58, 0);
  root.add(echinus);
  const volute = new THREE.Mesh(cylinderGeo, stoneMat);
  volute.name = 'volute';
  volute.position.set(-0.36, 3.7, 0);
  volute.rotation.set(deg(90), 0, 0);
  root.add(volute);
  const voluteWaist = new THREE.Mesh(cylinderGeo2, stone2Mat);
  voluteWaist.name = 'voluteWaist';
  voluteWaist.position.set(-0.36, 3.7, 0);
  voluteWaist.rotation.set(deg(90), 0, 0);
  root.add(voluteWaist);
  const scroll = new THREE.Mesh(torusGeo, stone2Mat);
  scroll.name = 'scroll';
  scroll.position.set(-0.36, 3.7, -0.33);
  root.add(scroll);
  const scrollEye = new THREE.Mesh(cylinderGeo3, stone3Mat);
  scrollEye.name = 'scrollEye';
  scrollEye.position.set(-0.36, 3.7, -0.335);
  scrollEye.rotation.set(deg(90), 0, 0);
  root.add(scrollEye);
  const scroll2 = new THREE.Mesh(torusGeo, stone2Mat);
  scroll2.name = 'scroll';
  scroll2.position.set(-0.36, 3.7, 0.33);
  root.add(scroll2);
  const scrollEye2 = new THREE.Mesh(cylinderGeo3, stone3Mat);
  scrollEye2.name = 'scrollEye';
  scrollEye2.position.set(-0.36, 3.7, 0.335);
  scrollEye2.rotation.set(deg(90), 0, 0);
  root.add(scrollEye2);
  const volute2 = new THREE.Mesh(cylinderGeo, stoneMat);
  volute2.name = 'volute';
  volute2.position.set(0.36, 3.7, 0);
  volute2.rotation.set(deg(90), 0, 0);
  root.add(volute2);
  const voluteWaist2 = new THREE.Mesh(cylinderGeo2, stone2Mat);
  voluteWaist2.name = 'voluteWaist';
  voluteWaist2.position.set(0.36, 3.7, 0);
  voluteWaist2.rotation.set(deg(90), 0, 0);
  root.add(voluteWaist2);
  const scroll3 = new THREE.Mesh(torusGeo, stone2Mat);
  scroll3.name = 'scroll';
  scroll3.position.set(0.36, 3.7, -0.33);
  root.add(scroll3);
  const scrollEye3 = new THREE.Mesh(cylinderGeo3, stone3Mat);
  scrollEye3.name = 'scrollEye';
  scrollEye3.position.set(0.36, 3.7, -0.335);
  scrollEye3.rotation.set(deg(90), 0, 0);
  root.add(scrollEye3);
  const scroll4 = new THREE.Mesh(torusGeo, stone2Mat);
  scroll4.name = 'scroll';
  scroll4.position.set(0.36, 3.7, 0.33);
  root.add(scroll4);
  const scrollEye4 = new THREE.Mesh(cylinderGeo3, stone3Mat);
  scrollEye4.name = 'scrollEye';
  scrollEye4.position.set(0.36, 3.7, 0.335);
  scrollEye4.rotation.set(deg(90), 0, 0);
  root.add(scrollEye4);
  const voluteBand = new THREE.Mesh(new THREE.BoxGeometry(0.9, 0.06, 0.66), stone2Mat);
  voluteBand.name = 'voluteBand';
  voluteBand.position.set(0, 3.8, 0);
  root.add(voluteBand);
  const abacus = new THREE.Mesh(new THREE.BoxGeometry(0.98, 0.1, 0.98), stoneMat);
  abacus.name = 'abacus';
  abacus.position.set(0, 3.95, 0);
  root.add(abacus);

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

export default createPillar;

评分与评论

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

登录后即可评分和评论。

0 条评论

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

相关模型

同一分类或相似标签