Codels
1482 三角面0.85 × 0.79 × 0.88 m

在代码中使用

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

// 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 createMushroomMonster() {
  const root = new THREE.Group();
  root.name = 'MushroomMonster';

  // Materials
  const capMat = new THREE.MeshStandardMaterial({ name: 'cap', color: 0xd9443a, roughness: 0.55, flatShading: true });
  const spotMat = new THREE.MeshStandardMaterial({ name: 'spot', color: 0xfbf6ec, roughness: 0.6, flatShading: true });
  const stemMat = new THREE.MeshStandardMaterial({ name: 'stem', color: 0xf3e3c6, roughness: 0.8, flatShading: true });
  const gillMat = new THREE.MeshStandardMaterial({ name: 'gill', color: 0xc7baa2, roughness: 0.85, flatShading: true });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x21171a, roughness: 0.35, flatShading: true });
  const bootMat = new THREE.MeshStandardMaterial({ name: 'boot', color: 0x6b4430, roughness: 0.8, flatShading: true });

  // Shared geometries
  const cylinderGeo = new THREE.CylinderGeometry(0.045, 0.05, 0.08, 7);
  const sphereGeo = new THREE.SphereGeometry(0.07, 8, 5);
  const sphereGeo2 = new THREE.SphereGeometry(0.052, 8, 6);
  const sphereGeo3 = new THREE.SphereGeometry(0.024, 6, 4);
  const boxGeo = new THREE.BoxGeometry(0.008, 0.008, 0.004);
  const boxGeo2 = new THREE.BoxGeometry(0.085, 0.022, 0.02);
  const capsuleGeo = new THREE.CapsuleGeometry(0.04, 0.07, 2, 6);
  const boxGeo3 = new THREE.BoxGeometry(0.006, 0.008, 0.15);
  const sphereGeo4 = new THREE.SphereGeometry(0.07, 8, 3);
  const sphereGeo5 = new THREE.SphereGeometry(0.045, 8, 3);

  // Parts
  const legL = new THREE.Group();
  legL.name = 'legL';
  legL.position.set(0.09, 0.14, 0);
  root.add(legL);
  const legLStub = new THREE.Mesh(cylinderGeo, stemMat);
  legLStub.name = 'legLStub';
  legLStub.position.set(0, -0.04, 0);
  legL.add(legLStub);
  const bootL = new THREE.Mesh(sphereGeo, bootMat);
  bootL.name = 'bootL';
  bootL.position.set(0, -0.098, 0.025);
  bootL.scale.set(0.95, 0.6, 1.3);
  legL.add(bootL);
  const legR = new THREE.Group();
  legR.name = 'legR';
  legR.position.set(-0.09, 0.14, 0);
  root.add(legR);
  const legRStub = new THREE.Mesh(cylinderGeo, stemMat);
  legRStub.name = 'legRStub';
  legRStub.position.set(0, -0.04, 0);
  legR.add(legRStub);
  const bootR = new THREE.Mesh(sphereGeo, bootMat);
  bootR.name = 'bootR';
  bootR.position.set(0, -0.098, 0.025);
  bootR.scale.set(0.95, 0.6, 1.3);
  legR.add(bootR);
  const body = new THREE.Group();
  body.name = 'body';
  root.add(body);
  const stemBody = new THREE.Mesh(lathe([[0, 0], [0.17, 0], [0.21, 0.06], [0.225, 0.16], [0.205, 0.27], [0.165, 0.35], [0, 0.37]], 12), stemMat);
  stemBody.name = 'stemBody';
  stemBody.position.set(0, 0.1, 0);
  body.add(stemBody);
  const eyeL = new THREE.Mesh(sphereGeo2, spotMat);
  eyeL.name = 'eyeL';
  eyeL.position.set(0.075, 0.3, 0.1924);
  eyeL.rotation.set(0, deg(18), 0);
  eyeL.scale.set(0.9, 0.85, 0.45);
  body.add(eyeL);
  const pupilL = new THREE.Mesh(sphereGeo3, darkMat);
  pupilL.name = 'pupilL';
  pupilL.position.set(0.063, 0.292, 0.2124);
  pupilL.scale.set(1, 1.1, 0.5);
  body.add(pupilL);
  const eyeShineL = new THREE.Mesh(boxGeo, spotMat);
  eyeShineL.name = 'eyeShineL';
  eyeShineL.position.set(0.069, 0.308, 0.2244);
  body.add(eyeShineL);
  const browL = new THREE.Mesh(boxGeo2, darkMat);
  browL.name = 'browL';
  browL.position.set(0.08, 0.358, 0.1951);
  browL.rotation.set(0, deg(18), deg(24));
  body.add(browL);
  const eyeR = new THREE.Mesh(sphereGeo2, spotMat);
  eyeR.name = 'eyeR';
  eyeR.position.set(-0.075, 0.3, 0.1924);
  eyeR.rotation.set(0, deg(-18), 0);
  eyeR.scale.set(0.9, 0.85, 0.45);
  body.add(eyeR);
  const pupilR = new THREE.Mesh(sphereGeo3, darkMat);
  pupilR.name = 'pupilR';
  pupilR.position.set(-0.063, 0.292, 0.2124);
  pupilR.scale.set(1, 1.1, 0.5);
  body.add(pupilR);
  const eyeShineR = new THREE.Mesh(boxGeo, spotMat);
  eyeShineR.name = 'eyeShineR';
  eyeShineR.position.set(-0.069, 0.308, 0.2244);
  body.add(eyeShineR);
  const browR = new THREE.Mesh(boxGeo2, darkMat);
  browR.name = 'browR';
  browR.position.set(-0.08, 0.358, 0.1951);
  browR.rotation.set(0, deg(-18), deg(-24));
  body.add(browR);
  const frown = new THREE.Mesh(tube([[-0.06, 0.19, 0.2055], [-0.025, 0.214, 0.2195], [0.025, 0.214, 0.2195], [0.06, 0.19, 0.2055]], 0.009, 10, 4), darkMat);
  frown.name = 'frown';
  body.add(frown);
  const tooth = new THREE.Mesh(new THREE.ConeGeometry(0.014, 0.03, 4), spotMat);
  tooth.name = 'tooth';
  tooth.position.set(0.022, 0.202, 0.2215);
  tooth.rotation.set(deg(180), 0, 0);
  body.add(tooth);
  const armL = new THREE.Group();
  armL.name = 'armL';
  armL.position.set(0.205, 0.3, 0.01);
  armL.rotation.set(deg(-20), 0, deg(35));
  root.add(armL);
  const armLNub = new THREE.Mesh(capsuleGeo, stemMat);
  armLNub.name = 'armLNub';
  armLNub.position.set(0, -0.06, 0);
  armL.add(armLNub);
  const armR = new THREE.Group();
  armR.name = 'armR';
  armR.position.set(-0.205, 0.3, 0.01);
  armR.rotation.set(deg(-20), 0, deg(-35));
  root.add(armR);
  const armRNub = new THREE.Mesh(capsuleGeo, stemMat);
  armRNub.name = 'armRNub';
  armRNub.position.set(0, -0.06, 0);
  armR.add(armRNub);
  const cap = new THREE.Group();
  cap.name = 'cap';
  cap.position.set(0, 0.44, -0.01);
  cap.rotation.set(deg(-6), 0, deg(7));
  root.add(cap);
  const capDome = new THREE.Mesh(lathe([[0, 0], [0.4, 0.015], [0.44, 0.06], [0.43, 0.13], [0.37, 0.22], [0.27, 0.3], [0.14, 0.345], [0, 0.36]], 14), capMat);
  capDome.name = 'capDome';
  capDome.position.set(0, -0.03, 0);
  cap.add(capDome);
  const gills = new THREE.Mesh(new THREE.CircleGeometry(0.395, 14), gillMat);
  gills.name = 'gills';
  gills.position.set(0, -0.032, 0);
  gills.rotation.set(deg(90), 0, 0);
  cap.add(gills);
  const gillLine = new THREE.Mesh(boxGeo3, stemMat);
  gillLine.name = 'gillLine';
  gillLine.position.set(0, -0.036, 0.26);
  cap.add(gillLine);
  const gillLine2 = new THREE.Mesh(boxGeo3, stemMat);
  gillLine2.name = 'gillLine';
  gillLine2.position.set(0.1128, -0.036, 0.2343);
  gillLine2.rotation.set(0, deg(25.7143), 0);
  cap.add(gillLine2);
  const gillLine3 = new THREE.Mesh(boxGeo3, stemMat);
  gillLine3.name = 'gillLine';
  gillLine3.position.set(0.2033, -0.036, 0.1621);
  gillLine3.rotation.set(0, deg(51.4286), 0);
  cap.add(gillLine3);
  const gillLine4 = new THREE.Mesh(boxGeo3, stemMat);
  gillLine4.name = 'gillLine';
  gillLine4.position.set(0.2535, -0.036, 0.0579);
  gillLine4.rotation.set(0, deg(77.1429), 0);
  cap.add(gillLine4);
  const gillLine5 = new THREE.Mesh(boxGeo3, stemMat);
  gillLine5.name = 'gillLine';
  gillLine5.position.set(0.2535, -0.036, -0.0579);
  gillLine5.rotation.set(0, deg(102.8571), 0);
  cap.add(gillLine5);
  const gillLine6 = new THREE.Mesh(boxGeo3, stemMat);
  gillLine6.name = 'gillLine';
  gillLine6.position.set(0.2033, -0.036, -0.1621);
  gillLine6.rotation.set(0, deg(128.5714), 0);
  cap.add(gillLine6);
  const gillLine7 = new THREE.Mesh(boxGeo3, stemMat);
  gillLine7.name = 'gillLine';
  gillLine7.position.set(0.1128, -0.036, -0.2343);
  gillLine7.rotation.set(0, deg(154.2857), 0);
  cap.add(gillLine7);
  const gillLine8 = new THREE.Mesh(boxGeo3, stemMat);
  gillLine8.name = 'gillLine';
  gillLine8.position.set(0, -0.036, -0.26);
  gillLine8.rotation.set(0, deg(180), 0);
  cap.add(gillLine8);
  const gillLine9 = new THREE.Mesh(boxGeo3, stemMat);
  gillLine9.name = 'gillLine';
  gillLine9.position.set(-0.1128, -0.036, -0.2343);
  gillLine9.rotation.set(0, deg(205.7143), 0);
  cap.add(gillLine9);
  const gillLine10 = new THREE.Mesh(boxGeo3, stemMat);
  gillLine10.name = 'gillLine';
  gillLine10.position.set(-0.2033, -0.036, -0.1621);
  gillLine10.rotation.set(0, deg(231.4286), 0);
  cap.add(gillLine10);
  const gillLine11 = new THREE.Mesh(boxGeo3, stemMat);
  gillLine11.name = 'gillLine';
  gillLine11.position.set(-0.2535, -0.036, -0.0579);
  gillLine11.rotation.set(0, deg(257.1429), 0);
  cap.add(gillLine11);
  const gillLine12 = new THREE.Mesh(boxGeo3, stemMat);
  gillLine12.name = 'gillLine';
  gillLine12.position.set(-0.2535, -0.036, 0.0579);
  gillLine12.rotation.set(0, deg(282.8571), 0);
  cap.add(gillLine12);
  const gillLine13 = new THREE.Mesh(boxGeo3, stemMat);
  gillLine13.name = 'gillLine';
  gillLine13.position.set(-0.2033, -0.036, 0.1621);
  gillLine13.rotation.set(0, deg(308.5714), 0);
  cap.add(gillLine13);
  const gillLine14 = new THREE.Mesh(boxGeo3, stemMat);
  gillLine14.name = 'gillLine';
  gillLine14.position.set(-0.1128, -0.036, 0.2343);
  gillLine14.rotation.set(0, deg(334.2857), 0);
  cap.add(gillLine14);
  const capSpot1 = new THREE.Mesh(new THREE.SphereGeometry(0.09, 8, 3), spotMat);
  capSpot1.name = 'capSpot1';
  capSpot1.position.set(-0.0001, 0.324, -0.0006);
  capSpot1.rotation.set(deg(6.1137), deg(-0.0744), deg(-1.3929));
  capSpot1.scale.set(1, 0.3, 1);
  cap.add(capSpot1);
  const capSpot2 = new THREE.Mesh(sphereGeo4, spotMat);
  capSpot2.name = 'capSpot2';
  capSpot2.position.set(0.2182, 0.272, 0.0991);
  capSpot2.rotation.set(deg(8.3495), deg(-1.291), deg(-17.5497));
  capSpot2.scale.set(1, 0.3, 1);
  cap.add(capSpot2);
  const capSpot3 = new THREE.Mesh(new THREE.SphereGeometry(0.065, 8, 3), spotMat);
  capSpot3.name = 'capSpot3';
  capSpot3.position.set(-0.1982, 0.2723, 0.1391);
  capSpot3.rotation.set(deg(8.3495), deg(1.291), deg(17.5497));
  capSpot3.scale.set(1, 0.3, 1);
  cap.add(capSpot3);
  const capSpot4 = new THREE.Mesh(sphereGeo4, spotMat);
  capSpot4.name = 'capSpot4';
  capSpot4.position.set(0.0592, 0.2464, 0.2763);
  capSpot4.rotation.set(deg(38.2571), deg(-2.8221), deg(-8.1246));
  capSpot4.scale.set(1, 0.3, 1);
  cap.add(capSpot4);
  const capSpot5 = new THREE.Mesh(new THREE.SphereGeometry(0.06, 8, 3), spotMat);
  capSpot5.name = 'capSpot5';
  capSpot5.position.set(-0.1187, 0.2757, -0.1984);
  capSpot5.rotation.set(deg(-15.1708), deg(-1.61), deg(12.046));
  capSpot5.scale.set(1, 0.3, 1);
  cap.add(capSpot5);
  const capSpot6 = new THREE.Mesh(new THREE.SphereGeometry(0.055, 8, 3), spotMat);
  capSpot6.name = 'capSpot6';
  capSpot6.position.set(0.1987, 0.2663, -0.1684);
  capSpot6.rotation.set(deg(-15.1708), deg(1.61), deg(-12.046));
  capSpot6.scale.set(1, 0.3, 1);
  cap.add(capSpot6);
  const capSpot7 = new THREE.Mesh(sphereGeo5, spotMat);
  capSpot7.name = 'capSpot7';
  capSpot7.position.set(0.3262, 0.2106, -0.02);
  capSpot7.rotation.set(0, 0, deg(-39.3714));
  capSpot7.scale.set(1, 0.3, 1);
  cap.add(capSpot7);
  const capSpot8 = new THREE.Mesh(new THREE.SphereGeometry(0.05, 8, 3), spotMat);
  capSpot8.name = 'capSpot8';
  capSpot8.position.set(-0.3262, 0.2106, -0.04);
  capSpot8.rotation.set(0, 0, deg(39.3714));
  capSpot8.scale.set(1, 0.3, 1);
  cap.add(capSpot8);
  const capSpot9 = new THREE.Mesh(sphereGeo5, spotMat);
  capSpot9.name = 'capSpot9';
  capSpot9.position.set(-0.0789, 0.1743, 0.3551);
  capSpot9.rotation.set(deg(55.2304), deg(5.6653), deg(10.8064));
  capSpot9.scale.set(1, 0.3, 1);
  cap.add(capSpot9);

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

export default createMushroomMonster;

评分与评论

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

登录后即可评分和评论。

0 条评论

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

相关模型

同一分类或相似标签