Codels
496 tris0,08 × 0,09 × 0,08 m

Utiliser dans le code

Remixer dans l’éditeur
Module ES autonome — ne dépend que de three. Appelez la fonction factory et ajoutez le groupe à votre scène.
/**
 * Apple — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 496 · Size (W × H × D): 0.08 × 0.09 × 0.08 m
 *
 * Usage:
 *   import { createApple } from './apple.js';
 *   
 *   const model = createApple();
 *   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);
}

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

  // Materials
  const skinMat = new THREE.MeshStandardMaterial({ name: 'skin', color: 0xd42a2a, roughness: 0.45 });
  const stemMat = new THREE.MeshStandardMaterial({ name: 'stem', color: 0x6b4527, roughness: 0.9, flatShading: true });
  const leafMat = new THREE.MeshStandardMaterial({ name: 'leaf', color: 0x4f9a2e, roughness: 0.7, flatShading: true });

  // Parts
  const apple = new THREE.Group();
  apple.name = 'apple';
  apple.scale.setScalar(0.08);
  root.add(apple);
  const body = new THREE.Mesh(lathe([[0, 0.07], [0.08, 0.035], [0.18, 0], [0.3, 0.025], [0.4, 0.095], [0.47, 0.21], [0.5, 0.35], [0.495, 0.49], [0.46, 0.62], [0.39, 0.73], [0.29, 0.8], [0.18, 0.82], [0.09, 0.79], [0, 0.71]], 14), skinMat);
  body.name = 'body';
  apple.add(body);
  const stem = new THREE.Mesh(tube([[0, 0.68, 0], [0.01, 0.82, 0], [0.04, 0.95, 0.01], [0.08, 1.02, 0.02]], 0.028, 8, 5), stemMat);
  stem.name = 'stem';
  apple.add(stem);
  const leaf = new THREE.Mesh(extrude([[0, 0], [0.06, 0.0615], [0.12, 0.0986], [0.18, 0.1176], [0.24, 0.1176], [0.3, 0.0986], [0.36, 0.0615], [0.42, 0], [0.36, -0.0615], [0.3, -0.0986], [0.24, -0.1176], [0.18, -0.1176], [0.12, -0.0986], [0.06, -0.0615]], 0.012), leafMat);
  leaf.name = 'leaf';
  leaf.position.set(0.03, 0.86, 0.01);
  leaf.rotation.set(deg(-70), deg(-35), deg(25));
  apple.add(leaf);

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

export default createApple;

Notes et commentaires

—
Aucune note pour l’instant — soyez le premier.
5
0
4
0
3
0
2
0
1
0

Connectez-vous pour noter et commenter.

0 commentaire

Aucun commentaire pour l’instant. Dites comment vous avez utilisé ce modèle ou ce qui pourrait être amélioré.

Modèles similaires

Même catégorie ou étiquettes proches