140 lines
5.6 KiB
TypeScript
140 lines
5.6 KiB
TypeScript
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<void> {
|
|
////////// 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<string>();
|
|
|
|
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
|