Codels
1.1K tris2.69 × 3.32 × 1.93 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.
/**
 * Stone Well — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,105 · Size (W × H × D): 2.69 × 3.31 × 1.93 m
 *
 * Usage:
 *   import { createWell } from './well.js';
 *   
 *   const model = createWell();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

export function createWell() {
  const root = new THREE.Group();
  root.name = 'Well';

  // Materials
  const stoneMat = new THREE.MeshStandardMaterial({ name: 'stone', color: 0x8b867d, roughness: 0.95, flatShading: true });
  const stone2Mat = new THREE.MeshStandardMaterial({ name: 'stone2', color: 0x6e6962, roughness: 0.95, flatShading: true });
  const woodMat = new THREE.MeshStandardMaterial({ name: 'wood', color: 0x7a5435, roughness: 0.9, flatShading: true });
  const roofMat = new THREE.MeshStandardMaterial({ name: 'roof', color: 0x7c3b29, roughness: 0.85, flatShading: true });
  const ropeMat = new THREE.MeshStandardMaterial({ name: 'rope', color: 0xcdb685, roughness: 0.95, flatShading: true });
  const waterMat = new THREE.MeshStandardMaterial({ name: 'water', color: 0x2f6e8a, roughness: 0.15, metalness: 0.1, emissive: 0x0d2c3a, emissiveIntensity: 0.6, flatShading: true });
  const metalMat = new THREE.MeshStandardMaterial({ name: 'metal', color: 0x4d5156, roughness: 0.5, metalness: 0.6, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.5638, 0.12, 0.38);
  const boxGeo2 = new THREE.BoxGeometry(0.16, 2.35, 0.16);
  const boxGeo3 = new THREE.BoxGeometry(0.34, 0.14, 0.34);
  const boxGeo4 = new THREE.BoxGeometry(0.09, 0.6727, 0.09);
  const cylinderGeo = new THREE.CylinderGeometry(0.16, 0.16, 0.05, 8);
  const boxGeo5 = new THREE.BoxGeometry(2.54, 0.07, 1.1544);
  const boxGeo6 = new THREE.BoxGeometry(2.56, 0.05, 0.431);
  const boxGeo7 = new THREE.BoxGeometry(0.09, 1.0804, 0.09);
  const boxGeo8 = new THREE.BoxGeometry(0.14, 0.8, 0.14);

  // Parts
  const block = new THREE.Mesh(new THREE.BoxGeometry(0.3722, 0.2691, 0.243), stoneMat);
  block.name = 'block';
  block.position.set(0, 0.15, 0.7266);
  block.rotation.set(0, deg(-0.0753), 0);
  root.add(block);
  const block2 = new THREE.Mesh(new THREE.BoxGeometry(0.3772, 0.2653, 0.2621), stone2Mat);
  block2.name = 'block';
  block2.position.set(0.389, 0.15, 0.6054);
  block2.rotation.set(0, deg(31.0616), 0);
  root.add(block2);
  const block3 = new THREE.Mesh(new THREE.BoxGeometry(0.3898, 0.2759, 0.2752), stone2Mat);
  block3.name = 'block';
  block3.position.set(0.6608, 0.15, 0.3018);
  block3.rotation.set(0, deg(66.2169), 0);
  root.add(block3);
  const block4 = new THREE.Mesh(new THREE.BoxGeometry(0.3976, 0.2705, 0.2733), stoneMat);
  block4.name = 'block';
  block4.position.set(0.7063, 0.15, -0.1016);
  block4.rotation.set(0, deg(96.2282), 0);
  root.add(block4);
  const block5 = new THREE.Mesh(new THREE.BoxGeometry(0.3831, 0.2787, 0.2708), stoneMat);
  block5.name = 'block';
  block5.position.set(0.5527, 0.15, -0.4789);
  block5.rotation.set(0, deg(131.7678), 0);
  root.add(block5);
  const block6 = new THREE.Mesh(new THREE.BoxGeometry(0.3854, 0.2745, 0.2401), stone2Mat);
  block6.name = 'block';
  block6.position.set(0.1999, 0.15, -0.6809);
  block6.rotation.set(0, deg(163.5496), 0);
  root.add(block6);
  const block7 = new THREE.Mesh(new THREE.BoxGeometry(0.3948, 0.2736, 0.2715), stoneMat);
  block7.name = 'block';
  block7.position.set(-0.2059, 0.15, -0.7013);
  block7.rotation.set(0, deg(196.6907), 0);
  root.add(block7);
  const block8 = new THREE.Mesh(new THREE.BoxGeometry(0.3856, 0.2706, 0.2735), stoneMat);
  block8.name = 'block';
  block8.position.set(-0.5344, 0.15, -0.4631);
  block8.rotation.set(0, deg(228.9468), 0);
  root.add(block8);
  const block9 = new THREE.Mesh(new THREE.BoxGeometry(0.3935, 0.2755, 0.2742), stoneMat);
  block9.name = 'block';
  block9.position.set(-0.7126, 0.15, -0.1025);
  block9.rotation.set(0, deg(261.3073), 0);
  root.add(block9);
  const block10 = new THREE.Mesh(new THREE.BoxGeometry(0.3987, 0.2693, 0.2792), stoneMat);
  block10.name = 'block';
  block10.position.set(-0.6601, 0.15, 0.3015);
  block10.rotation.set(0, deg(295.3959), 0);
  root.add(block10);
  const block11 = new THREE.Mesh(new THREE.BoxGeometry(0.4088, 0.2753, 0.2423), stone2Mat);
  block11.name = 'block';
  block11.position.set(-0.3921, 0.15, 0.6102);
  block11.rotation.set(0, deg(327.4231), 0);
  root.add(block11);
  const block12 = new THREE.Mesh(new THREE.BoxGeometry(0.3845, 0.2708, 0.2516), stoneMat);
  block12.name = 'block';
  block12.position.set(0.2059, 0.45, 0.7014);
  block12.rotation.set(0, deg(16.5715), 0);
  root.add(block12);
  const block13 = new THREE.Mesh(new THREE.BoxGeometry(0.3863, 0.2751, 0.2469), stoneMat);
  block13.name = 'block';
  block13.position.set(0.5459, 0.45, 0.473);
  block13.rotation.set(0, deg(49.6632), 0);
  root.add(block13);
  const block14 = new THREE.Mesh(new THREE.BoxGeometry(0.4015, 0.2612, 0.2565), stone2Mat);
  block14.name = 'block';
  block14.position.set(0.7201, 0.45, 0.1035);
  block14.rotation.set(0, deg(82.581), 0);
  root.add(block14);
  const block15 = new THREE.Mesh(new THREE.BoxGeometry(0.3955, 0.2797, 0.2796), stoneMat);
  block15.name = 'block';
  block15.position.set(0.6624, 0.45, -0.3025);
  block15.rotation.set(0, deg(114.8767), 0);
  root.add(block15);
  const block16 = new THREE.Mesh(new THREE.BoxGeometry(0.4087, 0.2763, 0.2526), stoneMat);
  block16.name = 'block';
  block16.position.set(0.3955, 0.45, -0.6155);
  block16.rotation.set(0, deg(149.0485), 0);
  root.add(block16);
  const block17 = new THREE.Mesh(new THREE.BoxGeometry(0.3947, 0.2628, 0.2652), stoneMat);
  block17.name = 'block';
  block17.position.set(0, 0.45, -0.7167);
  block17.rotation.set(0, deg(179.0256), 0);
  root.add(block17);
  const block18 = new THREE.Mesh(new THREE.BoxGeometry(0.3727, 0.277, 0.2435), stoneMat);
  block18.name = 'block';
  block18.position.set(-0.3954, 0.45, -0.6153);
  block18.rotation.set(0, deg(214.2852), 0);
  root.add(block18);
  const block19 = new THREE.Mesh(new THREE.BoxGeometry(0.3975, 0.2621, 0.2515), stoneMat);
  block19.name = 'block';
  block19.position.set(-0.6421, 0.45, -0.2932);
  block19.rotation.set(0, deg(245.548), 0);
  root.add(block19);
  const block20 = new THREE.Mesh(new THREE.BoxGeometry(0.3709, 0.2632, 0.2659), stoneMat);
  block20.name = 'block';
  block20.position.set(-0.7032, 0.45, 0.1011);
  block20.rotation.set(0, deg(279.4927), 0);
  root.add(block20);
  const block21 = new THREE.Mesh(new THREE.BoxGeometry(0.403, 0.2625, 0.2477), stone2Mat);
  block21.name = 'block';
  block21.position.set(-0.5484, 0.45, 0.4752);
  block21.rotation.set(0, deg(311.3459), 0);
  root.add(block21);
  const block22 = new THREE.Mesh(new THREE.BoxGeometry(0.3938, 0.2746, 0.2527), stoneMat);
  block22.name = 'block';
  block22.position.set(-0.2043, 0.45, 0.6959);
  block22.rotation.set(0, deg(342.0137), 0);
  root.add(block22);
  const block23 = new THREE.Mesh(new THREE.BoxGeometry(0.3785, 0.2677, 0.2599), stoneMat);
  block23.name = 'block';
  block23.position.set(0, 0.75, 0.7339);
  block23.rotation.set(0, deg(0.2057), 0);
  root.add(block23);
  const block24 = new THREE.Mesh(new THREE.BoxGeometry(0.3975, 0.2602, 0.2585), stoneMat);
  block24.name = 'block';
  block24.position.set(0.3857, 0.75, 0.6001);
  block24.rotation.set(0, deg(32.0743), 0);
  root.add(block24);
  const block25 = new THREE.Mesh(new THREE.BoxGeometry(0.3855, 0.2798, 0.2432), stone2Mat);
  block25.name = 'block';
  block25.position.set(0.6536, 0.75, 0.2985);
  block25.rotation.set(0, deg(64.1942), 0);
  root.add(block25);
  const block26 = new THREE.Mesh(new THREE.BoxGeometry(0.4054, 0.2754, 0.2736), stone2Mat);
  block26.name = 'block';
  block26.position.set(0.7016, 0.75, -0.1009);
  block26.rotation.set(0, deg(96.4397), 0);
  root.add(block26);
  const block27 = new THREE.Mesh(new THREE.BoxGeometry(0.3811, 0.2627, 0.2451), stoneMat);
  block27.name = 'block';
  block27.position.set(0.5404, 0.75, -0.4683);
  block27.rotation.set(0, deg(129.8355), 0);
  root.add(block27);
  const block28 = new THREE.Mesh(new THREE.BoxGeometry(0.3926, 0.2693, 0.2554), stoneMat);
  block28.name = 'block';
  block28.position.set(0.1988, 0.75, -0.677);
  block28.rotation.set(0, deg(165.2137), 0);
  root.add(block28);
  const block29 = new THREE.Mesh(new THREE.BoxGeometry(0.3823, 0.2665, 0.2512), stone2Mat);
  block29.name = 'block';
  block29.position.set(-0.2063, 0.75, -0.7024);
  block29.rotation.set(0, deg(197.4312), 0);
  root.add(block29);
  const block30 = new THREE.Mesh(new THREE.BoxGeometry(0.3785, 0.2675, 0.2794), stone2Mat);
  block30.name = 'block';
  block30.position.set(-0.5331, 0.75, -0.4619);
  block30.rotation.set(0, deg(229.3533), 0);
  root.add(block30);
  const block31 = new THREE.Mesh(new THREE.BoxGeometry(0.3945, 0.2763, 0.241), stoneMat);
  block31.name = 'block';
  block31.position.set(-0.7027, 0.75, -0.101);
  block31.rotation.set(0, deg(261.0724), 0);
  root.add(block31);
  const block32 = new THREE.Mesh(new THREE.BoxGeometry(0.3713, 0.2695, 0.2673), stoneMat);
  block32.name = 'block';
  block32.position.set(-0.6436, 0.75, 0.2939);
  block32.rotation.set(0, deg(294.7106), 0);
  root.add(block32);
  const block33 = new THREE.Mesh(new THREE.BoxGeometry(0.4055, 0.2726, 0.2748), stoneMat);
  block33.name = 'block';
  block33.position.set(-0.3904, 0.75, 0.6075);
  block33.rotation.set(0, deg(327.6787), 0);
  root.add(block33);
  const capstone = new THREE.Mesh(boxGeo, stone2Mat);
  capstone.name = 'capstone';
  capstone.position.set(0.1444, 0.96, 0.7258);
  capstone.rotation.set(0, deg(11.25), 0);
  root.add(capstone);
  const capstone2 = new THREE.Mesh(boxGeo, stone2Mat);
  capstone2.name = 'capstone';
  capstone2.position.set(0.6153, 0.96, 0.4111);
  capstone2.rotation.set(0, deg(56.25), 0);
  root.add(capstone2);
  const capstone3 = new THREE.Mesh(boxGeo, stone2Mat);
  capstone3.name = 'capstone';
  capstone3.position.set(0.7258, 0.96, -0.1444);
  capstone3.rotation.set(0, deg(101.25), 0);
  root.add(capstone3);
  const capstone4 = new THREE.Mesh(boxGeo, stone2Mat);
  capstone4.name = 'capstone';
  capstone4.position.set(0.4111, 0.96, -0.6153);
  capstone4.rotation.set(0, deg(146.25), 0);
  root.add(capstone4);
  const capstone5 = new THREE.Mesh(boxGeo, stone2Mat);
  capstone5.name = 'capstone';
  capstone5.position.set(-0.1444, 0.96, -0.7258);
  capstone5.rotation.set(0, deg(191.25), 0);
  root.add(capstone5);
  const capstone6 = new THREE.Mesh(boxGeo, stone2Mat);
  capstone6.name = 'capstone';
  capstone6.position.set(-0.6153, 0.96, -0.4111);
  capstone6.rotation.set(0, deg(236.25), 0);
  root.add(capstone6);
  const capstone7 = new THREE.Mesh(boxGeo, stone2Mat);
  capstone7.name = 'capstone';
  capstone7.position.set(-0.7258, 0.96, 0.1444);
  capstone7.rotation.set(0, deg(281.25), 0);
  root.add(capstone7);
  const capstone8 = new THREE.Mesh(boxGeo, stone2Mat);
  capstone8.name = 'capstone';
  capstone8.position.set(-0.4111, 0.96, 0.6153);
  capstone8.rotation.set(0, deg(326.25), 0);
  root.add(capstone8);
  const shaftLining = new THREE.Mesh(new THREE.CylinderGeometry(0.585, 0.585, 0.96, 11, 1, true), stone2Mat);
  shaftLining.name = 'shaftLining';
  shaftLining.position.set(0, 0.5, 0);
  root.add(shaftLining);
  const water = new THREE.Mesh(new THREE.CircleGeometry(0.595, 11), waterMat);
  water.name = 'water';
  water.position.set(0, 0.58, 0);
  water.rotation.set(deg(-90), 0, 0);
  root.add(water);
  const post = new THREE.Mesh(boxGeo2, woodMat);
  post.name = 'post';
  post.position.set(-0.97, 1.175, 0);
  root.add(post);
  const postFoot = new THREE.Mesh(boxGeo3, stone2Mat);
  postFoot.name = 'postFoot';
  postFoot.position.set(-0.97, 0.07, 0);
  root.add(postFoot);
  const brace = new THREE.Mesh(boxGeo4, woodMat);
  brace.name = 'brace';
  brace.position.set(-0.745, 2.05, 0);
  brace.rotation.set(0, deg(180), deg(41.9872));
  root.add(brace);
  const post2 = new THREE.Mesh(boxGeo2, woodMat);
  post2.name = 'post';
  post2.position.set(0.97, 1.175, 0);
  root.add(post2);
  const postFoot2 = new THREE.Mesh(boxGeo3, stone2Mat);
  postFoot2.name = 'postFoot';
  postFoot2.position.set(0.97, 0.07, 0);
  root.add(postFoot2);
  const brace2 = new THREE.Mesh(boxGeo4, woodMat);
  brace2.name = 'brace';
  brace2.position.set(0.745, 2.05, 0);
  brace2.rotation.set(0, 0, deg(41.9872));
  root.add(brace2);
  const crossbeam = new THREE.Mesh(new THREE.BoxGeometry(2.3, 0.15, 0.16), woodMat);
  crossbeam.name = 'crossbeam';
  crossbeam.position.set(0, 2.395, 0);
  root.add(crossbeam);
  const axle = new THREE.Mesh(new THREE.CylinderGeometry(0.05, 0.05, 2.24, 6), woodMat);
  axle.name = 'axle';
  axle.position.set(0.07, 1.85, 0);
  axle.rotation.set(0, 0, deg(90));
  root.add(axle);
  const ropeDrum = new THREE.Mesh(new THREE.CylinderGeometry(0.13, 0.13, 0.765, 8), ropeMat);
  ropeDrum.name = 'ropeDrum';
  ropeDrum.position.set(0, 1.85, 0);
  ropeDrum.rotation.set(0, 0, deg(90));
  root.add(ropeDrum);
  const drumFlange = new THREE.Mesh(cylinderGeo, woodMat);
  drumFlange.name = 'drumFlange';
  drumFlange.position.set(-0.3825, 1.85, 0);
  drumFlange.rotation.set(0, 0, deg(90));
  root.add(drumFlange);
  const drumFlange2 = new THREE.Mesh(cylinderGeo, woodMat);
  drumFlange2.name = 'drumFlange';
  drumFlange2.position.set(0.3825, 1.85, 0);
  drumFlange2.rotation.set(0, 0, deg(90));
  root.add(drumFlange2);
  const crankArm = new THREE.Mesh(new THREE.BoxGeometry(0.05, 0.38, 0.07), metalMat);
  crankArm.name = 'crankArm';
  crankArm.position.set(1.15, 1.7, 0);
  root.add(crankArm);
  const crankHandle = new THREE.Mesh(new THREE.CylinderGeometry(0.035, 0.035, 0.24, 6), woodMat);
  crankHandle.name = 'crankHandle';
  crankHandle.position.set(1.27, 1.54, 0);
  crankHandle.rotation.set(0, 0, deg(90));
  root.add(crankHandle);
  const rope = new THREE.Mesh(new THREE.CylinderGeometry(0.014, 0.014, 0.15, 4), ropeMat);
  rope.name = 'rope';
  rope.position.set(0, 1.645, 0);
  root.add(rope);
  const bucket = new THREE.Mesh(new THREE.CylinderGeometry(0.16, 0.13, 0.3, 8), woodMat);
  bucket.name = 'bucket';
  bucket.position.set(0, 1.27, 0);
  root.add(bucket);
  const bucketBand = new THREE.Mesh(new THREE.CylinderGeometry(0.165, 0.165, 0.035, 8), metalMat);
  bucketBand.name = 'bucketBand';
  bucketBand.position.set(0, 1.36, 0);
  root.add(bucketBand);
  const bucketBand2 = new THREE.Mesh(new THREE.CylinderGeometry(0.145, 0.145, 0.035, 8), metalMat);
  bucketBand2.name = 'bucketBand';
  bucketBand2.position.set(0, 1.18, 0);
  root.add(bucketBand2);
  const bucketHandle = new THREE.Mesh(new THREE.TorusGeometry(0.15, 0.012, 3, 8, Math.PI), metalMat);
  bucketHandle.name = 'bucketHandle';
  bucketHandle.position.set(0, 1.42, 0);
  root.add(bucketHandle);
  const roofSlab = new THREE.Mesh(boxGeo5, roofMat);
  roofSlab.name = 'roofSlab';
  roofSlab.position.set(0, 2.7892, -0.4167);
  roofSlab.rotation.set(deg(-43), 0, 0);
  root.add(roofSlab);
  const shingles = new THREE.Mesh(boxGeo6, roofMat);
  shingles.name = 'shingles';
  shingles.position.set(0, 3.0992, -0.1797);
  shingles.rotation.set(deg(-49), 0, 0);
  root.add(shingles);
  const shingles2 = new THREE.Mesh(boxGeo6, roofMat);
  shingles2.name = 'shingles';
  shingles2.position.set(0, 2.8368, -0.4611);
  shingles2.rotation.set(deg(-49), 0, 0);
  root.add(shingles2);
  const shingles3 = new THREE.Mesh(boxGeo6, roofMat);
  shingles3.name = 'shingles';
  shingles3.position.set(0, 2.5743, -0.7425);
  shingles3.rotation.set(deg(-49), 0, 0);
  root.add(shingles3);
  const rafter = new THREE.Mesh(boxGeo7, woodMat);
  rafter.name = 'rafter';
  rafter.position.set(-0.97, 2.725, -0.3575);
  rafter.rotation.set(0, deg(-90), deg(138.5646));
  root.add(rafter);
  const rafter2 = new THREE.Mesh(boxGeo7, woodMat);
  rafter2.name = 'rafter';
  rafter2.position.set(0.97, 2.725, -0.3575);
  rafter2.rotation.set(0, deg(-90), deg(138.5646));
  root.add(rafter2);
  const roofSlab2 = new THREE.Mesh(boxGeo5, roofMat);
  roofSlab2.name = 'roofSlab';
  roofSlab2.position.set(0, 2.7892, 0.4167);
  roofSlab2.rotation.set(deg(43), 0, 0);
  root.add(roofSlab2);
  const shingles4 = new THREE.Mesh(boxGeo6, roofMat);
  shingles4.name = 'shingles';
  shingles4.position.set(0, 3.0992, 0.1797);
  shingles4.rotation.set(deg(49), 0, 0);
  root.add(shingles4);
  const shingles5 = new THREE.Mesh(boxGeo6, roofMat);
  shingles5.name = 'shingles';
  shingles5.position.set(0, 2.8368, 0.4611);
  shingles5.rotation.set(deg(49), 0, 0);
  root.add(shingles5);
  const shingles6 = new THREE.Mesh(boxGeo6, roofMat);
  shingles6.name = 'shingles';
  shingles6.position.set(0, 2.5743, 0.7425);
  shingles6.rotation.set(deg(49), 0, 0);
  root.add(shingles6);
  const rafter3 = new THREE.Mesh(boxGeo7, woodMat);
  rafter3.name = 'rafter';
  rafter3.position.set(-0.97, 2.725, 0.3575);
  rafter3.rotation.set(0, deg(90), deg(138.5646));
  root.add(rafter3);
  const rafter4 = new THREE.Mesh(boxGeo7, woodMat);
  rafter4.name = 'rafter';
  rafter4.position.set(0.97, 2.725, 0.3575);
  rafter4.rotation.set(0, deg(90), deg(138.5646));
  root.add(rafter4);
  const ridge = new THREE.Mesh(new THREE.BoxGeometry(2.6, 0.12, 0.12), woodMat);
  ridge.name = 'ridge';
  ridge.position.set(0, 3.23, 0);
  ridge.rotation.set(deg(45), 0, 0);
  root.add(ridge);
  const kingPost = new THREE.Mesh(boxGeo8, woodMat);
  kingPost.name = 'kingPost';
  kingPost.position.set(-0.97, 2.85, 0);
  root.add(kingPost);
  const kingPost2 = new THREE.Mesh(boxGeo8, woodMat);
  kingPost2.name = 'kingPost';
  kingPost2.position.set(0.97, 2.85, 0);
  root.add(kingPost2);

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

export default createWell;

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