Codels
1108 三角面0.15 × 0.08 × 0.15 m

在代码中使用

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

  // Materials
  const cupMat = new THREE.MeshStandardMaterial({ name: 'cup', color: 0xf3eee6, roughness: 0.25, flatShading: true });
  const coffeeMat = new THREE.MeshStandardMaterial({ name: 'coffee', color: 0xb97a4a, roughness: 0.2 });
  const artMat = new THREE.MeshStandardMaterial({ name: 'art', color: 0xf6ead8, roughness: 0.6, flatShading: true });

  // Parts
  const saucer = new THREE.Mesh(lathe([[0, 0], [0.045, 0], [0.066, 0.006], [0.076, 0.012], [0.074, 0.0145], [0.062, 0.0105], [0.036, 0.0075], [0, 0.0075]], 24), cupMat);
  saucer.name = 'saucer';
  root.add(saucer);
  const cup = new THREE.Mesh(lathe([[0, 0.0065], [0.025, 0.0065], [0.029, 0.0105], [0.033, 0.0175], [0.041, 0.0405], [0.0465, 0.0645], [0.049, 0.0805], [0.0475, 0.0833], [0.0448, 0.081], [0.0438, 0.0745], [0.036, 0.0485], [0.028, 0.0235], [0, 0.0205]], 20), cupMat);
  cup.name = 'cup';
  root.add(cup);
  const coffee = new THREE.Mesh(new THREE.CylinderGeometry(0.0438, 0.0438, 0.003, 20), coffeeMat);
  coffee.name = 'coffee';
  coffee.position.set(0, 0.071, 0);
  root.add(coffee);
  const latteArt = new THREE.Mesh(extrude([[0, 0.006], [0.0008, 0.0087], [0.0051, 0.0132], [0.0125, 0.0138], [0.0183, 0.0086], [0.0183, 0.0008], [0.0125, -0.0066], [0.0051, -0.0131], [0.0008, -0.0183], [0, -0.0204], [-0.0008, -0.0183], [-0.0051, -0.0131], [-0.0125, -0.0066], [-0.0183, 0.0008], [-0.0183, 0.0086], [-0.0125, 0.0138], [-0.0051, 0.0132], [-0.0008, 0.0087]], 0.0012), artMat);
  latteArt.name = 'latteArt';
  latteArt.position.set(0, 0.0731, 0.003);
  latteArt.rotation.set(deg(-90), 0, 0);
  root.add(latteArt);
  const handle = new THREE.Mesh(new THREE.TorusGeometry(0.0175, 0.0056, 6, 12, 3.6128), cupMat);
  handle.name = 'handle';
  handle.position.set(0.0445, 0.0485, 0);
  handle.rotation.set(0, 0, deg(-103.5));
  root.add(handle);

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

export default createCoffeeCup;

评分与评论

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

登录后即可评分和评论。

0 条评论

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

相关模型

同一分类或相似标签