Codels
1,5 k tris1,51 × 0,69 × 3,04 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.
/**
 * Rowboat — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,488 · Size (W × H × D): 1.51 × 0.69 × 3.04 m
 *
 * Usage:
 *   import { createRowboat } from './rowboat.js';
 *   
 *   const model = createRowboat();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

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

  // Materials
  const paintMat = new THREE.MeshStandardMaterial({ name: 'paint', color: 0x3e7bab, roughness: 0.65, flatShading: true });
  const bandMat = new THREE.MeshStandardMaterial({ name: 'band', color: 0xefe9dc, roughness: 0.7, flatShading: true });
  const woodMat = new THREE.MeshStandardMaterial({ name: 'wood', color: 0xb98654, roughness: 0.9, flatShading: true, side: THREE.DoubleSide });
  const darkWoodMat = new THREE.MeshStandardMaterial({ name: 'darkWood', color: 0x6f4a2c, roughness: 0.9, flatShading: true });
  const metalMat = new THREE.MeshStandardMaterial({ name: 'metal', color: 0x8f969e, roughness: 0.4, metalness: 0.6, flatShading: true });

  // Shared geometries
  const sphereGeo = new THREE.SphereGeometry(1, 12, 5, 0, Math.PI, Math.PI / 2, Math.PI / 2);
  const sphereGeo2 = new THREE.SphereGeometry(1, 12, 5, Math.PI, Math.PI, Math.PI / 2, Math.PI / 2);
  const boxGeo = new THREE.BoxGeometry(0.12, 0.025, 1.5);
  const torusGeo = new THREE.TorusGeometry(0.055, 0.014, 4, 8);
  const cylinderGeo = new THREE.CylinderGeometry(0.026, 0.026, 1.9, 6);
  const boxGeo2 = new THREE.BoxGeometry(0.5, 0.026, 0.16);
  const boxGeo3 = new THREE.BoxGeometry(0.18, 0.034, 0.05);

  // Parts
  const hull = new THREE.Group();
  hull.name = 'hull';
  root.add(hull);
  const hullBow = new THREE.Mesh(sphereGeo, paintMat);
  hullBow.name = 'hullBow';
  hullBow.position.set(0, 0.535, 0);
  hullBow.scale.set(0.7, 0.5, 1.8);
  hull.add(hullBow);
  const innerBow = new THREE.Mesh(sphereGeo, woodMat);
  innerBow.name = 'innerBow';
  innerBow.position.set(0, 0.535, 0);
  innerBow.scale.set(0.66, 0.46, 1.76);
  hull.add(innerBow);
  const bandBow = new THREE.Mesh(new THREE.SphereGeometry(1, 12, 1, 0, Math.PI, Math.PI / 2, 0.2), bandMat);
  bandBow.name = 'bandBow';
  bandBow.position.set(0, 0.535, 0);
  bandBow.scale.set(0.7056, 0.504, 1.8144);
  hull.add(bandBow);
  const hullStern = new THREE.Mesh(sphereGeo2, paintMat);
  hullStern.name = 'hullStern';
  hullStern.position.set(0, 0.535, 0);
  hullStern.scale.set(0.7, 0.5, 1.2);
  hull.add(hullStern);
  const innerStern = new THREE.Mesh(sphereGeo2, woodMat);
  innerStern.name = 'innerStern';
  innerStern.position.set(0, 0.535, 0);
  innerStern.scale.set(0.66, 0.46, 1.16);
  hull.add(innerStern);
  const bandStern = new THREE.Mesh(new THREE.SphereGeometry(1, 12, 1, Math.PI, Math.PI, Math.PI / 2, 0.2), bandMat);
  bandStern.name = 'bandStern';
  bandStern.position.set(0, 0.535, 0);
  bandStern.scale.set(0.7056, 0.504, 1.2096);
  hull.add(bandStern);
  const gunwale = new THREE.Mesh(tube([[0.68, 0.57, 0], [0.6467, 0.57, 0.5501], [0.5501, 0.57, 1.0463], [0.3997, 0.57, 1.4401], [0.2101, 0.57, 1.6929], [0, 0.57, 1.78], [-0.2101, 0.57, 1.6929], [-0.3997, 0.57, 1.4401], [-0.5501, 0.57, 1.0463], [-0.6467, 0.57, 0.5501], [-0.68, 0.57, 0], [-0.6467, 0.57, -0.3646], [-0.5501, 0.57, -0.6936], [-0.3997, 0.57, -0.9546], [-0.2101, 0.57, -1.1222], [0, 0.57, -1.18], [0.2101, 0.57, -1.1222], [0.3997, 0.57, -0.9546], [0.5501, 0.57, -0.6936], [0.6467, 0.57, -0.3646]], 0.042, 40, 6, true), darkWoodMat);
  gunwale.name = 'gunwale';
  hull.add(gunwale);
  const keel = new THREE.Mesh(tube([[0, 0.339, -1.104], [0, 0.1447, -0.75], [0, 0.063, -0.396], [0, 0.0353, -0.042], [0, 0.0426, 0.312], [0, 0.0705, 0.666], [0, 0.123, 1.02], [0, 0.212, 1.374], [0, 0.395, 1.728]], 0.035, 16, 5), darkWoodMat);
  keel.name = 'keel';
  hull.add(keel);
  const stemPost = new THREE.Mesh(new THREE.BoxGeometry(0.07, 0.26, 0.07), darkWoodMat);
  stemPost.name = 'stemPost';
  stemPost.position.set(0, 0.555, 1.77);
  stemPost.rotation.set(deg(-12), 0, 0);
  hull.add(stemPost);
  const sternBoard = new THREE.Mesh(new THREE.BoxGeometry(0.5, 0.18, 0.05), darkWoodMat);
  sternBoard.name = 'sternBoard';
  sternBoard.position.set(0, 0.495, -1.18);
  hull.add(sternBoard);
  const seatBow = new THREE.Mesh(new THREE.BoxGeometry(1.0456, 0.045, 0.22), darkWoodMat);
  seatBow.name = 'seatBow';
  seatBow.position.set(0, 0.405, 0.99);
  hull.add(seatBow);
  const seatMiddle = new THREE.Mesh(new THREE.BoxGeometry(1.2816, 0.045, 0.26), darkWoodMat);
  seatMiddle.name = 'seatMiddle';
  seatMiddle.position.set(0, 0.405, 0.144);
  hull.add(seatMiddle);
  const seatStern = new THREE.Mesh(new THREE.BoxGeometry(1.0863, 0.045, 0.3), darkWoodMat);
  seatStern.name = 'seatStern';
  seatStern.position.set(0, 0.405, -0.6);
  hull.add(seatStern);
  const floorboard1 = new THREE.Mesh(boxGeo, darkWoodMat);
  floorboard1.name = 'floorboard1';
  floorboard1.position.set(-0.16, 0.135, 0.12);
  hull.add(floorboard1);
  const floorboard2 = new THREE.Mesh(boxGeo, darkWoodMat);
  floorboard2.name = 'floorboard2';
  floorboard2.position.set(0, 0.135, 0.12);
  hull.add(floorboard2);
  const floorboard3 = new THREE.Mesh(boxGeo, darkWoodMat);
  floorboard3.name = 'floorboard3';
  floorboard3.position.set(0.16, 0.135, 0.12);
  hull.add(floorboard3);
  const oars = new THREE.Group();
  oars.name = 'oars';
  root.add(oars);
  const oarlockL = new THREE.Mesh(torusGeo, metalMat);
  oarlockL.name = 'oarlockL';
  oarlockL.position.set(0.6849, 0.615, -0.144);
  oars.add(oarlockL);
  const oarL = new THREE.Group();
  oarL.name = 'oarL';
  oarL.position.set(0.2, 0.4545, -0.45);
  oarL.rotation.set(0, deg(-90), 0);
  oars.add(oarL);
  const shaft = new THREE.Mesh(cylinderGeo, woodMat);
  shaft.name = 'shaft';
  shaft.position.set(0.5, 0, 0);
  shaft.rotation.set(0, 0, deg(90));
  oarL.add(shaft);
  const blade = new THREE.Mesh(boxGeo2, bandMat);
  blade.name = 'blade';
  blade.position.set(1.65, 0, 0);
  oarL.add(blade);
  const grip = new THREE.Mesh(boxGeo3, darkWoodMat);
  grip.name = 'grip';
  grip.position.set(-0.4, 0, 0);
  oarL.add(grip);
  const oarlockR = new THREE.Mesh(torusGeo, metalMat);
  oarlockR.name = 'oarlockR';
  oarlockR.position.set(-0.6849, 0.615, -0.144);
  oars.add(oarlockR);
  const oarR = new THREE.Group();
  oarR.name = 'oarR';
  oarR.position.set(-0.2, 0.5045, -0.45);
  oarR.rotation.set(0, deg(90), 0);
  oars.add(oarR);
  const shaft2 = new THREE.Mesh(cylinderGeo, woodMat);
  shaft2.name = 'shaft';
  shaft2.position.set(-0.5, 0, 0);
  shaft2.rotation.set(0, 0, deg(90));
  oarR.add(shaft2);
  const blade2 = new THREE.Mesh(boxGeo2, bandMat);
  blade2.name = 'blade';
  blade2.position.set(-1.65, 0, 0);
  oarR.add(blade2);
  const grip2 = new THREE.Mesh(boxGeo3, darkWoodMat);
  grip2.name = 'grip';
  grip2.position.set(0.4, 0, 0);
  oarR.add(grip2);

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

export default createRowboat;

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