Codels
1 mil tris0,92 × 1,79 × 1,17 m

Úsalo en código

Hacer remix en el editor
Módulo ES autónomo — solo depende de three. Llama a la función factory y añade el grupo a tu escena.
/**
 * 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;

Valoraciones y comentarios

—
Aún no hay valoraciones — sé el primero.
5
0
4
0
3
0
2
0
1
0

Inicia sesión para valorar y comentar.

0 comentarios

Aún no hay comentarios. Cuenta cómo usaste este modelo o qué se podría mejorar.

Modelos relacionados

Misma categoría o etiquetas similares