Codels
592 tris3,42 × 2,14 × 1,89 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.
/**
 * Solar Panel Array — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 592 · Size (W × H × D): 3.42 × 2.14 × 1.89 m
 *
 * Usage:
 *   import { createSolarPanel } from './solar-panel.js';
 *   
 *   const model = createSolarPanel();
 *   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 createSolarPanel() {
  const root = new THREE.Group();
  root.name = 'SolarPanel';

  // Materials
  const cellsMat = new THREE.MeshStandardMaterial({ name: 'cells', color: 0x21427e, roughness: 0.22, metalness: 0.45, flatShading: true });
  const frameMat = new THREE.MeshStandardMaterial({ name: 'frame', color: 0xc9ced5, roughness: 0.35, metalness: 0.6, flatShading: true });
  const steelMat = new THREE.MeshStandardMaterial({ name: 'steel', color: 0x6f7780, roughness: 0.5, metalness: 0.55, flatShading: true });
  const concreteMat = new THREE.MeshStandardMaterial({ name: 'concrete', color: 0xa7a299, roughness: 0.95, flatShading: true });
  const ledMat = new THREE.MeshStandardMaterial({ name: 'led', color: 0x5dff7a, roughness: 0.4, emissive: 0x3dff5f, emissiveIntensity: 1.6, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.5, 0.25, 0.5);
  const boxGeo2 = new THREE.BoxGeometry(0.13, 1.12, 0.13);
  const boxGeo3 = new THREE.BoxGeometry(0.2, 0.16, 0.2);
  const boxGeo4 = new THREE.BoxGeometry(0.06, 0.08, 1.932);
  const boxGeo5 = new THREE.BoxGeometry(1.62, 0.05, 2.1);
  const boxGeo6 = new THREE.BoxGeometry(1.54, 0.04, 2.02);
  const boxGeo7 = new THREE.BoxGeometry(0.014, 0.012, 2.02);
  const boxGeo8 = new THREE.BoxGeometry(1.54, 0.012, 0.014);
  const boxGeo9 = new THREE.BoxGeometry(0.04, 0.035, 2.1);
  const boxGeo10 = new THREE.BoxGeometry(1.62, 0.035, 0.04);

  // Parts
  const stand = new THREE.Group();
  stand.name = 'stand';
  root.add(stand);
  const footing1 = new THREE.Mesh(boxGeo, concreteMat);
  footing1.name = 'footing1';
  footing1.position.set(-1.36, 0.125, 0);
  stand.add(footing1);
  const post1 = new THREE.Mesh(boxGeo2, steelMat);
  post1.name = 'post1';
  post1.position.set(-1.36, 0.81, 0);
  stand.add(post1);
  const bearing1 = new THREE.Mesh(boxGeo3, steelMat);
  bearing1.name = 'bearing1';
  bearing1.position.set(-1.36, 1.39, 0);
  stand.add(bearing1);
  const footing2 = new THREE.Mesh(boxGeo, concreteMat);
  footing2.name = 'footing2';
  footing2.position.set(1.36, 0.125, 0);
  stand.add(footing2);
  const post2 = new THREE.Mesh(boxGeo2, steelMat);
  post2.name = 'post2';
  post2.position.set(1.36, 0.81, 0);
  stand.add(post2);
  const bearing2 = new THREE.Mesh(boxGeo3, steelMat);
  bearing2.name = 'bearing2';
  bearing2.position.set(1.36, 1.39, 0);
  stand.add(bearing2);
  const junctionBox = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.32, 0.12), frameMat);
  junctionBox.name = 'junctionBox';
  junctionBox.position.set(-1.36, 0.85, 0.13);
  stand.add(junctionBox);
  const statusLight = new THREE.Mesh(new THREE.BoxGeometry(0.05, 0.05, 0.02), ledMat);
  statusLight.name = 'statusLight';
  statusLight.position.set(-1.29, 0.94, 0.195);
  stand.add(statusLight);
  const cable = new THREE.Mesh(tube([[-1.42, 0.69, 0.13], [-1.48, 0.45, 0.2], [-1.56, 0.26, 0.3], [-1.66, 0.02, 0.38]], 0.022, 8, 5), steelMat);
  cable.name = 'cable';
  stand.add(cable);
  const panelArray = new THREE.Group();
  panelArray.name = 'panelArray';
  panelArray.position.set(0, 1.45, 0);
  panelArray.rotation.set(deg(28), 0, 0);
  root.add(panelArray);
  const torqueTube = new THREE.Mesh(new THREE.CylinderGeometry(0.07, 0.07, 3.42, 8), steelMat);
  torqueTube.name = 'torqueTube';
  torqueTube.rotation.set(0, 0, deg(90));
  panelArray.add(torqueTube);
  const panel1 = new THREE.Group();
  panel1.name = 'panel1';
  panel1.position.set(-0.85, 0, 0);
  panelArray.add(panel1);
  const box14 = new THREE.Mesh(boxGeo4, steelMat);
  box14.position.set(-0.486, 0.1, 0);
  panel1.add(box14);
  const box15 = new THREE.Mesh(boxGeo4, steelMat);
  box15.position.set(0.486, 0.1, 0);
  panel1.add(box15);
  const frame = new THREE.Mesh(boxGeo5, frameMat);
  frame.name = 'frame';
  frame.position.set(0, 0.165, 0);
  panel1.add(frame);
  const cells = new THREE.Mesh(boxGeo6, cellsMat);
  cells.name = 'cells';
  cells.position.set(0, 0.19, 0);
  panel1.add(cells);
  const box18 = new THREE.Mesh(boxGeo7, frameMat);
  box18.position.set(-0.385, 0.214, 0);
  panel1.add(box18);
  const box19 = new THREE.Mesh(boxGeo7, frameMat);
  box19.position.set(0, 0.214, 0);
  panel1.add(box19);
  const box20 = new THREE.Mesh(boxGeo7, frameMat);
  box20.position.set(0.385, 0.214, 0);
  panel1.add(box20);
  const box21 = new THREE.Mesh(boxGeo8, frameMat);
  box21.position.set(0, 0.214, -0.6733);
  panel1.add(box21);
  const box22 = new THREE.Mesh(boxGeo8, frameMat);
  box22.position.set(0, 0.214, -0.3367);
  panel1.add(box22);
  const box23 = new THREE.Mesh(boxGeo8, frameMat);
  box23.position.set(0, 0.214, 0);
  panel1.add(box23);
  const box24 = new THREE.Mesh(boxGeo8, frameMat);
  box24.position.set(0, 0.214, 0.3367);
  panel1.add(box24);
  const box25 = new THREE.Mesh(boxGeo8, frameMat);
  box25.position.set(0, 0.214, 0.6733);
  panel1.add(box25);
  const box26 = new THREE.Mesh(boxGeo9, frameMat);
  box26.position.set(-0.79, 0.205, 0);
  panel1.add(box26);
  const box27 = new THREE.Mesh(boxGeo10, frameMat);
  box27.position.set(0, 0.205, -1.03);
  panel1.add(box27);
  const box28 = new THREE.Mesh(boxGeo9, frameMat);
  box28.position.set(0.79, 0.205, 0);
  panel1.add(box28);
  const box29 = new THREE.Mesh(boxGeo10, frameMat);
  box29.position.set(0, 0.205, 1.03);
  panel1.add(box29);
  const panel2 = new THREE.Group();
  panel2.name = 'panel2';
  panel2.position.set(0.85, 0, 0);
  panelArray.add(panel2);
  const box31 = new THREE.Mesh(boxGeo4, steelMat);
  box31.position.set(-0.486, 0.1, 0);
  panel2.add(box31);
  const box32 = new THREE.Mesh(boxGeo4, steelMat);
  box32.position.set(0.486, 0.1, 0);
  panel2.add(box32);
  const frame2 = new THREE.Mesh(boxGeo5, frameMat);
  frame2.name = 'frame';
  frame2.position.set(0, 0.165, 0);
  panel2.add(frame2);
  const cells2 = new THREE.Mesh(boxGeo6, cellsMat);
  cells2.name = 'cells';
  cells2.position.set(0, 0.19, 0);
  panel2.add(cells2);
  const box35 = new THREE.Mesh(boxGeo7, frameMat);
  box35.position.set(-0.385, 0.214, 0);
  panel2.add(box35);
  const box36 = new THREE.Mesh(boxGeo7, frameMat);
  box36.position.set(0, 0.214, 0);
  panel2.add(box36);
  const box37 = new THREE.Mesh(boxGeo7, frameMat);
  box37.position.set(0.385, 0.214, 0);
  panel2.add(box37);
  const box38 = new THREE.Mesh(boxGeo8, frameMat);
  box38.position.set(0, 0.214, -0.6733);
  panel2.add(box38);
  const box39 = new THREE.Mesh(boxGeo8, frameMat);
  box39.position.set(0, 0.214, -0.3367);
  panel2.add(box39);
  const box40 = new THREE.Mesh(boxGeo8, frameMat);
  box40.position.set(0, 0.214, 0);
  panel2.add(box40);
  const box41 = new THREE.Mesh(boxGeo8, frameMat);
  box41.position.set(0, 0.214, 0.3367);
  panel2.add(box41);
  const box42 = new THREE.Mesh(boxGeo8, frameMat);
  box42.position.set(0, 0.214, 0.6733);
  panel2.add(box42);
  const box43 = new THREE.Mesh(boxGeo9, frameMat);
  box43.position.set(-0.79, 0.205, 0);
  panel2.add(box43);
  const box44 = new THREE.Mesh(boxGeo10, frameMat);
  box44.position.set(0, 0.205, -1.03);
  panel2.add(box44);
  const box45 = new THREE.Mesh(boxGeo9, frameMat);
  box45.position.set(0.79, 0.205, 0);
  panel2.add(box45);
  const box46 = new THREE.Mesh(boxGeo10, frameMat);
  box46.position.set(0, 0.205, 1.03);
  panel2.add(box46);

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

export default createSolarPanel;

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