Codels
620 tris0,82 × 1,89 × 0,71 m
Módulo ES autocontido — depende apenas do three. Chame a factory e adicione o grupo à sua cena.
/**
 * Sunflower — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 620 · Size (W × H × D): 0.82 × 1.89 × 0.70 m
 *
 * Usage:
 *   import { createSunflower } from './sunflower.js';
 *   
 *   const model = createSunflower();
 *   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);
}

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

  // Materials
  const stemMat = new THREE.MeshStandardMaterial({ name: 'stem', color: 0x4f8a35, roughness: 0.85, flatShading: true });
  const leafMat = new THREE.MeshStandardMaterial({ name: 'leaf', color: 0x4f9136, roughness: 0.85, flatShading: true });
  const petalMat = new THREE.MeshStandardMaterial({ name: 'petal', color: 0xf6c22b, roughness: 0.7, flatShading: true });
  const petalDeepMat = new THREE.MeshStandardMaterial({ name: 'petalDeep', color: 0xe28d28, roughness: 0.7, flatShading: true });
  const discMat = new THREE.MeshStandardMaterial({ name: 'disc', color: 0x5b3a1e, roughness: 0.9, flatShading: true });
  const seedsMat = new THREE.MeshStandardMaterial({ name: 'seeds', color: 0x3b2614, roughness: 0.95, flatShading: true });

  // Shared geometries
  const octahedronGeo = new THREE.OctahedronGeometry(1, 0);

  // Parts
  const stem = new THREE.Mesh(tube([[0, 0, 0], [0.01, 0.63, -0.01], [-0.005, 1.26, 0], [0, 1.4895, 0.0594], [0, 1.557, 0.1485]], 0.0246, 12, 5), stemMat);
  stem.name = 'stem';
  root.add(stem);
  const leaf1 = new THREE.Mesh(extrude([[0, 0], [0.0895, 0.1295], [0.2486, 0.1541], [0.4077, 0.0925], [0.4972, 0], [0.4077, -0.0925], [0.2486, -0.1541], [0.0895, -0.1295]], 0.01), leafMat);
  leaf1.name = 'leaf1';
  leaf1.position.set(0, 0.34, 0);
  leaf1.rotation.set(deg(94.7281), deg(-23.647), deg(11.6513));
  root.add(leaf1);
  const leaf2 = new THREE.Mesh(extrude([[0, 0], [0.0827, 0.1197], [0.2298, 0.1425], [0.3768, 0.0855], [0.4595, 0], [0.3768, -0.0855], [0.2298, -0.1425], [0.0827, -0.1197]], 0.01), leafMat);
  leaf2.name = 'leaf2';
  leaf2.position.set(0, 0.5467, 0);
  leaf2.rotation.set(deg(78.138), deg(23.4358), deg(-152.1611));
  root.add(leaf2);
  const leaf3 = new THREE.Mesh(extrude([[0, 0], [0.0759, 0.1099], [0.2109, 0.1308], [0.3459, 0.0785], [0.4219, 0], [0.3459, -0.0785], [0.2109, -0.1308], [0.0759, -0.1099]], 0.01), leafMat);
  leaf3.name = 'leaf3';
  leaf3.position.set(0, 0.7533, 0);
  leaf3.rotation.set(deg(109.6158), deg(-5.3579), deg(75.3182));
  root.add(leaf3);
  const leaf4 = new THREE.Mesh(extrude([[0, 0], [0.0692, 0.1], [0.1921, 0.1191], [0.315, 0.0715], [0.3842, 0], [0.315, -0.0715], [0.1921, -0.1191], [0.0692, -0.1]], 0.01), leafMat);
  leaf4.name = 'leaf4';
  leaf4.position.set(0, 0.96, 0);
  leaf4.rotation.set(deg(58.3634), deg(5.7108), deg(-99.1749));
  root.add(leaf4);
  const leaf5 = new THREE.Mesh(extrude([[0, 0], [0.0624, 0.0902], [0.1733, 0.1074], [0.2842, 0.0645], [0.3465, 0], [0.2842, -0.0645], [0.1733, -0.1074], [0.0624, -0.0902]], 0.01), leafMat);
  leaf5.name = 'leaf5';
  leaf5.position.set(0, 1.1667, 0);
  leaf5.rotation.set(deg(114.8541), deg(13.7648), deg(117.1882));
  root.add(leaf5);
  const head = new THREE.Group();
  head.name = 'head';
  head.position.set(0, 1.5894, 0.1809);
  head.rotation.set(deg(22), 0, 0);
  root.add(head);
  const calyx = new THREE.Mesh(new THREE.ConeGeometry(0.2106, 0.1485, 10), stemMat);
  calyx.name = 'calyx';
  calyx.position.set(0, 0, -0.081);
  calyx.rotation.set(deg(-90), 0, 0);
  head.add(calyx);
  const disc = new THREE.Mesh(new THREE.CylinderGeometry(0.1674, 0.1836, 0.0486, 12), discMat);
  disc.name = 'disc';
  disc.rotation.set(deg(90), 0, 0);
  head.add(disc);
  const seeds = new THREE.Mesh(new THREE.SphereGeometry(0.1512, 12, 2, 0, Math.PI * 2, 0, Math.PI / 2), seedsMat);
  seeds.name = 'seeds';
  seeds.position.set(0, 0, 0.0216);
  seeds.rotation.set(deg(90), 0, 0);
  seeds.scale.set(1, 0.32, 1);
  head.add(seeds);
  const petalA1 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA1.name = 'petalA1';
  petalA1.position.set(0.2543, 0.0109, 0.0296);
  petalA1.rotation.set(deg(0.7817), deg(-17.728), deg(2.5658));
  petalA1.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA1);
  const petalA2 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA2.name = 'petalA2';
  petalA2.position.set(0.2375, 0.0917, 0.0296);
  petalA2.rotation.set(deg(6.5757), deg(-16.5178), deg(22.0701));
  petalA2.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA2);
  const petalA3 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA3.name = 'petalA3';
  petalA3.position.set(0.1798, 0.1802, 0.0296);
  petalA3.rotation.set(deg(12.7616), deg(-12.4333), deg(46.4505));
  petalA3.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA3);
  const petalA4 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA4.name = 'petalA4';
  petalA4.position.set(0.0903, 0.238, 0.0296);
  petalA4.rotation.set(deg(16.6556), deg(-6.2094), deg(70.123));
  petalA4.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA4);
  const petalA5 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA5.name = 'petalA5';
  petalA5.position.set(0.0031, 0.2546, 0.0296);
  petalA5.rotation.set(deg(17.7434), deg(-0.2134), deg(89.333));
  petalA5.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA5);
  const petalA6 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA6.name = 'petalA6';
  petalA6.position.set(-0.1073, 0.2308, 0.0296);
  petalA6.rotation.set(deg(16.1812), deg(7.3824), deg(113.8842));
  petalA6.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA6);
  const petalA7 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA7.name = 'petalA7';
  petalA7.position.set(-0.1775, 0.1825, 0.0296);
  petalA7.rotation.set(deg(12.9221), deg(12.2662), deg(132.799));
  petalA7.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA7);
  const petalA8 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA8.name = 'petalA8';
  petalA8.position.set(-0.2361, 0.0952, 0.0296);
  petalA8.rotation.set(deg(6.8237), deg(16.4193), deg(157.0551));
  petalA8.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA8);
  const petalA9 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA9.name = 'petalA9';
  petalA9.position.set(-0.2544, -0.0088, 0.0296);
  petalA9.rotation.set(deg(-0.6363), deg(17.7336), deg(-177.9119));
  petalA9.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA9);
  const petalA10 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA10.name = 'petalA10';
  petalA10.position.set(-0.2339, -0.1005, 0.0296);
  petalA10.rotation.set(deg(-7.2002), deg(16.2614), deg(-155.7172));
  petalA10.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA10);
  const petalA11 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA11.name = 'petalA11';
  petalA11.position.set(-0.1782, -0.1818, 0.0296);
  petalA11.rotation.set(deg(-12.8757), deg(12.315), deg(-133.0173));
  petalA11.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA11);
  const petalA12 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA12.name = 'petalA12';
  petalA12.position.set(-0.102, -0.2332, 0.0296);
  petalA12.rotation.set(deg(-16.3401), deg(7.0156), deg(-112.6168));
  petalA12.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA12);
  const petalA13 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA13.name = 'petalA13';
  petalA13.position.set(0.0064, -0.2545, 0.0296);
  petalA13.rotation.set(deg(-17.7393), deg(-0.4422), deg(-88.6178));
  petalA13.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA13);
  const petalA14 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA14.name = 'petalA14';
  petalA14.position.set(0.0996, -0.2343, 0.0296);
  petalA14.rotation.set(deg(-16.4085), deg(-6.8502), deg(-67.9501));
  petalA14.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA14);
  const petalA15 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA15.name = 'petalA15';
  petalA15.position.set(0.1807, -0.1793, 0.0296);
  petalA15.rotation.set(deg(-12.7), deg(-12.4963), deg(-46.1648));
  petalA15.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA15);
  const petalA16 = new THREE.Mesh(octahedronGeo, petalMat);
  petalA16.name = 'petalA16';
  petalA16.position.set(0.2378, -0.0909, 0.0296);
  petalA16.rotation.set(deg(-6.5184), deg(-16.54), deg(-21.8684));
  petalA16.scale.set(0.0972, 0.0351, 0.0095);
  head.add(petalA16);
  const petalB1 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB1.name = 'petalB1';
  petalB1.position.set(0.238, 0.0571, -0.0038);
  petalB1.rotation.set(deg(2.0032), deg(-8.2939), deg(13.6292));
  petalB1.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB1);
  const petalB2 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB2.name = 'petalB2';
  petalB2.position.set(0.2077, 0.1295, -0.0038);
  petalB2.rotation.set(deg(4.5372), deg(-7.2317), deg(32.2268));
  petalB2.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB2);
  const petalB3 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB3.name = 'petalB3';
  petalB3.position.set(0.1392, 0.2013, -0.0038);
  petalB3.rotation.set(deg(7.0327), deg(-4.8408), deg(55.6261));
  petalB3.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB3);
  const petalB4 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB4.name = 'petalB4';
  petalB4.position.set(0.0571, 0.238, -0.0038);
  petalB4.rotation.set(deg(8.299), deg(-1.982), deg(76.6614));
  petalB4.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB4);
  const petalB5 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB5.name = 'petalB5';
  petalB5.position.set(-0.0452, 0.2406, -0.0038);
  petalB5.rotation.set(deg(8.3863), deg(1.5689), deg(100.5208));
  petalB5.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB5);
  const petalB6 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB6.name = 'petalB6';
  petalB6.position.set(-0.1325, 0.2058, -0.0038);
  petalB6.rotation.set(deg(7.1885), deg(4.6055), deg(122.4821));
  petalB6.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB6);
  const petalB7 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB7.name = 'petalB7';
  petalB7.position.set(-0.1977, 0.1443, -0.0038);
  petalB7.rotation.set(deg(5.0531), deg(6.8821), deg(143.5752));
  petalB7.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB7);
  const petalB8 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB8.name = 'petalB8';
  petalB8.position.set(-0.2381, 0.0569, -0.0038);
  petalB8.rotation.set(deg(1.9962), deg(8.2956), deg(166.419));
  petalB8.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB8);
  const petalB9 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB9.name = 'petalB9';
  petalB9.position.set(-0.2375, -0.0591, -0.0038);
  petalB9.rotation.set(deg(-2.075), deg(8.2764), deg(-165.8724));
  petalB9.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB9);
  const petalB10 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB10.name = 'petalB10';
  petalB10.position.set(-0.2081, -0.1289, -0.0038);
  petalB10.rotation.set(deg(-4.5168), deg(7.2444), deg(-147.935));
  petalB10.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB10);
  const petalB11 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB11.name = 'petalB11';
  petalB11.position.set(-0.1328, -0.2056, -0.0038);
  petalB11.rotation.set(deg(-7.1819), deg(4.6158), deg(-122.5637));
  petalB11.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB11);
  const petalB12 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB12.name = 'petalB12';
  petalB12.position.set(-0.0596, -0.2374, -0.0038);
  petalB12.rotation.set(deg(-8.2779), deg(2.0687), deg(-103.9343));
  petalB12.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB12);
  const petalB13 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB13.name = 'petalB13';
  petalB13.position.set(0.0584, -0.2377, -0.0038);
  petalB13.rotation.set(deg(-8.2878), deg(-2.0288), deg(-76.3402));
  petalB13.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB13);
  const petalB14 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB14.name = 'petalB14';
  petalB14.position.set(0.1354, -0.2039, -0.0038);
  petalB14.rotation.set(deg(-7.1235), deg(-4.7058), deg(-56.7169));
  petalB14.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB14);
  const petalB15 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB15.name = 'petalB15';
  petalB15.position.set(0.2072, -0.1303, -0.0038);
  petalB15.rotation.set(deg(-4.5651), deg(-7.2141), deg(-32.4492));
  petalB15.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB15);
  const petalB16 = new THREE.Mesh(octahedronGeo, petalDeepMat);
  petalB16.name = 'petalB16';
  petalB16.position.set(0.2416, -0.0394, -0.0038);
  petalB16.rotation.set(deg(-1.3847), deg(-8.4185), deg(-9.3756));
  petalB16.scale.set(0.0837, 0.0405, 0.0095);
  head.add(petalB16);

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

export default createSunflower;

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