Codels
3,6 k tris11,6 × 27,0 × 31,4 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.
/**
 * Pirate Galleon — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 3,620 · Size (W × H × D): 11.60 × 27.04 × 31.38 m
 *
 * Usage:
 *   import { createPirateShip } from './pirate-ship.js';
 *   
 *   const model = createPirateShip();
 *   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 createPirateShip() {
  const root = new THREE.Group();
  root.name = 'PirateShip';

  // Materials
  const hullMat = new THREE.MeshStandardMaterial({ name: 'hull', color: 0x5a3b25, roughness: 0.85, flatShading: true });
  const bottomMat = new THREE.MeshStandardMaterial({ name: 'bottom', color: 0x3b2618, roughness: 0.9, flatShading: true });
  const trimMat = new THREE.MeshStandardMaterial({ name: 'trim', color: 0xc99a3b, roughness: 0.5, metalness: 0.35, flatShading: true });
  const deckMat = new THREE.MeshStandardMaterial({ name: 'deck', color: 0xb08455, roughness: 0.9, flatShading: true });
  const sparMat = new THREE.MeshStandardMaterial({ name: 'spar', color: 0x6e4a2c, roughness: 0.85, flatShading: true });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x24252a, roughness: 0.6, metalness: 0.4, flatShading: true });
  const sailMat = new THREE.MeshStandardMaterial({ name: 'sail', color: 0xefe5cc, roughness: 0.9, flatShading: true, side: THREE.DoubleSide });
  const ropeMat = new THREE.MeshStandardMaterial({ name: 'rope', color: 0xc8b088, roughness: 0.95, flatShading: true });
  const glowMat = new THREE.MeshStandardMaterial({ name: 'glow', color: 0xffd27a, roughness: 0.5, emissive: 0xffb347, emissiveIntensity: 1.3, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.14, 0.62, 0.66);
  const cylinderGeo = new THREE.CylinderGeometry(0.11, 0.15, 1, 6);
  const boxGeo2 = new THREE.BoxGeometry(0.07, 0.66, 0.7);
  const boxGeo3 = new THREE.BoxGeometry(0.62, 0.72, 0.06);
  const boxGeo4 = new THREE.BoxGeometry(0.55, 0.6, 0.06);
  const cylinderGeo2 = new THREE.CylinderGeometry(0.05, 0.05, 0.7, 5);
  const boxGeo5 = new THREE.BoxGeometry(0.32, 0.45, 0.32);
  const coneGeo = new THREE.ConeGeometry(0.26, 0.3, 4);
  const boxGeo6 = new THREE.BoxGeometry(0.7, 0.6, 0.06);
  const boxGeo7 = new THREE.BoxGeometry(1.4, 0.06, 0.06);
  const sphereGeo = new THREE.SphereGeometry(0.24, 6, 4);
  const extrudeGeo = extrude([[0, 0], [-2.4, -0.2], [0, -0.55]], 0.03);
  const boxGeo8 = new THREE.BoxGeometry(0.05, 0.14, 1.6);
  const sphereGeo2 = new THREE.SphereGeometry(0.07, 4, 3);

  // Parts
  const hull = new THREE.Group();
  hull.name = 'hull';
  root.add(hull);
  const bottomHull = new THREE.Mesh(lathe([[0, -11], [2.9, -11], [3.35, -9], [3.6, -6], [3.62, -2], [3.5, 2], [3.15, 5.5], [2.45, 8.5], [1.65, 10.6], [0.85, 12], [0.3, 12.8], [0, 13.1]], 8, -Math.PI / 2, Math.PI), bottomMat);
  bottomHull.name = 'bottomHull';
  bottomHull.position.set(0, 2.9, 0);
  bottomHull.rotation.set(deg(90), 0, 0);
  bottomHull.scale.set(1, 1, 0.72);
  hull.add(bottomHull);
  const topsides = new THREE.Mesh(extrude([[-2.9, -11], [-3.35, -9], [-3.6, -6], [-3.62, -2], [-3.5, 2], [-3.15, 5.5], [-2.45, 8.5], [-1.65, 10.6], [-0.85, 12], [-0.3, 12.8], [0, 13.1], [0.3, 12.8], [0.85, 12], [1.65, 10.6], [2.45, 8.5], [3.15, 5.5], [3.5, 2], [3.62, -2], [3.6, -6], [3.35, -9], [2.9, -11]], 2.3), hullMat);
  topsides.name = 'topsides';
  topsides.position.set(0, 4.05, 0);
  topsides.rotation.set(deg(90), 0, 0);
  hull.add(topsides);
  const sterncastle = new THREE.Mesh(extrude([[-2.9, -11], [-3.35, -9], [-3.6, -6], [-3.607, -4.6], [3.607, -4.6], [3.6, -6], [3.35, -9], [2.9, -11]], 2.2), hullMat);
  sterncastle.name = 'sterncastle';
  sterncastle.position.set(0, 6.3, 0);
  sterncastle.rotation.set(deg(90), 0, 0);
  hull.add(sterncastle);
  const poopCabin = new THREE.Mesh(extrude([[-2.9, -11], [-3.35, -9], [-3.4167, -8.2], [3.4167, -8.2], [3.35, -9], [2.9, -11]], 1.7), hullMat);
  poopCabin.name = 'poopCabin';
  poopCabin.position.set(0, 8.25, 0);
  poopCabin.rotation.set(deg(90), 0, 0);
  hull.add(poopCabin);
  const forecastle = new THREE.Mesh(extrude([[-2.7533, 7.2], [-2.45, 8.5], [-1.65, 10.6], [-0.85, 12], [-0.3, 12.8], [0, 13.1], [0.3, 12.8], [0.85, 12], [1.65, 10.6], [2.45, 8.5], [2.7533, 7.2]], 1.9), hullMat);
  forecastle.name = 'forecastle';
  forecastle.position.set(0, 6.15, 0);
  forecastle.rotation.set(deg(90), 0, 0);
  hull.add(forecastle);
  const mainBulwark = new THREE.Mesh(extrude([[-2.9, -11], [-3.35, -9], [-3.6, -6], [-3.62, -2], [-3.5, 2], [-3.15, 5.5], [-2.45, 8.5], [-1.65, 10.6], [-0.85, 12], [-0.3, 12.8], [0, 13.1], [0.3, 12.8], [0.85, 12], [1.65, 10.6], [2.45, 8.5], [3.15, 5.5], [3.5, 2], [3.62, -2], [3.6, -6], [3.35, -9], [2.9, -11]], 1, [[[-2.7295, -10.78], [-3.13, -9], [-3.38, -6], [-3.4, -2], [-3.28, 2], [-2.93, 5.5], [-2.23, 8.5], [-1.43, 10.6], [-0.63, 12], [-0.2862, 12.5], [0.2862, 12.5], [0.63, 12], [1.43, 10.6], [2.23, 8.5], [2.93, 5.5], [3.28, 2], [3.4, -2], [3.38, -6], [3.13, -9], [2.7295, -10.78]]]), hullMat);
  mainBulwark.name = 'mainBulwark';
  mainBulwark.position.set(0, 5.7, 0);
  mainBulwark.rotation.set(deg(90), 0, 0);
  hull.add(mainBulwark);
  const mainDeck = new THREE.Mesh(extrude([[-2.7295, -10.78], [-3.13, -9], [-3.38, -6], [-3.4, -2], [-3.28, 2], [-2.93, 5.5], [-2.23, 8.5], [-1.43, 10.6], [-0.63, 12], [-0.2862, 12.5], [0.2862, 12.5], [0.63, 12], [1.43, 10.6], [2.23, 8.5], [2.93, 5.5], [3.28, 2], [3.4, -2], [3.38, -6], [3.13, -9], [2.7295, -10.78]], 0.06), deckMat);
  mainDeck.name = 'mainDeck';
  mainDeck.position.set(0, 5.23, 0);
  mainDeck.rotation.set(deg(90), 0, 0);
  hull.add(mainDeck);
  const mainRail = new THREE.Mesh(extrude([[-2.9, -11], [-3.35, -9], [-3.6, -6], [-3.62, -2], [-3.5, 2], [-3.15, 5.5], [-2.45, 8.5], [-1.65, 10.6], [-0.85, 12], [-0.3, 12.8], [0, 13.1], [0.3, 12.8], [0.85, 12], [1.65, 10.6], [2.45, 8.5], [3.15, 5.5], [3.5, 2], [3.62, -2], [3.6, -6], [3.35, -9], [2.9, -11]], 0.08, [[[-2.7295, -10.78], [-3.13, -9], [-3.38, -6], [-3.4, -2], [-3.28, 2], [-2.93, 5.5], [-2.23, 8.5], [-1.43, 10.6], [-0.63, 12], [-0.2862, 12.5], [0.2862, 12.5], [0.63, 12], [1.43, 10.6], [2.23, 8.5], [2.93, 5.5], [3.28, 2], [3.4, -2], [3.38, -6], [3.13, -9], [2.7295, -10.78]]]), sparMat);
  mainRail.name = 'mainRail';
  mainRail.position.set(0, 6.24, 0);
  mainRail.rotation.set(deg(90), 0, 0);
  mainRail.scale.set(1.01, 1.004, 1);
  hull.add(mainRail);
  const forecastleBulwark = new THREE.Mesh(extrude([[-2.7533, 7.2], [-2.45, 8.5], [-1.65, 10.6], [-0.85, 12], [-0.3, 12.8], [0, 13.1], [0.3, 12.8], [0.85, 12], [1.65, 10.6], [2.45, 8.5], [2.7533, 7.2]], 0.8, [[[-2.482, 7.42], [-2.23, 8.5], [-1.43, 10.6], [-0.63, 12], [-0.2862, 12.5], [0.2862, 12.5], [0.63, 12], [1.43, 10.6], [2.23, 8.5], [2.482, 7.42]]]), hullMat);
  forecastleBulwark.name = 'forecastleBulwark';
  forecastleBulwark.position.set(0, 7.5, 0);
  forecastleBulwark.rotation.set(deg(90), 0, 0);
  hull.add(forecastleBulwark);
  const forecastleDeck = new THREE.Mesh(extrude([[-2.482, 7.42], [-2.23, 8.5], [-1.43, 10.6], [-0.63, 12], [-0.2862, 12.5], [0.2862, 12.5], [0.63, 12], [1.43, 10.6], [2.23, 8.5], [2.482, 7.42]], 0.06), deckMat);
  forecastleDeck.name = 'forecastleDeck';
  forecastleDeck.position.set(0, 7.13, 0);
  forecastleDeck.rotation.set(deg(90), 0, 0);
  hull.add(forecastleDeck);
  const forecastleRail = new THREE.Mesh(extrude([[-2.7533, 7.2], [-2.45, 8.5], [-1.65, 10.6], [-0.85, 12], [-0.3, 12.8], [0, 13.1], [0.3, 12.8], [0.85, 12], [1.65, 10.6], [2.45, 8.5], [2.7533, 7.2]], 0.08, [[[-2.482, 7.42], [-2.23, 8.5], [-1.43, 10.6], [-0.63, 12], [-0.2862, 12.5], [0.2862, 12.5], [0.63, 12], [1.43, 10.6], [2.23, 8.5], [2.482, 7.42]]]), sparMat);
  forecastleRail.name = 'forecastleRail';
  forecastleRail.position.set(0, 7.94, 0);
  forecastleRail.rotation.set(deg(90), 0, 0);
  forecastleRail.scale.set(1.01, 1.004, 1);
  hull.add(forecastleRail);
  const quarterBulwark = new THREE.Mesh(extrude([[-2.9, -11], [-3.35, -9], [-3.6, -6], [-3.607, -4.6], [3.607, -4.6], [3.6, -6], [3.35, -9], [2.9, -11]], 0.9, [[[-2.7295, -10.78], [-3.13, -9], [-3.38, -6], [-3.3859, -4.82], [3.3859, -4.82], [3.38, -6], [3.13, -9], [2.7295, -10.78]]]), hullMat);
  quarterBulwark.name = 'quarterBulwark';
  quarterBulwark.position.set(0, 7.85, 0);
  quarterBulwark.rotation.set(deg(90), 0, 0);
  hull.add(quarterBulwark);
  const quarterDeck = new THREE.Mesh(extrude([[-2.7295, -10.78], [-3.13, -9], [-3.38, -6], [-3.3859, -4.82], [3.3859, -4.82], [3.38, -6], [3.13, -9], [2.7295, -10.78]], 0.06), deckMat);
  quarterDeck.name = 'quarterDeck';
  quarterDeck.position.set(0, 7.43, 0);
  quarterDeck.rotation.set(deg(90), 0, 0);
  hull.add(quarterDeck);
  const quarterRail = new THREE.Mesh(extrude([[-2.9, -11], [-3.35, -9], [-3.6, -6], [-3.607, -4.6], [3.607, -4.6], [3.6, -6], [3.35, -9], [2.9, -11]], 0.08, [[[-2.7295, -10.78], [-3.13, -9], [-3.38, -6], [-3.3859, -4.82], [3.3859, -4.82], [3.38, -6], [3.13, -9], [2.7295, -10.78]]]), sparMat);
  quarterRail.name = 'quarterRail';
  quarterRail.position.set(0, 8.34, 0);
  quarterRail.rotation.set(deg(90), 0, 0);
  quarterRail.scale.set(1.01, 1.004, 1);
  hull.add(quarterRail);
  const poopBulwark = new THREE.Mesh(extrude([[-2.9, -11], [-3.35, -9], [-3.4167, -8.2], [3.4167, -8.2], [3.35, -9], [2.9, -11]], 0.8, [[[-2.7295, -10.78], [-3.13, -9], [-3.1783, -8.42], [3.1783, -8.42], [3.13, -9], [2.7295, -10.78]]]), hullMat);
  poopBulwark.name = 'poopBulwark';
  poopBulwark.position.set(0, 9.5, 0);
  poopBulwark.rotation.set(deg(90), 0, 0);
  hull.add(poopBulwark);
  const poopDeck = new THREE.Mesh(extrude([[-2.7295, -10.78], [-3.13, -9], [-3.1783, -8.42], [3.1783, -8.42], [3.13, -9], [2.7295, -10.78]], 0.06), deckMat);
  poopDeck.name = 'poopDeck';
  poopDeck.position.set(0, 9.13, 0);
  poopDeck.rotation.set(deg(90), 0, 0);
  hull.add(poopDeck);
  const poopRail = new THREE.Mesh(extrude([[-2.9, -11], [-3.35, -9], [-3.4167, -8.2], [3.4167, -8.2], [3.35, -9], [2.9, -11]], 0.08, [[[-2.7295, -10.78], [-3.13, -9], [-3.1783, -8.42], [3.1783, -8.42], [3.13, -9], [2.7295, -10.78]]]), sparMat);
  poopRail.name = 'poopRail';
  poopRail.position.set(0, 9.94, 0);
  poopRail.rotation.set(deg(90), 0, 0);
  poopRail.scale.set(1.01, 1.004, 1);
  hull.add(poopRail);
  const waterlineWale = new THREE.Mesh(extrude([[-2.9, -11], [-3.35, -9], [-3.6, -6], [-3.62, -2], [-3.5, 2], [-3.15, 5.5], [-2.45, 8.5], [-1.65, 10.6], [-0.85, 12], [-0.3, 12.8], [0, 13.1], [0.3, 12.8], [0.85, 12], [1.65, 10.6], [2.45, 8.5], [3.15, 5.5], [3.5, 2], [3.62, -2], [3.6, -6], [3.35, -9], [2.9, -11]], 0.16), trimMat);
  waterlineWale.name = 'waterlineWale';
  waterlineWale.position.set(0, 3.03, 0);
  waterlineWale.rotation.set(deg(90), 0, 0);
  waterlineWale.scale.set(1.018, 1.004, 1);
  hull.add(waterlineWale);
  const lowerWale = new THREE.Mesh(extrude([[-2.9, -11], [-3.35, -9], [-3.6, -6], [-3.62, -2], [-3.5, 2], [-3.15, 5.5], [-2.45, 8.5], [-1.65, 10.6], [-0.85, 12], [-0.3, 12.8], [0, 13.1], [0.3, 12.8], [0.85, 12], [1.65, 10.6], [2.45, 8.5], [3.15, 5.5], [3.5, 2], [3.62, -2], [3.6, -6], [3.35, -9], [2.9, -11]], 0.12), trimMat);
  lowerWale.name = 'lowerWale';
  lowerWale.position.set(0, 3.58, 0);
  lowerWale.rotation.set(deg(90), 0, 0);
  lowerWale.scale.set(1.018, 1.004, 1);
  hull.add(lowerWale);
  const upperWale = new THREE.Mesh(extrude([[-2.9, -11], [-3.35, -9], [-3.6, -6], [-3.62, -2], [-3.5, 2], [-3.15, 5.5], [-2.45, 8.5], [-1.65, 10.6], [-0.85, 12], [-0.3, 12.8], [0, 13.1], [0.3, 12.8], [0.85, 12], [1.65, 10.6], [2.45, 8.5], [3.15, 5.5], [3.5, 2], [3.62, -2], [3.6, -6], [3.35, -9], [2.9, -11]], 0.14), trimMat);
  upperWale.name = 'upperWale';
  upperWale.position.set(0, 5.15, 0);
  upperWale.rotation.set(deg(90), 0, 0);
  upperWale.scale.set(1.018, 1.004, 1);
  hull.add(upperWale);
  const castleWale = new THREE.Mesh(extrude([[-2.9, -11], [-3.35, -9], [-3.6, -6], [-3.607, -4.6], [3.607, -4.6], [3.6, -6], [3.35, -9], [2.9, -11]], 0.14), trimMat);
  castleWale.name = 'castleWale';
  castleWale.position.set(0, 7.33, 0);
  castleWale.rotation.set(deg(90), 0, 0);
  castleWale.scale.set(1.02, 1.004, 1);
  hull.add(castleWale);
  const keel = new THREE.Mesh(extrude([[-10.9, 0], [6, 0], [8.6, 0.72], [10.7, 1.38], [12.2, 2], [13.15, 2.6], [13.45, 3.3], [13.5, 5.6], [13.05, 5.6], [13, 3], [12.1, 2.5], [10.6, 1.95], [8.5, 1.4], [6, 1], [-10.9, 1]], 0.3), sparMat);
  keel.name = 'keel';
  keel.rotation.set(0, deg(-90), 0);
  hull.add(keel);
  const rudder = new THREE.Mesh(extrude([[-11, 0.1], [-11.9, 0.35], [-12, 4.4], [-11, 4.4]], 0.26), sparMat);
  rudder.name = 'rudder';
  rudder.rotation.set(0, deg(-90), 0);
  hull.add(rudder);
  const gunPortL1 = new THREE.Mesh(boxGeo, darkMat);
  gunPortL1.name = 'gunPortL1';
  gunPortL1.position.set(3.4333, 4.2, -8);
  gunPortL1.rotation.set(0, deg(4.7636), 0);
  hull.add(gunPortL1);
  const cannonL1 = new THREE.Mesh(cylinderGeo, darkMat);
  cannonL1.name = 'cannonL1';
  cannonL1.position.set(3.7333, 4.18, -8);
  cannonL1.rotation.set(0, deg(4.7636), deg(90));
  hull.add(cannonL1);
  const portLidL1 = new THREE.Mesh(boxGeo2, trimMat);
  portLidL1.name = 'portLidL1';
  portLidL1.position.set(3.7333, 4.42, -8);
  portLidL1.rotation.set(0, deg(4.7636), deg(68));
  hull.add(portLidL1);
  const gunPortR1 = new THREE.Mesh(boxGeo, darkMat);
  gunPortR1.name = 'gunPortR1';
  gunPortR1.position.set(-3.4333, 4.2, -8);
  gunPortR1.rotation.set(0, deg(-4.7636), 0);
  hull.add(gunPortR1);
  const cannonR1 = new THREE.Mesh(cylinderGeo, darkMat);
  cannonR1.name = 'cannonR1';
  cannonR1.position.set(-3.7333, 4.18, -8);
  cannonR1.rotation.set(0, deg(-4.7636), deg(90));
  hull.add(cannonR1);
  const portLidR1 = new THREE.Mesh(boxGeo2, trimMat);
  portLidR1.name = 'portLidR1';
  portLidR1.position.set(-3.7333, 4.42, -8);
  portLidR1.rotation.set(0, deg(-4.7636), deg(-68));
  hull.add(portLidR1);
  const gunPortL2 = new THREE.Mesh(boxGeo, darkMat);
  gunPortL2.name = 'gunPortL2';
  gunPortL2.position.set(3.6025, 4.2, -5.5);
  gunPortL2.rotation.set(0, deg(0.2865), 0);
  hull.add(gunPortL2);
  const cannonL2 = new THREE.Mesh(cylinderGeo, darkMat);
  cannonL2.name = 'cannonL2';
  cannonL2.position.set(3.9025, 4.18, -5.5);
  cannonL2.rotation.set(0, deg(0.2865), deg(90));
  hull.add(cannonL2);
  const portLidL2 = new THREE.Mesh(boxGeo2, trimMat);
  portLidL2.name = 'portLidL2';
  portLidL2.position.set(3.9025, 4.42, -5.5);
  portLidL2.rotation.set(0, deg(0.2865), deg(68));
  hull.add(portLidL2);
  const gunPortR2 = new THREE.Mesh(boxGeo, darkMat);
  gunPortR2.name = 'gunPortR2';
  gunPortR2.position.set(-3.6025, 4.2, -5.5);
  gunPortR2.rotation.set(0, deg(-0.2865), 0);
  hull.add(gunPortR2);
  const cannonR2 = new THREE.Mesh(cylinderGeo, darkMat);
  cannonR2.name = 'cannonR2';
  cannonR2.position.set(-3.9025, 4.18, -5.5);
  cannonR2.rotation.set(0, deg(-0.2865), deg(90));
  hull.add(cannonR2);
  const portLidR2 = new THREE.Mesh(boxGeo2, trimMat);
  portLidR2.name = 'portLidR2';
  portLidR2.position.set(-3.9025, 4.42, -5.5);
  portLidR2.rotation.set(0, deg(-0.2865), deg(-68));
  hull.add(portLidR2);
  const gunPortL3 = new THREE.Mesh(boxGeo, darkMat);
  gunPortL3.name = 'gunPortL3';
  gunPortL3.position.set(3.615, 4.2, -3);
  gunPortL3.rotation.set(0, deg(0.2865), 0);
  hull.add(gunPortL3);
  const cannonL3 = new THREE.Mesh(cylinderGeo, darkMat);
  cannonL3.name = 'cannonL3';
  cannonL3.position.set(3.915, 4.18, -3);
  cannonL3.rotation.set(0, deg(0.2865), deg(90));
  hull.add(cannonL3);
  const portLidL3 = new THREE.Mesh(boxGeo2, trimMat);
  portLidL3.name = 'portLidL3';
  portLidL3.position.set(3.915, 4.42, -3);
  portLidL3.rotation.set(0, deg(0.2865), deg(68));
  hull.add(portLidL3);
  const gunPortR3 = new THREE.Mesh(boxGeo, darkMat);
  gunPortR3.name = 'gunPortR3';
  gunPortR3.position.set(-3.615, 4.2, -3);
  gunPortR3.rotation.set(0, deg(-0.2865), 0);
  hull.add(gunPortR3);
  const cannonR3 = new THREE.Mesh(cylinderGeo, darkMat);
  cannonR3.name = 'cannonR3';
  cannonR3.position.set(-3.915, 4.18, -3);
  cannonR3.rotation.set(0, deg(-0.2865), deg(90));
  hull.add(cannonR3);
  const portLidR3 = new THREE.Mesh(boxGeo2, trimMat);
  portLidR3.name = 'portLidR3';
  portLidR3.position.set(-3.915, 4.42, -3);
  portLidR3.rotation.set(0, deg(-0.2865), deg(-68));
  hull.add(portLidR3);
  const gunPortL4 = new THREE.Mesh(boxGeo, darkMat);
  gunPortL4.name = 'gunPortL4';
  gunPortL4.position.set(3.575, 4.2, -0.5);
  gunPortL4.rotation.set(0, deg(-1.7184), 0);
  hull.add(gunPortL4);
  const cannonL4 = new THREE.Mesh(cylinderGeo, darkMat);
  cannonL4.name = 'cannonL4';
  cannonL4.position.set(3.875, 4.18, -0.5);
  cannonL4.rotation.set(0, deg(-1.7184), deg(90));
  hull.add(cannonL4);
  const portLidL4 = new THREE.Mesh(boxGeo2, trimMat);
  portLidL4.name = 'portLidL4';
  portLidL4.position.set(3.875, 4.42, -0.5);
  portLidL4.rotation.set(0, deg(-1.7184), deg(68));
  hull.add(portLidL4);
  const gunPortR4 = new THREE.Mesh(boxGeo, darkMat);
  gunPortR4.name = 'gunPortR4';
  gunPortR4.position.set(-3.575, 4.2, -0.5);
  gunPortR4.rotation.set(0, deg(1.7184), 0);
  hull.add(gunPortR4);
  const cannonR4 = new THREE.Mesh(cylinderGeo, darkMat);
  cannonR4.name = 'cannonR4';
  cannonR4.position.set(-3.875, 4.18, -0.5);
  cannonR4.rotation.set(0, deg(1.7184), deg(90));
  hull.add(cannonR4);
  const portLidR4 = new THREE.Mesh(boxGeo2, trimMat);
  portLidR4.name = 'portLidR4';
  portLidR4.position.set(-3.875, 4.42, -0.5);
  portLidR4.rotation.set(0, deg(1.7184), deg(-68));
  hull.add(portLidR4);
  const gunPortL5 = new THREE.Mesh(boxGeo, darkMat);
  gunPortL5.name = 'gunPortL5';
  gunPortL5.position.set(3.5, 4.2, 2);
  gunPortL5.rotation.set(0, deg(-3.719), 0);
  hull.add(gunPortL5);
  const cannonL5 = new THREE.Mesh(cylinderGeo, darkMat);
  cannonL5.name = 'cannonL5';
  cannonL5.position.set(3.8, 4.18, 2);
  cannonL5.rotation.set(0, deg(-3.719), deg(90));
  hull.add(cannonL5);
  const portLidL5 = new THREE.Mesh(boxGeo2, trimMat);
  portLidL5.name = 'portLidL5';
  portLidL5.position.set(3.8, 4.42, 2);
  portLidL5.rotation.set(0, deg(-3.719), deg(68));
  hull.add(portLidL5);
  const gunPortR5 = new THREE.Mesh(boxGeo, darkMat);
  gunPortR5.name = 'gunPortR5';
  gunPortR5.position.set(-3.5, 4.2, 2);
  gunPortR5.rotation.set(0, deg(3.719), 0);
  hull.add(gunPortR5);
  const cannonR5 = new THREE.Mesh(cylinderGeo, darkMat);
  cannonR5.name = 'cannonR5';
  cannonR5.position.set(-3.8, 4.18, 2);
  cannonR5.rotation.set(0, deg(3.719), deg(90));
  hull.add(cannonR5);
  const portLidR5 = new THREE.Mesh(boxGeo2, trimMat);
  portLidR5.name = 'portLidR5';
  portLidR5.position.set(-3.8, 4.42, 2);
  portLidR5.rotation.set(0, deg(3.719), deg(-68));
  hull.add(portLidR5);
  const gunPortL6 = new THREE.Mesh(boxGeo, darkMat);
  gunPortL6.name = 'gunPortL6';
  gunPortL6.position.set(3.25, 4.2, 4.5);
  gunPortL6.rotation.set(0, deg(-5.7106), 0);
  hull.add(gunPortL6);
  const cannonL6 = new THREE.Mesh(cylinderGeo, darkMat);
  cannonL6.name = 'cannonL6';
  cannonL6.position.set(3.55, 4.18, 4.5);
  cannonL6.rotation.set(0, deg(-5.7106), deg(90));
  hull.add(cannonL6);
  const portLidL6 = new THREE.Mesh(boxGeo2, trimMat);
  portLidL6.name = 'portLidL6';
  portLidL6.position.set(3.55, 4.42, 4.5);
  portLidL6.rotation.set(0, deg(-5.7106), deg(68));
  hull.add(portLidL6);
  const gunPortR6 = new THREE.Mesh(boxGeo, darkMat);
  gunPortR6.name = 'gunPortR6';
  gunPortR6.position.set(-3.25, 4.2, 4.5);
  gunPortR6.rotation.set(0, deg(5.7106), 0);
  hull.add(gunPortR6);
  const cannonR6 = new THREE.Mesh(cylinderGeo, darkMat);
  cannonR6.name = 'cannonR6';
  cannonR6.position.set(-3.55, 4.18, 4.5);
  cannonR6.rotation.set(0, deg(5.7106), deg(90));
  hull.add(cannonR6);
  const portLidR6 = new THREE.Mesh(boxGeo2, trimMat);
  portLidR6.name = 'portLidR6';
  portLidR6.position.set(-3.55, 4.42, 4.5);
  portLidR6.rotation.set(0, deg(5.7106), deg(-68));
  hull.add(portLidR6);
  const gunPortL7 = new THREE.Mesh(boxGeo, darkMat);
  gunPortL7.name = 'gunPortL7';
  gunPortL7.position.set(2.8, 4.2, 7);
  gunPortL7.rotation.set(0, deg(-13.134), 0);
  hull.add(gunPortL7);
  const cannonL7 = new THREE.Mesh(cylinderGeo, darkMat);
  cannonL7.name = 'cannonL7';
  cannonL7.position.set(3.1, 4.18, 7);
  cannonL7.rotation.set(0, deg(-13.134), deg(90));
  hull.add(cannonL7);
  const portLidL7 = new THREE.Mesh(boxGeo2, trimMat);
  portLidL7.name = 'portLidL7';
  portLidL7.position.set(3.1, 4.42, 7);
  portLidL7.rotation.set(0, deg(-13.134), deg(68));
  hull.add(portLidL7);
  const gunPortR7 = new THREE.Mesh(boxGeo, darkMat);
  gunPortR7.name = 'gunPortR7';
  gunPortR7.position.set(-2.8, 4.2, 7);
  gunPortR7.rotation.set(0, deg(13.134), 0);
  hull.add(gunPortR7);
  const cannonR7 = new THREE.Mesh(cylinderGeo, darkMat);
  cannonR7.name = 'cannonR7';
  cannonR7.position.set(-3.1, 4.18, 7);
  cannonR7.rotation.set(0, deg(13.134), deg(90));
  hull.add(cannonR7);
  const portLidR7 = new THREE.Mesh(boxGeo2, trimMat);
  portLidR7.name = 'portLidR7';
  portLidR7.position.set(-3.1, 4.42, 7);
  portLidR7.rotation.set(0, deg(13.134), deg(-68));
  hull.add(portLidR7);
  const sternWindow1 = new THREE.Mesh(boxGeo3, glowMat);
  sternWindow1.name = 'sternWindow1';
  sternWindow1.position.set(-2, 6.5, -11.02);
  hull.add(sternWindow1);
  const sternWindow2 = new THREE.Mesh(boxGeo3, glowMat);
  sternWindow2.name = 'sternWindow2';
  sternWindow2.position.set(-1, 6.5, -11.02);
  hull.add(sternWindow2);
  const sternWindow3 = new THREE.Mesh(boxGeo3, glowMat);
  sternWindow3.name = 'sternWindow3';
  sternWindow3.position.set(0, 6.5, -11.02);
  hull.add(sternWindow3);
  const sternWindow4 = new THREE.Mesh(boxGeo3, glowMat);
  sternWindow4.name = 'sternWindow4';
  sternWindow4.position.set(1, 6.5, -11.02);
  hull.add(sternWindow4);
  const sternWindow5 = new THREE.Mesh(boxGeo3, glowMat);
  sternWindow5.name = 'sternWindow5';
  sternWindow5.position.set(2, 6.5, -11.02);
  hull.add(sternWindow5);
  const galleryWindow1 = new THREE.Mesh(boxGeo4, glowMat);
  galleryWindow1.name = 'galleryWindow1';
  galleryWindow1.position.set(-1.5, 8.25, -11.02);
  hull.add(galleryWindow1);
  const galleryWindow2 = new THREE.Mesh(boxGeo4, glowMat);
  galleryWindow2.name = 'galleryWindow2';
  galleryWindow2.position.set(-0.5, 8.25, -11.02);
  hull.add(galleryWindow2);
  const galleryWindow3 = new THREE.Mesh(boxGeo4, glowMat);
  galleryWindow3.name = 'galleryWindow3';
  galleryWindow3.position.set(0.5, 8.25, -11.02);
  hull.add(galleryWindow3);
  const galleryWindow4 = new THREE.Mesh(boxGeo4, glowMat);
  galleryWindow4.name = 'galleryWindow4';
  galleryWindow4.position.set(1.5, 8.25, -11.02);
  hull.add(galleryWindow4);
  const sternTrim = new THREE.Mesh(new THREE.BoxGeometry(5.6, 0.12, 0.3), trimMat);
  sternTrim.name = 'sternTrim';
  sternTrim.position.set(0, 5.7, -11.08);
  hull.add(sternTrim);
  const galleryTrim = new THREE.Mesh(new THREE.BoxGeometry(4.6, 0.12, 0.3), trimMat);
  galleryTrim.name = 'galleryTrim';
  galleryTrim.position.set(0, 7.65, -11.08);
  hull.add(galleryTrim);
  const cylinder78 = new THREE.Mesh(cylinderGeo2, darkMat);
  cylinder78.position.set(-2.2, 10.33, -10.7);
  hull.add(cylinder78);
  const sternLantern = new THREE.Mesh(boxGeo5, glowMat);
  sternLantern.name = 'sternLantern';
  sternLantern.position.set(-2.2, 10.85, -10.7);
  hull.add(sternLantern);
  const cone80 = new THREE.Mesh(coneGeo, darkMat);
  cone80.position.set(-2.2, 11.22, -10.7);
  cone80.rotation.set(0, deg(45), 0);
  hull.add(cone80);
  const cylinder81 = new THREE.Mesh(cylinderGeo2, darkMat);
  cylinder81.position.set(0, 10.33, -10.7);
  hull.add(cylinder81);
  const sternLantern2 = new THREE.Mesh(boxGeo5, glowMat);
  sternLantern2.name = 'sternLantern';
  sternLantern2.position.set(0, 10.85, -10.7);
  hull.add(sternLantern2);
  const cone83 = new THREE.Mesh(coneGeo, darkMat);
  cone83.position.set(0, 11.22, -10.7);
  cone83.rotation.set(0, deg(45), 0);
  hull.add(cone83);
  const cylinder84 = new THREE.Mesh(cylinderGeo2, darkMat);
  cylinder84.position.set(2.2, 10.33, -10.7);
  hull.add(cylinder84);
  const sternLantern3 = new THREE.Mesh(boxGeo5, glowMat);
  sternLantern3.name = 'sternLantern';
  sternLantern3.position.set(2.2, 10.85, -10.7);
  hull.add(sternLantern3);
  const cone86 = new THREE.Mesh(coneGeo, darkMat);
  cone86.position.set(2.2, 11.22, -10.7);
  cone86.rotation.set(0, deg(45), 0);
  hull.add(cone86);
  const cabinDoor = new THREE.Mesh(new THREE.BoxGeometry(1, 1.7, 0.08), darkMat);
  cabinDoor.name = 'cabinDoor';
  cabinDoor.position.set(0, 6.1, -4.57);
  hull.add(cabinDoor);
  const cabinWindow = new THREE.Mesh(boxGeo6, glowMat);
  cabinWindow.name = 'cabinWindow';
  cabinWindow.position.set(-1.7, 6.5, -4.57);
  hull.add(cabinWindow);
  const cabinWindow2 = new THREE.Mesh(boxGeo6, glowMat);
  cabinWindow2.name = 'cabinWindow';
  cabinWindow2.position.set(1.7, 6.5, -4.57);
  hull.add(cabinWindow2);
  const forecastleDoor = new THREE.Mesh(new THREE.BoxGeometry(0.9, 1.4, 0.08), darkMat);
  forecastleDoor.name = 'forecastleDoor';
  forecastleDoor.position.set(0, 5.95, 7.17);
  hull.add(forecastleDoor);
  const helmStand = new THREE.Group();
  helmStand.name = 'helmStand';
  root.add(helmStand);
  const helmPost = new THREE.Mesh(new THREE.BoxGeometry(0.3, 0.9, 0.3), sparMat);
  helmPost.name = 'helmPost';
  helmPost.position.set(0, 7.91, -5.7);
  helmStand.add(helmPost);
  const helm = new THREE.Group();
  helm.name = 'helm';
  helm.position.set(0, 8.5, -5.48);
  root.add(helm);
  const wheelRim = new THREE.Mesh(new THREE.TorusGeometry(0.55, 0.05, 4, 12), sparMat);
  wheelRim.name = 'wheelRim';
  helm.add(wheelRim);
  const box95 = new THREE.Mesh(boxGeo7, sparMat);
  helm.add(box95);
  const box96 = new THREE.Mesh(boxGeo7, sparMat);
  box96.rotation.set(0, 0, deg(45));
  helm.add(box96);
  const box97 = new THREE.Mesh(boxGeo7, sparMat);
  box97.rotation.set(0, 0, deg(90));
  helm.add(box97);
  const box98 = new THREE.Mesh(boxGeo7, sparMat);
  box98.rotation.set(0, 0, deg(135));
  helm.add(box98);
  const wheelHub = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, 0.16, 6), trimMat);
  wheelHub.name = 'wheelHub';
  wheelHub.rotation.set(deg(90), 0, 0);
  helm.add(wheelHub);
  const bowsprit = new THREE.Mesh(new THREE.CylinderGeometry(0.12, 0.2, 7.6, 6), sparMat);
  bowsprit.name = 'bowsprit';
  bowsprit.position.set(0, 8.0997, 15.7708);
  bowsprit.rotation.set(deg(70), 0, 0);
  root.add(bowsprit);
  const foreMast = new THREE.Group();
  foreMast.name = 'foreMast';
  foreMast.position.set(0, 0, 8.4);
  root.add(foreMast);
  const mast = new THREE.Mesh(new THREE.CylinderGeometry(0.2, 0.32, 18.9, 8), sparMat);
  mast.name = 'mast';
  mast.position.set(0, 14.25, 0);
  foreMast.add(mast);
  const truck = new THREE.Mesh(sphereGeo, trimMat);
  truck.name = 'truck';
  truck.position.set(0, 23.8, 0);
  foreMast.add(truck);
  const yard1 = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, 10.6, 6), sparMat);
  yard1.name = 'yard1';
  yard1.position.set(0, 12.8, 0.25);
  yard1.rotation.set(0, 0, deg(90));
  foreMast.add(yard1);
  const sail1 = new THREE.Mesh(new THREE.CylinderGeometry(8.4585, 9.0101, 4, 6, 1, true, -0.575, 1.15), sailMat);
  sail1.name = 'sail1';
  sail1.position.set(0, 10.65, -7.0797);
  foreMast.add(sail1);
  const yard2 = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, 8.4, 6), sparMat);
  yard2.name = 'yard2';
  yard2.position.set(0, 17.6, 0.25);
  yard2.rotation.set(0, 0, deg(90));
  foreMast.add(yard2);
  const sail2 = new THREE.Mesh(new THREE.CylinderGeometry(6.4358, 7.5391, 4.2, 6, 1, true, -0.575, 1.15), sailMat);
  sail2.name = 'sail2';
  sail2.position.set(0, 15.35, -5.6138);
  foreMast.add(sail2);
  const yard3 = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, 6.2, 6), sparMat);
  yard3.name = 'yard3';
  yard3.position.set(0, 21.5, 0.25);
  yard3.rotation.set(0, 0, deg(90));
  foreMast.add(yard3);
  const sail3 = new THREE.Mesh(new THREE.CylinderGeometry(4.4131, 5.5164, 2.6, 6, 1, true, -0.575, 1.15), sailMat);
  sail3.name = 'sail3';
  sail3.position.set(0, 20.05, -3.9164);
  foreMast.add(sail3);
  const pennant = new THREE.Mesh(extrudeGeo, trimMat);
  pennant.name = 'pennant';
  pennant.position.set(0, 23.5, 0);
  pennant.rotation.set(0, deg(-90), 0);
  foreMast.add(pennant);
  const mainMast = new THREE.Group();
  mainMast.name = 'mainMast';
  mainMast.position.set(0, 0, 1);
  root.add(mainMast);
  const mast2 = new THREE.Mesh(new THREE.CylinderGeometry(0.2, 0.32, 21.9, 8), sparMat);
  mast2.name = 'mast';
  mast2.position.set(0, 15.75, 0);
  mainMast.add(mast2);
  const truck2 = new THREE.Mesh(sphereGeo, trimMat);
  truck2.name = 'truck';
  truck2.position.set(0, 26.8, 0);
  mainMast.add(truck2);
  const yard12 = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, 11.6, 6), sparMat);
  yard12.name = 'yard1';
  yard12.position.set(0, 13.2, 0.25);
  yard12.rotation.set(0, 0, deg(90));
  mainMast.add(yard12);
  const sail12 = new THREE.Mesh(new THREE.CylinderGeometry(9.3778, 9.9295, 4.6, 6, 1, true, -0.575, 1.15), sailMat);
  sail12.name = 'sail1';
  sail12.position.set(0, 10.75, -7.8513);
  mainMast.add(sail12);
  const yard22 = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, 9.2, 6), sparMat);
  yard22.name = 'yard2';
  yard22.position.set(0, 18.6, 0.25);
  yard22.rotation.set(0, 0, deg(90));
  mainMast.add(yard22);
  const sail22 = new THREE.Mesh(new THREE.CylinderGeometry(7.1713, 8.4585, 4.8, 6, 1, true, -0.575, 1.15), sailMat);
  sail22.name = 'sail2';
  sail22.position.set(0, 16.05, -6.3082);
  mainMast.add(sail22);
  const yard32 = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, 6.8, 6), sparMat);
  yard32.name = 'yard3';
  yard32.position.set(0, 23.4, 0.25);
  yard32.rotation.set(0, 0, deg(90));
  mainMast.add(yard32);
  const sail32 = new THREE.Mesh(new THREE.CylinderGeometry(4.9647, 6.068, 3, 6, 1, true, -0.575, 1.15), sailMat);
  sail32.name = 'sail3';
  sail32.position.set(0, 21.75, -4.3793);
  mainMast.add(sail32);
  const crowsNest = new THREE.Mesh(new THREE.CylinderGeometry(0.9, 0.72, 0.85, 10), deckMat);
  crowsNest.name = 'crowsNest';
  crowsNest.position.set(0, 19.925, 0);
  mainMast.add(crowsNest);
  const crowsNestRail = new THREE.Mesh(new THREE.TorusGeometry(0.9, 0.06, 4, 12), sparMat);
  crowsNestRail.name = 'crowsNestRail';
  crowsNestRail.position.set(0, 20.38, 0);
  crowsNestRail.rotation.set(deg(90), 0, 0);
  mainMast.add(crowsNestRail);
  const jollyRoger = new THREE.Group();
  jollyRoger.name = 'jollyRoger';
  jollyRoger.position.set(0, 26.5, 0);
  mainMast.add(jollyRoger);
  const flag = new THREE.Mesh(new THREE.BoxGeometry(0.03, 1.9, 2.8), darkMat);
  flag.name = 'flag';
  flag.position.set(0, -0.95, -1.4);
  jollyRoger.add(flag);
  const skull = new THREE.Mesh(new THREE.SphereGeometry(0.36, 8, 6), sailMat);
  skull.name = 'skull';
  skull.position.set(0, -0.82, -1.4);
  skull.scale.set(0.16, 1, 0.92);
  jollyRoger.add(skull);
  const jaw = new THREE.Mesh(new THREE.BoxGeometry(0.06, 0.2, 0.36), sailMat);
  jaw.name = 'jaw';
  jaw.position.set(0, -1.2, -1.4);
  jollyRoger.add(jaw);
  const crossbone = new THREE.Mesh(boxGeo8, sailMat);
  crossbone.name = 'crossbone';
  crossbone.position.set(0, -1.45, -1.4);
  crossbone.rotation.set(deg(28), 0, 0);
  jollyRoger.add(crossbone);
  const eye = new THREE.Mesh(sphereGeo2, darkMat);
  eye.name = 'eye';
  eye.position.set(0, -0.8, -1.27);
  eye.scale.set(0.9, 1, 1);
  jollyRoger.add(eye);
  const crossbone2 = new THREE.Mesh(boxGeo8, sailMat);
  crossbone2.name = 'crossbone';
  crossbone2.position.set(0, -1.45, -1.4);
  crossbone2.rotation.set(deg(-28), 0, 0);
  jollyRoger.add(crossbone2);
  const eye2 = new THREE.Mesh(sphereGeo2, darkMat);
  eye2.name = 'eye';
  eye2.position.set(0, -0.8, -1.53);
  eye2.scale.set(0.9, 1, 1);
  jollyRoger.add(eye2);
  const mizzenMast = new THREE.Group();
  mizzenMast.name = 'mizzenMast';
  mizzenMast.position.set(0, 0, -6.6);
  root.add(mizzenMast);
  const mast3 = new THREE.Mesh(new THREE.CylinderGeometry(0.2, 0.32, 15.4, 8), sparMat);
  mast3.name = 'mast';
  mast3.position.set(0, 12.5, 0);
  mizzenMast.add(mast3);
  const truck3 = new THREE.Mesh(sphereGeo, trimMat);
  truck3.name = 'truck';
  truck3.position.set(0, 20.3, 0);
  mizzenMast.add(truck3);
  const lateenYard = new THREE.Mesh(tube([[0, 10.1, 3.2], [0, 17.8, -4.6]], 0.09, 1, 5), sparMat);
  lateenYard.name = 'lateenYard';
  mizzenMast.add(lateenYard);
  const lateenSail = new THREE.Mesh(extrude([[3, 10.2], [-4.4, 17.55], [-4.3, 10.1]], 0.05), sailMat);
  lateenSail.name = 'lateenSail';
  lateenSail.position.set(0.18, 0, 0);
  lateenSail.rotation.set(0, deg(-90), 0);
  mizzenMast.add(lateenSail);
  const pennant2 = new THREE.Mesh(extrudeGeo, trimMat);
  pennant2.name = 'pennant';
  pennant2.position.set(0, 20, 0);
  pennant2.rotation.set(0, deg(-90), 0);
  mizzenMast.add(pennant2);
  const rigging = new THREE.Group();
  rigging.name = 'rigging';
  root.add(rigging);
  const shroudforeMast = new THREE.Mesh(tube([[2.8967, 7.9, 6.8], [0.28, 17.2, 8.4]], 0.035, 1, 3), ropeMat);
  shroudforeMast.name = 'shroudforeMast';
  rigging.add(shroudforeMast);
  const shroudforeMast2 = new THREE.Mesh(tube([[2.6633, 7.9, 7.8], [0.28, 17.2, 8.4]], 0.035, 1, 3), ropeMat);
  shroudforeMast2.name = 'shroudforeMast';
  rigging.add(shroudforeMast2);
  const shroudforeMast3 = new THREE.Mesh(tube([[2.3857, 7.9, 8.8], [0.28, 17.2, 8.4]], 0.035, 1, 3), ropeMat);
  shroudforeMast3.name = 'shroudforeMast';
  rigging.add(shroudforeMast3);
  const shroudforeMast4 = new THREE.Mesh(tube([[-2.8967, 7.9, 6.8], [-0.28, 17.2, 8.4]], 0.035, 1, 3), ropeMat);
  shroudforeMast4.name = 'shroudforeMast';
  rigging.add(shroudforeMast4);
  const shroudforeMast5 = new THREE.Mesh(tube([[-2.6633, 7.9, 7.8], [-0.28, 17.2, 8.4]], 0.035, 1, 3), ropeMat);
  shroudforeMast5.name = 'shroudforeMast';
  rigging.add(shroudforeMast5);
  const shroudforeMast6 = new THREE.Mesh(tube([[-2.3857, 7.9, 8.8], [-0.28, 17.2, 8.4]], 0.035, 1, 3), ropeMat);
  shroudforeMast6.name = 'shroudforeMast';
  rigging.add(shroudforeMast6);
  const shroudmainMast = new THREE.Mesh(tube([[3.628, 6.2, -0.6], [0.28, 19.5, 1]], 0.035, 1, 3), ropeMat);
  shroudmainMast.name = 'shroudmainMast';
  rigging.add(shroudmainMast);
  const shroudmainMast2 = new THREE.Mesh(tube([[3.598, 6.2, 0.4], [0.28, 19.5, 1]], 0.035, 1, 3), ropeMat);
  shroudmainMast2.name = 'shroudmainMast';
  rigging.add(shroudmainMast2);
  const shroudmainMast3 = new THREE.Mesh(tube([[3.568, 6.2, 1.4], [0.28, 19.5, 1]], 0.035, 1, 3), ropeMat);
  shroudmainMast3.name = 'shroudmainMast';
  rigging.add(shroudmainMast3);
  const shroudmainMast4 = new THREE.Mesh(tube([[-3.628, 6.2, -0.6], [-0.28, 19.5, 1]], 0.035, 1, 3), ropeMat);
  shroudmainMast4.name = 'shroudmainMast';
  rigging.add(shroudmainMast4);
  const shroudmainMast5 = new THREE.Mesh(tube([[-3.598, 6.2, 0.4], [-0.28, 19.5, 1]], 0.035, 1, 3), ropeMat);
  shroudmainMast5.name = 'shroudmainMast';
  rigging.add(shroudmainMast5);
  const shroudmainMast6 = new THREE.Mesh(tube([[-3.568, 6.2, 1.4], [-0.28, 19.5, 1]], 0.035, 1, 3), ropeMat);
  shroudmainMast6.name = 'shroudmainMast';
  rigging.add(shroudmainMast6);
  const shroudmizzenMast = new THREE.Mesh(tube([[3.4667, 8.3, -8.2], [0.28, 15.2, -6.6]], 0.035, 1, 3), ropeMat);
  shroudmizzenMast.name = 'shroudmizzenMast';
  rigging.add(shroudmizzenMast);
  const shroudmizzenMast2 = new THREE.Mesh(tube([[3.55, 8.3, -7.2], [0.28, 15.2, -6.6]], 0.035, 1, 3), ropeMat);
  shroudmizzenMast2.name = 'shroudmizzenMast';
  rigging.add(shroudmizzenMast2);
  const shroudmizzenMast3 = new THREE.Mesh(tube([[3.6333, 8.3, -6.2], [0.28, 15.2, -6.6]], 0.035, 1, 3), ropeMat);
  shroudmizzenMast3.name = 'shroudmizzenMast';
  rigging.add(shroudmizzenMast3);
  const shroudmizzenMast4 = new THREE.Mesh(tube([[-3.4667, 8.3, -8.2], [-0.28, 15.2, -6.6]], 0.035, 1, 3), ropeMat);
  shroudmizzenMast4.name = 'shroudmizzenMast';
  rigging.add(shroudmizzenMast4);
  const shroudmizzenMast5 = new THREE.Mesh(tube([[-3.55, 8.3, -7.2], [-0.28, 15.2, -6.6]], 0.035, 1, 3), ropeMat);
  shroudmizzenMast5.name = 'shroudmizzenMast';
  rigging.add(shroudmizzenMast5);
  const shroudmizzenMast6 = new THREE.Mesh(tube([[-3.6333, 8.3, -6.2], [-0.28, 15.2, -6.6]], 0.035, 1, 3), ropeMat);
  shroudmizzenMast6.name = 'shroudmizzenMast';
  rigging.add(shroudmizzenMast6);
  const foreStay = new THREE.Mesh(tube([[0, 23.1, 8.4], [0, 9.3994, 19.3417]], 0.045, 1, 3), ropeMat);
  foreStay.name = 'foreStay';
  rigging.add(foreStay);
  const mainStay = new THREE.Mesh(tube([[0, 26.1, 1], [0, 19.4, 8.4]], 0.045, 1, 3), ropeMat);
  mainStay.name = 'mainStay';
  rigging.add(mainStay);
  const mizzenStay = new THREE.Mesh(tube([[0, 19.8, -6.6], [0, 17.2, 1]], 0.04, 1, 3), ropeMat);
  mizzenStay.name = 'mizzenStay';
  rigging.add(mizzenStay);
  const jib = new THREE.Mesh(extrude([[9.713, 19.8719], [18.7946, 9.9944], [15.8137, 8.4697]], 0.05), sailMat);
  jib.name = 'jib';
  jib.rotation.set(0, deg(-90), 0);
  rigging.add(jib);

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

export default createPirateShip;

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