Codels
632 треуг.0,15 × 0,14 × 0,04 m

Использовать в коде

Ремикс в редакторе
Самодостаточный ES-модуль — зависит только от three. Вызовите фабрику и добавьте группу в сцену.
/**
 * Watermelon — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 632 · Size (W × H × D): 0.15 × 0.14 × 0.04 m
 *
 * Usage:
 *   import { createWatermelon } from './watermelon.js';
 *   
 *   const model = createWatermelon();
 *   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 createWatermelon() {
  const root = new THREE.Group();
  root.name = 'Watermelon';

  // Materials
  const skinMat = new THREE.MeshStandardMaterial({ name: 'skin', color: 0x2a7a30, roughness: 0.55, flatShading: true });
  const rindMat = new THREE.MeshStandardMaterial({ name: 'rind', color: 0xe8f2c4, roughness: 0.7, flatShading: true });
  const fleshMat = new THREE.MeshStandardMaterial({ name: 'flesh', color: 0xf2414f, roughness: 0.6, flatShading: true });
  const seedMat = new THREE.MeshStandardMaterial({ name: 'seed', color: 0x241a14, roughness: 0.4, flatShading: true });

  // Shared geometries
  const sphereGeo = new THREE.SphereGeometry(0.0049, 5, 4);

  // Parts
  const slice = new THREE.Group();
  slice.name = 'slice';
  slice.position.set(0, 0.14, 0);
  root.add(slice);
  const flesh = new THREE.Mesh(extrude([[-0.0594, -0.095], [-0.0484, -0.101], [-0.0368, -0.1058], [-0.0248, -0.1092], [-0.0125, -0.1113], [0, -0.112], [0.0125, -0.1113], [0.0248, -0.1092], [0.0368, -0.1058], [0.0484, -0.101], [0.0594, -0.095], [0, 0]], 0.0392), fleshMat);
  flesh.name = 'flesh';
  slice.add(flesh);
  const rind = new THREE.Mesh(extrude([[-0.0683, -0.1092], [-0.0557, -0.1162], [-0.0424, -0.1216], [-0.0285, -0.1256], [-0.0144, -0.128], [0, -0.1288], [0.0144, -0.128], [0.0285, -0.1256], [0.0424, -0.1216], [0.0557, -0.1162], [0.0683, -0.1092], [0.0594, -0.095], [0.0484, -0.101], [0.0368, -0.1058], [0.0248, -0.1092], [0.0125, -0.1113], [0, -0.112], [-0.0125, -0.1113], [-0.0248, -0.1092], [-0.0368, -0.1058], [-0.0484, -0.101], [-0.0594, -0.095]], 0.0392), rindMat);
  rind.name = 'rind';
  slice.add(rind);
  const skin = new THREE.Mesh(extrude([[-0.0742, -0.1187], [-0.0605, -0.1263], [-0.046, -0.1322], [-0.031, -0.1365], [-0.0156, -0.1391], [0, -0.14], [0.0156, -0.1391], [0.031, -0.1365], [0.046, -0.1322], [0.0605, -0.1263], [0.0742, -0.1187], [0.0683, -0.1092], [0.0557, -0.1162], [0.0424, -0.1216], [0.0285, -0.1256], [0.0144, -0.128], [0, -0.1288], [-0.0144, -0.128], [-0.0285, -0.1256], [-0.0424, -0.1216], [-0.0557, -0.1162], [-0.0683, -0.1092]], 0.0392), skinMat);
  skin.name = 'skin';
  slice.add(skin);
  const seedFront1 = new THREE.Mesh(sphereGeo, seedMat);
  seedFront1.name = 'seedFront1';
  seedFront1.position.set(-0.0127, -0.0848, 0.0196);
  seedFront1.rotation.set(0, 0, deg(-8.4986));
  seedFront1.scale.set(0.6, 1, 0.45);
  slice.add(seedFront1);
  const seedFront2 = new THREE.Mesh(sphereGeo, seedMat);
  seedFront2.name = 'seedFront2';
  seedFront2.position.set(-0.0151, -0.0481, 0.0196);
  seedFront2.rotation.set(0, 0, deg(-17.4397));
  seedFront2.scale.set(0.6, 1, 0.45);
  slice.add(seedFront2);
  const seedFront3 = new THREE.Mesh(sphereGeo, seedMat);
  seedFront3.name = 'seedFront3';
  seedFront3.position.set(0.0003, -0.051, 0.0196);
  seedFront3.rotation.set(0, 0, deg(0.3567));
  seedFront3.scale.set(0.6, 1, 0.45);
  slice.add(seedFront3);
  const seedFront4 = new THREE.Mesh(sphereGeo, seedMat);
  seedFront4.name = 'seedFront4';
  seedFront4.position.set(0.0133, -0.041, 0.0196);
  seedFront4.rotation.set(0, 0, deg(17.9805));
  seedFront4.scale.set(0.6, 1, 0.45);
  slice.add(seedFront4);
  const seedFront5 = new THREE.Mesh(sphereGeo, seedMat);
  seedFront5.name = 'seedFront5';
  seedFront5.position.set(0.0112, -0.0696, 0.0196);
  seedFront5.rotation.set(0, 0, deg(9.1749));
  seedFront5.scale.set(0.6, 1, 0.45);
  slice.add(seedFront5);
  const seedFront6 = new THREE.Mesh(sphereGeo, seedMat);
  seedFront6.name = 'seedFront6';
  seedFront6.position.set(-0.0088, -0.0774, 0.0196);
  seedFront6.rotation.set(0, 0, deg(-6.4885));
  seedFront6.scale.set(0.6, 1, 0.45);
  slice.add(seedFront6);
  const seedFront7 = new THREE.Mesh(sphereGeo, seedMat);
  seedFront7.name = 'seedFront7';
  seedFront7.position.set(0.0242, -0.0722, 0.0196);
  seedFront7.rotation.set(0, 0, deg(18.5106));
  seedFront7.scale.set(0.6, 1, 0.45);
  slice.add(seedFront7);
  const seedBack1 = new THREE.Mesh(sphereGeo, seedMat);
  seedBack1.name = 'seedBack1';
  seedBack1.position.set(-0.0127, -0.0848, -0.0196);
  seedBack1.rotation.set(0, 0, deg(-8.4986));
  seedBack1.scale.set(0.6, 1, 0.45);
  slice.add(seedBack1);
  const seedBack2 = new THREE.Mesh(sphereGeo, seedMat);
  seedBack2.name = 'seedBack2';
  seedBack2.position.set(-0.0151, -0.0481, -0.0196);
  seedBack2.rotation.set(0, 0, deg(-17.4397));
  seedBack2.scale.set(0.6, 1, 0.45);
  slice.add(seedBack2);
  const seedBack3 = new THREE.Mesh(sphereGeo, seedMat);
  seedBack3.name = 'seedBack3';
  seedBack3.position.set(0.0003, -0.051, -0.0196);
  seedBack3.rotation.set(0, 0, deg(0.3567));
  seedBack3.scale.set(0.6, 1, 0.45);
  slice.add(seedBack3);
  const seedBack4 = new THREE.Mesh(sphereGeo, seedMat);
  seedBack4.name = 'seedBack4';
  seedBack4.position.set(0.0133, -0.041, -0.0196);
  seedBack4.rotation.set(0, 0, deg(17.9805));
  seedBack4.scale.set(0.6, 1, 0.45);
  slice.add(seedBack4);
  const seedBack5 = new THREE.Mesh(sphereGeo, seedMat);
  seedBack5.name = 'seedBack5';
  seedBack5.position.set(0.0112, -0.0696, -0.0196);
  seedBack5.rotation.set(0, 0, deg(9.1749));
  seedBack5.scale.set(0.6, 1, 0.45);
  slice.add(seedBack5);
  const seedBack6 = new THREE.Mesh(sphereGeo, seedMat);
  seedBack6.name = 'seedBack6';
  seedBack6.position.set(-0.0088, -0.0774, -0.0196);
  seedBack6.rotation.set(0, 0, deg(-6.4885));
  seedBack6.scale.set(0.6, 1, 0.45);
  slice.add(seedBack6);
  const seedBack7 = new THREE.Mesh(sphereGeo, seedMat);
  seedBack7.name = 'seedBack7';
  seedBack7.position.set(0.0242, -0.0722, -0.0196);
  seedBack7.rotation.set(0, 0, deg(18.5106));
  seedBack7.scale.set(0.6, 1, 0.45);
  slice.add(seedBack7);

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

export default createWatermelon;

Оценки и комментарии

—
Оценок пока нет — будьте первым.
5
0
4
0
3
0
2
0
1
0

Войдите, чтобы ставить оценки и оставлять комментарии.

0 комментариев

Комментариев пока нет. Расскажите, как вы использовали эту модель или что можно улучшить.

Похожие модели

Та же категория или похожие теги