1588 ポリゴン23.8 × 15.9 × 34.5 m
コードで使う
エディターでリミックスspace-shuttle.js · 355 行
自己完結型の ES モジュールで、依存先は three のみです。ファクトリー関数を呼び出し、返された group をシーンに追加してください。
/**
* Space Shuttle — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 1,588 · Size (W × H × D): 23.80 × 15.94 × 34.48 m
*
* Usage:
* import { createSpaceShuttle } from './space-shuttle.js';
*
* const model = createSpaceShuttle();
* 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);
}
// Extrude a 2D outline along Z (centered). bevel = [thickness, size, segments].
function extrude(outline, depth, holes = [], bevel = null) {
const shape = new THREE.Shape(outline.map(([x, y]) => new THREE.Vector2(x, y)));
for (const hole of holes) shape.holes.push(new THREE.Path(hole.map(([x, y]) => new THREE.Vector2(x, y))));
const options = bevel
? { depth, bevelEnabled: true, bevelThickness: bevel[0], bevelSize: bevel[1], bevelSegments: bevel[2] }
: { depth, bevelEnabled: false };
return new THREE.ExtrudeGeometry(shape, options).translate(0, 0, -depth / 2);
}
export function createSpaceShuttle() {
const root = new THREE.Group();
root.name = 'SpaceShuttle';
// Materials
const whiteMat = new THREE.MeshStandardMaterial({ name: 'white', color: 0xebe9e3, roughness: 0.55, metalness: 0.05, flatShading: true });
const tilesMat = new THREE.MeshStandardMaterial({ name: 'tiles', color: 0x26272b, roughness: 0.8, flatShading: true });
const metalMat = new THREE.MeshStandardMaterial({ name: 'metal', color: 0x9aa0a8, roughness: 0.35, metalness: 0.7, flatShading: true });
const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x1d1f23, roughness: 0.6, metalness: 0.3, flatShading: true });
const glassMat = new THREE.MeshStandardMaterial({ name: 'glass', color: 0x25313e, roughness: 0.2, metalness: 0.35 });
// Shared geometries
const boxGeo = new THREE.BoxGeometry(0.05, 0.42, 0.9);
const boxGeo2 = new THREE.BoxGeometry(0.05, 0.04, 17.5);
const boxGeo3 = new THREE.BoxGeometry(5.6, 0.08, 0.06);
const capsuleGeo = new THREE.CapsuleGeometry(1, 4.6, 3, 8);
const cylinderGeo = new THREE.CylinderGeometry(0.42, 0.25, 0.7, 8);
const cylinderGeo2 = new THREE.CylinderGeometry(1.12, 0.5, 2.8, 12);
const cylinderGeo3 = new THREE.CylinderGeometry(1.04, 1.04, 0.04, 12);
const cylinderGeo4 = new THREE.CylinderGeometry(0.45, 0.45, 0.36, 12);
const cylinderGeo5 = new THREE.CylinderGeometry(0.225, 0.225, 0.38, 8);
const cylinderGeo6 = new THREE.CylinderGeometry(0.16, 0.2, 2.1, 8);
const boxGeo4 = new THREE.BoxGeometry(0.08, 1.47, 1.4);
const cylinderGeo7 = new THREE.CylinderGeometry(0.6, 0.6, 0.36, 12);
const cylinderGeo8 = new THREE.CylinderGeometry(0.3, 0.3, 0.38, 8);
// Parts
const orbiter = new THREE.Group();
orbiter.name = 'orbiter';
orbiter.position.set(0, 5, 0);
root.add(orbiter);
const fuselageTop = new THREE.Mesh(lathe([[0, -14], [2.45, -14], [2.8, -13.3], [2.8, 9]], 5, 1.1781, Math.PI * 1.25), whiteMat);
fuselageTop.name = 'fuselageTop';
fuselageTop.rotation.set(deg(90), 0, 0);
orbiter.add(fuselageTop);
const fuselageBelly = new THREE.Mesh(lathe([[0, -14], [2.45, -14], [2.8, -13.3], [2.8, 9]], 3, -1.1781, Math.PI * 0.75), tilesMat);
fuselageBelly.name = 'fuselageBelly';
fuselageBelly.rotation.set(deg(90), 0, 0);
orbiter.add(fuselageBelly);
const noseSection = new THREE.Group();
noseSection.name = 'noseSection';
noseSection.position.set(0, 2.5869, 9);
noseSection.rotation.set(deg(6), 0, 0);
orbiter.add(noseSection);
const noseShape = new THREE.Group();
noseShape.name = 'noseShape';
noseShape.position.set(0, -2.5869, -9);
noseSection.add(noseShape);
const noseTop = new THREE.Mesh(lathe([[2.8, 9], [2.8, 11], [2.6, 12.8], [2.15, 14.4], [1.55, 15.9], [0.95, 17]], 5, 1.1781, Math.PI * 1.25), whiteMat);
noseTop.name = 'noseTop';
noseTop.rotation.set(deg(90), 0, 0);
noseShape.add(noseTop);
const noseBelly = new THREE.Mesh(lathe([[2.8, 9], [2.8, 11], [2.6, 12.8], [2.15, 14.4], [1.55, 15.9], [0.95, 17]], 3, -1.1781, Math.PI * 0.75), tilesMat);
noseBelly.name = 'noseBelly';
noseBelly.rotation.set(deg(90), 0, 0);
noseShape.add(noseBelly);
const noseCap = new THREE.Mesh(lathe([[0.95, 17], [0.45, 17.7], [0, 18]], 8, 0.3927, Math.PI * 2), tilesMat);
noseCap.name = 'noseCap';
noseCap.rotation.set(deg(90), 0, 0);
noseShape.add(noseCap);
const cockpit = new THREE.Mesh(extrude([[11.2, 2.4369], [14.5, 1.85], [13.25, 2.82], [11.2, 2.95]], 2.6), whiteMat);
cockpit.name = 'cockpit';
cockpit.rotation.set(0, deg(-90), 0);
noseShape.add(cockpit);
const windshield = new THREE.Mesh(new THREE.BoxGeometry(2.3, 0.05, 1.45), glassMat);
windshield.name = 'windshield';
windshield.position.set(0, 2.36, 13.89);
windshield.rotation.set(deg(38), 0, 0);
noseShape.add(windshield);
const sideWindow = new THREE.Mesh(boxGeo, glassMat);
sideWindow.name = 'sideWindow';
sideWindow.position.set(1.31, 2.6, 12.6);
noseShape.add(sideWindow);
const sideWindow2 = new THREE.Mesh(boxGeo, glassMat);
sideWindow2.name = 'sideWindow';
sideWindow2.position.set(-1.31, 2.6, 12.6);
noseShape.add(sideWindow2);
const payloadSeam = new THREE.Mesh(new THREE.BoxGeometry(0.06, 0.04, 17.5), darkMat);
payloadSeam.name = 'payloadSeam';
payloadSeam.position.set(0, 2.5969, -3.6);
orbiter.add(payloadSeam);
const doorHinge = new THREE.Mesh(boxGeo2, darkMat);
doorHinge.name = 'doorHinge';
doorHinge.position.set(1.05, 2.5919, -3.6);
orbiter.add(doorHinge);
const doorHinge2 = new THREE.Mesh(boxGeo2, darkMat);
doorHinge2.name = 'doorHinge';
doorHinge2.position.set(-1.05, 2.5919, -3.6);
orbiter.add(doorHinge2);
const wingL = new THREE.Group();
wingL.name = 'wingL';
wingL.position.set(0, -2, 0);
orbiter.add(wingL);
const wingTop = new THREE.Mesh(extrude([[2, 6], [2.6, 6], [5, -1.5], [11.9, -10.6], [11.9, -12.4], [2, -13.6]], 0.28), whiteMat);
wingTop.name = 'wingTop';
wingTop.position.set(0, 0.14, 0);
wingTop.rotation.set(deg(90), 0, 0);
wingL.add(wingTop);
const wingBelly = new THREE.Mesh(extrude([[2, 6], [2.6, 6], [5, -1.5], [11.9, -10.6], [11.9, -12.4], [2, -13.6]], 0.3), tilesMat);
wingBelly.name = 'wingBelly';
wingBelly.position.set(0, -0.15, 0);
wingBelly.rotation.set(deg(90), 0, 0);
wingL.add(wingBelly);
const elevonLine = new THREE.Mesh(boxGeo3, darkMat);
elevonLine.name = 'elevonLine';
elevonLine.position.set(7, 0.29, -12);
elevonLine.rotation.set(0, deg(7), 0);
wingL.add(elevonLine);
const wingR = new THREE.Group();
wingR.name = 'wingR';
wingR.position.set(0, -2, 0);
orbiter.add(wingR);
const wingTop2 = new THREE.Mesh(extrude([[-2, 6], [-2.6, 6], [-5, -1.5], [-11.9, -10.6], [-11.9, -12.4], [-2, -13.6]], 0.28), whiteMat);
wingTop2.name = 'wingTop';
wingTop2.position.set(0, 0.14, 0);
wingTop2.rotation.set(deg(90), 0, 0);
wingR.add(wingTop2);
const wingBelly2 = new THREE.Mesh(extrude([[-2, 6], [-2.6, 6], [-5, -1.5], [-11.9, -10.6], [-11.9, -12.4], [-2, -13.6]], 0.3), tilesMat);
wingBelly2.name = 'wingBelly';
wingBelly2.position.set(0, -0.15, 0);
wingBelly2.rotation.set(deg(90), 0, 0);
wingR.add(wingBelly2);
const elevonLine2 = new THREE.Mesh(boxGeo3, darkMat);
elevonLine2.name = 'elevonLine';
elevonLine2.position.set(-7, 0.29, -12);
elevonLine2.rotation.set(0, deg(-7), 0);
wingR.add(elevonLine2);
const tailFin = new THREE.Mesh(extrude([[-5.6, 2.3869], [-11.4, 10.8869], [-13.3, 10.8869], [-14.1, 2.3869]], 0.45, [], [0.05, 0.05, 1]), whiteMat);
tailFin.name = 'tailFin';
tailFin.rotation.set(0, deg(-90), 0);
orbiter.add(tailFin);
const rudderLine = new THREE.Mesh(new THREE.BoxGeometry(0.6, 6.8, 0.08), darkMat);
rudderLine.name = 'rudderLine';
rudderLine.position.set(0, 7.1869, -12.25);
rudderLine.rotation.set(deg(-7), 0, 0);
orbiter.add(rudderLine);
const omsPodL = new THREE.Mesh(capsuleGeo, whiteMat);
omsPodL.name = 'omsPodL';
omsPodL.position.set(1.75, 2.15, -10.4);
omsPodL.rotation.set(deg(90), 0, 0);
omsPodL.scale.set(1, 1, 0.85);
orbiter.add(omsPodL);
const omsNozzle = new THREE.Mesh(cylinderGeo, metalMat);
omsNozzle.name = 'omsNozzle';
omsNozzle.position.set(1.75, 2.15, -13.65);
omsNozzle.rotation.set(deg(-90), 0, 0);
orbiter.add(omsNozzle);
const omsPodR = new THREE.Mesh(capsuleGeo, whiteMat);
omsPodR.name = 'omsPodR';
omsPodR.position.set(-1.75, 2.15, -10.4);
omsPodR.rotation.set(deg(90), 0, 0);
omsPodR.scale.set(1, 1, 0.85);
orbiter.add(omsPodR);
const omsNozzle2 = new THREE.Mesh(cylinderGeo, metalMat);
omsNozzle2.name = 'omsNozzle';
omsNozzle2.position.set(-1.75, 2.15, -13.65);
omsNozzle2.rotation.set(deg(-90), 0, 0);
orbiter.add(omsNozzle2);
const bodyFlap = new THREE.Mesh(new THREE.BoxGeometry(4.6, 0.32, 2), tilesMat);
bodyFlap.name = 'bodyFlap';
bodyFlap.position.set(0, -2.35, -14.8);
orbiter.add(bodyFlap);
const mainEngineTop = new THREE.Group();
mainEngineTop.name = 'mainEngineTop';
mainEngineTop.position.set(0, 1.25, -14);
orbiter.add(mainEngineTop);
const bell = new THREE.Mesh(cylinderGeo2, metalMat);
bell.name = 'bell';
bell.position.set(0, 0, -1.4);
bell.rotation.set(deg(-90), 0, 0);
mainEngineTop.add(bell);
const nozzleExit = new THREE.Mesh(cylinderGeo3, darkMat);
nozzleExit.name = 'nozzleExit';
nozzleExit.position.set(0, 0, -2.78);
nozzleExit.rotation.set(deg(90), 0, 0);
mainEngineTop.add(nozzleExit);
const mainEngineL = new THREE.Group();
mainEngineL.name = 'mainEngineL';
mainEngineL.position.set(1.3, -0.95, -14);
orbiter.add(mainEngineL);
const bell2 = new THREE.Mesh(cylinderGeo2, metalMat);
bell2.name = 'bell';
bell2.position.set(0, 0, -1.4);
bell2.rotation.set(deg(-90), 0, 0);
mainEngineL.add(bell2);
const nozzleExit2 = new THREE.Mesh(cylinderGeo3, darkMat);
nozzleExit2.name = 'nozzleExit';
nozzleExit2.position.set(0, 0, -2.78);
nozzleExit2.rotation.set(deg(90), 0, 0);
mainEngineL.add(nozzleExit2);
const mainEngineR = new THREE.Group();
mainEngineR.name = 'mainEngineR';
mainEngineR.position.set(-1.3, -0.95, -14);
orbiter.add(mainEngineR);
const bell3 = new THREE.Mesh(cylinderGeo2, metalMat);
bell3.name = 'bell';
bell3.position.set(0, 0, -1.4);
bell3.rotation.set(deg(-90), 0, 0);
mainEngineR.add(bell3);
const nozzleExit3 = new THREE.Mesh(cylinderGeo3, darkMat);
nozzleExit3.name = 'nozzleExit';
nozzleExit3.position.set(0, 0, -2.78);
nozzleExit3.rotation.set(deg(90), 0, 0);
mainEngineR.add(nozzleExit3);
const noseGear = new THREE.Group();
noseGear.name = 'noseGear';
noseGear.position.set(0, -2.5869, 12.6);
orbiter.add(noseGear);
const strut = new THREE.Mesh(new THREE.CylinderGeometry(0.16, 0.2, 1.9631, 8), metalMat);
strut.name = 'strut';
strut.position.set(0, -0.9816, 0);
noseGear.add(strut);
const gearDoor = new THREE.Mesh(new THREE.BoxGeometry(0.08, 1.3742, 1.4), tilesMat);
gearDoor.name = 'gearDoor';
gearDoor.position.set(0.35, -0.8834, 0.1);
noseGear.add(gearDoor);
const wheels = new THREE.Group();
wheels.name = 'wheels';
wheels.position.set(0, -1.9631, 0);
noseGear.add(wheels);
const tire = new THREE.Mesh(cylinderGeo4, darkMat);
tire.name = 'tire';
tire.position.set(-0.32, 0, 0);
tire.rotation.set(0, 0, deg(90));
wheels.add(tire);
const hub = new THREE.Mesh(cylinderGeo5, metalMat);
hub.name = 'hub';
hub.position.set(-0.32, 0, 0);
hub.rotation.set(0, 0, deg(90));
wheels.add(hub);
const tire2 = new THREE.Mesh(cylinderGeo4, darkMat);
tire2.name = 'tire';
tire2.position.set(0.32, 0, 0);
tire2.rotation.set(0, 0, deg(90));
wheels.add(tire2);
const hub2 = new THREE.Mesh(cylinderGeo5, metalMat);
hub2.name = 'hub';
hub2.position.set(0.32, 0, 0);
hub2.rotation.set(0, 0, deg(90));
wheels.add(hub2);
const mainGearL = new THREE.Group();
mainGearL.name = 'mainGearL';
mainGearL.position.set(3.3, -2.3, -4.6);
orbiter.add(mainGearL);
const strut2 = new THREE.Mesh(cylinderGeo6, metalMat);
strut2.name = 'strut';
strut2.position.set(0, -1.05, 0);
mainGearL.add(strut2);
const gearDoor2 = new THREE.Mesh(boxGeo4, tilesMat);
gearDoor2.name = 'gearDoor';
gearDoor2.position.set(0.45, -0.945, 0.1);
mainGearL.add(gearDoor2);
const wheels2 = new THREE.Group();
wheels2.name = 'wheels';
wheels2.position.set(0, -2.1, 0);
mainGearL.add(wheels2);
const tire3 = new THREE.Mesh(cylinderGeo7, darkMat);
tire3.name = 'tire';
tire3.position.set(-0.32, 0, 0);
tire3.rotation.set(0, 0, deg(90));
wheels2.add(tire3);
const hub3 = new THREE.Mesh(cylinderGeo8, metalMat);
hub3.name = 'hub';
hub3.position.set(-0.32, 0, 0);
hub3.rotation.set(0, 0, deg(90));
wheels2.add(hub3);
const tire4 = new THREE.Mesh(cylinderGeo7, darkMat);
tire4.name = 'tire';
tire4.position.set(0.32, 0, 0);
tire4.rotation.set(0, 0, deg(90));
wheels2.add(tire4);
const hub4 = new THREE.Mesh(cylinderGeo8, metalMat);
hub4.name = 'hub';
hub4.position.set(0.32, 0, 0);
hub4.rotation.set(0, 0, deg(90));
wheels2.add(hub4);
const mainGearR = new THREE.Group();
mainGearR.name = 'mainGearR';
mainGearR.position.set(-3.3, -2.3, -4.6);
orbiter.add(mainGearR);
const strut3 = new THREE.Mesh(cylinderGeo6, metalMat);
strut3.name = 'strut';
strut3.position.set(0, -1.05, 0);
mainGearR.add(strut3);
const gearDoor3 = new THREE.Mesh(boxGeo4, tilesMat);
gearDoor3.name = 'gearDoor';
gearDoor3.position.set(-0.45, -0.945, 0.1);
mainGearR.add(gearDoor3);
const wheels3 = new THREE.Group();
wheels3.name = 'wheels';
wheels3.position.set(0, -2.1, 0);
mainGearR.add(wheels3);
const tire5 = new THREE.Mesh(cylinderGeo7, darkMat);
tire5.name = 'tire';
tire5.position.set(-0.32, 0, 0);
tire5.rotation.set(0, 0, deg(90));
wheels3.add(tire5);
const hub5 = new THREE.Mesh(cylinderGeo8, metalMat);
hub5.name = 'hub';
hub5.position.set(-0.32, 0, 0);
hub5.rotation.set(0, 0, deg(90));
wheels3.add(hub5);
const tire6 = new THREE.Mesh(cylinderGeo7, darkMat);
tire6.name = 'tire';
tire6.position.set(0.32, 0, 0);
tire6.rotation.set(0, 0, deg(90));
wheels3.add(tire6);
const hub6 = new THREE.Mesh(cylinderGeo8, metalMat);
hub6.name = 'hub';
hub6.position.set(0.32, 0, 0);
hub6.rotation.set(0, 0, deg(90));
wheels3.add(hub6);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createSpaceShuttle;
評価とコメント
0 件のコメント
まだコメントはありません。このモデルの使い方や改善できる点を共有しましょう。
関連モデル
同じカテゴリまたは似たタグ









