891 lines
35 KiB
TypeScript
891 lines
35 KiB
TypeScript
import { useEffect } from "react";
|
|
import * as THREE from "three";
|
|
import gsap from "gsap";
|
|
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
|
|
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
|
|
import {
|
|
useSocketStore,
|
|
useActiveLayer,
|
|
useWallItems,
|
|
useLayers,
|
|
useUpdateScene,
|
|
useWalls,
|
|
useDeletedLines,
|
|
useNewLines,
|
|
useZonePoints,
|
|
useZones,
|
|
} from "../../../store/builder/store";
|
|
|
|
import * as Types from "../../../types/world/worldTypes";
|
|
import * as CONSTANTS from "../../../types/world/worldConstants";
|
|
|
|
// import { setFloorItemApi } from "../../services/factoryBuilder/assest/floorAsset/setFloorItemApi";
|
|
import objectLineToArray from "../../builder/geomentries/lines/lineConvertions/objectLineToArray";
|
|
import addLineToScene from "../../builder/geomentries/lines/addLineToScene";
|
|
import updateLinesPositions from "../../builder/geomentries/lines/updateLinesPositions";
|
|
import updateLines from "../../builder/geomentries/lines/updateLines";
|
|
import updateDistanceText from "../../builder/geomentries/lines/updateDistanceText";
|
|
import updateFloorLines from "../../builder/geomentries/floors/updateFloorLines";
|
|
import loadWalls from "../../builder/geomentries/walls/loadWalls";
|
|
import RemoveConnectedLines from "../../builder/geomentries/lines/removeConnectedLines";
|
|
import Layer2DVisibility from "../../builder/geomentries/layers/layer2DVisibility";
|
|
import { retrieveGLTF, storeGLTF } from "../../../utils/indexDB/idbUtils";
|
|
import { getZonesApi } from "../../../services/factoryBuilder/zones/getZonesApi";
|
|
import { useParams } from "react-router-dom";
|
|
import { useAssetsStore } from "../../../store/builder/useAssetStore";
|
|
import { useEventsStore } from "../../../store/simulation/useEventsStore";
|
|
import { useProductStore } from "../../../store/simulation/useProductStore";
|
|
|
|
export default function SocketResponses({
|
|
floorPlanGroup,
|
|
lines,
|
|
floorGroup,
|
|
floorGroupAisle,
|
|
scene,
|
|
onlyFloorlines,
|
|
itemsGroup,
|
|
isTempLoader,
|
|
tempLoader,
|
|
currentLayerPoint,
|
|
floorPlanGroupPoint,
|
|
floorPlanGroupLine,
|
|
zoneGroup,
|
|
dragPointControls,
|
|
}: any) {
|
|
const { socket } = useSocketStore();
|
|
const { activeLayer, setActiveLayer } = useActiveLayer();
|
|
const { wallItems, setWallItems } = useWallItems();
|
|
const { setLayers } = useLayers();
|
|
const { setUpdateScene } = useUpdateScene();
|
|
const { setWalls } = useWalls();
|
|
const { setDeletedLines } = useDeletedLines();
|
|
const { setNewLines } = useNewLines();
|
|
const { zones, setZones } = useZones();
|
|
const { zonePoints, setZonePoints } = useZonePoints();
|
|
const { projectId } = useParams();
|
|
const { addAsset, updateAsset, removeAsset } = useAssetsStore();
|
|
|
|
useEffect(() => {
|
|
const email = localStorage.getItem("email");
|
|
const organization = email!.split("@")[1].split(".")[0];
|
|
|
|
if (!socket) return;
|
|
|
|
socket.on("cameraCreateResponse", (data: any) => {
|
|
//
|
|
});
|
|
|
|
socket.on("userConnectRespones", (data: any) => {
|
|
//
|
|
});
|
|
|
|
socket.on("userDisConnectRespones", (data: any) => {
|
|
//
|
|
});
|
|
|
|
socket.on("v1:camera:Response:update", (data: any) => {
|
|
console.log('dataCamera: ', data);
|
|
//
|
|
});
|
|
|
|
socket.on("EnvironmentUpdateResponse", (data: any) => {
|
|
//
|
|
});
|
|
|
|
socket.on("v1:model-asset:response:add", async (data: any) => {
|
|
//
|
|
if (socket.id === data.socketId) {
|
|
return;
|
|
}
|
|
if (organization !== data.organization) {
|
|
return;
|
|
}
|
|
console.log('data.data: ', data);
|
|
if (data.message === "Model created successfully") {
|
|
try {
|
|
|
|
const asset: Asset = {
|
|
modelUuid: data.data.modelUuid,
|
|
modelName: data.data.modelName,
|
|
assetId: data.data.modelfileID,
|
|
position: data.data.position,
|
|
rotation: [data.data.rotation.x, data.data.rotation.y, data.data.rotation.z],
|
|
isLocked: data.data.isLocked,
|
|
isCollidable: false,
|
|
isVisible: data.data.isVisible,
|
|
opacity: 1,
|
|
}
|
|
|
|
addAsset(asset);
|
|
|
|
echo.success("Added model through collaboration");
|
|
} catch (error) {
|
|
echo.error("Failed to create model through collaboration");
|
|
}
|
|
} else if (data.message === "Model updated successfully") {
|
|
try {
|
|
|
|
const asset: Asset = {
|
|
modelUuid: data.data.modelUuid,
|
|
modelName: data.data.modelName,
|
|
assetId: data.data.modelfileID,
|
|
position: data.data.position,
|
|
rotation: [data.data.rotation.x, data.data.rotation.y, data.data.rotation.z],
|
|
isLocked: data.data.isLocked,
|
|
isCollidable: false,
|
|
isVisible: data.data.isVisible,
|
|
opacity: 1,
|
|
}
|
|
|
|
updateAsset(asset.modelUuid, {
|
|
position: asset.position,
|
|
rotation: asset.rotation,
|
|
});
|
|
|
|
echo.success("Updated model through collaboration");
|
|
} catch (error) {
|
|
echo.error("Failed to update model through collaboration");
|
|
}
|
|
} else {
|
|
echo.error("Failed executing action from collaboration");
|
|
}
|
|
});
|
|
|
|
socket.on("v1:model-asset:response:delete", (data: any) => {
|
|
if (socket.id === data.socketId) {
|
|
return;
|
|
}
|
|
if (organization !== data.organization) {
|
|
return;
|
|
}
|
|
if (data.message === "Model deleted successfully") {
|
|
try {
|
|
const deletedUUID = data.data.modelUuid;
|
|
|
|
useEventsStore.getState().removeEvent(deletedUUID);
|
|
useProductStore.getState().deleteEvent(deletedUUID);
|
|
|
|
removeAsset(deletedUUID);
|
|
|
|
echo.success("Model Removed successfully through collaboration");
|
|
} catch (error) {
|
|
echo.error("Failed to remove model through collaboration");
|
|
}
|
|
}
|
|
});
|
|
|
|
socket.on("v1:Line:response:update", (data: any) => {
|
|
console.log('data: ', data);
|
|
if (socket.id === data.socketId) {
|
|
return;
|
|
}
|
|
if (organization !== data.organization) {
|
|
return;
|
|
}
|
|
if (data.message === "line updated") {
|
|
const DraggedUUID = data.data.uuid;
|
|
const DraggedPosition = new THREE.Vector3(
|
|
data.data.position.x,
|
|
data.data.position.y,
|
|
data.data.position.z
|
|
);
|
|
|
|
const point = floorPlanGroupPoint.current.getObjectByProperty(
|
|
"uuid",
|
|
DraggedUUID
|
|
);
|
|
point.position.set(
|
|
DraggedPosition.x,
|
|
DraggedPosition.y,
|
|
DraggedPosition.z
|
|
);
|
|
const affectedLines = updateLinesPositions(
|
|
{ uuid: DraggedUUID, position: DraggedPosition },
|
|
lines
|
|
);
|
|
|
|
updateLines(floorPlanGroupLine, affectedLines);
|
|
updateDistanceText(scene, floorPlanGroupLine, affectedLines);
|
|
updateFloorLines(onlyFloorlines, {
|
|
uuid: DraggedUUID,
|
|
position: DraggedPosition,
|
|
});
|
|
|
|
loadWalls(lines, setWalls);
|
|
setUpdateScene(true);
|
|
}
|
|
});
|
|
|
|
socket.on("v1:Line:response:delete", (data: any) => {
|
|
console.log('data: ', data);
|
|
if (socket.id === data.socketId) {
|
|
return;
|
|
}
|
|
if (organization !== data.organization) {
|
|
return;
|
|
}
|
|
if (data.message === "line deleted") {
|
|
const line = objectLineToArray(data.data);
|
|
const linePoints = line;
|
|
const connectedpoints = [linePoints[0][1], linePoints[1][1]];
|
|
|
|
onlyFloorlines.current = onlyFloorlines.current
|
|
.map((floorline: any) =>
|
|
floorline.filter(
|
|
(line: any) =>
|
|
line[0][1] !== connectedpoints[0] &&
|
|
line[1][1] !== connectedpoints[1]
|
|
)
|
|
)
|
|
.filter((floorline: any) => floorline.length > 0);
|
|
|
|
const removedLine = lines.current.find(
|
|
(item: any) =>
|
|
(item[0][1] === linePoints[0][1] &&
|
|
item[1][1] === linePoints[1][1]) ||
|
|
(item[0][1] === linePoints[1][1] && item[1][1] === linePoints[0][1])
|
|
);
|
|
lines.current = lines.current.filter(
|
|
(item: any) => item !== removedLine
|
|
);
|
|
|
|
floorPlanGroupLine.current.children.forEach((line: any) => {
|
|
const linePoints = line.userData.linePoints as [
|
|
number,
|
|
string,
|
|
number
|
|
][];
|
|
const uuid1 = linePoints[0][1];
|
|
const uuid2 = linePoints[1][1];
|
|
|
|
if (
|
|
(uuid1 === connectedpoints[0] && uuid2 === connectedpoints[1]) ||
|
|
(uuid1 === connectedpoints[1] && uuid2 === connectedpoints[0])
|
|
) {
|
|
line.material.dispose();
|
|
line.geometry.dispose();
|
|
floorPlanGroupLine.current.remove(line);
|
|
setDeletedLines([line.userData.linePoints]);
|
|
}
|
|
});
|
|
|
|
connectedpoints.forEach((pointUUID) => {
|
|
let isConnected = false;
|
|
floorPlanGroupLine.current.children.forEach((line: any) => {
|
|
const linePoints = line.userData.linePoints;
|
|
const uuid1 = linePoints[0][1];
|
|
const uuid2 = linePoints[1][1];
|
|
if (uuid1 === pointUUID || uuid2 === pointUUID) {
|
|
isConnected = true;
|
|
}
|
|
});
|
|
|
|
if (!isConnected) {
|
|
floorPlanGroupPoint.current.children.forEach((point: any) => {
|
|
if (point.uuid === pointUUID) {
|
|
point.material.dispose();
|
|
point.geometry.dispose();
|
|
floorPlanGroupPoint.current.remove(point);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
loadWalls(lines, setWalls);
|
|
setUpdateScene(true);
|
|
|
|
echo.success("Line Removed!");
|
|
}
|
|
});
|
|
|
|
socket.on("v1:Line:response:delete:point", (data: any) => {
|
|
console.log('datapoint: ', data);
|
|
if (socket.id === data.socketId) {
|
|
return;
|
|
}
|
|
if (organization !== data.organization) {
|
|
return;
|
|
}
|
|
if (data.message === "point deleted") {
|
|
const point = floorPlanGroupPoint.current?.getObjectByProperty(
|
|
"uuid",
|
|
data.data
|
|
);
|
|
point.material.dispose();
|
|
point.geometry.dispose();
|
|
floorPlanGroupPoint.current.remove(point);
|
|
|
|
onlyFloorlines.current = onlyFloorlines.current
|
|
.map((floorline: any) =>
|
|
floorline.filter(
|
|
(line: any) =>
|
|
line[0][1] !== data.data && line[1][1] !== data.data
|
|
)
|
|
)
|
|
.filter((floorline: any) => floorline.length > 0);
|
|
|
|
RemoveConnectedLines(
|
|
data.data,
|
|
floorPlanGroupLine,
|
|
floorPlanGroupPoint,
|
|
setDeletedLines,
|
|
lines
|
|
);
|
|
|
|
loadWalls(lines, setWalls);
|
|
setUpdateScene(true);
|
|
|
|
echo.success("Point Removed!");
|
|
}
|
|
});
|
|
|
|
socket.on("v1:Line:response:delete:layer", async (data: any) => {
|
|
console.log('data: ', data);
|
|
if (socket.id === data.socketId) {
|
|
return;
|
|
}
|
|
if (organization !== data.organization) {
|
|
return;
|
|
}
|
|
if (data.message === "layer deleted") {
|
|
setActiveLayer(1);
|
|
const removedLayer = data.data;
|
|
const removedLines: Types.Lines = lines.current.filter(
|
|
(line: any) => line[0][2] === removedLayer
|
|
);
|
|
|
|
////////// Remove Points and lines from the removed layer //////////
|
|
|
|
removedLines.forEach(async (line) => {
|
|
line.forEach(async (removedPoint) => {
|
|
const removableLines: THREE.Mesh[] = [];
|
|
const connectedpoints: string[] = [];
|
|
|
|
floorPlanGroupLine.current.children.forEach((line: any) => {
|
|
const linePoints = line.userData.linePoints as [
|
|
number,
|
|
string,
|
|
number
|
|
][];
|
|
const uuid1 = linePoints[0][1];
|
|
const uuid2 = linePoints[1][1];
|
|
|
|
if (uuid1 === removedPoint[1] || uuid2 === removedPoint[1]) {
|
|
connectedpoints.push(uuid1 === removedPoint[1] ? uuid2 : uuid1);
|
|
removableLines.push(line as THREE.Mesh);
|
|
}
|
|
});
|
|
|
|
if (removableLines.length > 0) {
|
|
removableLines.forEach((line: any) => {
|
|
lines.current = lines.current.filter(
|
|
(item: any) =>
|
|
JSON.stringify(item) !==
|
|
JSON.stringify(line.userData.linePoints)
|
|
);
|
|
line.material.dispose();
|
|
line.geometry.dispose();
|
|
floorPlanGroupLine.current.remove(line);
|
|
});
|
|
}
|
|
|
|
const point = floorPlanGroupPoint.current.getObjectByProperty(
|
|
"uuid",
|
|
removedPoint[1]
|
|
);
|
|
if (point) {
|
|
point.material.dispose();
|
|
point.geometry.dispose();
|
|
floorPlanGroupPoint.current.remove(point);
|
|
}
|
|
});
|
|
});
|
|
|
|
////////// Update the remaining lines layer values in the userData and in lines.current //////////
|
|
|
|
let remaining = lines.current.filter(
|
|
(line: any) => line[0][2] !== removedLayer
|
|
);
|
|
let updatedLines: Types.Lines = [];
|
|
remaining.forEach((line: any) => {
|
|
let newLines = JSON.parse(JSON.stringify(line));
|
|
if (newLines[0][2] > removedLayer) {
|
|
newLines[0][2] -= 1;
|
|
newLines[1][2] -= 1;
|
|
}
|
|
|
|
const matchingLine = floorPlanGroupLine.current.children.find(
|
|
(l: any) =>
|
|
l.userData.linePoints[0][1] === line[0][1] &&
|
|
l.userData.linePoints[1][1] === line[1][1]
|
|
);
|
|
if (matchingLine) {
|
|
const updatedUserData = JSON.parse(
|
|
JSON.stringify(matchingLine.userData)
|
|
);
|
|
updatedUserData.linePoints[0][2] = newLines[0][2];
|
|
updatedUserData.linePoints[1][2] = newLines[1][2];
|
|
matchingLine.userData = updatedUserData;
|
|
}
|
|
updatedLines.push(newLines);
|
|
});
|
|
|
|
lines.current = updatedLines;
|
|
localStorage.setItem("Lines", JSON.stringify(lines.current));
|
|
|
|
////////// Also remove OnlyFloorLines and update it in localstorage //////////
|
|
|
|
onlyFloorlines.current = onlyFloorlines.current.filter((floor: any) => {
|
|
return floor[0][0][2] !== removedLayer;
|
|
});
|
|
const meshToRemove = floorGroup.current?.children.find(
|
|
(mesh: any) => mesh.name === `Only_Floor_Line_${removedLayer}`
|
|
);
|
|
if (meshToRemove) {
|
|
meshToRemove.geometry.dispose();
|
|
meshToRemove.material.dispose();
|
|
floorGroup.current?.remove(meshToRemove);
|
|
}
|
|
|
|
const zonesData = await getZonesApi(organization,projectId);
|
|
const highestLayer = Math.max(
|
|
1,
|
|
lines.current.reduce(
|
|
(maxLayer: number, segment: any) =>
|
|
Math.max(maxLayer, segment.layer || 0),
|
|
0
|
|
),
|
|
zonesData.reduce(
|
|
(maxLayer: number, zone: any) =>
|
|
Math.max(maxLayer, zone.layer || 0),
|
|
0
|
|
)
|
|
);
|
|
|
|
setLayers(highestLayer);
|
|
|
|
loadWalls(lines, setWalls);
|
|
setUpdateScene(true);
|
|
|
|
echo.success("Layer Removed!");
|
|
}
|
|
});
|
|
}, [socket]);
|
|
|
|
useEffect(() => {
|
|
if (!socket) return;
|
|
const email = localStorage.getItem("email");
|
|
const organization = email!.split("@")[1].split(".")[0];
|
|
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
|
|
|
socket.on("v1:wallItem:Response:Delete", (data: any) => {
|
|
if (socket.id === data.socketId) {
|
|
return;
|
|
}
|
|
if (organization !== data.organization) {
|
|
return;
|
|
}
|
|
if (data.message === "wallitem deleted") {
|
|
const deletedUUID = data.data.modelUuid;
|
|
let WallItemsRef = wallItems;
|
|
const Items = WallItemsRef.filter((item: any) => item.model?.uuid !== deletedUUID);
|
|
|
|
setWallItems([]);
|
|
setTimeout(async () => {
|
|
WallItemsRef = Items;
|
|
setWallItems(WallItemsRef);
|
|
const WallItemsForStorage = WallItemsRef.map((item: any) => {
|
|
const { model, ...rest } = item;
|
|
return {
|
|
...rest,
|
|
modelUuid: model?.uuid,
|
|
};
|
|
});
|
|
|
|
localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage));
|
|
echo.success("Model Removed!");
|
|
}, 50);
|
|
}
|
|
});
|
|
|
|
socket.on("v1:wallItems:Response:Update", (data: any) => {
|
|
//
|
|
if (socket.id === data.socketId) {
|
|
return;
|
|
}
|
|
if (organization !== data.organization) {
|
|
return;
|
|
}
|
|
if (data.message === "wallIitem created") {
|
|
const loader = new GLTFLoader();
|
|
const dracoLoader = new DRACOLoader();
|
|
|
|
dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/');
|
|
loader.setDRACOLoader(dracoLoader);
|
|
|
|
// Check THREE.js cache first
|
|
const cachedModel = THREE.Cache.get(data.data.modelfileID);
|
|
if (cachedModel) {
|
|
handleModelLoad(cachedModel);
|
|
return;
|
|
}
|
|
|
|
// Check IndexedDB cache
|
|
retrieveGLTF(data.data.modelfileID).then((cachedModelBlob) => {
|
|
if (cachedModelBlob) {
|
|
const blobUrl = URL.createObjectURL(cachedModelBlob);
|
|
loader.load(blobUrl, (gltf) => {
|
|
URL.revokeObjectURL(blobUrl);
|
|
THREE.Cache.remove(blobUrl);
|
|
THREE.Cache.add(data.data.modelfileID, gltf);
|
|
handleModelLoad(gltf);
|
|
});
|
|
return;
|
|
}
|
|
})
|
|
|
|
// Load from backend if not in any cache
|
|
loader.load(`${url_Backend_dwinzo}/api/v2/AssetFile/${data.data.modelfileID}`, async (gltf) => {
|
|
try {
|
|
const modelBlob = await fetch(`${url_Backend_dwinzo}/api/v2/AssetFile/${data.data.modelfileID}`).then((res) => res.blob());
|
|
await storeGLTF(data.data.modelfileID, modelBlob);
|
|
THREE.Cache.add(data.data.modelfileID, gltf);
|
|
await handleModelLoad(gltf);
|
|
} catch (error) {
|
|
|
|
handleModelLoad(gltf);
|
|
}
|
|
});
|
|
|
|
async function handleModelLoad(gltf: GLTF) {
|
|
const model = gltf.scene.clone();
|
|
model.uuid = data.data.modelUuid;
|
|
|
|
model.children[0].children.forEach((child) => {
|
|
if (child.name !== "CSG_REF") {
|
|
child.castShadow = true;
|
|
child.receiveShadow = true;
|
|
}
|
|
});
|
|
|
|
const newWallItem = {
|
|
type: data.data.type,
|
|
model: model,
|
|
modelName: data.data.modelName,
|
|
modelfileID: data.data.modelfileID,
|
|
scale: data.data.scale,
|
|
csgscale: data.data.csgscale,
|
|
csgposition: data.data.csgposition,
|
|
position: data.data.position,
|
|
quaternion: data.data.quaternion,
|
|
};
|
|
|
|
setWallItems((prevItems: Types.wallItems) => {
|
|
const updatedItems = [...prevItems, newWallItem];
|
|
|
|
const WallItemsForStorage = updatedItems.map(item => {
|
|
const { model, ...rest } = item;
|
|
return {
|
|
...rest,
|
|
modelUuid: model?.uuid,
|
|
};
|
|
});
|
|
|
|
localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage));
|
|
echo.success("Model Added!");
|
|
return updatedItems;
|
|
});
|
|
}
|
|
|
|
} else if (data.message === "wallIitem updated") {
|
|
const updatedUUID = data.data.modelUuid;
|
|
|
|
setWallItems((prevItems: any) => {
|
|
const updatedItems = prevItems.map((item: any) => {
|
|
if (item.model.uuid === updatedUUID) {
|
|
return {
|
|
...item,
|
|
position: data.data.position,
|
|
quaternion: data.data.quaternion,
|
|
scale: data.data.scale,
|
|
csgscale: data.data.csgscale,
|
|
csgposition: data.data.csgposition,
|
|
};
|
|
}
|
|
return item;
|
|
});
|
|
|
|
const WallItemsForStorage = updatedItems.map((item: any) => {
|
|
const { model, ...rest } = item;
|
|
return {
|
|
...rest,
|
|
modelUuid: model?.uuid,
|
|
};
|
|
});
|
|
|
|
localStorage.setItem(
|
|
"WallItems",
|
|
JSON.stringify(WallItemsForStorage)
|
|
);
|
|
echo.success("Model Updated!");
|
|
|
|
return updatedItems;
|
|
});
|
|
}
|
|
});
|
|
|
|
return () => {
|
|
socket.off("v1:wallItem:Response:Delete");
|
|
socket.off("v1:wallItems:Response:Update");
|
|
};
|
|
}, [wallItems]);
|
|
|
|
function getPointColor(lineType: string | undefined): string {
|
|
switch (lineType) {
|
|
case CONSTANTS.lineConfig.wallName:
|
|
return CONSTANTS.pointConfig.wallOuterColor;
|
|
case CONSTANTS.lineConfig.floorName:
|
|
return CONSTANTS.pointConfig.floorOuterColor;
|
|
case CONSTANTS.lineConfig.aisleName:
|
|
return CONSTANTS.pointConfig.aisleOuterColor;
|
|
default:
|
|
return CONSTANTS.pointConfig.defaultOuterColor;
|
|
}
|
|
}
|
|
|
|
function getLineColor(lineType: string | undefined): string {
|
|
switch (lineType) {
|
|
case CONSTANTS.lineConfig.wallName:
|
|
return CONSTANTS.lineConfig.wallColor;
|
|
case CONSTANTS.lineConfig.floorName:
|
|
return CONSTANTS.lineConfig.floorColor;
|
|
case CONSTANTS.lineConfig.aisleName:
|
|
return CONSTANTS.lineConfig.aisleColor;
|
|
default:
|
|
return CONSTANTS.lineConfig.defaultColor;
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (!socket) return;
|
|
const email = localStorage.getItem("email");
|
|
const organization = email!.split("@")[1].split(".")[0];
|
|
|
|
socket.on("v1:Line:response:create", async (data: any) => {
|
|
console.log('data: ', data);
|
|
//
|
|
if (socket.id === data.socketId) {
|
|
return;
|
|
}
|
|
if (organization !== data.organization) {
|
|
return;
|
|
}
|
|
if (data.message === "line create") {
|
|
const line: Types.Line = objectLineToArray(data.data);
|
|
const type = line[0][3];
|
|
const pointColour = getPointColor(type);
|
|
const lineColour = getLineColor(type);
|
|
setNewLines([line]);
|
|
|
|
line.forEach((line) => {
|
|
const existingPoint =
|
|
floorPlanGroupPoint.current?.getObjectByProperty("uuid", line[1]);
|
|
if (existingPoint) {
|
|
return;
|
|
}
|
|
const geometry = new THREE.BoxGeometry(
|
|
...CONSTANTS.pointConfig.boxScale
|
|
);
|
|
const material = new THREE.ShaderMaterial({
|
|
uniforms: {
|
|
uOuterColor: { value: new THREE.Color(pointColour) }, // Blue color for the border
|
|
uInnerColor: {
|
|
value: new THREE.Color(CONSTANTS.pointConfig.defaultInnerColor),
|
|
}, // White color for the inner square
|
|
},
|
|
vertexShader: `
|
|
varying vec2 vUv;
|
|
|
|
void main() {
|
|
vUv = uv;
|
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
}
|
|
`,
|
|
fragmentShader: `
|
|
varying vec2 vUv;
|
|
uniform vec3 uOuterColor;
|
|
uniform vec3 uInnerColor;
|
|
|
|
void main() {
|
|
// Define the size of the white square as a proportion of the face
|
|
float borderThickness = 0.2; // Adjust this value for border thickness
|
|
if (vUv.x > borderThickness && vUv.x < 1.0 - borderThickness &&
|
|
vUv.y > borderThickness && vUv.y < 1.0 - borderThickness) {
|
|
gl_FragColor = vec4(uInnerColor, 1.0); // White inner square
|
|
} else {
|
|
gl_FragColor = vec4(uOuterColor, 1.0); // Blue border
|
|
}
|
|
}
|
|
`,
|
|
});
|
|
const point = new THREE.Mesh(geometry, material);
|
|
point.name = "point";
|
|
point.uuid = line[1];
|
|
point.userData = { type: type, color: pointColour };
|
|
point.position.set(line[0].x, line[0].y, line[0].z);
|
|
currentLayerPoint.current.push(point);
|
|
|
|
floorPlanGroupPoint.current?.add(point);
|
|
});
|
|
if (dragPointControls.current) {
|
|
dragPointControls.current!.objects = currentLayerPoint.current;
|
|
}
|
|
addLineToScene(
|
|
new THREE.Vector3(line[0][0].x, line[0][0].y, line[0][0].z),
|
|
new THREE.Vector3(line[1][0].x, line[1][0].y, line[1][0].z),
|
|
lineColour,
|
|
line,
|
|
floorPlanGroupLine
|
|
);
|
|
lines.current.push(line);
|
|
|
|
const zonesData = await getZonesApi(organization,projectId);
|
|
const highestLayer = Math.max(
|
|
1,
|
|
lines.current.reduce(
|
|
(maxLayer: number, segment: any) =>
|
|
Math.max(maxLayer, segment.layer || 0),
|
|
0
|
|
),
|
|
zonesData.reduce(
|
|
(maxLayer: number, zone: any) =>
|
|
Math.max(maxLayer, zone.layer || 0),
|
|
0
|
|
)
|
|
);
|
|
|
|
setLayers(highestLayer);
|
|
|
|
Layer2DVisibility(
|
|
activeLayer,
|
|
floorPlanGroup,
|
|
floorPlanGroupLine,
|
|
floorPlanGroupPoint,
|
|
currentLayerPoint,
|
|
dragPointControls
|
|
);
|
|
|
|
loadWalls(lines, setWalls);
|
|
setUpdateScene(true);
|
|
}
|
|
});
|
|
|
|
return () => {
|
|
socket.off("v1:Line:response:create");
|
|
};
|
|
}, [socket, activeLayer]);
|
|
|
|
useEffect(() => {
|
|
if (!socket) return;
|
|
const email = localStorage.getItem("email");
|
|
const organization = email!.split("@")[1].split(".")[0];
|
|
|
|
socket.on("v1:zone:response:updates", (data: any) => {
|
|
console.log('data: ', data);
|
|
if (socket.id === data.socketId) {
|
|
return;
|
|
}
|
|
if (organization !== data.organization) {
|
|
return;
|
|
}
|
|
|
|
if (data.message === "zone created") {
|
|
const pointsArray: [number, number, number][] = data.data.points;
|
|
const vector3Array = pointsArray.map(
|
|
([x, y, z]) => new THREE.Vector3(x, y, z)
|
|
);
|
|
const newZones = [...zones, data.data];
|
|
setZones(newZones);
|
|
const updatedZonePoints = [...zonePoints, ...vector3Array];
|
|
setZonePoints(updatedZonePoints);
|
|
|
|
const highestLayer = Math.max(
|
|
1,
|
|
lines.current.reduce(
|
|
(maxLayer: number, segment: any) =>
|
|
Math.max(maxLayer, segment.layer || 0),
|
|
0
|
|
),
|
|
newZones.reduce(
|
|
(maxLayer: number, zone: any) =>
|
|
Math.max(maxLayer, zone.layer || 0),
|
|
0
|
|
)
|
|
);
|
|
|
|
setLayers(highestLayer);
|
|
setUpdateScene(true);
|
|
}
|
|
|
|
if (data.message === "zone updated") {
|
|
const updatedZones = zones.map((zone: any) =>
|
|
zone.zoneUuid === data.data.zoneUuid ? data.data : zone
|
|
);
|
|
setZones(updatedZones);
|
|
setUpdateScene(true);
|
|
}
|
|
});
|
|
|
|
socket.on("v1:zone:response:delete", (data: any) => {
|
|
console.log('data: ', data);
|
|
if (socket.id === data.socketId) {
|
|
return;
|
|
}
|
|
if (organization !== data.organization) {
|
|
return;
|
|
}
|
|
if (data.message === "zone deleted") {
|
|
const updatedZones = zones.filter(
|
|
(zone: any) => zone.zoneUuid !== data.data.zoneUuid
|
|
);
|
|
setZones(updatedZones);
|
|
|
|
const zoneIndex = zones.findIndex(
|
|
(zone: any) => zone.zoneUuid === data.data.zoneUuid
|
|
);
|
|
if (zoneIndex !== -1) {
|
|
const updatedzonePoints = zonePoints.filter(
|
|
(_: any, index: any) =>
|
|
index < zoneIndex * 4 || index >= zoneIndex * 4 + 4
|
|
);
|
|
setZonePoints(updatedzonePoints);
|
|
}
|
|
|
|
const highestLayer = Math.max(
|
|
1,
|
|
lines.current.reduce(
|
|
(maxLayer: number, segment: any) =>
|
|
Math.max(maxLayer, segment.layer || 0),
|
|
0
|
|
),
|
|
updatedZones.reduce(
|
|
(maxLayer: number, zone: any) =>
|
|
Math.max(maxLayer, zone.layer || 0),
|
|
0
|
|
)
|
|
);
|
|
|
|
setLayers(highestLayer);
|
|
setUpdateScene(true);
|
|
}
|
|
});
|
|
|
|
return () => {
|
|
socket.off("v1:zone:response:updates");
|
|
socket.off("v1:zone:response:delete");
|
|
};
|
|
}, [socket, zones, zonePoints]);
|
|
|
|
return <></>;
|
|
}
|