Codels
1,2 B üçgen5,84 × 2,05 × 1,57 m
Bağımsız bir ES modülü — yalnızca three paketine bağımlıdır. Fabrika fonksiyonunu çağırıp dönen grubu sahnene ekle.
/**
 * Satellite — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the model (it floats — pickups, planets)
 * Triangles: 1,152 · Size (W × H × D): 5.84 × 2.04 × 1.57 m
 *
 * Usage:
 *   import { createSatellite } from './satellite.js';
 *   
 *   const model = createSatellite();
 *   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);
}

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

  // Materials
  const foilMat = new THREE.MeshStandardMaterial({ name: 'foil', color: 0xd9a83c, roughness: 0.35, metalness: 0.7, flatShading: true });
  const seamMat = new THREE.MeshStandardMaterial({ name: 'seam', color: 0x7a5a1e, roughness: 0.6, metalness: 0.4, flatShading: true });
  const frameMat = new THREE.MeshStandardMaterial({ name: 'frame', color: 0xc9ced6, roughness: 0.35, metalness: 0.7, flatShading: true });
  const panelBackMat = new THREE.MeshStandardMaterial({ name: 'panelBack', color: 0x1b2238, roughness: 0.7, flatShading: true });
  const cellMat = new THREE.MeshStandardMaterial({ name: 'cell', color: 0x2c55b8, roughness: 0.25, metalness: 0.5, flatShading: true });
  const whiteMat = new THREE.MeshStandardMaterial({ name: 'white', color: 0xeef0f3, roughness: 0.45, flatShading: true, side: THREE.DoubleSide });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x2a2d33, roughness: 0.5, metalness: 0.5, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(1.012, 0.025, 1.012);
  const boxGeo2 = new THREE.BoxGeometry(0.8, 0.06, 0.8);
  const cylinderGeo = new THREE.CylinderGeometry(0.035, 0.035, 0.45, 6);
  const cylinderGeo2 = new THREE.CylinderGeometry(0.07, 0.07, 0.1, 8);
  const boxGeo3 = new THREE.BoxGeometry(0.95, 1.05, 0.035);
  const boxGeo4 = new THREE.BoxGeometry(0.97, 0.03, 0.045);
  const boxGeo5 = new THREE.BoxGeometry(0.425, 0.31, 0.012);
  const boxGeo6 = new THREE.BoxGeometry(0.08, 0.05, 0.03);
  const boxGeo7 = new THREE.BoxGeometry(0.04, 0.05, 0.03);

  // Parts
  const bus = new THREE.Mesh(new THREE.BoxGeometry(1, 1.2, 1), foilMat);
  bus.name = 'bus';
  root.add(bus);
  const seamLow = new THREE.Mesh(boxGeo, seamMat);
  seamLow.name = 'seamLow';
  seamLow.position.set(0, -0.3, 0);
  root.add(seamLow);
  const seamHigh = new THREE.Mesh(boxGeo, seamMat);
  seamHigh.name = 'seamHigh';
  seamHigh.position.set(0, 0.3, 0);
  root.add(seamHigh);
  const topDeck = new THREE.Mesh(boxGeo2, frameMat);
  topDeck.name = 'topDeck';
  topDeck.position.set(0, 0.63, 0);
  root.add(topDeck);
  const bottomDeck = new THREE.Mesh(boxGeo2, frameMat);
  bottomDeck.name = 'bottomDeck';
  bottomDeck.position.set(0, -0.63, 0);
  root.add(bottomDeck);
  const thruster = new THREE.Mesh(new THREE.CylinderGeometry(0.08, 0.17, 0.22, 10), darkMat);
  thruster.name = 'thruster';
  thruster.position.set(0, -0.77, 0);
  root.add(thruster);
  const whip1 = new THREE.Mesh(new THREE.CylinderGeometry(0.012, 0.012, 0.55, 5), frameMat);
  whip1.name = 'whip1';
  whip1.position.set(-0.28, 0.9, -0.25);
  whip1.rotation.set(0, 0, deg(18));
  root.add(whip1);
  const whip2 = new THREE.Mesh(new THREE.CylinderGeometry(0.012, 0.012, 0.45, 5), frameMat);
  whip2.name = 'whip2';
  whip2.position.set(0.3, 0.85, -0.3);
  whip2.rotation.set(deg(-15), 0, deg(-12));
  root.add(whip2);
  const beacon = new THREE.Mesh(new THREE.SphereGeometry(0.06, 6, 4), whiteMat);
  beacon.name = 'beacon';
  beacon.position.set(0, 0.7, 0.2);
  root.add(beacon);
  const wingRight = new THREE.Group();
  wingRight.name = 'wingRight';
  wingRight.position.set(0.5, 0, 0);
  wingRight.rotation.set(deg(20), 0, 0);
  root.add(wingRight);
  const arm = new THREE.Mesh(cylinderGeo, frameMat);
  arm.name = 'arm';
  arm.position.set(0.225, 0, 0);
  arm.rotation.set(0, 0, deg(90));
  wingRight.add(arm);
  const drive = new THREE.Mesh(cylinderGeo2, darkMat);
  drive.name = 'drive';
  drive.position.set(0.05, 0, 0);
  drive.rotation.set(0, 0, deg(90));
  wingRight.add(drive);
  const panel1 = new THREE.Mesh(boxGeo3, panelBackMat);
  panel1.name = 'panel1';
  panel1.position.set(0.925, 0, 0);
  wingRight.add(panel1);
  const box14 = new THREE.Mesh(boxGeo4, frameMat);
  box14.position.set(0.925, 0.525, 0);
  wingRight.add(box14);
  const box15 = new THREE.Mesh(boxGeo4, frameMat);
  box15.position.set(0.925, -0.525, 0);
  wingRight.add(box15);
  const box16 = new THREE.Mesh(boxGeo5, cellMat);
  box16.position.set(0.7025, 0.33, 0.02);
  wingRight.add(box16);
  const box17 = new THREE.Mesh(boxGeo5, cellMat);
  box17.position.set(1.1475, 0.33, 0.02);
  wingRight.add(box17);
  const box18 = new THREE.Mesh(boxGeo5, cellMat);
  box18.position.set(0.7025, 0, 0.02);
  wingRight.add(box18);
  const box19 = new THREE.Mesh(boxGeo5, cellMat);
  box19.position.set(1.1475, 0, 0.02);
  wingRight.add(box19);
  const box20 = new THREE.Mesh(boxGeo5, cellMat);
  box20.position.set(0.7025, -0.33, 0.02);
  wingRight.add(box20);
  const box21 = new THREE.Mesh(boxGeo5, cellMat);
  box21.position.set(1.1475, -0.33, 0.02);
  wingRight.add(box21);
  const panel2 = new THREE.Mesh(boxGeo3, panelBackMat);
  panel2.name = 'panel2';
  panel2.position.set(1.935, 0, 0);
  wingRight.add(panel2);
  const box23 = new THREE.Mesh(boxGeo4, frameMat);
  box23.position.set(1.935, 0.525, 0);
  wingRight.add(box23);
  const box24 = new THREE.Mesh(boxGeo4, frameMat);
  box24.position.set(1.935, -0.525, 0);
  wingRight.add(box24);
  const box25 = new THREE.Mesh(boxGeo5, cellMat);
  box25.position.set(1.7125, 0.33, 0.02);
  wingRight.add(box25);
  const box26 = new THREE.Mesh(boxGeo5, cellMat);
  box26.position.set(2.1575, 0.33, 0.02);
  wingRight.add(box26);
  const box27 = new THREE.Mesh(boxGeo5, cellMat);
  box27.position.set(1.7125, 0, 0.02);
  wingRight.add(box27);
  const box28 = new THREE.Mesh(boxGeo5, cellMat);
  box28.position.set(2.1575, 0, 0.02);
  wingRight.add(box28);
  const box29 = new THREE.Mesh(boxGeo5, cellMat);
  box29.position.set(1.7125, -0.33, 0.02);
  wingRight.add(box29);
  const box30 = new THREE.Mesh(boxGeo5, cellMat);
  box30.position.set(2.1575, -0.33, 0.02);
  wingRight.add(box30);
  const box31 = new THREE.Mesh(boxGeo6, frameMat);
  box31.position.set(1.43, 0, 0);
  wingRight.add(box31);
  const box32 = new THREE.Mesh(boxGeo7, frameMat);
  box32.position.set(0.46, 0, 0);
  wingRight.add(box32);
  const wingLeft = new THREE.Group();
  wingLeft.name = 'wingLeft';
  wingLeft.position.set(-0.5, 0, 0);
  wingLeft.rotation.set(deg(20), 0, deg(180));
  root.add(wingLeft);
  const arm2 = new THREE.Mesh(cylinderGeo, frameMat);
  arm2.name = 'arm';
  arm2.position.set(0.225, 0, 0);
  arm2.rotation.set(0, 0, deg(90));
  wingLeft.add(arm2);
  const drive2 = new THREE.Mesh(cylinderGeo2, darkMat);
  drive2.name = 'drive';
  drive2.position.set(0.05, 0, 0);
  drive2.rotation.set(0, 0, deg(90));
  wingLeft.add(drive2);
  const panel12 = new THREE.Mesh(boxGeo3, panelBackMat);
  panel12.name = 'panel1';
  panel12.position.set(0.925, 0, 0);
  wingLeft.add(panel12);
  const box37 = new THREE.Mesh(boxGeo4, frameMat);
  box37.position.set(0.925, 0.525, 0);
  wingLeft.add(box37);
  const box38 = new THREE.Mesh(boxGeo4, frameMat);
  box38.position.set(0.925, -0.525, 0);
  wingLeft.add(box38);
  const box39 = new THREE.Mesh(boxGeo5, cellMat);
  box39.position.set(0.7025, 0.33, 0.02);
  wingLeft.add(box39);
  const box40 = new THREE.Mesh(boxGeo5, cellMat);
  box40.position.set(1.1475, 0.33, 0.02);
  wingLeft.add(box40);
  const box41 = new THREE.Mesh(boxGeo5, cellMat);
  box41.position.set(0.7025, 0, 0.02);
  wingLeft.add(box41);
  const box42 = new THREE.Mesh(boxGeo5, cellMat);
  box42.position.set(1.1475, 0, 0.02);
  wingLeft.add(box42);
  const box43 = new THREE.Mesh(boxGeo5, cellMat);
  box43.position.set(0.7025, -0.33, 0.02);
  wingLeft.add(box43);
  const box44 = new THREE.Mesh(boxGeo5, cellMat);
  box44.position.set(1.1475, -0.33, 0.02);
  wingLeft.add(box44);
  const panel22 = new THREE.Mesh(boxGeo3, panelBackMat);
  panel22.name = 'panel2';
  panel22.position.set(1.935, 0, 0);
  wingLeft.add(panel22);
  const box46 = new THREE.Mesh(boxGeo4, frameMat);
  box46.position.set(1.935, 0.525, 0);
  wingLeft.add(box46);
  const box47 = new THREE.Mesh(boxGeo4, frameMat);
  box47.position.set(1.935, -0.525, 0);
  wingLeft.add(box47);
  const box48 = new THREE.Mesh(boxGeo5, cellMat);
  box48.position.set(1.7125, 0.33, 0.02);
  wingLeft.add(box48);
  const box49 = new THREE.Mesh(boxGeo5, cellMat);
  box49.position.set(2.1575, 0.33, 0.02);
  wingLeft.add(box49);
  const box50 = new THREE.Mesh(boxGeo5, cellMat);
  box50.position.set(1.7125, 0, 0.02);
  wingLeft.add(box50);
  const box51 = new THREE.Mesh(boxGeo5, cellMat);
  box51.position.set(2.1575, 0, 0.02);
  wingLeft.add(box51);
  const box52 = new THREE.Mesh(boxGeo5, cellMat);
  box52.position.set(1.7125, -0.33, 0.02);
  wingLeft.add(box52);
  const box53 = new THREE.Mesh(boxGeo5, cellMat);
  box53.position.set(2.1575, -0.33, 0.02);
  wingLeft.add(box53);
  const box54 = new THREE.Mesh(boxGeo6, frameMat);
  box54.position.set(1.43, 0, 0);
  wingLeft.add(box54);
  const box55 = new THREE.Mesh(boxGeo7, frameMat);
  box55.position.set(0.46, 0, 0);
  wingLeft.add(box55);
  const dishAntenna = new THREE.Group();
  dishAntenna.name = 'dishAntenna';
  dishAntenna.position.set(0, 0.12, 0.6);
  dishAntenna.rotation.set(deg(70), 0, 0);
  root.add(dishAntenna);
  const dish = new THREE.Mesh(lathe([[0, 0], [0.0917, 0.005], [0.1833, 0.02], [0.275, 0.045], [0.3667, 0.08], [0.4583, 0.125], [0.55, 0.1801]], 18), whiteMat);
  dish.name = 'dish';
  dishAntenna.add(dish);
  const dishHub = new THREE.Mesh(new THREE.CylinderGeometry(0.05, 0.07, 0.12, 8), frameMat);
  dishHub.name = 'dishHub';
  dishHub.position.set(0, -0.02, 0);
  dishAntenna.add(dishHub);
  const feed = new THREE.Mesh(new THREE.ConeGeometry(0.06, 0.1, 8), darkMat);
  feed.name = 'feed';
  feed.position.set(0, 0.42, 0);
  feed.rotation.set(deg(180), 0, 0);
  dishAntenna.add(feed);
  const tube60 = new THREE.Mesh(tube([[0.4675, 0.1301, 0], [0.2338, 0.295, 0], [0, 0.44, 0]], 0.012, 4, 4), frameMat);
  dishAntenna.add(tube60);
  const tube61 = new THREE.Mesh(tube([[-0.2337, 0.1301, 0.4049], [-0.1169, 0.295, 0.2024], [0, 0.44, 0]], 0.012, 4, 4), frameMat);
  dishAntenna.add(tube61);
  const tube62 = new THREE.Mesh(tube([[-0.2338, 0.1301, -0.4049], [-0.1169, 0.295, -0.2024], [0, 0.44, 0]], 0.012, 4, 4), frameMat);
  dishAntenna.add(tube62);
  const dishMount = new THREE.Mesh(new THREE.CylinderGeometry(0.05, 0.05, 0.16, 6), frameMat);
  dishMount.name = 'dishMount';
  dishMount.position.set(0, 0.1, 0.55);
  dishMount.rotation.set(deg(90), 0, 0);
  root.add(dishMount);

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

export default createSatellite;

Puanlar ve yorumlar

—
Henüz puan yok — ilk puanı sen ver.
5
0
4
0
3
0
2
0
1
0

Puan vermek ve yorum yapmak için giriş yap.

0 yorum

Henüz yorum yok. Bu modeli nasıl kullandığını ya da neyin daha iyi olabileceğini paylaş.

Benzer modeller

Aynı kategori ya da benzer etiketler