import * as THREE from 'three'; import * as turf from '@turf/turf'; import * as CONSTANTS from '../../../../types/world/worldConstants'; import * as Types from "../../../../types/world/worldTypes"; import getRoomsFromLines from '../lines/getRoomsFromLines'; async function loadWalls( lines: Types.RefLines, setWalls: any, ): Promise { ////////// Removes the old walls if any, Checks if there is any overlapping in lines if any updates it , starts function that creates floor and roof ////////// const Walls: Types.Walls = []; const Rooms: Types.Rooms = []; localStorage.setItem("Lines", JSON.stringify(lines.current)); if (lines.current.length > 1) { ////////// Add Walls that are forming a room ////////// const wallSet = new Set(); const rooms: Types.Rooms = await getRoomsFromLines(lines); Rooms.push(...rooms); Rooms.forEach(({ coordinates: room, layer }) => { for (let i = 0; i < room.length - 1; i++) { const uuid1 = room[i].uuid; const uuid2 = room[(i + 1) % room.length].uuid; const wallId = `${uuid1}_${uuid2}`; if (!wallSet.has(wallId)) { const p1 = room[i].position; const p2 = room[(i + 1) % room.length].position; const shape = new THREE.Shape(); shape.moveTo(0, 0); shape.lineTo(0, CONSTANTS.wallConfig.height); shape.lineTo(p2.distanceTo(p1), CONSTANTS.wallConfig.height); shape.lineTo(p2.distanceTo(p1), 0); shape.lineTo(0, 0); const extrudeSettings = { depth: CONSTANTS.wallConfig.width, bevelEnabled: false }; const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); const angle = Math.atan2(p2.z - p1.z, p2.x - p1.x); Walls.push([geometry, [0, -angle, 0], [p1.x, (layer - 1) * CONSTANTS.wallConfig.height, p1.z], "RoomWall", layer]); wallSet.add(wallId); } } }); ////////// Add Walls that are not forming any room ////////// lines.current.forEach(line => { if (line[0][3] && line[1][3] !== CONSTANTS.lineConfig.wallName) { return; } const [uuid1, uuid2] = line.map(point => point[1]); let isInRoom = false; const lineLayer = line[0][2]; for (let room of Rooms) { const roomLayer = room.layer; if (roomLayer !== lineLayer) continue; for (let i = 0; i < room.coordinates.length - 1; i++) { const roomUuid1 = room.coordinates[i].uuid; const roomUuid2 = room.coordinates[(i + 1) % room.coordinates.length].uuid; if ( (uuid1 === roomUuid1 && uuid2 === roomUuid2) || (uuid1 === roomUuid2 && uuid2 === roomUuid1) ) { isInRoom = true; break; } } if (isInRoom) break; } if (!isInRoom) { const p1 = new THREE.Vector3(line[0][0].x, 0, line[0][0].z); const p2 = new THREE.Vector3(line[1][0].x, 0, line[1][0].z); let isCollinear = false; for (let room of Rooms) { if (room.layer !== lineLayer) continue; for (let i = 0; i < room.coordinates.length - 1; i++) { const roomP1 = room.coordinates[i].position; const roomP2 = room.coordinates[(i + 1) % room.coordinates.length].position; const lineFeature = turf.lineString([[p1.x, p1.z], [p2.x, p2.z]]); const roomFeature = turf.lineString([[roomP1.x, roomP1.z], [roomP2.x, roomP2.z]]); if (turf.booleanOverlap(lineFeature, roomFeature)) { isCollinear = true; break; } } if (isCollinear) break; } if (!isCollinear) { const shape = new THREE.Shape(); shape.moveTo(0, 0); shape.lineTo(0, CONSTANTS.wallConfig.height); shape.lineTo(p2.distanceTo(p1), CONSTANTS.wallConfig.height); shape.lineTo(p2.distanceTo(p1), 0); shape.lineTo(0, 0); const extrudeSettings = { depth: CONSTANTS.wallConfig.width, bevelEnabled: false }; const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); const angle = Math.atan2(p2.z - p1.z, p2.x - p1.x); Walls.push([geometry, [0, -angle, 0], [p1.x, (lineLayer - 1) * CONSTANTS.wallConfig.height, p1.z], "SegmentWall", lineLayer]); } } }); setWalls(Walls); } else { setWalls([]); } } export default loadWalls; // A----- B----- C // | | | // | | | // | | | // F----- E----- D // 1. A -> B, B -> C, C -> D, D -> E, E -> F, F -> A, B -> E // 2. E -> F, F -> A, A -> B, B -> E, E -> D, D -> C, C -> B