Codels
1,7 mil tris4,91 × 9,62 × 4,91 m
Módulo ES autocontido — depende apenas do three. Chame a factory e adicione o grupo à sua cena.
/**
 * Retro Rocket — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,748 · Size (W × H × D): 4.91 × 9.62 × 4.91 m
 *
 * Usage:
 *   import { createRocket } from './rocket.js';
 *   
 *   const model = createRocket();
 *   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);
}

export function createRocket() {
  const root = new THREE.Group();
  root.name = 'Rocket';

  // Materials
  const bodyMat = new THREE.MeshStandardMaterial({ name: 'body', color: 0xece6d8, roughness: 0.4, metalness: 0.25, flatShading: true });
  const accentMat = new THREE.MeshStandardMaterial({ name: 'accent', color: 0xd8433a, roughness: 0.4, metalness: 0.2, flatShading: true });
  const glassMat = new THREE.MeshStandardMaterial({ name: 'glass', color: 0x2b3c52, roughness: 0.15, metalness: 0.3, emissive: 0x3c6d9c, emissiveIntensity: 0.35, flatShading: true });
  const metalMat = new THREE.MeshStandardMaterial({ name: 'metal', color: 0x4b5059, roughness: 0.45, metalness: 0.7, flatShading: true });
  const flameMat = new THREE.MeshStandardMaterial({ name: 'flame', color: 0xff8a2a, roughness: 0.6, emissive: 0xff6a10, emissiveIntensity: 1.6, flatShading: true });
  const coreMat = new THREE.MeshStandardMaterial({ name: 'core', color: 0xfff2b0, roughness: 0.6, emissive: 0xffe27a, emissiveIntensity: 1.8, flatShading: true });

  // Shared geometries
  const sphereGeo = new THREE.SphereGeometry(0.035, 4, 3);
  const extrudeGeo = extrude([[0.6, 4.8], [0.6, 2.05], [2.1, 0.3], [2.45, 0.1], [2.55, 0.62], [2.38, 1.9], [1.13, 4.45]], 0.14, [], [0.04, 0.04, 2]);
  const cylinderGeo = new THREE.CylinderGeometry(0.24, 0.3, 0.12, 8);

  // Parts
  const body = new THREE.Group();
  body.name = 'body';
  body.position.set(0, 0.5, 0);
  root.add(body);
  const lowerHull = new THREE.Mesh(lathe([[0, 1.42], [0.62, 1.42], [0.95, 1.8], [1.12, 2.6], [1.16, 3.2]], 16), bodyMat);
  lowerHull.name = 'lowerHull';
  lowerHull.rotation.set(0, deg(11.25), 0);
  body.add(lowerHull);
  const band = new THREE.Mesh(lathe([[1.16, 3.2], [1.165, 3.38], [1.16, 3.56]], 16), accentMat);
  band.name = 'band';
  band.rotation.set(0, deg(11.25), 0);
  body.add(band);
  const upperHull = new THREE.Mesh(lathe([[1.16, 3.56], [1.16, 4.9], [1.1, 5.8], [0.95, 6.6]], 16), bodyMat);
  upperHull.name = 'upperHull';
  upperHull.rotation.set(0, deg(11.25), 0);
  body.add(upperHull);
  const noseCone = new THREE.Mesh(lathe([[0.95, 6.6], [0.72, 7.3], [0.45, 7.9], [0.2, 8.35], [0, 8.5]], 16), accentMat);
  noseCone.name = 'noseCone';
  noseCone.rotation.set(0, deg(11.25), 0);
  body.add(noseCone);
  const antenna = new THREE.Mesh(new THREE.CylinderGeometry(0.025, 0.04, 0.6, 5), metalMat);
  antenna.name = 'antenna';
  antenna.position.set(0, 8.72, 0);
  body.add(antenna);
  const antennaTip = new THREE.Mesh(new THREE.SphereGeometry(0.07, 6, 4), accentMat);
  antennaTip.name = 'antennaTip';
  antennaTip.position.set(0, 9.05, 0);
  body.add(antennaTip);
  const portholeMainRim = new THREE.Mesh(new THREE.TorusGeometry(0.3, 0.06, 5, 16), metalMat);
  portholeMainRim.name = 'portholeMainRim';
  portholeMainRim.position.set(0, 5.25, 1.1332);
  body.add(portholeMainRim);
  const portholeMain = new THREE.Mesh(new THREE.CylinderGeometry(0.29, 0.29, 0.06, 14), glassMat);
  portholeMain.name = 'portholeMain';
  portholeMain.position.set(0, 5.25, 1.1132);
  portholeMain.rotation.set(deg(90), 0, 0);
  body.add(portholeMain);
  const portholeSmallRim = new THREE.Mesh(new THREE.TorusGeometry(0.186, 0.0372, 5, 16), metalMat);
  portholeSmallRim.name = 'portholeSmallRim';
  portholeSmallRim.position.set(0, 4.3, 1.1577);
  body.add(portholeSmallRim);
  const portholeSmall = new THREE.Mesh(new THREE.CylinderGeometry(0.1798, 0.1798, 0.06, 14), glassMat);
  portholeSmall.name = 'portholeSmall';
  portholeSmall.position.set(0, 4.3, 1.1377);
  portholeSmall.rotation.set(deg(90), 0, 0);
  body.add(portholeSmall);
  const sphere12 = new THREE.Mesh(sphereGeo, metalMat);
  sphere12.position.set(0.3002, 3.1, 1.1205);
  body.add(sphere12);
  const sphere13 = new THREE.Mesh(sphereGeo, metalMat);
  sphere13.position.set(0.8202, 3.1, 0.8202);
  body.add(sphere13);
  const sphere14 = new THREE.Mesh(sphereGeo, metalMat);
  sphere14.position.set(1.1205, 3.1, 0.3002);
  body.add(sphere14);
  const sphere15 = new THREE.Mesh(sphereGeo, metalMat);
  sphere15.position.set(1.1205, 3.1, -0.3002);
  body.add(sphere15);
  const sphere16 = new THREE.Mesh(sphereGeo, metalMat);
  sphere16.position.set(0.8202, 3.1, -0.8202);
  body.add(sphere16);
  const sphere17 = new THREE.Mesh(sphereGeo, metalMat);
  sphere17.position.set(0.3002, 3.1, -1.1205);
  body.add(sphere17);
  const sphere18 = new THREE.Mesh(sphereGeo, metalMat);
  sphere18.position.set(-0.3002, 3.1, -1.1205);
  body.add(sphere18);
  const sphere19 = new THREE.Mesh(sphereGeo, metalMat);
  sphere19.position.set(-0.8202, 3.1, -0.8202);
  body.add(sphere19);
  const sphere20 = new THREE.Mesh(sphereGeo, metalMat);
  sphere20.position.set(-1.1205, 3.1, -0.3002);
  body.add(sphere20);
  const sphere21 = new THREE.Mesh(sphereGeo, metalMat);
  sphere21.position.set(-1.1205, 3.1, 0.3002);
  body.add(sphere21);
  const sphere22 = new THREE.Mesh(sphereGeo, metalMat);
  sphere22.position.set(-0.8202, 3.1, 0.8202);
  body.add(sphere22);
  const sphere23 = new THREE.Mesh(sphereGeo, metalMat);
  sphere23.position.set(-0.3002, 3.1, 1.1205);
  body.add(sphere23);
  const engineMount = new THREE.Mesh(new THREE.CylinderGeometry(0.62, 0.62, 0.3, 14), metalMat);
  engineMount.name = 'engineMount';
  engineMount.position.set(0, 1.45, 0);
  body.add(engineMount);
  const nozzle = new THREE.Mesh(new THREE.CylinderGeometry(0.5, 0.74, 0.62, 14), metalMat);
  nozzle.name = 'nozzle';
  nozzle.position.set(0, 1.11, 0);
  body.add(nozzle);
  const nozzleGlow = new THREE.Mesh(new THREE.CylinderGeometry(0.62, 0.62, 0.02, 14), coreMat);
  nozzleGlow.name = 'nozzleGlow';
  nozzleGlow.position.set(0, 0.795, 0);
  body.add(nozzleGlow);
  const flame = new THREE.Mesh(new THREE.ConeGeometry(0.62, 1.26, 10), flameMat);
  flame.name = 'flame';
  flame.position.set(0, 0.17, 0);
  flame.rotation.set(deg(180), 0, 0);
  body.add(flame);
  const flameCore = new THREE.Mesh(new THREE.ConeGeometry(0.38, 0.9072, 8), coreMat);
  flameCore.name = 'flameCore';
  flameCore.position.set(0, 0.3364, 0);
  flameCore.rotation.set(deg(180), 0, 0);
  body.add(flameCore);
  const fins = new THREE.Group();
  fins.name = 'fins';
  root.add(fins);
  const fin1 = new THREE.Mesh(extrudeGeo, accentMat);
  fin1.name = 'fin1';
  fin1.rotation.set(0, deg(-25), 0);
  fins.add(fin1);
  const footPad1 = new THREE.Mesh(cylinderGeo, metalMat);
  footPad1.name = 'footPad1';
  footPad1.position.set(2.157, 0.06, 1.0058);
  fins.add(footPad1);
  const fin2 = new THREE.Mesh(extrudeGeo, accentMat);
  fin2.name = 'fin2';
  fin2.rotation.set(0, deg(65), 0);
  fins.add(fin2);
  const footPad2 = new THREE.Mesh(cylinderGeo, metalMat);
  footPad2.name = 'footPad2';
  footPad2.position.set(1.0058, 0.06, -2.157);
  fins.add(footPad2);
  const fin3 = new THREE.Mesh(extrudeGeo, accentMat);
  fin3.name = 'fin3';
  fin3.rotation.set(0, deg(155), 0);
  fins.add(fin3);
  const footPad3 = new THREE.Mesh(cylinderGeo, metalMat);
  footPad3.name = 'footPad3';
  footPad3.position.set(-2.157, 0.06, -1.0058);
  fins.add(footPad3);
  const fin4 = new THREE.Mesh(extrudeGeo, accentMat);
  fin4.name = 'fin4';
  fin4.rotation.set(0, deg(245), 0);
  fins.add(fin4);
  const footPad4 = new THREE.Mesh(cylinderGeo, metalMat);
  footPad4.name = 'footPad4';
  footPad4.position.set(-1.0058, 0.06, 2.157);
  fins.add(footPad4);

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

export default createRocket;

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