1 тыс. треуг.0,92 × 1,79 × 1,17 m
Использовать в коде
Ремикс в редактореpirate.js · 422 строки
Самодостаточный ES-модуль — зависит только от three. Вызовите фабрику и добавьте группу в сцену.
/**
* Pirate — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 1,028 · Size (W × H × D): 0.92 × 1.79 × 1.17 m
*
* Usage:
* import { createPirate } from './pirate.js';
*
* const model = createPirate();
* model.position.set(0, 0, 0);
* scene.add(model);
*/
import * as THREE from 'three';
const deg = THREE.MathUtils.degToRad;
// 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 createPirate() {
const root = new THREE.Group();
root.name = 'Pirate';
// Materials
const skinMat = new THREE.MeshStandardMaterial({ name: 'skin', color: 0xeebc93, roughness: 0.8, flatShading: true });
const coatMat = new THREE.MeshStandardMaterial({ name: 'coat', color: 0xb2272f, roughness: 0.85, flatShading: true });
const coatDarkMat = new THREE.MeshStandardMaterial({ name: 'coatDark', color: 0x62151a, roughness: 0.85, flatShading: true });
const shirtMat = new THREE.MeshStandardMaterial({ name: 'shirt', color: 0xf1ead9, roughness: 0.9, flatShading: true });
const hatMat = new THREE.MeshStandardMaterial({ name: 'hat', color: 0x2c2830, roughness: 0.75, flatShading: true });
const blackMat = new THREE.MeshStandardMaterial({ name: 'black', color: 0x1e1b1f, roughness: 0.6, flatShading: true });
const goldMat = new THREE.MeshStandardMaterial({ name: 'gold', color: 0xf0c04a, roughness: 0.3, metalness: 0.65, flatShading: true });
const beardMat = new THREE.MeshStandardMaterial({ name: 'beard', color: 0x2b1d17, roughness: 0.95, flatShading: true });
const woodMat = new THREE.MeshStandardMaterial({ name: 'wood', color: 0x8a5c37, roughness: 0.85, flatShading: true });
const bladeMat = new THREE.MeshStandardMaterial({ name: 'blade', color: 0xdfe5ec, roughness: 0.2, metalness: 0.8, flatShading: true });
// Shared geometries
const boxGeo = new THREE.BoxGeometry(0.05, 0.33, 0.012);
const boxGeo2 = new THREE.BoxGeometry(0.035, 0.035, 0.02);
const boxGeo3 = new THREE.BoxGeometry(0.04, 0.32, 0.3);
const boxGeo4 = new THREE.BoxGeometry(0.13, 0.32, 0.04);
const boxGeo5 = new THREE.BoxGeometry(0.02, 0.32, 0.045);
const boxGeo6 = new THREE.BoxGeometry(0.16, 0.36, 0.18);
const boxGeo7 = new THREE.BoxGeometry(0.2, 0.12, 0.21);
const boxGeo8 = new THREE.BoxGeometry(0.205, 0.025, 0.215);
const boxGeo9 = new THREE.BoxGeometry(0.11, 0.11, 0.11);
const boxGeo10 = new THREE.BoxGeometry(0.13, 0.045, 0.05);
const boxGeo11 = new THREE.BoxGeometry(0.04, 0.06, 0.045);
const boxGeo12 = new THREE.BoxGeometry(0.6942, 0.2, 0.035);
const boxGeo13 = new THREE.BoxGeometry(0.6942, 0.025, 0.04);
const boxGeo14 = new THREE.BoxGeometry(0.12, 0.022, 0.01);
const boxGeo15 = new THREE.BoxGeometry(0.014, 0.014, 0.01);
// Parts
const legL = new THREE.Group();
legL.name = 'legL';
legL.position.set(0.105, 0.58, 0);
root.add(legL);
const trouserL = new THREE.Mesh(new THREE.BoxGeometry(0.19, 0.32, 0.21), coatDarkMat);
trouserL.name = 'trouserL';
trouserL.position.set(0, -0.16, 0);
legL.add(trouserL);
const bootL = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.26, 0.22), blackMat);
bootL.name = 'bootL';
bootL.position.set(0, -0.45, 0.005);
legL.add(bootL);
const bootCuffL = new THREE.Mesh(new THREE.BoxGeometry(0.24, 0.07, 0.25), blackMat);
bootCuffL.name = 'bootCuffL';
bootCuffL.position.set(0, -0.31, 0.005);
bootCuffL.rotation.set(deg(-6), 0, 0);
legL.add(bootCuffL);
const bootToeL = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.06, 0.08), blackMat);
bootToeL.name = 'bootToeL';
bootToeL.position.set(0, -0.55, 0.14);
legL.add(bootToeL);
const legR = new THREE.Group();
legR.name = 'legR';
legR.position.set(-0.105, 0.58, 0);
root.add(legR);
const pegThigh = new THREE.Mesh(new THREE.BoxGeometry(0.19, 0.24, 0.21), coatDarkMat);
pegThigh.name = 'pegThigh';
pegThigh.position.set(0, -0.12, 0);
legR.add(pegThigh);
const pegCuff = new THREE.Mesh(new THREE.CylinderGeometry(0.075, 0.08, 0.07, 8), woodMat);
pegCuff.name = 'pegCuff';
pegCuff.position.set(0, -0.27, 0);
legR.add(pegCuff);
const peg = new THREE.Mesh(new THREE.CylinderGeometry(0.055, 0.032, 0.28, 7), woodMat);
peg.name = 'peg';
peg.position.set(0, -0.44, 0);
legR.add(peg);
const pegTip = new THREE.Mesh(new THREE.CylinderGeometry(0.04, 0.04, 0.03, 7), blackMat);
pegTip.name = 'pegTip';
pegTip.position.set(0, -0.565, 0);
legR.add(pegTip);
const body = new THREE.Group();
body.name = 'body';
root.add(body);
const coat = new THREE.Mesh(new THREE.BoxGeometry(0.47, 0.56, 0.28), coatMat);
coat.name = 'coat';
coat.position.set(0, 0.82, 0);
body.add(coat);
const shirtV = new THREE.Mesh(extrude([[-0.12, 0], [0.12, 0], [0, -0.3]], 0.01), shirtMat);
shirtV.name = 'shirtV';
shirtV.position.set(0, 1.1, 0.142);
body.add(shirtV);
const ruffle = new THREE.Mesh(new THREE.BoxGeometry(0.06, 0.1, 0.03), shirtMat);
ruffle.name = 'ruffle';
ruffle.position.set(0, 1, 0.152);
ruffle.rotation.set(0, 0, deg(45));
body.add(ruffle);
const lapelL = new THREE.Mesh(boxGeo, coatDarkMat);
lapelL.name = 'lapelL';
lapelL.position.set(0.065, 0.97, 0.146);
lapelL.rotation.set(0, 0, deg(21));
body.add(lapelL);
const button = new THREE.Mesh(boxGeo2, goldMat);
button.name = 'button';
button.position.set(0.155, 0.89, 0.148);
body.add(button);
const button2 = new THREE.Mesh(boxGeo2, goldMat);
button2.name = 'button';
button2.position.set(0.155, 0.77, 0.148);
body.add(button2);
const lapelR = new THREE.Mesh(boxGeo, coatDarkMat);
lapelR.name = 'lapelR';
lapelR.position.set(-0.065, 0.97, 0.146);
lapelR.rotation.set(0, 0, deg(-21));
body.add(lapelR);
const button3 = new THREE.Mesh(boxGeo2, goldMat);
button3.name = 'button';
button3.position.set(-0.155, 0.89, 0.148);
body.add(button3);
const button4 = new THREE.Mesh(boxGeo2, goldMat);
button4.name = 'button';
button4.position.set(-0.155, 0.77, 0.148);
body.add(button4);
const belt = new THREE.Mesh(new THREE.BoxGeometry(0.482, 0.08, 0.292), blackMat);
belt.name = 'belt';
belt.position.set(0, 0.63, 0);
body.add(belt);
const buckle = new THREE.Mesh(new THREE.BoxGeometry(0.12, 0.1, 0.02), goldMat);
buckle.name = 'buckle';
buckle.position.set(0, 0.63, 0.154);
body.add(buckle);
const buckleHole = new THREE.Mesh(new THREE.BoxGeometry(0.06, 0.05, 0.022), blackMat);
buckleHole.name = 'buckleHole';
buckleHole.position.set(0, 0.63, 0.156);
body.add(buckleHole);
const coatTailBack = new THREE.Mesh(new THREE.BoxGeometry(0.51, 0.32, 0.04), coatMat);
coatTailBack.name = 'coatTailBack';
coatTailBack.position.set(0, 0.44, -0.14);
coatTailBack.rotation.set(deg(-8), 0, 0);
body.add(coatTailBack);
const coatTailL = new THREE.Mesh(boxGeo3, coatMat);
coatTailL.name = 'coatTailL';
coatTailL.position.set(0.245, 0.44, -0.005);
coatTailL.rotation.set(0, 0, deg(7));
body.add(coatTailL);
const coatFrontL = new THREE.Mesh(boxGeo4, coatMat);
coatFrontL.name = 'coatFrontL';
coatFrontL.position.set(0.18, 0.44, 0.14);
coatFrontL.rotation.set(deg(8), 0, deg(4));
body.add(coatFrontL);
const coatEdgeL = new THREE.Mesh(boxGeo5, goldMat);
coatEdgeL.name = 'coatEdgeL';
coatEdgeL.position.set(0.11, 0.44, 0.142);
coatEdgeL.rotation.set(deg(8), 0, deg(4));
body.add(coatEdgeL);
const coatTailR = new THREE.Mesh(boxGeo3, coatMat);
coatTailR.name = 'coatTailR';
coatTailR.position.set(-0.245, 0.44, -0.005);
coatTailR.rotation.set(0, 0, deg(-7));
body.add(coatTailR);
const coatFrontR = new THREE.Mesh(boxGeo4, coatMat);
coatFrontR.name = 'coatFrontR';
coatFrontR.position.set(-0.18, 0.44, 0.14);
coatFrontR.rotation.set(deg(8), 0, deg(-4));
body.add(coatFrontR);
const coatEdgeR = new THREE.Mesh(boxGeo5, goldMat);
coatEdgeR.name = 'coatEdgeR';
coatEdgeR.position.set(-0.11, 0.44, 0.142);
coatEdgeR.rotation.set(deg(8), 0, deg(-4));
body.add(coatEdgeR);
const armL = new THREE.Group();
armL.name = 'armL';
armL.position.set(0.315, 1.04, 0);
armL.rotation.set(0, 0, deg(7));
root.add(armL);
const sleeveL = new THREE.Mesh(boxGeo6, coatMat);
sleeveL.name = 'sleeveL';
sleeveL.position.set(0, -0.16, 0);
armL.add(sleeveL);
const cuffL = new THREE.Mesh(boxGeo7, coatDarkMat);
cuffL.name = 'cuffL';
cuffL.position.set(0, -0.36, 0);
armL.add(cuffL);
const cuffTrimL = new THREE.Mesh(boxGeo8, goldMat);
cuffTrimL.name = 'cuffTrimL';
cuffTrimL.position.set(0, -0.31, 0);
armL.add(cuffTrimL);
const handL = new THREE.Mesh(boxGeo9, skinMat);
handL.name = 'handL';
handL.position.set(0, -0.47, 0);
armL.add(handL);
const armR = new THREE.Group();
armR.name = 'armR';
armR.position.set(-0.315, 1.04, 0);
armR.rotation.set(deg(-58), 0, deg(-6));
root.add(armR);
const sleeveR = new THREE.Mesh(boxGeo6, coatMat);
sleeveR.name = 'sleeveR';
sleeveR.position.set(0, -0.16, 0);
armR.add(sleeveR);
const cuffR = new THREE.Mesh(boxGeo7, coatDarkMat);
cuffR.name = 'cuffR';
cuffR.position.set(0, -0.36, 0);
armR.add(cuffR);
const cuffTrimR = new THREE.Mesh(boxGeo8, goldMat);
cuffTrimR.name = 'cuffTrimR';
cuffTrimR.position.set(0, -0.31, 0);
armR.add(cuffTrimR);
const handR = new THREE.Mesh(boxGeo9, skinMat);
handR.name = 'handR';
handR.position.set(0, -0.47, 0);
armR.add(handR);
const cutlass = new THREE.Group();
cutlass.name = 'cutlass';
cutlass.position.set(0, -0.47, 0);
cutlass.rotation.set(deg(95), 0, 0);
armR.add(cutlass);
const grip = new THREE.Mesh(new THREE.BoxGeometry(0.04, 0.13, 0.04), blackMat);
grip.name = 'grip';
cutlass.add(grip);
const pommel = new THREE.Mesh(new THREE.BoxGeometry(0.055, 0.04, 0.055), goldMat);
pommel.name = 'pommel';
pommel.position.set(0, -0.08, 0);
cutlass.add(pommel);
const crossguard = new THREE.Mesh(new THREE.BoxGeometry(0.16, 0.035, 0.06), goldMat);
crossguard.name = 'crossguard';
crossguard.position.set(0, 0.075, 0);
cutlass.add(crossguard);
const knuckleBow = new THREE.Mesh(new THREE.BoxGeometry(0.025, 0.14, 0.025), goldMat);
knuckleBow.name = 'knuckleBow';
knuckleBow.position.set(0.075, 0, 0);
cutlass.add(knuckleBow);
const blade = new THREE.Mesh(extrude([[-0.028, 0], [0.032, 0], [0.046, 0.2], [0.05, 0.38], [0.035, 0.52], [0, 0.62], [-0.045, 0.68], [-0.032, 0.58], [-0.018, 0.47], [-0.016, 0.32], [-0.022, 0.16]], 0.018), bladeMat);
blade.name = 'blade';
blade.position.set(0, 0.09, 0);
cutlass.add(blade);
const head = new THREE.Group();
head.name = 'head';
head.position.set(0, 1.08, 0);
root.add(head);
const skull = new THREE.Mesh(new THREE.BoxGeometry(0.46, 0.46, 0.46), skinMat);
skull.name = 'skull';
skull.position.set(0, 0.25, 0);
head.add(skull);
const eyeL = new THREE.Mesh(new THREE.BoxGeometry(0.055, 0.075, 0.01), blackMat);
eyeL.name = 'eyeL';
eyeL.position.set(0.095, 0.27, 0.233);
head.add(eyeL);
const eyeShineL = new THREE.Mesh(new THREE.BoxGeometry(0.0209, 0.0209, 0.006), shirtMat);
eyeShineL.name = 'eyeShineL';
eyeShineL.position.set(0.1027, 0.2865, 0.239);
head.add(eyeShineL);
const eyePatch = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.09, 0.016), blackMat);
eyePatch.name = 'eyePatch';
eyePatch.position.set(-0.095, 0.27, 0.238);
head.add(eyePatch);
const patchStrap = new THREE.Mesh(new THREE.BoxGeometry(0.36, 0.022, 0.01), blackMat);
patchStrap.name = 'patchStrap';
patchStrap.position.set(0.02, 0.36, 0.235);
patchStrap.rotation.set(0, 0, deg(-27));
head.add(patchStrap);
const patchStrapSide = new THREE.Mesh(new THREE.BoxGeometry(0.01, 0.022, 0.345), blackMat);
patchStrapSide.name = 'patchStrapSide';
patchStrapSide.position.set(-0.233, 0.29, -0.05);
patchStrapSide.rotation.set(deg(-12), 0, 0);
head.add(patchStrapSide);
const nose = new THREE.Mesh(new THREE.BoxGeometry(0.08, 0.09, 0.07), skinMat);
nose.name = 'nose';
nose.position.set(0, 0.21, 0.26);
head.add(nose);
const beardJaw = new THREE.Mesh(new THREE.BoxGeometry(0.472, 0.16, 0.32), beardMat);
beardJaw.name = 'beardJaw';
beardJaw.position.set(0, 0.094, 0.076);
head.add(beardJaw);
const beardChin = new THREE.Mesh(extrude([[-0.2, 0], [0.2, 0], [0.12, -0.1], [0, -0.15], [-0.12, -0.1]], 0.14), beardMat);
beardChin.name = 'beardChin';
beardChin.position.set(0, 0.04, 0.18);
head.add(beardChin);
const mouth = new THREE.Mesh(new THREE.BoxGeometry(0.07, 0.03, 0.012), coatDarkMat);
mouth.name = 'mouth';
mouth.position.set(0, 0.13, 0.24);
head.add(mouth);
const mustacheL = new THREE.Mesh(boxGeo10, beardMat);
mustacheL.name = 'mustacheL';
mustacheL.position.set(0.07, 0.16, 0.255);
mustacheL.rotation.set(0, 0, deg(12));
head.add(mustacheL);
const mustacheCurlL = new THREE.Mesh(boxGeo11, beardMat);
mustacheCurlL.name = 'mustacheCurlL';
mustacheCurlL.position.set(0.14, 0.185, 0.255);
mustacheCurlL.rotation.set(0, 0, deg(-20));
head.add(mustacheCurlL);
const mustacheR = new THREE.Mesh(boxGeo10, beardMat);
mustacheR.name = 'mustacheR';
mustacheR.position.set(-0.07, 0.16, 0.255);
mustacheR.rotation.set(0, 0, deg(-12));
head.add(mustacheR);
const mustacheCurlR = new THREE.Mesh(boxGeo11, beardMat);
mustacheCurlR.name = 'mustacheCurlR';
mustacheCurlR.position.set(-0.14, 0.185, 0.255);
mustacheCurlR.rotation.set(0, 0, deg(20));
head.add(mustacheCurlR);
const hairBack = new THREE.Mesh(new THREE.BoxGeometry(0.472, 0.3, 0.14), beardMat);
hairBack.name = 'hairBack';
hairBack.position.set(0, 0.27, -0.166);
head.add(hairBack);
const ponytail = new THREE.Mesh(new THREE.BoxGeometry(0.07, 0.16, 0.07), beardMat);
ponytail.name = 'ponytail';
ponytail.position.set(0, 0.13, -0.255);
ponytail.rotation.set(deg(15), 0, 0);
head.add(ponytail);
const earring = new THREE.Mesh(new THREE.TorusGeometry(0.035, 0.009, 4, 10), goldMat);
earring.name = 'earring';
earring.position.set(0.242, 0.13, -0.02);
earring.rotation.set(0, deg(90), 0);
head.add(earring);
const tricorn = new THREE.Group();
tricorn.name = 'tricorn';
tricorn.position.set(0, 0.44, -0.01);
tricorn.rotation.set(deg(-6), 0, 0);
head.add(tricorn);
const hatBrim = new THREE.Mesh(extrude([[0, 0.4], [0.43, -0.22], [-0.43, -0.22]], 0.03), hatMat);
hatBrim.name = 'hatBrim';
hatBrim.position.set(0, 0.015, 0);
hatBrim.rotation.set(deg(90), 0, 0);
tricorn.add(hatBrim);
const hatCrown = new THREE.Mesh(new THREE.CylinderGeometry(0.2121, 0.297, 0.15, 4, 1, false, Math.PI / 4), hatMat);
hatCrown.name = 'hatCrown';
hatCrown.position.set(0, 0.075, -0.01);
tricorn.add(hatCrown);
const hatDome = new THREE.Mesh(new THREE.SphereGeometry(0.2, 8, 3, 0, Math.PI * 2, 0, Math.PI / 2), hatMat);
hatDome.name = 'hatDome';
hatDome.position.set(0, 0.14, -0.01);
hatDome.scale.set(1, 0.55, 1);
tricorn.add(hatDome);
const hatFlap1 = new THREE.Mesh(boxGeo12, hatMat);
hatFlap1.name = 'hatFlap1';
hatFlap1.position.set(0.2064, 0.12, 0.0864);
hatFlap1.rotation.set(deg(20.4541), deg(53.4905), deg(-16.6877));
tricorn.add(hatFlap1);
const hatTrim1 = new THREE.Mesh(boxGeo13, goldMat);
hatTrim1.name = 'hatTrim1';
hatTrim1.position.set(0.2235, 0.2178, 0.0982);
hatTrim1.rotation.set(deg(20.4541), deg(53.4905), deg(-16.6877));
tricorn.add(hatTrim1);
const hatFlap2 = new THREE.Mesh(new THREE.BoxGeometry(0.7912, 0.2, 0.035), hatMat);
hatFlap2.name = 'hatFlap2';
hatFlap2.position.set(0, 0.12, -0.2112);
hatFlap2.rotation.set(deg(168), 0, deg(180));
tricorn.add(hatFlap2);
const hatTrim2 = new THREE.Mesh(new THREE.BoxGeometry(0.7912, 0.025, 0.04), goldMat);
hatTrim2.name = 'hatTrim2';
hatTrim2.position.set(0, 0.2178, -0.232);
hatTrim2.rotation.set(deg(168), 0, deg(180));
tricorn.add(hatTrim2);
const hatFlap3 = new THREE.Mesh(boxGeo12, hatMat);
hatFlap3.name = 'hatFlap3';
hatFlap3.position.set(-0.2064, 0.12, 0.0864);
hatFlap3.rotation.set(deg(20.4541), deg(-53.4905), deg(16.6877));
tricorn.add(hatFlap3);
const hatTrim3 = new THREE.Mesh(boxGeo13, goldMat);
hatTrim3.name = 'hatTrim3';
hatTrim3.position.set(-0.2235, 0.2178, 0.0982);
hatTrim3.rotation.set(deg(20.4541), deg(-53.4905), deg(16.6877));
tricorn.add(hatTrim3);
const hatBadge = new THREE.Group();
hatBadge.name = 'hatBadge';
hatBadge.position.set(0, 0.13, 0.385);
hatBadge.rotation.set(deg(-12), 0, 0);
tricorn.add(hatBadge);
const boneA = new THREE.Mesh(boxGeo14, shirtMat);
boneA.name = 'boneA';
boneA.rotation.set(0, 0, deg(35));
hatBadge.add(boneA);
const boneB = new THREE.Mesh(boxGeo14, shirtMat);
boneB.name = 'boneB';
boneB.rotation.set(0, 0, deg(-35));
hatBadge.add(boneB);
const skullBadge = new THREE.Mesh(new THREE.BoxGeometry(0.06, 0.055, 0.02), shirtMat);
skullBadge.name = 'skullBadge';
skullBadge.position.set(0, 0.008, 0.008);
hatBadge.add(skullBadge);
const skullEye = new THREE.Mesh(boxGeo15, blackMat);
skullEye.name = 'skullEye';
skullEye.position.set(0.013, 0.013, 0.02);
hatBadge.add(skullEye);
const skullEye2 = new THREE.Mesh(boxGeo15, blackMat);
skullEye2.name = 'skullEye';
skullEye2.position.set(-0.013, 0.013, 0.02);
hatBadge.add(skullEye2);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createPirate;
Оценки и комментарии
0 комментариев
Комментариев пока нет. Расскажите, как вы использовали эту модель или что можно улучшить.
Похожие модели
Та же категория или похожие теги









