1,2 k tris1,01 × 1,67 × 0,68 m
Utiliser dans le code
Remixer dans l’éditeurastronaut.js · 281 lignes
Module ES autonome — ne dépend que de three. Appelez la fonction factory et ajoutez le groupe à votre scène.
/**
* Astronaut — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 1,152 · Size (W × H × D): 1.01 × 1.67 × 0.68 m
*
* Usage:
* import { createAstronaut } from './astronaut.js';
*
* const model = createAstronaut();
* 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 createAstronaut() {
const root = new THREE.Group();
root.name = 'Astronaut';
// Materials
const suitMat = new THREE.MeshStandardMaterial({ name: 'suit', color: 0xf1f0ea, roughness: 0.75, flatShading: true });
const jointMat = new THREE.MeshStandardMaterial({ name: 'joint', color: 0xb1b5bb, roughness: 0.55, metalness: 0.3, flatShading: true });
const accentMat = new THREE.MeshStandardMaterial({ name: 'accent', color: 0xf07a2b, roughness: 0.7, flatShading: true });
const visorMat = new THREE.MeshStandardMaterial({ name: 'visor', color: 0x253766, roughness: 0.08, metalness: 0.75 });
const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x3a3d46, roughness: 0.7, flatShading: true });
const shineMat = new THREE.MeshStandardMaterial({ name: 'shine', color: 0xffffff, roughness: 0.2, emissive: 0xffffff, emissiveIntensity: 0.4, flatShading: true });
const redMat = new THREE.MeshStandardMaterial({ name: 'red', color: 0xff4a4a, roughness: 0.3, emissive: 0xff2a2a, emissiveIntensity: 0.9, flatShading: true });
const greenMat = new THREE.MeshStandardMaterial({ name: 'green', color: 0x56f08a, roughness: 0.3, emissive: 0x2fe06a, emissiveIntensity: 0.8, flatShading: true });
// Shared geometries
const boxGeo = new THREE.BoxGeometry(0.21, 0.46, 0.23);
const boxGeo2 = new THREE.BoxGeometry(0.222, 0.05, 0.242);
const boxGeo3 = new THREE.BoxGeometry(0.225, 0.15, 0.31);
const boxGeo4 = new THREE.BoxGeometry(0.237, 0.035, 0.322);
const boxGeo5 = new THREE.BoxGeometry(0.04, 0.04, 0.02);
const cylinderGeo = new THREE.CylinderGeometry(0.055, 0.055, 0.42, 8);
const boxGeo6 = new THREE.BoxGeometry(0.17, 0.25, 0.19);
const boxGeo7 = new THREE.BoxGeometry(0.182, 0.045, 0.202);
const boxGeo8 = new THREE.BoxGeometry(0.16, 0.18, 0.18);
const boxGeo9 = new THREE.BoxGeometry(0.18, 0.05, 0.2);
const boxGeo10 = new THREE.BoxGeometry(0.16, 0.12, 0.18);
const cylinderGeo2 = new THREE.CylinderGeometry(0.085, 0.085, 0.06, 8);
const cylinderGeo3 = new THREE.CylinderGeometry(0.05, 0.05, 0.02, 8);
// Parts
const legL = new THREE.Group();
legL.name = 'legL';
legL.position.set(0.125, 0.56, 0);
root.add(legL);
const suitLegL = new THREE.Mesh(boxGeo, suitMat);
suitLegL.name = 'suitLegL';
suitLegL.position.set(0, -0.23, 0);
legL.add(suitLegL);
const kneeBandL = new THREE.Mesh(boxGeo2, accentMat);
kneeBandL.name = 'kneeBandL';
kneeBandL.position.set(0, -0.22, 0);
legL.add(kneeBandL);
const bootL = new THREE.Mesh(boxGeo3, darkMat);
bootL.name = 'bootL';
bootL.position.set(0, -0.485, 0.03);
legL.add(bootL);
const bootSoleL = new THREE.Mesh(boxGeo4, jointMat);
bootSoleL.name = 'bootSoleL';
bootSoleL.position.set(0, -0.5485, 0.03);
legL.add(bootSoleL);
const legR = new THREE.Group();
legR.name = 'legR';
legR.position.set(-0.125, 0.56, 0);
root.add(legR);
const suitLegR = new THREE.Mesh(boxGeo, suitMat);
suitLegR.name = 'suitLegR';
suitLegR.position.set(0, -0.23, 0);
legR.add(suitLegR);
const kneeBandR = new THREE.Mesh(boxGeo2, accentMat);
kneeBandR.name = 'kneeBandR';
kneeBandR.position.set(0, -0.22, 0);
legR.add(kneeBandR);
const bootR = new THREE.Mesh(boxGeo3, darkMat);
bootR.name = 'bootR';
bootR.position.set(0, -0.485, 0.03);
legR.add(bootR);
const bootSoleR = new THREE.Mesh(boxGeo4, jointMat);
bootSoleR.name = 'bootSoleR';
bootSoleR.position.set(0, -0.5485, 0.03);
legR.add(bootSoleR);
const body = new THREE.Group();
body.name = 'body';
root.add(body);
const torso = new THREE.Mesh(new THREE.BoxGeometry(0.52, 0.59, 0.34), suitMat);
torso.name = 'torso';
torso.position.set(0, 0.795, 0);
body.add(torso);
const belt = new THREE.Mesh(new THREE.BoxGeometry(0.532, 0.08, 0.352), jointMat);
belt.name = 'belt';
belt.position.set(0, 0.56, 0);
body.add(belt);
const beltBuckle = new THREE.Mesh(new THREE.BoxGeometry(0.08, 0.06, 0.02), accentMat);
beltBuckle.name = 'beltBuckle';
beltBuckle.position.set(0, 0.56, 0.184);
body.add(beltBuckle);
const chestPanel = new THREE.Mesh(new THREE.BoxGeometry(0.24, 0.15, 0.05), jointMat);
chestPanel.name = 'chestPanel';
chestPanel.position.set(0, 0.84, 0.195);
body.add(chestPanel);
const buttonRed = new THREE.Mesh(boxGeo5, redMat);
buttonRed.name = 'buttonRed';
buttonRed.position.set(-0.065, 0.865, 0.22);
body.add(buttonRed);
const buttonGreen = new THREE.Mesh(boxGeo5, greenMat);
buttonGreen.name = 'buttonGreen';
buttonGreen.position.set(0, 0.865, 0.22);
body.add(buttonGreen);
const buttonAccent = new THREE.Mesh(boxGeo5, accentMat);
buttonAccent.name = 'buttonAccent';
buttonAccent.position.set(0.065, 0.865, 0.22);
body.add(buttonAccent);
const panelSlot = new THREE.Mesh(new THREE.BoxGeometry(0.17, 0.03, 0.02), darkMat);
panelSlot.name = 'panelSlot';
panelSlot.position.set(0, 0.805, 0.22);
body.add(panelSlot);
const chestPatch = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.07, 0.01), accentMat);
chestPatch.name = 'chestPatch';
chestPatch.position.set(0.14, 0.98, 0.173);
body.add(chestPatch);
const hose = new THREE.Mesh(tube([[-0.12, 0.82, 0.195], [-0.25, 0.79, 0.16], [-0.29, 0.86, 0], [-0.24, 0.94, -0.17]], 0.025, 10, 5), jointMat);
hose.name = 'hose';
body.add(hose);
const backpack = new THREE.Group();
backpack.name = 'backpack';
backpack.position.set(0, 0.83, -0.26);
body.add(backpack);
const packShell = new THREE.Mesh(new THREE.BoxGeometry(0.46, 0.52, 0.18), suitMat);
packShell.name = 'packShell';
backpack.add(packShell);
const packStripe = new THREE.Mesh(new THREE.BoxGeometry(0.472, 0.06, 0.192), accentMat);
packStripe.name = 'packStripe';
packStripe.position.set(0, 0.14, 0);
backpack.add(packStripe);
const packVent = new THREE.Mesh(new THREE.BoxGeometry(0.3, 0.12, 0.02), jointMat);
packVent.name = 'packVent';
packVent.position.set(0, -0.12, -0.096);
backpack.add(packVent);
const tankL = new THREE.Mesh(cylinderGeo, jointMat);
tankL.name = 'tankL';
tankL.position.set(0.255, 0, 0);
backpack.add(tankL);
const tankR = new THREE.Mesh(cylinderGeo, jointMat);
tankR.name = 'tankR';
tankR.position.set(-0.255, 0, 0);
backpack.add(tankR);
const packLight = new THREE.Mesh(new THREE.BoxGeometry(0.05, 0.05, 0.02), greenMat);
packLight.name = 'packLight';
packLight.position.set(0.13, 0.2, -0.096);
backpack.add(packLight);
const armL = new THREE.Group();
armL.name = 'armL';
armL.position.set(0.34, 1.03, 0);
armL.rotation.set(0, 0, deg(9));
root.add(armL);
const upperArmL = new THREE.Mesh(boxGeo6, suitMat);
upperArmL.name = 'upperArmL';
upperArmL.position.set(0, -0.1, 0);
armL.add(upperArmL);
const armBandL = new THREE.Mesh(boxGeo7, accentMat);
armBandL.name = 'armBandL';
armBandL.position.set(0, -0.19, 0);
armL.add(armBandL);
const forearmL = new THREE.Mesh(boxGeo8, suitMat);
forearmL.name = 'forearmL';
forearmL.position.set(0, -0.31, 0);
armL.add(forearmL);
const cuffL = new THREE.Mesh(boxGeo9, jointMat);
cuffL.name = 'cuffL';
cuffL.position.set(0, -0.4, 0);
armL.add(cuffL);
const gloveL = new THREE.Mesh(boxGeo10, accentMat);
gloveL.name = 'gloveL';
gloveL.position.set(0, -0.48, 0.005);
armL.add(gloveL);
const armR = new THREE.Group();
armR.name = 'armR';
armR.position.set(-0.34, 1.03, 0);
armR.rotation.set(0, 0, deg(-9));
root.add(armR);
const upperArmR = new THREE.Mesh(boxGeo6, suitMat);
upperArmR.name = 'upperArmR';
upperArmR.position.set(0, -0.1, 0);
armR.add(upperArmR);
const armBandR = new THREE.Mesh(boxGeo7, accentMat);
armBandR.name = 'armBandR';
armBandR.position.set(0, -0.19, 0);
armR.add(armBandR);
const forearmR = new THREE.Mesh(boxGeo8, suitMat);
forearmR.name = 'forearmR';
forearmR.position.set(0, -0.31, 0);
armR.add(forearmR);
const cuffR = new THREE.Mesh(boxGeo9, jointMat);
cuffR.name = 'cuffR';
cuffR.position.set(0, -0.4, 0);
armR.add(cuffR);
const gloveR = new THREE.Mesh(boxGeo10, accentMat);
gloveR.name = 'gloveR';
gloveR.position.set(0, -0.48, 0.005);
armR.add(gloveR);
const head = new THREE.Group();
head.name = 'head';
head.position.set(0, 1.09, 0);
root.add(head);
const neckRing = new THREE.Mesh(new THREE.CylinderGeometry(0.2, 0.22, 0.08, 10), jointMat);
neckRing.name = 'neckRing';
head.add(neckRing);
const helmet = new THREE.Mesh(new THREE.SphereGeometry(0.3, 12, 8), suitMat);
helmet.name = 'helmet';
helmet.position.set(0, 0.27, 0);
head.add(helmet);
const visorFrame = new THREE.Mesh(new THREE.SphereGeometry(0.305, 10, 5, 0.4458, 2.25, 0.82, 1.38), jointMat);
visorFrame.name = 'visorFrame';
visorFrame.position.set(0, 0.27, 0);
head.add(visorFrame);
const visorGlass = new THREE.Mesh(new THREE.SphereGeometry(0.311, 10, 5, 0.5958, 1.95, 0.92, 1.16), visorMat);
visorGlass.name = 'visorGlass';
visorGlass.position.set(0, 0.27, 0);
head.add(visorGlass);
const visorGlint = new THREE.Mesh(new THREE.BoxGeometry(0.13, 0.032, 0.008), shineMat);
visorGlint.name = 'visorGlint';
visorGlint.position.set(-0.1201, 0.3332, 0.2854);
visorGlint.rotation.set(deg(-12.4871), deg(-22.3337), deg(25.5256));
head.add(visorGlint);
const visorGlintDot = new THREE.Mesh(new THREE.BoxGeometry(0.035, 0.035, 0.008), shineMat);
visorGlintDot.name = 'visorGlintDot';
visorGlintDot.position.set(-0.0632, 0.3648, 0.2947);
visorGlintDot.rotation.set(deg(-17.8295), deg(-11.537), deg(26.1843));
head.add(visorGlintDot);
const earPodL = new THREE.Mesh(cylinderGeo2, jointMat);
earPodL.name = 'earPodL';
earPodL.position.set(0.295, 0.27, 0);
earPodL.rotation.set(0, 0, deg(90));
head.add(earPodL);
const earCapL = new THREE.Mesh(cylinderGeo3, accentMat);
earCapL.name = 'earCapL';
earCapL.position.set(0.33, 0.27, 0);
earCapL.rotation.set(0, 0, deg(90));
head.add(earCapL);
const earPodR = new THREE.Mesh(cylinderGeo2, jointMat);
earPodR.name = 'earPodR';
earPodR.position.set(-0.295, 0.27, 0);
earPodR.rotation.set(0, 0, deg(90));
head.add(earPodR);
const earCapR = new THREE.Mesh(cylinderGeo3, accentMat);
earCapR.name = 'earCapR';
earCapR.position.set(-0.33, 0.27, 0);
earCapR.rotation.set(0, 0, deg(90));
head.add(earCapR);
const antenna = new THREE.Mesh(new THREE.CylinderGeometry(0.012, 0.012, 0.2, 5), darkMat);
antenna.name = 'antenna';
antenna.position.set(0.31, 0.42, -0.04);
antenna.rotation.set(0, 0, deg(-10));
head.add(antenna);
const antennaLight = new THREE.Mesh(new THREE.SphereGeometry(0.03, 6, 4), redMat);
antennaLight.name = 'antennaLight';
antennaLight.position.set(0.327, 0.525, -0.04);
head.add(antennaLight);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createAstronaut;
Notes et commentaires
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









