3,1 тыс. треуг.13,9 × 12,9 × 6,35 m
Использовать в коде
Ремикс в редактореcastle-gate.js · 1 168 строк
Самодостаточный ES-модуль — зависит только от three. Вызовите фабрику и добавьте группу в сцену.
/**
* Castle Gatehouse — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 3,092 · Size (W × H × D): 13.92 × 12.86 × 6.35 m
*
* Usage:
* import { createCastleGate } from './castle-gate.js';
*
* const model = createCastleGate();
* 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;
}
// 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 createCastleGate() {
const root = new THREE.Group();
root.name = 'CastleGate';
// Materials
const stoneMat = new THREE.MeshStandardMaterial({ name: 'stone', color: 0xa39c90, roughness: 0.95, flatShading: true });
const trimMat = new THREE.MeshStandardMaterial({ name: 'trim', color: 0x868076, roughness: 0.95, flatShading: true });
const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x2e2c28, roughness: 1, flatShading: true });
const pavingMat = new THREE.MeshStandardMaterial({ name: 'paving', color: 0x6a655e, roughness: 1, flatShading: true });
const woodMat = new THREE.MeshStandardMaterial({ name: 'wood', color: 0x6a4529, roughness: 0.9, flatShading: true });
const ironMat = new THREE.MeshStandardMaterial({ name: 'iron', color: 0x303236, roughness: 0.5, metalness: 0.7, flatShading: true });
const bannerMat = new THREE.MeshStandardMaterial({ name: 'banner', color: 0x2f4f8f, roughness: 0.85, flatShading: true });
const goldMat = new THREE.MeshStandardMaterial({ name: 'gold', color: 0xd1a23a, roughness: 0.45, metalness: 0.5, flatShading: true });
// Shared geometries
const boxGeo = new THREE.BoxGeometry(7.1, 0.2, 0.12);
const extrudeGeo = extrude([[-1.7999, 2.9216], [-1.7527, 3.3098], [-2.2883, 3.435], [-2.3498, 2.9282]], 0.16);
const extrudeGeo2 = extrude([[-1.7424, 3.3517], [-1.6037, 3.7173], [-2.0938, 3.9671], [-2.2748, 3.4897]], 0.16);
const extrudeGeo3 = extrude([[-1.5837, 3.7556], [-1.3615, 4.0774], [-1.7776, 4.4371], [-2.0676, 4.017]], 0.16);
const extrudeGeo4 = extrude([[-1.3329, 4.1097], [-1.0402, 4.369], [-1.3581, 4.8179], [-1.7402, 4.4793]], 0.16);
const extrudeGeo5 = extrude([[-1.0047, 4.3935], [-0.6584, 4.5752], [-0.8596, 5.0871], [-1.3116, 4.8499]], 0.16);
const extrudeGeo6 = extrude([[-0.618, 4.5906], [-0.2384, 4.6841], [-0.3112, 5.2293], [-0.8069, 5.1071]], 0.16);
const extrudeGeo7 = extrude([[-0.1955, 4.6894], [0.1955, 4.6894], [0.277, 5.4349], [-0.277, 5.4349]], 0.26);
const extrudeGeo8 = extrude([[0.2384, 4.6841], [0.618, 4.5906], [0.8069, 5.1071], [0.3112, 5.2293]], 0.16);
const extrudeGeo9 = extrude([[0.6584, 4.5752], [1.0047, 4.3935], [1.3116, 4.8499], [0.8596, 5.0871]], 0.16);
const extrudeGeo10 = extrude([[1.0402, 4.369], [1.3329, 4.1097], [1.7402, 4.4793], [1.3581, 4.8179]], 0.16);
const extrudeGeo11 = extrude([[1.3615, 4.0774], [1.5837, 3.7556], [2.0676, 4.017], [1.7776, 4.4371]], 0.16);
const extrudeGeo12 = extrude([[1.6037, 3.7173], [1.7424, 3.3517], [2.2748, 3.4897], [2.0938, 3.9671]], 0.16);
const extrudeGeo13 = extrude([[1.7527, 3.3098], [1.7999, 2.9216], [2.3498, 2.9282], [2.2883, 3.435]], 0.16);
const boxGeo2 = new THREE.BoxGeometry(0.08, 3.15, 0.2);
const boxGeo3 = new THREE.BoxGeometry(0.24, 0.55, 0.42);
const boxGeo4 = new THREE.BoxGeometry(1.04, 0.08, 0.58);
const cylinderGeo = new THREE.CylinderGeometry(2.28, 2.62, 1.1, 12);
const cylinderGeo2 = new THREE.CylinderGeometry(2.2, 2.2, 8.5, 12);
const cylinderGeo3 = new THREE.CylinderGeometry(2.28, 2.28, 0.2, 12);
const boxGeo5 = new THREE.BoxGeometry(0.3, 0.5, 0.4);
const cylinderGeo4 = new THREE.CylinderGeometry(2.58, 2.58, 0.6, 12);
const cylinderGeo5 = new THREE.CylinderGeometry(2.63, 2.63, 0.1, 12);
const boxGeo6 = new THREE.BoxGeometry(0.8916, 0.8, 0.4);
const boxGeo7 = new THREE.BoxGeometry(0.9516, 0.08, 0.46);
const boxGeo8 = new THREE.BoxGeometry(0.36, 1.1, 0.06);
const boxGeo9 = new THREE.BoxGeometry(0.12, 0.85, 0.06);
const boxGeo10 = new THREE.BoxGeometry(0.32, 0.1, 0.06);
const cylinderGeo6 = new THREE.CylinderGeometry(0.035, 0.035, 1.25, 5);
const extrudeGeo14 = extrude([[-0.5, 0], [0.5, 0], [0.5, -2.9], [0, -2.45], [-0.5, -2.9]], 0.04);
const boxGeo11 = new THREE.BoxGeometry(0.12, 1.6, 0.02);
const cylinderGeo7 = new THREE.CylinderGeometry(1.95, 1.95, 0.05, 12);
const boxGeo12 = new THREE.BoxGeometry(0.07, 4.8, 0.07);
const coneGeo = new THREE.ConeGeometry(0.055, 0.14, 4);
const boxGeo13 = new THREE.BoxGeometry(3.52, 0.07, 0.06);
const boxGeo14 = new THREE.BoxGeometry(1.76, 3.25, 0.12);
const boxGeo15 = new THREE.BoxGeometry(1.71, 0.12, 0.03);
// Parts
const gatehouse = new THREE.Mesh(extrude([[-3.5, 0], [-1.8, 0], [-1.8, 2.9], [-1.7387, 3.3659], [-1.5588, 3.8], [-1.2728, 4.1728], [-0.9, 4.4588], [-0.4659, 4.6387], [0, 4.7], [0.4659, 4.6387], [0.9, 4.4588], [1.2728, 4.1728], [1.5588, 3.8], [1.7387, 3.3659], [1.8, 2.9], [1.8, 0], [3.5, 0], [3.5, 7.2], [-3.5, 7.2]], 5), stoneMat);
gatehouse.name = 'gatehouse';
root.add(gatehouse);
const passageFloor = new THREE.Mesh(new THREE.BoxGeometry(3.58, 0.05, 6.2), pavingMat);
passageFloor.name = 'passageFloor';
passageFloor.position.set(0, 0.025, 0.6);
root.add(passageFloor);
const plinth = new THREE.Mesh(jitter(new THREE.BoxGeometry(1.8, 0.6, 5.2), 0.01, 1), trimMat);
plinth.name = 'plinth';
plinth.position.set(-2.65, 0.3, 0);
root.add(plinth);
const plinth2 = new THREE.Mesh(jitter(new THREE.BoxGeometry(1.8, 0.6, 5.2), 0.01, 2), trimMat);
plinth2.name = 'plinth';
plinth2.position.set(2.65, 0.3, 0);
root.add(plinth2);
const stringCourse = new THREE.Mesh(boxGeo, trimMat);
stringCourse.name = 'stringCourse';
stringCourse.position.set(0, 5.45, -2.55);
root.add(stringCourse);
const stringCourse2 = new THREE.Mesh(boxGeo, trimMat);
stringCourse2.name = 'stringCourse';
stringCourse2.position.set(0, 5.45, 2.55);
root.add(stringCourse2);
const voussoir = new THREE.Mesh(extrudeGeo, stoneMat);
voussoir.name = 'voussoir';
voussoir.position.set(0, 0, -2.52);
root.add(voussoir);
const voussoir2 = new THREE.Mesh(extrudeGeo2, trimMat);
voussoir2.name = 'voussoir';
voussoir2.position.set(0, 0, -2.52);
root.add(voussoir2);
const voussoir3 = new THREE.Mesh(extrudeGeo3, stoneMat);
voussoir3.name = 'voussoir';
voussoir3.position.set(0, 0, -2.52);
root.add(voussoir3);
const voussoir4 = new THREE.Mesh(extrudeGeo4, trimMat);
voussoir4.name = 'voussoir';
voussoir4.position.set(0, 0, -2.52);
root.add(voussoir4);
const voussoir5 = new THREE.Mesh(extrudeGeo5, stoneMat);
voussoir5.name = 'voussoir';
voussoir5.position.set(0, 0, -2.52);
root.add(voussoir5);
const voussoir6 = new THREE.Mesh(extrudeGeo6, trimMat);
voussoir6.name = 'voussoir';
voussoir6.position.set(0, 0, -2.52);
root.add(voussoir6);
const keystone = new THREE.Mesh(extrudeGeo7, stoneMat);
keystone.name = 'keystone';
keystone.position.set(0, 0, -2.52);
root.add(keystone);
const voussoir7 = new THREE.Mesh(extrudeGeo8, trimMat);
voussoir7.name = 'voussoir';
voussoir7.position.set(0, 0, -2.52);
root.add(voussoir7);
const voussoir8 = new THREE.Mesh(extrudeGeo9, stoneMat);
voussoir8.name = 'voussoir';
voussoir8.position.set(0, 0, -2.52);
root.add(voussoir8);
const voussoir9 = new THREE.Mesh(extrudeGeo10, trimMat);
voussoir9.name = 'voussoir';
voussoir9.position.set(0, 0, -2.52);
root.add(voussoir9);
const voussoir10 = new THREE.Mesh(extrudeGeo11, stoneMat);
voussoir10.name = 'voussoir';
voussoir10.position.set(0, 0, -2.52);
root.add(voussoir10);
const voussoir11 = new THREE.Mesh(extrudeGeo12, trimMat);
voussoir11.name = 'voussoir';
voussoir11.position.set(0, 0, -2.52);
root.add(voussoir11);
const voussoir12 = new THREE.Mesh(extrudeGeo13, stoneMat);
voussoir12.name = 'voussoir';
voussoir12.position.set(0, 0, -2.52);
root.add(voussoir12);
const voussoir13 = new THREE.Mesh(extrudeGeo, stoneMat);
voussoir13.name = 'voussoir';
voussoir13.position.set(0, 0, 2.52);
root.add(voussoir13);
const voussoir14 = new THREE.Mesh(extrudeGeo2, trimMat);
voussoir14.name = 'voussoir';
voussoir14.position.set(0, 0, 2.52);
root.add(voussoir14);
const voussoir15 = new THREE.Mesh(extrudeGeo3, stoneMat);
voussoir15.name = 'voussoir';
voussoir15.position.set(0, 0, 2.52);
root.add(voussoir15);
const voussoir16 = new THREE.Mesh(extrudeGeo4, trimMat);
voussoir16.name = 'voussoir';
voussoir16.position.set(0, 0, 2.52);
root.add(voussoir16);
const voussoir17 = new THREE.Mesh(extrudeGeo5, stoneMat);
voussoir17.name = 'voussoir';
voussoir17.position.set(0, 0, 2.52);
root.add(voussoir17);
const voussoir18 = new THREE.Mesh(extrudeGeo6, trimMat);
voussoir18.name = 'voussoir';
voussoir18.position.set(0, 0, 2.52);
root.add(voussoir18);
const keystone2 = new THREE.Mesh(extrudeGeo7, stoneMat);
keystone2.name = 'keystone';
keystone2.position.set(0, 0, 2.52);
root.add(keystone2);
const voussoir19 = new THREE.Mesh(extrudeGeo8, trimMat);
voussoir19.name = 'voussoir';
voussoir19.position.set(0, 0, 2.52);
root.add(voussoir19);
const voussoir20 = new THREE.Mesh(extrudeGeo9, stoneMat);
voussoir20.name = 'voussoir';
voussoir20.position.set(0, 0, 2.52);
root.add(voussoir20);
const voussoir21 = new THREE.Mesh(extrudeGeo10, trimMat);
voussoir21.name = 'voussoir';
voussoir21.position.set(0, 0, 2.52);
root.add(voussoir21);
const voussoir22 = new THREE.Mesh(extrudeGeo11, stoneMat);
voussoir22.name = 'voussoir';
voussoir22.position.set(0, 0, 2.52);
root.add(voussoir22);
const voussoir23 = new THREE.Mesh(extrudeGeo12, trimMat);
voussoir23.name = 'voussoir';
voussoir23.position.set(0, 0, 2.52);
root.add(voussoir23);
const voussoir24 = new THREE.Mesh(extrudeGeo13, stoneMat);
voussoir24.name = 'voussoir';
voussoir24.position.set(0, 0, 2.52);
root.add(voussoir24);
const faceStone = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.4746, 0.3173, 0.06), 0.008, 3), trimMat);
faceStone.name = 'faceStone';
faceStone.position.set(-2.7013, 5.3972, 2.515);
root.add(faceStone);
const faceStone2 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.8275, 0.2988, 0.06), 0.008, 4), stoneMat);
faceStone2.name = 'faceStone';
faceStone2.position.set(2.813, 4.4241, 2.515);
root.add(faceStone2);
const faceStone3 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.51, 0.3064, 0.06), 0.008, 5), trimMat);
faceStone3.name = 'faceStone';
faceStone3.position.set(2.9791, 4.0467, 2.515);
root.add(faceStone3);
const faceStone4 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.767, 0.2579, 0.06), 0.008, 6), stoneMat);
faceStone4.name = 'faceStone';
faceStone4.position.set(2.7652, 5.2711, 2.515);
root.add(faceStone4);
const faceStone5 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.5204, 0.2512, 0.06), 0.008, 7), stoneMat);
faceStone5.name = 'faceStone';
faceStone5.position.set(-2.6572, 4.3764, 2.515);
root.add(faceStone5);
const faceStone6 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.6424, 0.2484, 0.06), 0.008, 8), trimMat);
faceStone6.name = 'faceStone';
faceStone6.position.set(2.8063, 6.0559, 2.515);
root.add(faceStone6);
const faceStone7 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.4768, 0.3051, 0.06), 0.008, 9), stoneMat);
faceStone7.name = 'faceStone';
faceStone7.position.set(-1.5173, 5.7723, 2.515);
root.add(faceStone7);
const faceStone8 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.814, 0.3082, 0.06), 0.008, 10), stoneMat);
faceStone8.name = 'faceStone';
faceStone8.position.set(-2.5019, 6.1497, 2.515);
root.add(faceStone8);
const portcullisGroove = new THREE.Mesh(boxGeo2, darkMat);
portcullisGroove.name = 'portcullisGroove';
portcullisGroove.position.set(-1.78, 1.615, 1.75);
root.add(portcullisGroove);
const portcullisGroove2 = new THREE.Mesh(boxGeo2, darkMat);
portcullisGroove2.name = 'portcullisGroove';
portcullisGroove2.position.set(1.78, 1.615, 1.75);
root.add(portcullisGroove2);
const corbel = new THREE.Mesh(boxGeo3, trimMat);
corbel.name = 'corbel';
corbel.position.set(-3.15, 6.9, 2.67);
root.add(corbel);
const corbel2 = new THREE.Mesh(boxGeo3, trimMat);
corbel2.name = 'corbel';
corbel2.position.set(-2.3625, 6.9, 2.67);
root.add(corbel2);
const corbel3 = new THREE.Mesh(boxGeo3, trimMat);
corbel3.name = 'corbel';
corbel3.position.set(-1.575, 6.9, 2.67);
root.add(corbel3);
const corbel4 = new THREE.Mesh(boxGeo3, trimMat);
corbel4.name = 'corbel';
corbel4.position.set(-0.7875, 6.9, 2.67);
root.add(corbel4);
const corbel5 = new THREE.Mesh(boxGeo3, trimMat);
corbel5.name = 'corbel';
corbel5.position.set(0, 6.9, 2.67);
root.add(corbel5);
const corbel6 = new THREE.Mesh(boxGeo3, trimMat);
corbel6.name = 'corbel';
corbel6.position.set(0.7875, 6.9, 2.67);
root.add(corbel6);
const corbel7 = new THREE.Mesh(boxGeo3, trimMat);
corbel7.name = 'corbel';
corbel7.position.set(1.575, 6.9, 2.67);
root.add(corbel7);
const corbel8 = new THREE.Mesh(boxGeo3, trimMat);
corbel8.name = 'corbel';
corbel8.position.set(2.3625, 6.9, 2.67);
root.add(corbel8);
const corbel9 = new THREE.Mesh(boxGeo3, trimMat);
corbel9.name = 'corbel';
corbel9.position.set(3.15, 6.9, 2.67);
root.add(corbel9);
const frontParapet = new THREE.Mesh(new THREE.BoxGeometry(7.05, 0.75, 0.5), stoneMat);
frontParapet.name = 'frontParapet';
frontParapet.position.set(0, 7.525, 2.63);
root.add(frontParapet);
const backParapet = new THREE.Mesh(new THREE.BoxGeometry(6.9, 0.6, 0.4), stoneMat);
backParapet.name = 'backParapet';
backParapet.position.set(0, 7.5, -2.3);
root.add(backParapet);
const walkway = new THREE.Mesh(new THREE.BoxGeometry(6.6, 0.05, 4.2), pavingMat);
walkway.name = 'walkway';
walkway.position.set(0, 7.225, 0);
root.add(walkway);
const merlon = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.96, 0.75, 0.5), 0.012, 11), stoneMat);
merlon.name = 'merlon';
merlon.position.set(-3, 8.275, 2.63);
root.add(merlon);
const merlonCap = new THREE.Mesh(boxGeo4, trimMat);
merlonCap.name = 'merlonCap';
merlonCap.position.set(-3, 8.69, 2.63);
root.add(merlonCap);
const merlon2 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.96, 0.7, 0.4), 0.012, 12), stoneMat);
merlon2.name = 'merlon';
merlon2.position.set(-3, 8.15, -2.3);
root.add(merlon2);
const merlon3 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.96, 0.75, 0.5), 0.012, 13), stoneMat);
merlon3.name = 'merlon';
merlon3.position.set(-1, 8.275, 2.63);
root.add(merlon3);
const merlonCap2 = new THREE.Mesh(boxGeo4, trimMat);
merlonCap2.name = 'merlonCap';
merlonCap2.position.set(-1, 8.69, 2.63);
root.add(merlonCap2);
const merlon4 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.96, 0.7, 0.4), 0.012, 14), stoneMat);
merlon4.name = 'merlon';
merlon4.position.set(-1, 8.15, -2.3);
root.add(merlon4);
const merlon5 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.96, 0.75, 0.5), 0.012, 15), stoneMat);
merlon5.name = 'merlon';
merlon5.position.set(1, 8.275, 2.63);
root.add(merlon5);
const merlonCap3 = new THREE.Mesh(boxGeo4, trimMat);
merlonCap3.name = 'merlonCap';
merlonCap3.position.set(1, 8.69, 2.63);
root.add(merlonCap3);
const merlon6 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.96, 0.7, 0.4), 0.012, 16), stoneMat);
merlon6.name = 'merlon';
merlon6.position.set(1, 8.15, -2.3);
root.add(merlon6);
const merlon7 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.96, 0.75, 0.5), 0.012, 17), stoneMat);
merlon7.name = 'merlon';
merlon7.position.set(3, 8.275, 2.63);
root.add(merlon7);
const merlonCap4 = new THREE.Mesh(boxGeo4, trimMat);
merlonCap4.name = 'merlonCap';
merlonCap4.position.set(3, 8.69, 2.63);
root.add(merlonCap4);
const merlon8 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.96, 0.7, 0.4), 0.012, 18), stoneMat);
merlon8.name = 'merlon';
merlon8.position.set(3, 8.15, -2.3);
root.add(merlon8);
const coatOfArms = new THREE.Mesh(extrude([[-0.55, 0.45], [0.55, 0.45], [0.55, -0.1], [0.3, -0.48], [0, -0.62], [-0.3, -0.48], [-0.55, -0.1]], 0.1), bannerMat);
coatOfArms.name = 'coatOfArms';
coatOfArms.position.set(0, 6.45, 2.57);
root.add(coatOfArms);
const armsCross = new THREE.Mesh(new THREE.BoxGeometry(0.14, 0.75, 0.06), goldMat);
armsCross.name = 'armsCross';
armsCross.position.set(0, 6.4, 2.64);
root.add(armsCross);
const armsCross2 = new THREE.Mesh(new THREE.BoxGeometry(0.75, 0.14, 0.06), goldMat);
armsCross2.name = 'armsCross';
armsCross2.position.set(0, 6.53, 2.64);
root.add(armsCross2);
const leftTower = new THREE.Group();
leftTower.name = 'leftTower';
leftTower.position.set(-4.35, 0, 0.7);
root.add(leftTower);
const towerPlinth = new THREE.Mesh(cylinderGeo, trimMat);
towerPlinth.name = 'towerPlinth';
towerPlinth.position.set(0, 0.55, 0);
towerPlinth.rotation.set(0, deg(15), 0);
leftTower.add(towerPlinth);
const towerBody = new THREE.Mesh(cylinderGeo2, stoneMat);
towerBody.name = 'towerBody';
towerBody.position.set(0, 5.35, 0);
towerBody.rotation.set(0, deg(15), 0);
leftTower.add(towerBody);
const towerString = new THREE.Mesh(cylinderGeo3, trimMat);
towerString.name = 'towerString';
towerString.position.set(0, 5.45, 0);
towerString.rotation.set(0, deg(15), 0);
leftTower.add(towerString);
const towerCorbel = new THREE.Group();
towerCorbel.name = 'towerCorbel';
towerCorbel.position.set(0.5953, 9.28, 2.2216);
towerCorbel.rotation.set(0, deg(15), 0);
leftTower.add(towerCorbel);
const box75 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel.add(box75);
const towerCorbel2 = new THREE.Group();
towerCorbel2.name = 'towerCorbel';
towerCorbel2.position.set(1.6263, 9.28, 1.6263);
towerCorbel2.rotation.set(0, deg(45), 0);
leftTower.add(towerCorbel2);
const box77 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel2.add(box77);
const towerCorbel3 = new THREE.Group();
towerCorbel3.name = 'towerCorbel';
towerCorbel3.position.set(2.2216, 9.28, 0.5953);
towerCorbel3.rotation.set(0, deg(75), 0);
leftTower.add(towerCorbel3);
const box79 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel3.add(box79);
const towerCorbel4 = new THREE.Group();
towerCorbel4.name = 'towerCorbel';
towerCorbel4.position.set(2.2216, 9.28, -0.5953);
towerCorbel4.rotation.set(0, deg(105), 0);
leftTower.add(towerCorbel4);
const box81 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel4.add(box81);
const towerCorbel5 = new THREE.Group();
towerCorbel5.name = 'towerCorbel';
towerCorbel5.position.set(1.6263, 9.28, -1.6263);
towerCorbel5.rotation.set(0, deg(135), 0);
leftTower.add(towerCorbel5);
const box83 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel5.add(box83);
const towerCorbel6 = new THREE.Group();
towerCorbel6.name = 'towerCorbel';
towerCorbel6.position.set(0.5953, 9.28, -2.2216);
towerCorbel6.rotation.set(0, deg(165), 0);
leftTower.add(towerCorbel6);
const box85 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel6.add(box85);
const towerCorbel7 = new THREE.Group();
towerCorbel7.name = 'towerCorbel';
towerCorbel7.position.set(-0.5953, 9.28, -2.2216);
towerCorbel7.rotation.set(0, deg(195), 0);
leftTower.add(towerCorbel7);
const box87 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel7.add(box87);
const towerCorbel8 = new THREE.Group();
towerCorbel8.name = 'towerCorbel';
towerCorbel8.position.set(-1.6263, 9.28, -1.6263);
towerCorbel8.rotation.set(0, deg(225), 0);
leftTower.add(towerCorbel8);
const box89 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel8.add(box89);
const towerCorbel9 = new THREE.Group();
towerCorbel9.name = 'towerCorbel';
towerCorbel9.position.set(-2.2216, 9.28, -0.5953);
towerCorbel9.rotation.set(0, deg(255), 0);
leftTower.add(towerCorbel9);
const box91 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel9.add(box91);
const towerCorbel10 = new THREE.Group();
towerCorbel10.name = 'towerCorbel';
towerCorbel10.position.set(-2.2216, 9.28, 0.5953);
towerCorbel10.rotation.set(0, deg(285), 0);
leftTower.add(towerCorbel10);
const box93 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel10.add(box93);
const towerCorbel11 = new THREE.Group();
towerCorbel11.name = 'towerCorbel';
towerCorbel11.position.set(-1.6263, 9.28, 1.6263);
towerCorbel11.rotation.set(0, deg(315), 0);
leftTower.add(towerCorbel11);
const box95 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel11.add(box95);
const towerCorbel12 = new THREE.Group();
towerCorbel12.name = 'towerCorbel';
towerCorbel12.position.set(-0.5953, 9.28, 2.2216);
towerCorbel12.rotation.set(0, deg(345), 0);
leftTower.add(towerCorbel12);
const box97 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel12.add(box97);
const towerParapet = new THREE.Mesh(cylinderGeo4, stoneMat);
towerParapet.name = 'towerParapet';
towerParapet.position.set(0, 9.9, 0);
towerParapet.rotation.set(0, deg(15), 0);
leftTower.add(towerParapet);
const towerLip = new THREE.Mesh(cylinderGeo5, trimMat);
towerLip.name = 'towerLip';
towerLip.position.set(0, 10.2, 0);
towerLip.rotation.set(0, deg(15), 0);
leftTower.add(towerLip);
const towerMerlon = new THREE.Group();
towerMerlon.name = 'towerMerlon';
towerMerlon.position.set(0.7355, 10.22, 2.2635);
towerMerlon.rotation.set(0, deg(18), 0);
leftTower.add(towerMerlon);
const box101 = new THREE.Mesh(boxGeo6, stoneMat);
box101.position.set(0, 0.4, 0);
towerMerlon.add(box101);
const box102 = new THREE.Mesh(boxGeo7, trimMat);
box102.position.set(0, 0.84, 0);
towerMerlon.add(box102);
const towerMerlon2 = new THREE.Group();
towerMerlon2.name = 'towerMerlon';
towerMerlon2.position.set(1.9255, 10.22, 1.3989);
towerMerlon2.rotation.set(0, deg(54), 0);
leftTower.add(towerMerlon2);
const box104 = new THREE.Mesh(boxGeo6, stoneMat);
box104.position.set(0, 0.4, 0);
towerMerlon2.add(box104);
const box105 = new THREE.Mesh(boxGeo7, trimMat);
box105.position.set(0, 0.84, 0);
towerMerlon2.add(box105);
const towerMerlon3 = new THREE.Group();
towerMerlon3.name = 'towerMerlon';
towerMerlon3.position.set(2.38, 10.22, 0);
towerMerlon3.rotation.set(0, deg(90), 0);
leftTower.add(towerMerlon3);
const box107 = new THREE.Mesh(boxGeo6, stoneMat);
box107.position.set(0, 0.4, 0);
towerMerlon3.add(box107);
const box108 = new THREE.Mesh(boxGeo7, trimMat);
box108.position.set(0, 0.84, 0);
towerMerlon3.add(box108);
const towerMerlon4 = new THREE.Group();
towerMerlon4.name = 'towerMerlon';
towerMerlon4.position.set(1.9255, 10.22, -1.3989);
towerMerlon4.rotation.set(0, deg(126), 0);
leftTower.add(towerMerlon4);
const box110 = new THREE.Mesh(boxGeo6, stoneMat);
box110.position.set(0, 0.4, 0);
towerMerlon4.add(box110);
const box111 = new THREE.Mesh(boxGeo7, trimMat);
box111.position.set(0, 0.84, 0);
towerMerlon4.add(box111);
const towerMerlon5 = new THREE.Group();
towerMerlon5.name = 'towerMerlon';
towerMerlon5.position.set(0.7355, 10.22, -2.2635);
towerMerlon5.rotation.set(0, deg(162), 0);
leftTower.add(towerMerlon5);
const box113 = new THREE.Mesh(boxGeo6, stoneMat);
box113.position.set(0, 0.4, 0);
towerMerlon5.add(box113);
const box114 = new THREE.Mesh(boxGeo7, trimMat);
box114.position.set(0, 0.84, 0);
towerMerlon5.add(box114);
const towerMerlon6 = new THREE.Group();
towerMerlon6.name = 'towerMerlon';
towerMerlon6.position.set(-0.7355, 10.22, -2.2635);
towerMerlon6.rotation.set(0, deg(198), 0);
leftTower.add(towerMerlon6);
const box116 = new THREE.Mesh(boxGeo6, stoneMat);
box116.position.set(0, 0.4, 0);
towerMerlon6.add(box116);
const box117 = new THREE.Mesh(boxGeo7, trimMat);
box117.position.set(0, 0.84, 0);
towerMerlon6.add(box117);
const towerMerlon7 = new THREE.Group();
towerMerlon7.name = 'towerMerlon';
towerMerlon7.position.set(-1.9255, 10.22, -1.3989);
towerMerlon7.rotation.set(0, deg(234), 0);
leftTower.add(towerMerlon7);
const box119 = new THREE.Mesh(boxGeo6, stoneMat);
box119.position.set(0, 0.4, 0);
towerMerlon7.add(box119);
const box120 = new THREE.Mesh(boxGeo7, trimMat);
box120.position.set(0, 0.84, 0);
towerMerlon7.add(box120);
const towerMerlon8 = new THREE.Group();
towerMerlon8.name = 'towerMerlon';
towerMerlon8.position.set(-2.38, 10.22, 0);
towerMerlon8.rotation.set(0, deg(270), 0);
leftTower.add(towerMerlon8);
const box122 = new THREE.Mesh(boxGeo6, stoneMat);
box122.position.set(0, 0.4, 0);
towerMerlon8.add(box122);
const box123 = new THREE.Mesh(boxGeo7, trimMat);
box123.position.set(0, 0.84, 0);
towerMerlon8.add(box123);
const towerMerlon9 = new THREE.Group();
towerMerlon9.name = 'towerMerlon';
towerMerlon9.position.set(-1.9255, 10.22, 1.3989);
towerMerlon9.rotation.set(0, deg(306), 0);
leftTower.add(towerMerlon9);
const box125 = new THREE.Mesh(boxGeo6, stoneMat);
box125.position.set(0, 0.4, 0);
towerMerlon9.add(box125);
const box126 = new THREE.Mesh(boxGeo7, trimMat);
box126.position.set(0, 0.84, 0);
towerMerlon9.add(box126);
const towerMerlon10 = new THREE.Group();
towerMerlon10.name = 'towerMerlon';
towerMerlon10.position.set(-0.7355, 10.22, 2.2635);
towerMerlon10.rotation.set(0, deg(342), 0);
leftTower.add(towerMerlon10);
const box128 = new THREE.Mesh(boxGeo6, stoneMat);
box128.position.set(0, 0.4, 0);
towerMerlon10.add(box128);
const box129 = new THREE.Mesh(boxGeo7, trimMat);
box129.position.set(0, 0.84, 0);
towerMerlon10.add(box129);
const arrowSlit = new THREE.Group();
arrowSlit.name = 'arrowSlit';
arrowSlit.position.set(-1.8403, 2.4, 1.0625);
arrowSlit.rotation.set(0, deg(-60), 0);
leftTower.add(arrowSlit);
const box131 = new THREE.Mesh(boxGeo8, trimMat);
arrowSlit.add(box131);
const box132 = new THREE.Mesh(boxGeo9, darkMat);
box132.position.set(0, 0, 0.014);
arrowSlit.add(box132);
const box133 = new THREE.Mesh(boxGeo10, darkMat);
box133.position.set(0, 0.12, 0.014);
arrowSlit.add(box133);
const arrowSlit2 = new THREE.Group();
arrowSlit2.name = 'arrowSlit';
arrowSlit2.position.set(-2.0526, 4.8, -0.55);
arrowSlit2.rotation.set(0, deg(-105), 0);
leftTower.add(arrowSlit2);
const box135 = new THREE.Mesh(boxGeo8, trimMat);
arrowSlit2.add(box135);
const box136 = new THREE.Mesh(boxGeo9, darkMat);
box136.position.set(0, 0, 0.014);
arrowSlit2.add(box136);
const box137 = new THREE.Mesh(boxGeo10, darkMat);
box137.position.set(0, 0.12, 0.014);
arrowSlit2.add(box137);
const arrowSlit3 = new THREE.Group();
arrowSlit3.name = 'arrowSlit';
arrowSlit3.position.set(-1.0625, 6, 1.8403);
arrowSlit3.rotation.set(0, deg(-30), 0);
leftTower.add(arrowSlit3);
const box139 = new THREE.Mesh(boxGeo8, trimMat);
arrowSlit3.add(box139);
const box140 = new THREE.Mesh(boxGeo9, darkMat);
box140.position.set(0, 0, 0.014);
arrowSlit3.add(box140);
const box141 = new THREE.Mesh(boxGeo10, darkMat);
box141.position.set(0, 0.12, 0.014);
arrowSlit3.add(box141);
const arrowSlit4 = new THREE.Group();
arrowSlit4.name = 'arrowSlit';
arrowSlit4.position.set(0.369, 3.4, 2.0928);
arrowSlit4.rotation.set(0, deg(10), 0);
leftTower.add(arrowSlit4);
const box143 = new THREE.Mesh(boxGeo8, trimMat);
arrowSlit4.add(box143);
const box144 = new THREE.Mesh(boxGeo9, darkMat);
box144.position.set(0, 0, 0.014);
arrowSlit4.add(box144);
const box145 = new THREE.Mesh(boxGeo10, darkMat);
box145.position.set(0, 0.12, 0.014);
arrowSlit4.add(box145);
const banner = new THREE.Group();
banner.name = 'banner';
banner.position.set(0.2957, 8.6, 2.1044);
banner.rotation.set(0, deg(8), 0);
leftTower.add(banner);
const bannerRod = new THREE.Mesh(cylinderGeo6, woodMat);
bannerRod.name = 'bannerRod';
bannerRod.position.set(0, 0, 0.12);
bannerRod.rotation.set(0, 0, deg(90));
banner.add(bannerRod);
const bannerCloth = new THREE.Mesh(extrudeGeo14, bannerMat);
bannerCloth.name = 'bannerCloth';
bannerCloth.position.set(0, -0.02, 0.1);
banner.add(bannerCloth);
const bannerStripe = new THREE.Mesh(boxGeo11, goldMat);
bannerStripe.name = 'bannerStripe';
bannerStripe.position.set(0, -1.1, 0.125);
banner.add(bannerStripe);
const rightTower = new THREE.Group();
rightTower.name = 'rightTower';
rightTower.position.set(4.35, 0, 0.7);
root.add(rightTower);
const towerPlinth2 = new THREE.Mesh(cylinderGeo, trimMat);
towerPlinth2.name = 'towerPlinth';
towerPlinth2.position.set(0, 0.55, 0);
towerPlinth2.rotation.set(0, deg(15), 0);
rightTower.add(towerPlinth2);
const towerBody2 = new THREE.Mesh(cylinderGeo2, stoneMat);
towerBody2.name = 'towerBody';
towerBody2.position.set(0, 5.35, 0);
towerBody2.rotation.set(0, deg(15), 0);
rightTower.add(towerBody2);
const towerString2 = new THREE.Mesh(cylinderGeo3, trimMat);
towerString2.name = 'towerString';
towerString2.position.set(0, 5.45, 0);
towerString2.rotation.set(0, deg(15), 0);
rightTower.add(towerString2);
const towerCorbel13 = new THREE.Group();
towerCorbel13.name = 'towerCorbel';
towerCorbel13.position.set(0.5953, 9.28, 2.2216);
towerCorbel13.rotation.set(0, deg(15), 0);
rightTower.add(towerCorbel13);
const box155 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel13.add(box155);
const towerCorbel14 = new THREE.Group();
towerCorbel14.name = 'towerCorbel';
towerCorbel14.position.set(1.6263, 9.28, 1.6263);
towerCorbel14.rotation.set(0, deg(45), 0);
rightTower.add(towerCorbel14);
const box157 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel14.add(box157);
const towerCorbel15 = new THREE.Group();
towerCorbel15.name = 'towerCorbel';
towerCorbel15.position.set(2.2216, 9.28, 0.5953);
towerCorbel15.rotation.set(0, deg(75), 0);
rightTower.add(towerCorbel15);
const box159 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel15.add(box159);
const towerCorbel16 = new THREE.Group();
towerCorbel16.name = 'towerCorbel';
towerCorbel16.position.set(2.2216, 9.28, -0.5953);
towerCorbel16.rotation.set(0, deg(105), 0);
rightTower.add(towerCorbel16);
const box161 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel16.add(box161);
const towerCorbel17 = new THREE.Group();
towerCorbel17.name = 'towerCorbel';
towerCorbel17.position.set(1.6263, 9.28, -1.6263);
towerCorbel17.rotation.set(0, deg(135), 0);
rightTower.add(towerCorbel17);
const box163 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel17.add(box163);
const towerCorbel18 = new THREE.Group();
towerCorbel18.name = 'towerCorbel';
towerCorbel18.position.set(0.5953, 9.28, -2.2216);
towerCorbel18.rotation.set(0, deg(165), 0);
rightTower.add(towerCorbel18);
const box165 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel18.add(box165);
const towerCorbel19 = new THREE.Group();
towerCorbel19.name = 'towerCorbel';
towerCorbel19.position.set(-0.5953, 9.28, -2.2216);
towerCorbel19.rotation.set(0, deg(195), 0);
rightTower.add(towerCorbel19);
const box167 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel19.add(box167);
const towerCorbel20 = new THREE.Group();
towerCorbel20.name = 'towerCorbel';
towerCorbel20.position.set(-1.6263, 9.28, -1.6263);
towerCorbel20.rotation.set(0, deg(225), 0);
rightTower.add(towerCorbel20);
const box169 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel20.add(box169);
const towerCorbel21 = new THREE.Group();
towerCorbel21.name = 'towerCorbel';
towerCorbel21.position.set(-2.2216, 9.28, -0.5953);
towerCorbel21.rotation.set(0, deg(255), 0);
rightTower.add(towerCorbel21);
const box171 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel21.add(box171);
const towerCorbel22 = new THREE.Group();
towerCorbel22.name = 'towerCorbel';
towerCorbel22.position.set(-2.2216, 9.28, 0.5953);
towerCorbel22.rotation.set(0, deg(285), 0);
rightTower.add(towerCorbel22);
const box173 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel22.add(box173);
const towerCorbel23 = new THREE.Group();
towerCorbel23.name = 'towerCorbel';
towerCorbel23.position.set(-1.6263, 9.28, 1.6263);
towerCorbel23.rotation.set(0, deg(315), 0);
rightTower.add(towerCorbel23);
const box175 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel23.add(box175);
const towerCorbel24 = new THREE.Group();
towerCorbel24.name = 'towerCorbel';
towerCorbel24.position.set(-0.5953, 9.28, 2.2216);
towerCorbel24.rotation.set(0, deg(345), 0);
rightTower.add(towerCorbel24);
const box177 = new THREE.Mesh(boxGeo5, trimMat);
towerCorbel24.add(box177);
const towerParapet2 = new THREE.Mesh(cylinderGeo4, stoneMat);
towerParapet2.name = 'towerParapet';
towerParapet2.position.set(0, 9.9, 0);
towerParapet2.rotation.set(0, deg(15), 0);
rightTower.add(towerParapet2);
const towerLip2 = new THREE.Mesh(cylinderGeo5, trimMat);
towerLip2.name = 'towerLip';
towerLip2.position.set(0, 10.2, 0);
towerLip2.rotation.set(0, deg(15), 0);
rightTower.add(towerLip2);
const towerMerlon11 = new THREE.Group();
towerMerlon11.name = 'towerMerlon';
towerMerlon11.position.set(0.7355, 10.22, 2.2635);
towerMerlon11.rotation.set(0, deg(18), 0);
rightTower.add(towerMerlon11);
const box181 = new THREE.Mesh(boxGeo6, stoneMat);
box181.position.set(0, 0.4, 0);
towerMerlon11.add(box181);
const box182 = new THREE.Mesh(boxGeo7, trimMat);
box182.position.set(0, 0.84, 0);
towerMerlon11.add(box182);
const towerMerlon12 = new THREE.Group();
towerMerlon12.name = 'towerMerlon';
towerMerlon12.position.set(1.9255, 10.22, 1.3989);
towerMerlon12.rotation.set(0, deg(54), 0);
rightTower.add(towerMerlon12);
const box184 = new THREE.Mesh(boxGeo6, stoneMat);
box184.position.set(0, 0.4, 0);
towerMerlon12.add(box184);
const box185 = new THREE.Mesh(boxGeo7, trimMat);
box185.position.set(0, 0.84, 0);
towerMerlon12.add(box185);
const towerMerlon13 = new THREE.Group();
towerMerlon13.name = 'towerMerlon';
towerMerlon13.position.set(2.38, 10.22, 0);
towerMerlon13.rotation.set(0, deg(90), 0);
rightTower.add(towerMerlon13);
const box187 = new THREE.Mesh(boxGeo6, stoneMat);
box187.position.set(0, 0.4, 0);
towerMerlon13.add(box187);
const box188 = new THREE.Mesh(boxGeo7, trimMat);
box188.position.set(0, 0.84, 0);
towerMerlon13.add(box188);
const towerMerlon14 = new THREE.Group();
towerMerlon14.name = 'towerMerlon';
towerMerlon14.position.set(1.9255, 10.22, -1.3989);
towerMerlon14.rotation.set(0, deg(126), 0);
rightTower.add(towerMerlon14);
const box190 = new THREE.Mesh(boxGeo6, stoneMat);
box190.position.set(0, 0.4, 0);
towerMerlon14.add(box190);
const box191 = new THREE.Mesh(boxGeo7, trimMat);
box191.position.set(0, 0.84, 0);
towerMerlon14.add(box191);
const towerMerlon15 = new THREE.Group();
towerMerlon15.name = 'towerMerlon';
towerMerlon15.position.set(0.7355, 10.22, -2.2635);
towerMerlon15.rotation.set(0, deg(162), 0);
rightTower.add(towerMerlon15);
const box193 = new THREE.Mesh(boxGeo6, stoneMat);
box193.position.set(0, 0.4, 0);
towerMerlon15.add(box193);
const box194 = new THREE.Mesh(boxGeo7, trimMat);
box194.position.set(0, 0.84, 0);
towerMerlon15.add(box194);
const towerMerlon16 = new THREE.Group();
towerMerlon16.name = 'towerMerlon';
towerMerlon16.position.set(-0.7355, 10.22, -2.2635);
towerMerlon16.rotation.set(0, deg(198), 0);
rightTower.add(towerMerlon16);
const box196 = new THREE.Mesh(boxGeo6, stoneMat);
box196.position.set(0, 0.4, 0);
towerMerlon16.add(box196);
const box197 = new THREE.Mesh(boxGeo7, trimMat);
box197.position.set(0, 0.84, 0);
towerMerlon16.add(box197);
const towerMerlon17 = new THREE.Group();
towerMerlon17.name = 'towerMerlon';
towerMerlon17.position.set(-1.9255, 10.22, -1.3989);
towerMerlon17.rotation.set(0, deg(234), 0);
rightTower.add(towerMerlon17);
const box199 = new THREE.Mesh(boxGeo6, stoneMat);
box199.position.set(0, 0.4, 0);
towerMerlon17.add(box199);
const box200 = new THREE.Mesh(boxGeo7, trimMat);
box200.position.set(0, 0.84, 0);
towerMerlon17.add(box200);
const towerMerlon18 = new THREE.Group();
towerMerlon18.name = 'towerMerlon';
towerMerlon18.position.set(-2.38, 10.22, 0);
towerMerlon18.rotation.set(0, deg(270), 0);
rightTower.add(towerMerlon18);
const box202 = new THREE.Mesh(boxGeo6, stoneMat);
box202.position.set(0, 0.4, 0);
towerMerlon18.add(box202);
const box203 = new THREE.Mesh(boxGeo7, trimMat);
box203.position.set(0, 0.84, 0);
towerMerlon18.add(box203);
const towerMerlon19 = new THREE.Group();
towerMerlon19.name = 'towerMerlon';
towerMerlon19.position.set(-1.9255, 10.22, 1.3989);
towerMerlon19.rotation.set(0, deg(306), 0);
rightTower.add(towerMerlon19);
const box205 = new THREE.Mesh(boxGeo6, stoneMat);
box205.position.set(0, 0.4, 0);
towerMerlon19.add(box205);
const box206 = new THREE.Mesh(boxGeo7, trimMat);
box206.position.set(0, 0.84, 0);
towerMerlon19.add(box206);
const towerMerlon20 = new THREE.Group();
towerMerlon20.name = 'towerMerlon';
towerMerlon20.position.set(-0.7355, 10.22, 2.2635);
towerMerlon20.rotation.set(0, deg(342), 0);
rightTower.add(towerMerlon20);
const box208 = new THREE.Mesh(boxGeo6, stoneMat);
box208.position.set(0, 0.4, 0);
towerMerlon20.add(box208);
const box209 = new THREE.Mesh(boxGeo7, trimMat);
box209.position.set(0, 0.84, 0);
towerMerlon20.add(box209);
const arrowSlit5 = new THREE.Group();
arrowSlit5.name = 'arrowSlit';
arrowSlit5.position.set(1.8403, 2.4, 1.0625);
arrowSlit5.rotation.set(0, deg(60), 0);
rightTower.add(arrowSlit5);
const box211 = new THREE.Mesh(boxGeo8, trimMat);
arrowSlit5.add(box211);
const box212 = new THREE.Mesh(boxGeo9, darkMat);
box212.position.set(0, 0, 0.014);
arrowSlit5.add(box212);
const box213 = new THREE.Mesh(boxGeo10, darkMat);
box213.position.set(0, 0.12, 0.014);
arrowSlit5.add(box213);
const arrowSlit6 = new THREE.Group();
arrowSlit6.name = 'arrowSlit';
arrowSlit6.position.set(2.0526, 4.8, -0.55);
arrowSlit6.rotation.set(0, deg(105), 0);
rightTower.add(arrowSlit6);
const box215 = new THREE.Mesh(boxGeo8, trimMat);
arrowSlit6.add(box215);
const box216 = new THREE.Mesh(boxGeo9, darkMat);
box216.position.set(0, 0, 0.014);
arrowSlit6.add(box216);
const box217 = new THREE.Mesh(boxGeo10, darkMat);
box217.position.set(0, 0.12, 0.014);
arrowSlit6.add(box217);
const arrowSlit7 = new THREE.Group();
arrowSlit7.name = 'arrowSlit';
arrowSlit7.position.set(1.0625, 6, 1.8403);
arrowSlit7.rotation.set(0, deg(30), 0);
rightTower.add(arrowSlit7);
const box219 = new THREE.Mesh(boxGeo8, trimMat);
arrowSlit7.add(box219);
const box220 = new THREE.Mesh(boxGeo9, darkMat);
box220.position.set(0, 0, 0.014);
arrowSlit7.add(box220);
const box221 = new THREE.Mesh(boxGeo10, darkMat);
box221.position.set(0, 0.12, 0.014);
arrowSlit7.add(box221);
const arrowSlit8 = new THREE.Group();
arrowSlit8.name = 'arrowSlit';
arrowSlit8.position.set(-0.369, 3.4, 2.0928);
arrowSlit8.rotation.set(0, deg(-10), 0);
rightTower.add(arrowSlit8);
const box223 = new THREE.Mesh(boxGeo8, trimMat);
arrowSlit8.add(box223);
const box224 = new THREE.Mesh(boxGeo9, darkMat);
box224.position.set(0, 0, 0.014);
arrowSlit8.add(box224);
const box225 = new THREE.Mesh(boxGeo10, darkMat);
box225.position.set(0, 0.12, 0.014);
arrowSlit8.add(box225);
const banner2 = new THREE.Group();
banner2.name = 'banner';
banner2.position.set(-0.2957, 8.6, 2.1044);
banner2.rotation.set(0, deg(-8), 0);
rightTower.add(banner2);
const bannerRod2 = new THREE.Mesh(cylinderGeo6, woodMat);
bannerRod2.name = 'bannerRod';
bannerRod2.position.set(0, 0, 0.12);
bannerRod2.rotation.set(0, 0, deg(90));
banner2.add(bannerRod2);
const bannerCloth2 = new THREE.Mesh(extrudeGeo14, bannerMat);
bannerCloth2.name = 'bannerCloth';
bannerCloth2.position.set(0, -0.02, 0.1);
banner2.add(bannerCloth2);
const bannerStripe2 = new THREE.Mesh(boxGeo11, goldMat);
bannerStripe2.name = 'bannerStripe';
bannerStripe2.position.set(0, -1.1, 0.125);
banner2.add(bannerStripe2);
const flagPole = new THREE.Mesh(new THREE.CylinderGeometry(0.05, 0.06, 3.2, 6), woodMat);
flagPole.name = 'flagPole';
flagPole.position.set(4.35, 11.25, 0.7);
root.add(flagPole);
const pennant = new THREE.Mesh(extrude([[0, 0], [1.9, 0.08], [1.4, 0.5], [1.9, 0.92], [0, 1]], 0.04), bannerMat);
pennant.name = 'pennant';
pennant.position.set(4.39, 11.7, 0.7);
pennant.rotation.set(0, deg(-20), 0);
root.add(pennant);
const towerFloor = new THREE.Mesh(cylinderGeo7, pavingMat);
towerFloor.name = 'towerFloor';
towerFloor.position.set(-4.35, 10.225, 0.7);
towerFloor.rotation.set(0, deg(15), 0);
root.add(towerFloor);
const towerFloor2 = new THREE.Mesh(cylinderGeo7, pavingMat);
towerFloor2.name = 'towerFloor';
towerFloor2.position.set(4.35, 10.225, 0.7);
towerFloor2.rotation.set(0, deg(15), 0);
root.add(towerFloor2);
const portcullisBar = new THREE.Mesh(boxGeo12, ironMat);
portcullisBar.name = 'portcullisBar';
portcullisBar.position.set(-1.6, 4.3875, 1.75);
root.add(portcullisBar);
const portcullisSpike = new THREE.Mesh(coneGeo, ironMat);
portcullisSpike.name = 'portcullisSpike';
portcullisSpike.position.set(-1.6, 1.9375, 1.75);
portcullisSpike.rotation.set(deg(180), deg(45), 0);
root.add(portcullisSpike);
const portcullisBar2 = new THREE.Mesh(boxGeo12, ironMat);
portcullisBar2.name = 'portcullisBar';
portcullisBar2.position.set(-1.28, 4.3875, 1.75);
root.add(portcullisBar2);
const portcullisSpike2 = new THREE.Mesh(coneGeo, ironMat);
portcullisSpike2.name = 'portcullisSpike';
portcullisSpike2.position.set(-1.28, 1.9375, 1.75);
portcullisSpike2.rotation.set(deg(180), deg(45), 0);
root.add(portcullisSpike2);
const portcullisBar3 = new THREE.Mesh(boxGeo12, ironMat);
portcullisBar3.name = 'portcullisBar';
portcullisBar3.position.set(-0.96, 4.3875, 1.75);
root.add(portcullisBar3);
const portcullisSpike3 = new THREE.Mesh(coneGeo, ironMat);
portcullisSpike3.name = 'portcullisSpike';
portcullisSpike3.position.set(-0.96, 1.9375, 1.75);
portcullisSpike3.rotation.set(deg(180), deg(45), 0);
root.add(portcullisSpike3);
const portcullisBar4 = new THREE.Mesh(boxGeo12, ironMat);
portcullisBar4.name = 'portcullisBar';
portcullisBar4.position.set(-0.64, 4.3875, 1.75);
root.add(portcullisBar4);
const portcullisSpike4 = new THREE.Mesh(coneGeo, ironMat);
portcullisSpike4.name = 'portcullisSpike';
portcullisSpike4.position.set(-0.64, 1.9375, 1.75);
portcullisSpike4.rotation.set(deg(180), deg(45), 0);
root.add(portcullisSpike4);
const portcullisBar5 = new THREE.Mesh(boxGeo12, ironMat);
portcullisBar5.name = 'portcullisBar';
portcullisBar5.position.set(-0.32, 4.3875, 1.75);
root.add(portcullisBar5);
const portcullisSpike5 = new THREE.Mesh(coneGeo, ironMat);
portcullisSpike5.name = 'portcullisSpike';
portcullisSpike5.position.set(-0.32, 1.9375, 1.75);
portcullisSpike5.rotation.set(deg(180), deg(45), 0);
root.add(portcullisSpike5);
const portcullisBar6 = new THREE.Mesh(boxGeo12, ironMat);
portcullisBar6.name = 'portcullisBar';
portcullisBar6.position.set(0, 4.3875, 1.75);
root.add(portcullisBar6);
const portcullisSpike6 = new THREE.Mesh(coneGeo, ironMat);
portcullisSpike6.name = 'portcullisSpike';
portcullisSpike6.position.set(0, 1.9375, 1.75);
portcullisSpike6.rotation.set(deg(180), deg(45), 0);
root.add(portcullisSpike6);
const portcullisBar7 = new THREE.Mesh(boxGeo12, ironMat);
portcullisBar7.name = 'portcullisBar';
portcullisBar7.position.set(0.32, 4.3875, 1.75);
root.add(portcullisBar7);
const portcullisSpike7 = new THREE.Mesh(coneGeo, ironMat);
portcullisSpike7.name = 'portcullisSpike';
portcullisSpike7.position.set(0.32, 1.9375, 1.75);
portcullisSpike7.rotation.set(deg(180), deg(45), 0);
root.add(portcullisSpike7);
const portcullisBar8 = new THREE.Mesh(boxGeo12, ironMat);
portcullisBar8.name = 'portcullisBar';
portcullisBar8.position.set(0.64, 4.3875, 1.75);
root.add(portcullisBar8);
const portcullisSpike8 = new THREE.Mesh(coneGeo, ironMat);
portcullisSpike8.name = 'portcullisSpike';
portcullisSpike8.position.set(0.64, 1.9375, 1.75);
portcullisSpike8.rotation.set(deg(180), deg(45), 0);
root.add(portcullisSpike8);
const portcullisBar9 = new THREE.Mesh(boxGeo12, ironMat);
portcullisBar9.name = 'portcullisBar';
portcullisBar9.position.set(0.96, 4.3875, 1.75);
root.add(portcullisBar9);
const portcullisSpike9 = new THREE.Mesh(coneGeo, ironMat);
portcullisSpike9.name = 'portcullisSpike';
portcullisSpike9.position.set(0.96, 1.9375, 1.75);
portcullisSpike9.rotation.set(deg(180), deg(45), 0);
root.add(portcullisSpike9);
const portcullisBar10 = new THREE.Mesh(boxGeo12, ironMat);
portcullisBar10.name = 'portcullisBar';
portcullisBar10.position.set(1.28, 4.3875, 1.75);
root.add(portcullisBar10);
const portcullisSpike10 = new THREE.Mesh(coneGeo, ironMat);
portcullisSpike10.name = 'portcullisSpike';
portcullisSpike10.position.set(1.28, 1.9375, 1.75);
portcullisSpike10.rotation.set(deg(180), deg(45), 0);
root.add(portcullisSpike10);
const portcullisBar11 = new THREE.Mesh(boxGeo12, ironMat);
portcullisBar11.name = 'portcullisBar';
portcullisBar11.position.set(1.6, 4.3875, 1.75);
root.add(portcullisBar11);
const portcullisSpike11 = new THREE.Mesh(coneGeo, ironMat);
portcullisSpike11.name = 'portcullisSpike';
portcullisSpike11.position.set(1.6, 1.9375, 1.75);
portcullisSpike11.rotation.set(deg(180), deg(45), 0);
root.add(portcullisSpike11);
const portcullisRail = new THREE.Mesh(boxGeo13, ironMat);
portcullisRail.name = 'portcullisRail';
portcullisRail.position.set(0, 2.4375, 1.8);
root.add(portcullisRail);
const portcullisRail2 = new THREE.Mesh(boxGeo13, ironMat);
portcullisRail2.name = 'portcullisRail';
portcullisRail2.position.set(0, 2.9175, 1.8);
root.add(portcullisRail2);
const portcullisRail3 = new THREE.Mesh(boxGeo13, ironMat);
portcullisRail3.name = 'portcullisRail';
portcullisRail3.position.set(0, 3.3975, 1.8);
root.add(portcullisRail3);
const portcullisRail4 = new THREE.Mesh(boxGeo13, ironMat);
portcullisRail4.name = 'portcullisRail';
portcullisRail4.position.set(0, 3.8775, 1.8);
root.add(portcullisRail4);
const portcullisRail5 = new THREE.Mesh(boxGeo13, ironMat);
portcullisRail5.name = 'portcullisRail';
portcullisRail5.position.set(0, 4.3575, 1.8);
root.add(portcullisRail5);
const portcullisRail6 = new THREE.Mesh(boxGeo13, ironMat);
portcullisRail6.name = 'portcullisRail';
portcullisRail6.position.set(0, 4.8375, 1.8);
root.add(portcullisRail6);
const portcullisRail7 = new THREE.Mesh(boxGeo13, ironMat);
portcullisRail7.name = 'portcullisRail';
portcullisRail7.position.set(0, 5.3175, 1.8);
root.add(portcullisRail7);
const portcullisRail8 = new THREE.Mesh(boxGeo13, ironMat);
portcullisRail8.name = 'portcullisRail';
portcullisRail8.position.set(0, 5.7975, 1.8);
root.add(portcullisRail8);
const portcullisRail9 = new THREE.Mesh(boxGeo13, ironMat);
portcullisRail9.name = 'portcullisRail';
portcullisRail9.position.set(0, 6.2775, 1.8);
root.add(portcullisRail9);
const gateLeaf = new THREE.Group();
gateLeaf.name = 'gateLeaf';
gateLeaf.position.set(-1.76, 0.05, -0.6);
gateLeaf.rotation.set(0, deg(82), 0);
root.add(gateLeaf);
const leaf = new THREE.Mesh(boxGeo14, woodMat);
leaf.name = 'leaf';
leaf.position.set(0.88, 1.625, 0);
gateLeaf.add(leaf);
const leafBand = new THREE.Mesh(boxGeo15, ironMat);
leafBand.name = 'leafBand';
leafBand.position.set(0.88, 0.5, 0.075);
gateLeaf.add(leafBand);
const leafBand2 = new THREE.Mesh(boxGeo15, ironMat);
leafBand2.name = 'leafBand';
leafBand2.position.set(0.88, 1.625, 0.075);
gateLeaf.add(leafBand2);
const leafBand3 = new THREE.Mesh(boxGeo15, ironMat);
leafBand3.name = 'leafBand';
leafBand3.position.set(0.88, 2.75, 0.075);
gateLeaf.add(leafBand3);
const gateLeaf2 = new THREE.Group();
gateLeaf2.name = 'gateLeaf';
gateLeaf2.position.set(1.76, 0.05, -0.6);
gateLeaf2.rotation.set(0, deg(98), 0);
root.add(gateLeaf2);
const leaf2 = new THREE.Mesh(boxGeo14, woodMat);
leaf2.name = 'leaf';
leaf2.position.set(0.88, 1.625, 0);
gateLeaf2.add(leaf2);
const leafBand4 = new THREE.Mesh(boxGeo15, ironMat);
leafBand4.name = 'leafBand';
leafBand4.position.set(0.88, 0.5, 0.075);
gateLeaf2.add(leafBand4);
const leafBand5 = new THREE.Mesh(boxGeo15, ironMat);
leafBand5.name = 'leafBand';
leafBand5.position.set(0.88, 1.625, 0.075);
gateLeaf2.add(leafBand5);
const leafBand6 = new THREE.Mesh(boxGeo15, ironMat);
leafBand6.name = 'leafBand';
leafBand6.position.set(0.88, 2.75, 0.075);
gateLeaf2.add(leafBand6);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createCastleGate;
Оценки и комментарии
0 комментариев
Комментариев пока нет. Расскажите, как вы использовали эту модель или что можно улучшить.
Похожие модели
Та же категория или похожие теги









