Codels
408 tris2.00 × 2.00 × 2.00 m

Use it in code

Remix in the editor
Self-contained ES module — only depends on three. Call the factory and add the group to your scene.
/**
 * Warp Pipe — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 408 · Size (W × H × D): 2.00 × 2.00 × 2.00 m
 *
 * Usage:
 *   import { createWarpPipe } from './warp-pipe.js';
 *   
 *   const model = createWarpPipe();
 *   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);
}

export function createWarpPipe() {
  const root = new THREE.Group();
  root.name = 'WarpPipe';

  // Materials
  const pipeMat = new THREE.MeshStandardMaterial({ name: 'pipe', color: 0x38b54a, roughness: 0.35, flatShading: true });
  const shineMat = new THREE.MeshStandardMaterial({ name: 'shine', color: 0x9cdaa5, roughness: 0.3, flatShading: true });
  const insideMat = new THREE.MeshStandardMaterial({ name: 'inside', color: 0x0f3116, roughness: 0.9, flatShading: true });

  // Parts
  const body = new THREE.Mesh(new THREE.CylinderGeometry(0.86, 0.86, 1.56, 20, 1, true), pipeMat);
  body.name = 'body';
  body.position.set(0, 0.78, 0);
  root.add(body);
  const lip = new THREE.Mesh(lathe([[0.84, 1.5], [1, 1.5], [1, 1.95], [0.95, 2], [0.77, 2], [0.74, 1.97], [0.74, 1.82]], 20), pipeMat);
  lip.name = 'lip';
  root.add(lip);
  const opening = new THREE.Mesh(lathe([[0.74, 1.82], [0.74, 0.6], [0, 0.6]], 20), insideMat);
  opening.name = 'opening';
  root.add(opening);
  const shineBody1 = new THREE.Mesh(new THREE.BoxGeometry(0.16, 1.38, 0.02), shineMat);
  shineBody1.name = 'shineBody1';
  shineBody1.position.set(-0.3874, 0.75, 0.7604);
  shineBody1.rotation.set(0, deg(-27), 0);
  root.add(shineBody1);
  const shineLip1 = new THREE.Mesh(new THREE.BoxGeometry(0.16, 0.37, 0.02), shineMat);
  shineLip1.name = 'shineLip1';
  shineLip1.position.set(-0.4502, 1.725, 0.8836);
  shineLip1.rotation.set(0, deg(-27), 0);
  root.add(shineLip1);
  const shineBody2 = new THREE.Mesh(new THREE.BoxGeometry(0.06, 1.38, 0.02), shineMat);
  shineBody2.name = 'shineBody2';
  shineBody2.position.set(-0.1335, 0.75, 0.8429);
  shineBody2.rotation.set(0, deg(-9), 0);
  root.add(shineBody2);
  const shineLip2 = new THREE.Mesh(new THREE.BoxGeometry(0.06, 0.37, 0.02), shineMat);
  shineLip2.name = 'shineLip2';
  shineLip2.position.set(-0.1551, 1.725, 0.9795);
  shineLip2.rotation.set(0, deg(-9), 0);
  root.add(shineLip2);

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

export default createWarpPipe;

Ratings & comments

—
No ratings yet — be the first.
5
0
4
0
3
0
2
0
1
0

Sign in to rate and comment.

0 comments

No comments yet. Share how you used this model or what could be better.

Related models

Same category or similar tags