Codels
1,3 mil tris0,07 × 0,12 × 0,07 m
Módulo ES autocontido — depende apenas do three. Chame a factory e adicione o grupo à sua cena.
/**
 * Cupcake — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,302 · Size (W × H × D): 0.07 × 0.12 × 0.07 m
 *
 * Usage:
 *   import { createCupcake } from './cupcake.js';
 *   
 *   const model = createCupcake();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

// Tube along a smooth curve through the given points.
function tube(path, radius, tubularSegments, radialSegments, closed = false) {
  const curve = new THREE.CatmullRomCurve3(path.map(([x, y, z]) => new THREE.Vector3(x, y, z)), closed);
  return new THREE.TubeGeometry(curve, tubularSegments, radius, radialSegments, closed);
}

export function createCupcake() {
  const root = new THREE.Group();
  root.name = 'Cupcake';

  // Materials
  const sprinkle1Mat = new THREE.MeshStandardMaterial({ name: 'sprinkle1', color: 0xff5a5f, roughness: 0.4, flatShading: true });
  const sprinkle2Mat = new THREE.MeshStandardMaterial({ name: 'sprinkle2', color: 0xffd23f, roughness: 0.4, flatShading: true });
  const sprinkle3Mat = new THREE.MeshStandardMaterial({ name: 'sprinkle3', color: 0x3ec1d3, roughness: 0.4, flatShading: true });
  const sprinkle4Mat = new THREE.MeshStandardMaterial({ name: 'sprinkle4', color: 0x7ed957, roughness: 0.4, flatShading: true });
  const wrapAMat = new THREE.MeshStandardMaterial({ name: 'wrapA', color: 0x6cc3d5, roughness: 0.7, flatShading: true });
  const wrapBMat = new THREE.MeshStandardMaterial({ name: 'wrapB', color: 0x9fd8e4, roughness: 0.7, flatShading: true });
  const cakeMat = new THREE.MeshStandardMaterial({ name: 'cake', color: 0xc98a4b, roughness: 0.85, flatShading: true });
  const frostingMat = new THREE.MeshStandardMaterial({ name: 'frosting', color: 0xf7a8c8, roughness: 0.45 });
  const cherryMat = new THREE.MeshStandardMaterial({ name: 'cherry', color: 0xd3182f, roughness: 0.2 });
  const stemMat = new THREE.MeshStandardMaterial({ name: 'stem', color: 0x5b8a2a, roughness: 0.8, flatShading: true });

  // Shared geometries
  const cylinderGeo = new THREE.CylinderGeometry(0.033, 0.026, 0.042, 12);
  const boxGeo = new THREE.BoxGeometry(0.0065, 0.0018, 0.0018);

  // Parts
  const wrapperA = new THREE.Mesh(cylinderGeo, wrapAMat);
  wrapperA.name = 'wrapperA';
  wrapperA.position.set(0, 0.021, 0);
  root.add(wrapperA);
  const wrapperB = new THREE.Mesh(cylinderGeo, wrapBMat);
  wrapperB.name = 'wrapperB';
  wrapperB.position.set(0, 0.021, 0);
  wrapperB.rotation.set(0, deg(15), 0);
  root.add(wrapperB);
  const muffinTop = new THREE.Mesh(new THREE.SphereGeometry(0.037, 14, 4, 0, Math.PI * 2, 0, Math.PI / 2), cakeMat);
  muffinTop.name = 'muffinTop';
  muffinTop.position.set(0, 0.04, 0);
  muffinTop.scale.set(1, 0.55, 1);
  root.add(muffinTop);
  const frostingBase = new THREE.Mesh(new THREE.SphereGeometry(0.031, 14, 5, 0, Math.PI * 2, 0, Math.PI / 2), frostingMat);
  frostingBase.name = 'frostingBase';
  frostingBase.position.set(0, 0.048, 0);
  frostingBase.scale.set(1, 0.42, 1);
  root.add(frostingBase);
  const frostingSwirl = new THREE.Mesh(tube([[0, 0.054, 0.028], [0.0099, 0.0547, 0.0255], [0.0181, 0.0554, 0.0198], [0.0235, 0.056, 0.0116], [0.0255, 0.0567, 0.0022], [0.024, 0.0574, -0.0071], [0.0194, 0.0581, -0.0149], [0.0123, 0.0588, -0.0204], [0.004, 0.0595, -0.0229], [-0.0045, 0.0601, -0.0222], [-0.0119, 0.0608, -0.0186], [-0.0174, 0.0615, -0.0126], [-0.0202, 0.0622, -0.0053], [-0.0202, 0.0629, 0.0023], [-0.0174, 0.0635, 0.0092], [-0.0125, 0.0642, 0.0145], [-0.0062, 0.0649, 0.0175], [0.0005, 0.0656, 0.0179], [0.0068, 0.0663, 0.016], [0.0117, 0.067, 0.012], [0.0147, 0.0676, 0.0067], [0.0156, 0.0683, 0.0009], [0.0143, 0.069, -0.0046], [0.0112, 0.0697, -0.0091], [0.0068, 0.0704, -0.012], [0.0019, 0.071, -0.0131], [-0.0029, 0.0717, -0.0123], [-0.0068, 0.0724, -0.0099], [-0.0095, 0.0731, -0.0065], [-0.0106, 0.0738, -0.0025], [-0.0102, 0.0745, 0.0015], [-0.0084, 0.0751, 0.0048], [-0.0058, 0.0758, 0.007], [-0.0026, 0.0765, 0.0081], [0.0005, 0.0772, 0.0079], [0.003, 0.0779, 0.0067], [0.0048, 0.0785, 0.0047], [0.0057, 0.0792, 0.0024], [0.0055, 0.0799, 0.0002], [0.0047, 0.0806, -0.0017], [0.0033, 0.0813, -0.0029], [0.0018, 0.082, -0.0033], [0.0004, 0.0826, -0.0032], [-0.0007, 0.0833, -0.0025], [-0.0012, 0.084, -0.0016]], 0.0085, 40, 6), frostingMat);
  frostingSwirl.name = 'frostingSwirl';
  root.add(frostingSwirl);
  const frostingSwirlEnd = new THREE.Mesh(new THREE.SphereGeometry(0.0085, 8, 6), frostingMat);
  frostingSwirlEnd.name = 'frostingSwirlEnd';
  frostingSwirlEnd.position.set(0, 0.054, 0.028);
  root.add(frostingSwirlEnd);
  const frostingPeak = new THREE.Mesh(new THREE.ConeGeometry(0.0075, 0.016, 7), frostingMat);
  frostingPeak.name = 'frostingPeak';
  frostingPeak.position.set(0.0008, 0.09, -0.0016);
  frostingPeak.rotation.set(0, 0, deg(-14));
  root.add(frostingPeak);
  const cherry = new THREE.Mesh(new THREE.SphereGeometry(0.0095, 9, 7), cherryMat);
  cherry.name = 'cherry';
  cherry.position.set(0.003, 0.096, 0.002);
  root.add(cherry);
  const cherryStem = new THREE.Mesh(tube([[0.003, 0.103, 0.002], [0.005, 0.112, 0], [0.011, 0.12, -0.004]], 0.0011, 6, 3), stemMat);
  cherryStem.name = 'cherryStem';
  root.add(cherryStem);
  const sprinkle1 = new THREE.Mesh(boxGeo, sprinkle1Mat);
  sprinkle1.name = 'sprinkle1';
  sprinkle1.position.set(0.0099, 0.076, -0.0175);
  sprinkle1.rotation.set(deg(-134.0535), deg(21.4385), deg(-172.7806));
  root.add(sprinkle1);
  const sprinkle2 = new THREE.Mesh(boxGeo, sprinkle2Mat);
  sprinkle2.name = 'sprinkle2';
  sprinkle2.position.set(0.005, 0.0651, -0.0292);
  sprinkle2.rotation.set(deg(-137.5921), deg(7.2817), deg(130.8012));
  root.add(sprinkle2);
  const sprinkle3 = new THREE.Mesh(boxGeo, sprinkle3Mat);
  sprinkle3.name = 'sprinkle3';
  sprinkle3.position.set(0.0292, 0.0617, 0.0144);
  sprinkle3.rotation.set(deg(-63.8838), deg(41.8383), deg(133.3985));
  root.add(sprinkle3);
  const sprinkle4 = new THREE.Mesh(boxGeo, sprinkle4Mat);
  sprinkle4.name = 'sprinkle4';
  sprinkle4.position.set(0.0028, 0.0767, -0.0193);
  sprinkle4.rotation.set(deg(-137.7212), deg(6.0722), deg(98.0803));
  root.add(sprinkle4);
  const sprinkle5 = new THREE.Mesh(boxGeo, sprinkle1Mat);
  sprinkle5.name = 'sprinkle5';
  sprinkle5.position.set(-0.0139, 0.0808, 0.0079);
  sprinkle5.rotation.set(deg(-61.3491), deg(-40.3324), deg(16.7184));
  root.add(sprinkle5);
  const sprinkle6 = new THREE.Mesh(boxGeo, sprinkle2Mat);
  sprinkle6.name = 'sprinkle6';
  sprinkle6.position.set(-0.0104, 0.0781, -0.0152);
  sprinkle6.rotation.set(deg(-132.5268), deg(-24.806), deg(80.1691));
  root.add(sprinkle6);
  const sprinkle7 = new THREE.Mesh(boxGeo, sprinkle3Mat);
  sprinkle7.name = 'sprinkle7';
  sprinkle7.position.set(0.016, 0.0754, -0.0131);
  sprinkle7.rotation.set(deg(-125.1205), deg(35.1287), deg(65.2226));
  root.add(sprinkle7);
  const sprinkle8 = new THREE.Mesh(boxGeo, sprinkle4Mat);
  sprinkle8.name = 'sprinkle8';
  sprinkle8.position.set(-0.0084, 0.0706, 0.0234);
  sprinkle8.rotation.set(deg(-43.6985), deg(-14.4647), deg(48.256));
  root.add(sprinkle8);
  const sprinkle9 = new THREE.Mesh(boxGeo, sprinkle1Mat);
  sprinkle9.name = 'sprinkle9';
  sprinkle9.position.set(-0.0139, 0.0808, 0.0079);
  sprinkle9.rotation.set(deg(-61.3491), deg(-40.3324), deg(27.282));
  root.add(sprinkle9);
  const sprinkle10 = new THREE.Mesh(boxGeo, sprinkle2Mat);
  sprinkle10.name = 'sprinkle10';
  sprinkle10.position.set(-0.0043, 0.0774, -0.0185);
  sprinkle10.rotation.set(deg(-137.2617), deg(-9.6921), deg(105.7752));
  root.add(sprinkle10);
  const sprinkle11 = new THREE.Mesh(boxGeo, sprinkle3Mat);
  sprinkle11.name = 'sprinkle11';
  sprinkle11.position.set(-0.0058, 0.0658, -0.0284);
  sprinkle11.rotation.set(deg(-137.4391), deg(-8.4885), deg(-18.1519));
  root.add(sprinkle11);
  const sprinkle12 = new THREE.Mesh(boxGeo, sprinkle4Mat);
  sprinkle12.name = 'sprinkle12';
  sprinkle12.position.set(-0.0147, 0.0788, -0.01);
  sprinkle12.rotation.set(deg(-122.0943), deg(-37.848), deg(-26.082));
  root.add(sprinkle12);
  const sprinkle13 = new THREE.Mesh(boxGeo, sprinkle1Mat);
  sprinkle13.name = 'sprinkle13';
  sprinkle13.position.set(-0.0154, 0.0665, -0.0239);
  sprinkle13.rotation.set(deg(-133.0677), deg(-23.6942), deg(-29.394));
  root.add(sprinkle13);
  const sprinkle14 = new THREE.Mesh(boxGeo, sprinkle2Mat);
  sprinkle14.name = 'sprinkle14';
  sprinkle14.position.set(0.0007, 0.0713, 0.0243);
  sprinkle14.rotation.set(deg(-41.9988), deg(1.2162), deg(178.9627));
  root.add(sprinkle14);
  const sprinkle15 = new THREE.Mesh(boxGeo, sprinkle3Mat);
  sprinkle15.name = 'sprinkle15';
  sprinkle15.position.set(-0.0058, 0.0658, -0.0284);
  sprinkle15.rotation.set(deg(-137.4391), deg(-8.4885), deg(-7.0051));
  root.add(sprinkle15);
  const sprinkle16 = new THREE.Mesh(boxGeo, sprinkle4Mat);
  sprinkle16.name = 'sprinkle16';
  sprinkle16.position.set(-0.0164, 0.0801, 0.0024);
  sprinkle16.rotation.set(deg(-81.0144), deg(-47.3688), deg(15.9791));
  root.add(sprinkle16);
  const sprinkle17 = new THREE.Mesh(boxGeo, sprinkle1Mat);
  sprinkle17.name = 'sprinkle17';
  sprinkle17.position.set(-0.023, 0.0692, 0.0122);
  sprinkle17.rotation.set(deg(-62.5924), deg(-41.1014), deg(151.7553));
  root.add(sprinkle17);
  const sprinkle18 = new THREE.Mesh(boxGeo, sprinkle2Mat);
  sprinkle18.name = 'sprinkle18';
  sprinkle18.position.set(-0.0154, 0.0665, -0.0239);
  sprinkle18.rotation.set(deg(-133.0677), deg(-23.6942), deg(17.9173));
  root.add(sprinkle18);
  const sprinkle19 = new THREE.Mesh(boxGeo, sprinkle3Mat);
  sprinkle19.name = 'sprinkle19';
  sprinkle19.position.set(0.005, 0.0651, -0.0292);
  sprinkle19.rotation.set(deg(-137.5921), deg(7.2817), deg(175.0894));
  root.add(sprinkle19);
  const sprinkle20 = new THREE.Mesh(boxGeo, sprinkle4Mat);
  sprinkle20.name = 'sprinkle20';
  sprinkle20.position.set(0.0028, 0.0767, -0.0193);
  sprinkle20.rotation.set(deg(-137.7212), deg(6.0722), deg(173.8078));
  root.add(sprinkle20);
  const sprinkle21 = new THREE.Mesh(boxGeo, sprinkle1Mat);
  sprinkle21.name = 'sprinkle21';
  sprinkle21.position.set(0.0092, 0.072, 0.0218);
  sprinkle21.rotation.set(deg(-44.3354), deg(16.8186), deg(151.8061));
  root.add(sprinkle21);
  const sprinkle22 = new THREE.Mesh(boxGeo, sprinkle2Mat);
  sprinkle22.name = 'sprinkle22';
  sprinkle22.position.set(0.016, 0.0754, -0.0131);
  sprinkle22.rotation.set(deg(-125.1205), deg(35.1287), deg(87.868));
  root.add(sprinkle22);

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

export default createCupcake;

Avaliações e comentários

—
Nenhuma avaliação ainda — seja o primeiro.
5
0
4
0
3
0
2
0
1
0

Entre para avaliar e comentar.

0 comentário

Nenhum comentário ainda. Conte como você usou este modelo ou o que poderia melhorar.

Modelos relacionados

Mesma categoria ou tags parecidas