Codels
1,1 B üçgen7,50 × 2,02 × 2,32 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.
/**
 * Wooden Bridge — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,092 · Size (W × H × D): 7.50 × 2.02 × 2.32 m
 *
 * Usage:
 *   import { createWoodenBridge } from './wooden-bridge.js';
 *   
 *   const model = createWoodenBridge();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

// Deterministic vertex displacement (organic low-poly look).
function jitter(geometry, amount, seed) {
  const pos = geometry.attributes.position;
  const h = (a, b, c, s) => {
    let x = Math.imul(a, 73856093) ^ Math.imul(b, 19349663) ^ Math.imul(c, 83492791) ^ Math.imul(s, 2654435761);
    x = Math.imul(x ^ (x >>> 16), 2246822507);
    x = Math.imul(x ^ (x >>> 13), 3266489909);
    return ((x ^ (x >>> 16)) >>> 0) / 4294967295 - 0.5;
  };
  for (let i = 0; i < pos.count; i++) {
    const x = pos.getX(i), y = pos.getY(i), z = pos.getZ(i);
    const qx = Math.round(x * 1000), qy = Math.round(y * 1000), qz = Math.round(z * 1000);
    pos.setXYZ(i, x + h(qx, qy, qz, seed) * 2 * amount, y + h(qx, qy, qz, seed + 1) * 2 * amount, z + h(qx, qy, qz, seed + 2) * 2 * amount);
  }
  pos.needsUpdate = true;
  geometry.computeVertexNormals();
  return geometry;
}

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

  // Materials
  const plankMat = new THREE.MeshStandardMaterial({ name: 'plank', color: 0xa5743f, roughness: 0.9, flatShading: true });
  const plank2Mat = new THREE.MeshStandardMaterial({ name: 'plank2', color: 0x8c6033, roughness: 0.9, flatShading: true });
  const beamMat = new THREE.MeshStandardMaterial({ name: 'beam', color: 0x6a4528, roughness: 0.95, flatShading: true });
  const stoneMat = new THREE.MeshStandardMaterial({ name: 'stone', color: 0x75706a, roughness: 0.95, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.12, 1.2583, 0.12);
  const boxGeo2 = new THREE.BoxGeometry(0.215, 0.07, 1.7838);
  const boxGeo3 = new THREE.BoxGeometry(0.15, 1.32, 0.15);
  const cylinderGeo = new THREE.CylinderGeometry(0, 0.1125, 0.12, 4);
  const boxGeo4 = new THREE.BoxGeometry(0.1, 1.2, 0.1);
  const boxGeo5 = new THREE.BoxGeometry(0.07, 1.4817, 0.1);
  const boxGeo6 = new THREE.BoxGeometry(0.05, 1.4817, 0.05);
  const boxGeo7 = new THREE.BoxGeometry(0.04, 1.6323, 0.04);
  const boxGeo8 = new THREE.BoxGeometry(0.07, 1.4314, 0.1);
  const boxGeo9 = new THREE.BoxGeometry(0.05, 1.4314, 0.05);
  const boxGeo10 = new THREE.BoxGeometry(0.04, 1.5188, 0.04);
  const boxGeo11 = new THREE.BoxGeometry(0.04, 1.4476, 0.04);
  const boxGeo12 = new THREE.BoxGeometry(0.04, 1.4251, 0.04);

  // Parts
  const abutment = new THREE.Mesh(jitter(new THREE.BoxGeometry(1, 0.32, 2.3), 0.015, 3), stoneMat);
  abutment.name = 'abutment';
  abutment.position.set(-2.75, 0.172, 0);
  root.add(abutment);
  const abutmentStep = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.6, 0.17, 2.1), 0.015, 5), stoneMat);
  abutmentStep.name = 'abutmentStep';
  abutmentStep.position.set(-3.45, 0.097, 0);
  root.add(abutmentStep);
  const abutment2 = new THREE.Mesh(jitter(new THREE.BoxGeometry(1, 0.32, 2.3), 0.015, 2), stoneMat);
  abutment2.name = 'abutment';
  abutment2.position.set(2.75, 0.172, 0);
  root.add(abutment2);
  const abutmentStep2 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.6, 0.17, 2.1), 0.015, 4), stoneMat);
  abutmentStep2.name = 'abutmentStep';
  abutmentStep2.position.set(3.45, 0.097, 0);
  root.add(abutmentStep2);
  const stringer = new THREE.Mesh(tube([[-2.95, 0.2698, -0.72], [-2.2125, 0.5237, -0.72], [-1.475, 0.705, -0.72], [-0.7375, 0.8137, -0.72], [0, 0.85, -0.72], [0.7375, 0.8137, -0.72], [1.475, 0.705, -0.72], [2.2125, 0.5237, -0.72], [2.95, 0.2698, -0.72]], 0.1, 16, 4), beamMat);
  stringer.name = 'stringer';
  root.add(stringer);
  const stringer2 = new THREE.Mesh(tube([[-2.95, 0.2698, 0.72], [-2.2125, 0.5237, 0.72], [-1.475, 0.705, 0.72], [-0.7375, 0.8137, 0.72], [0, 0.85, 0.72], [0.7375, 0.8137, 0.72], [1.475, 0.705, 0.72], [2.2125, 0.5237, 0.72], [2.95, 0.2698, 0.72]], 0.1, 16, 4), beamMat);
  stringer2.name = 'stringer';
  root.add(stringer2);
  const strut = new THREE.Mesh(boxGeo, beamMat);
  strut.name = 'strut';
  strut.position.set(-1.95, 0.4893, -0.72);
  strut.rotation.set(0, deg(180), deg(72.4939));
  root.add(strut);
  const strut2 = new THREE.Mesh(boxGeo, beamMat);
  strut2.name = 'strut';
  strut2.position.set(-1.95, 0.4893, 0.72);
  strut2.rotation.set(0, deg(180), deg(72.4939));
  root.add(strut2);
  const strut3 = new THREE.Mesh(boxGeo, beamMat);
  strut3.name = 'strut';
  strut3.position.set(1.95, 0.4893, -0.72);
  strut3.rotation.set(0, 0, deg(72.4939));
  root.add(strut3);
  const strut4 = new THREE.Mesh(boxGeo, beamMat);
  strut4.name = 'strut';
  strut4.position.set(1.95, 0.4893, 0.72);
  strut4.rotation.set(0, 0, deg(72.4939));
  root.add(strut4);
  const plank = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.808), plankMat);
  plank.name = 'plank';
  plank.position.set(-2.88, 0.4269, -0.0271);
  plank.rotation.set(0, deg(-1.1117), deg(21.0068));
  root.add(plank);
  const plank2 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7408), plank2Mat);
  plank2.name = 'plank';
  plank2.position.set(-2.64, 0.5186, 0.0035);
  plank2.rotation.set(0, deg(0.8894), deg(19.3921));
  root.add(plank2);
  const plank3 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8187), plankMat);
  plank3.name = 'plank';
  plank3.position.set(-2.4, 0.5985, -0.02);
  plank3.rotation.set(0, deg(0.1457), deg(17.7447));
  root.add(plank3);
  const plank4 = new THREE.Mesh(boxGeo2, plankMat);
  plank4.name = 'plank';
  plank4.position.set(-2.16, 0.6753, -0.0226);
  plank4.rotation.set(0, deg(0.3515), deg(16.0664));
  root.add(plank4);
  const plank5 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7921), plankMat);
  plank5.name = 'plank';
  plank5.position.set(-1.92, 0.7373, -0.0238);
  plank5.rotation.set(0, deg(0.59), deg(14.3593));
  root.add(plank5);
  const plank6 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7884), plank2Mat);
  plank6.name = 'plank';
  plank6.position.set(-1.68, 0.7946, -0.0276);
  plank6.rotation.set(0, deg(-1.0527), deg(12.6258));
  root.add(plank6);
  const plank7 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7747), plankMat);
  plank7.name = 'plank';
  plank7.position.set(-1.44, 0.8451, 0.0135);
  plank7.rotation.set(0, deg(-0.671), deg(10.8685));
  root.add(plank7);
  const plank8 = new THREE.Mesh(boxGeo2, plank2Mat);
  plank8.name = 'plank';
  plank8.position.set(-1.2, 0.8914, -0.0289);
  plank8.rotation.set(0, deg(0.0716), deg(9.0903));
  root.add(plank8);
  const plank9 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7499), plank2Mat);
  plank9.name = 'plank';
  plank9.position.set(-0.96, 0.9225, -0.0229);
  plank9.rotation.set(0, deg(-0.7878), deg(7.2942));
  root.add(plank9);
  const plank10 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7715), plankMat);
  plank10.name = 'plank';
  plank10.position.set(-0.72, 0.9458, -0.0198);
  plank10.rotation.set(0, deg(0.6217), deg(5.4836));
  root.add(plank10);
  const plank11 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7592), plank2Mat);
  plank11.name = 'plank';
  plank11.position.set(-0.48, 0.9668, 0.024);
  plank11.rotation.set(0, deg(1.1897), deg(3.6619));
  root.add(plank11);
  const plank12 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8319), plank2Mat);
  plank12.name = 'plank';
  plank12.position.set(-0.24, 0.9797, -0.0272);
  plank12.rotation.set(0, deg(0.6687), deg(1.8328));
  root.add(plank12);
  const plank13 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7579), plank2Mat);
  plank13.name = 'plank';
  plank13.position.set(0, 0.9807, 0.0118);
  plank13.rotation.set(0, deg(0.7961), 0);
  root.add(plank13);
  const plank14 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8561), plankMat);
  plank14.name = 'plank';
  plank14.position.set(0.24, 0.98, 0.0118);
  plank14.rotation.set(0, deg(0.9706), deg(-1.8328));
  root.add(plank14);
  const plank15 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8171), plankMat);
  plank15.name = 'plank';
  plank15.position.set(0.48, 0.9722, 0.0254);
  plank15.rotation.set(0, deg(0.0885), deg(-3.6619));
  root.add(plank15);
  const plank16 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8331), plankMat);
  plank16.name = 'plank';
  plank16.position.set(0.72, 0.9546, -0.0138);
  plank16.rotation.set(0, deg(0.352), deg(-5.4836));
  root.add(plank16);
  const plank17 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.765), plankMat);
  plank17.name = 'plank';
  plank17.position.set(0.96, 0.9251, -0.0058);
  plank17.rotation.set(0, deg(-0.9303), deg(-7.2942));
  root.add(plank17);
  const plank18 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7487), plankMat);
  plank18.name = 'plank';
  plank18.position.set(1.2, 0.8844, 0.0256);
  plank18.rotation.set(0, deg(0.6926), deg(-9.0903));
  root.add(plank18);
  const plank19 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7831), plankMat);
  plank19.name = 'plank';
  plank19.position.set(1.44, 0.8516, -0.0212);
  plank19.rotation.set(0, deg(-0.3655), deg(-10.8685));
  root.add(plank19);
  const plank20 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7563), plankMat);
  plank20.name = 'plank';
  plank20.position.set(1.68, 0.7948, -0.0075);
  plank20.rotation.set(0, deg(-0.7818), deg(-12.6258));
  root.add(plank20);
  const plank21 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8151), plankMat);
  plank21.name = 'plank';
  plank21.position.set(1.92, 0.7371, 0.0206);
  plank21.rotation.set(0, deg(1.103), deg(-14.3593));
  root.add(plank21);
  const plank22 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8089), plank2Mat);
  plank22.name = 'plank';
  plank22.position.set(2.16, 0.6691, 0.0004);
  plank22.rotation.set(0, deg(-0.7146), deg(-16.0664));
  root.add(plank22);
  const plank23 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8411), plankMat);
  plank23.name = 'plank';
  plank23.position.set(2.4, 0.6054, 0.0152);
  plank23.rotation.set(0, deg(0.9122), deg(-17.7447));
  root.add(plank23);
  const plank24 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8455), plank2Mat);
  plank24.name = 'plank';
  plank24.position.set(2.64, 0.5249, 0.0147);
  plank24.rotation.set(0, deg(-1.0455), deg(-19.3921));
  root.add(plank24);
  const plank25 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.754), plank2Mat);
  plank25.name = 'plank';
  plank25.position.set(2.88, 0.4358, -0.021);
  plank25.rotation.set(0, deg(-0.3847), deg(-21.0068));
  root.add(plank25);
  const endPost = new THREE.Mesh(boxGeo3, beamMat);
  endPost.name = 'endPost';
  endPost.position.set(-2.85, 0.9385, -0.88);
  root.add(endPost);
  const postCap = new THREE.Mesh(cylinderGeo, beamMat);
  postCap.name = 'postCap';
  postCap.position.set(-2.85, 1.6585, -0.88);
  postCap.rotation.set(0, deg(45), 0);
  root.add(postCap);
  const post = new THREE.Mesh(boxGeo4, beamMat);
  post.name = 'post';
  post.position.set(-1.425, 1.2846, -0.88);
  root.add(post);
  const post2 = new THREE.Mesh(boxGeo4, beamMat);
  post2.name = 'post';
  post2.position.set(0, 1.42, -0.88);
  root.add(post2);
  const post3 = new THREE.Mesh(boxGeo4, beamMat);
  post3.name = 'post';
  post3.position.set(1.425, 1.2846, -0.88);
  root.add(post3);
  const endPost2 = new THREE.Mesh(boxGeo3, beamMat);
  endPost2.name = 'endPost';
  endPost2.position.set(2.85, 0.9385, -0.88);
  root.add(endPost2);
  const postCap2 = new THREE.Mesh(cylinderGeo, beamMat);
  postCap2.name = 'postCap';
  postCap2.position.set(2.85, 1.6585, -0.88);
  postCap2.rotation.set(0, deg(45), 0);
  root.add(postCap2);
  const handrail = new THREE.Mesh(boxGeo5, plankMat);
  handrail.name = 'handrail';
  handrail.position.set(-2.1375, 1.6316, -0.88);
  handrail.rotation.set(0, deg(180), deg(74.0924));
  root.add(handrail);
  const midRail = new THREE.Mesh(boxGeo6, plank2Mat);
  midRail.name = 'midRail';
  midRail.position.set(-2.1375, 1.1816, -0.88);
  midRail.rotation.set(0, deg(180), deg(74.0924));
  root.add(midRail);
  const infill = new THREE.Mesh(boxGeo7, beamMat);
  infill.name = 'infill';
  infill.position.set(-2.1375, 0.9566, -0.88);
  infill.rotation.set(0, deg(180), deg(60.8086));
  root.add(infill);
  const handrail2 = new THREE.Mesh(boxGeo8, plankMat);
  handrail2.name = 'handrail';
  handrail2.position.set(-0.7125, 1.9023, -0.88);
  handrail2.rotation.set(0, deg(180), deg(84.5732));
  root.add(handrail2);
  const midRail2 = new THREE.Mesh(boxGeo9, plank2Mat);
  midRail2.name = 'midRail';
  midRail2.position.set(-0.7125, 1.4523, -0.88);
  midRail2.rotation.set(0, deg(180), deg(84.5732));
  root.add(midRail2);
  const infill2 = new THREE.Mesh(boxGeo10, beamMat);
  infill2.name = 'infill';
  infill2.position.set(-0.7125, 1.2273, -0.88);
  infill2.rotation.set(0, deg(180), deg(69.7619));
  root.add(infill2);
  const handrail3 = new THREE.Mesh(boxGeo8, plankMat);
  handrail3.name = 'handrail';
  handrail3.position.set(0.7125, 1.9023, -0.88);
  handrail3.rotation.set(0, deg(180), deg(95.4268));
  root.add(handrail3);
  const midRail3 = new THREE.Mesh(boxGeo9, plank2Mat);
  midRail3.name = 'midRail';
  midRail3.position.set(0.7125, 1.4523, -0.88);
  midRail3.rotation.set(0, deg(180), deg(95.4268));
  root.add(midRail3);
  const infill3 = new THREE.Mesh(boxGeo11, beamMat);
  infill3.name = 'infill';
  infill3.position.set(0.7125, 1.2273, -0.88);
  infill3.rotation.set(0, deg(180), deg(79.8691));
  root.add(infill3);
  const handrail4 = new THREE.Mesh(boxGeo5, plankMat);
  handrail4.name = 'handrail';
  handrail4.position.set(2.1375, 1.6316, -0.88);
  handrail4.rotation.set(0, deg(180), deg(105.9076));
  root.add(handrail4);
  const midRail4 = new THREE.Mesh(boxGeo6, plank2Mat);
  midRail4.name = 'midRail';
  midRail4.position.set(2.1375, 1.1816, -0.88);
  midRail4.rotation.set(0, deg(180), deg(105.9076));
  root.add(midRail4);
  const infill4 = new THREE.Mesh(boxGeo12, beamMat);
  infill4.name = 'infill';
  infill4.position.set(2.1375, 0.9566, -0.88);
  infill4.rotation.set(0, deg(180), deg(90.6483));
  root.add(infill4);
  const endPost3 = new THREE.Mesh(boxGeo3, beamMat);
  endPost3.name = 'endPost';
  endPost3.position.set(-2.85, 0.9385, 0.88);
  root.add(endPost3);
  const postCap3 = new THREE.Mesh(cylinderGeo, beamMat);
  postCap3.name = 'postCap';
  postCap3.position.set(-2.85, 1.6585, 0.88);
  postCap3.rotation.set(0, deg(45), 0);
  root.add(postCap3);
  const post4 = new THREE.Mesh(boxGeo4, beamMat);
  post4.name = 'post';
  post4.position.set(-1.425, 1.2846, 0.88);
  root.add(post4);
  const post5 = new THREE.Mesh(boxGeo4, beamMat);
  post5.name = 'post';
  post5.position.set(0, 1.42, 0.88);
  root.add(post5);
  const post6 = new THREE.Mesh(boxGeo4, beamMat);
  post6.name = 'post';
  post6.position.set(1.425, 1.2846, 0.88);
  root.add(post6);
  const endPost4 = new THREE.Mesh(boxGeo3, beamMat);
  endPost4.name = 'endPost';
  endPost4.position.set(2.85, 0.9385, 0.88);
  root.add(endPost4);
  const postCap4 = new THREE.Mesh(cylinderGeo, beamMat);
  postCap4.name = 'postCap';
  postCap4.position.set(2.85, 1.6585, 0.88);
  postCap4.rotation.set(0, deg(45), 0);
  root.add(postCap4);
  const handrail5 = new THREE.Mesh(boxGeo5, plankMat);
  handrail5.name = 'handrail';
  handrail5.position.set(-2.1375, 1.6316, 0.88);
  handrail5.rotation.set(0, deg(180), deg(74.0924));
  root.add(handrail5);
  const midRail5 = new THREE.Mesh(boxGeo6, plank2Mat);
  midRail5.name = 'midRail';
  midRail5.position.set(-2.1375, 1.1816, 0.88);
  midRail5.rotation.set(0, deg(180), deg(74.0924));
  root.add(midRail5);
  const infill5 = new THREE.Mesh(boxGeo7, beamMat);
  infill5.name = 'infill';
  infill5.position.set(-2.1375, 0.9566, 0.88);
  infill5.rotation.set(0, deg(180), deg(60.8086));
  root.add(infill5);
  const handrail6 = new THREE.Mesh(boxGeo8, plankMat);
  handrail6.name = 'handrail';
  handrail6.position.set(-0.7125, 1.9023, 0.88);
  handrail6.rotation.set(0, deg(180), deg(84.5732));
  root.add(handrail6);
  const midRail6 = new THREE.Mesh(boxGeo9, plank2Mat);
  midRail6.name = 'midRail';
  midRail6.position.set(-0.7125, 1.4523, 0.88);
  midRail6.rotation.set(0, deg(180), deg(84.5732));
  root.add(midRail6);
  const infill6 = new THREE.Mesh(boxGeo10, beamMat);
  infill6.name = 'infill';
  infill6.position.set(-0.7125, 1.2273, 0.88);
  infill6.rotation.set(0, deg(180), deg(69.7619));
  root.add(infill6);
  const handrail7 = new THREE.Mesh(boxGeo8, plankMat);
  handrail7.name = 'handrail';
  handrail7.position.set(0.7125, 1.9023, 0.88);
  handrail7.rotation.set(0, deg(180), deg(95.4268));
  root.add(handrail7);
  const midRail7 = new THREE.Mesh(boxGeo9, plank2Mat);
  midRail7.name = 'midRail';
  midRail7.position.set(0.7125, 1.4523, 0.88);
  midRail7.rotation.set(0, deg(180), deg(95.4268));
  root.add(midRail7);
  const infill7 = new THREE.Mesh(boxGeo11, beamMat);
  infill7.name = 'infill';
  infill7.position.set(0.7125, 1.2273, 0.88);
  infill7.rotation.set(0, deg(180), deg(79.8691));
  root.add(infill7);
  const handrail8 = new THREE.Mesh(boxGeo5, plankMat);
  handrail8.name = 'handrail';
  handrail8.position.set(2.1375, 1.6316, 0.88);
  handrail8.rotation.set(0, deg(180), deg(105.9076));
  root.add(handrail8);
  const midRail8 = new THREE.Mesh(boxGeo6, plank2Mat);
  midRail8.name = 'midRail';
  midRail8.position.set(2.1375, 1.1816, 0.88);
  midRail8.rotation.set(0, deg(180), deg(105.9076));
  root.add(midRail8);
  const infill8 = new THREE.Mesh(boxGeo12, beamMat);
  infill8.name = 'infill';
  infill8.position.set(2.1375, 0.9566, 0.88);
  infill8.rotation.set(0, deg(180), deg(90.6483));
  root.add(infill8);

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

export default createWoodenBridge;

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