import { useEffect } from "react"; import { useDeleteModels, useDeletePointOrLine, useObjectPosition, useObjectRotation, useObjectScale, useSelectedWallItem, useSocketStore, useWallItems } from "../../../store/store"; import { Csg } from "../csg/csg"; import * as Types from "../../../types/world/worldTypes"; import * as CONSTANTS from "../../../types/world/worldConstants"; import * as THREE from "three"; import { useThree } from "@react-three/fiber"; import handleMeshMissed from "../eventFunctions/handleMeshMissed"; import DeleteWallItems from "../geomentries/walls/deleteWallItems"; import loadInitialWallItems from "../../scene/IntialLoad/loadInitialWallItems"; import AddWallItems from "../geomentries/walls/addWallItems"; const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletableWallItem, selectedItemsIndex, setSelectedItemsIndex, CSGGroup }: any) => { const { deleteModels, setDeleteModels } = useDeleteModels(); const { wallItems, setWallItems } = useWallItems(); const { objectPosition, setObjectPosition } = useObjectPosition(); const { objectScale, setObjectScale } = useObjectScale(); const { objectRotation, setObjectRotation } = useObjectRotation(); const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine(); const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem(); const { socket } = useSocketStore(); const state = useThree(); const { pointer, camera, raycaster } = state; useEffect(() => { // Load Wall Items from the backend loadInitialWallItems(setWallItems, AssetConfigurations); }, []); ////////// Update the Scale value changes in thewallItems State ////////// ////////// Update the Position value changes in the selected item ////////// ////////// Update the Rotation value changes in the selected item ////////// useEffect(() => { if (objectScale.x && objectScale.y && objectScale.z) { let ScaledWallItems: Types.wallItems = []; wallItems.forEach((items: any) => { if (items.model?.uuid === currentWallItem.current?.parent?.uuid) { items.scale = [objectScale.x, objectScale.y, objectScale.z]; } ScaledWallItems.push(items); }); setWallItems(ScaledWallItems); } }, [objectScale]); useEffect(() => { if (objectPosition.x && objectPosition.y && objectPosition.z) { let ScaledWallItems: Types.wallItems = []; wallItems.forEach((items: any) => { if (items.model?.uuid === currentWallItem.current?.parent?.uuid) { items.position = [objectPosition.x, objectPosition.y, objectPosition.z]; } ScaledWallItems.push(items); }); setWallItems(ScaledWallItems); } }, [objectPosition]); useEffect(() => { if (objectRotation.x && objectRotation.y && objectRotation.z) { let ScaledWallItems: Types.wallItems = []; wallItems.forEach((items: any) => { if (items.model?.uuid === currentWallItem.current?.parent?.uuid) { const radiansX = objectRotation.x * (Math.PI / 180); const radiansY = objectRotation.y * (Math.PI / 180); const radiansZ = objectRotation.z * (Math.PI / 180); const quaternion = new THREE.Quaternion().setFromEuler( new THREE.Euler(radiansX, radiansY, radiansZ) ); items.quaternion = [quaternion.x, quaternion.y, quaternion.z, quaternion.w]; } ScaledWallItems.push(items); }); setWallItems(ScaledWallItems); } }, [objectRotation]); useEffect(() => { const canvasElement = state.gl.domElement; function handlePointerMove(e: any) { if (selectedItemsIndex !== null && !deletePointOrLine && e.buttons === 1) { const Raycaster = state.raycaster; const intersects = Raycaster.intersectObjects(CSGGroup.current?.children[0].children!, true); const Object = intersects.find((child) => child.object.name.includes("WallRaycastReference")); if (Object) { (state.controls as any)!.enabled = false; setWallItems((prevItems: any) => { const updatedItems = [...prevItems]; let position: [number, number, number] = [0, 0, 0]; if (updatedItems[selectedItemsIndex].type === "Fixed-Move") { position = [Object!.point.x, Math.floor(Object!.point.y / CONSTANTS.wallConfig.height) * CONSTANTS.wallConfig.height, Object!.point.z]; } else if (updatedItems[selectedItemsIndex].type === "Free-Move") { position = [Object!.point.x, Object!.point.y, Object!.point.z]; } requestAnimationFrame(() => { setObjectPosition(new THREE.Vector3(...position)); setObjectRotation({ x: THREE.MathUtils.radToDeg(Object!.object.rotation.x), y: THREE.MathUtils.radToDeg(Object!.object.rotation.y), z: THREE.MathUtils.radToDeg(Object!.object.rotation.z), }); }); updatedItems[selectedItemsIndex] = { ...updatedItems[selectedItemsIndex], position: position, quaternion: Object!.object.quaternion.clone() as Types.QuaternionType, }; return updatedItems; }); } } } async function handlePointerUp() { const Raycaster = state.raycaster; const intersects = Raycaster.intersectObjects(CSGGroup.current?.children[0].children!, true); const Object = intersects.find((child) => child.object.name.includes("WallRaycastReference")); if (Object) { if (selectedItemsIndex !== null) { let currentItem: any = null; setWallItems((prevItems: any) => { const updatedItems = [...prevItems]; const WallItemsForStorage = updatedItems.map((item) => { const { model, ...rest } = item; return { ...rest, modeluuid: model?.uuid, }; }); currentItem = updatedItems[selectedItemsIndex]; localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage)); return updatedItems; }); setTimeout(async () => { const email = localStorage.getItem('email') const organization = (email!.split("@")[1]).split(".")[0]; //REST // await setWallItem( // organization, // currentItem?.model?.uuid, // currentItem.modelname, // currentItem.type!, // currentItem.csgposition!, // currentItem.csgscale!, // currentItem.position, // currentItem.quaternion, // currentItem.scale!, // ) //SOCKET const data = { organization: organization, modeluuid: currentItem.model?.uuid!, modelname: currentItem.modelname!, type: currentItem.type!, csgposition: currentItem.csgposition!, csgscale: currentItem.csgscale!, position: currentItem.position!, quaternion: currentItem.quaternion, scale: currentItem.scale!, socketId: socket.id } socket.emit('v1:wallItems:set', data); }, 0); (state.controls as any)!.enabled = true; } } } canvasElement.addEventListener("pointermove", handlePointerMove); canvasElement.addEventListener("pointerup", handlePointerUp); return () => { canvasElement.removeEventListener("pointermove", handlePointerMove); canvasElement.removeEventListener("pointerup", handlePointerUp); }; }, [selectedItemsIndex]); useEffect(() => { const canvasElement = state.gl.domElement; let drag = false; let isLeftMouseDown = false; const onMouseDown = (evt: any) => { if (evt.button === 0) { isLeftMouseDown = true; drag = false; } }; const onMouseUp = (evt: any) => { if (evt.button === 0) { isLeftMouseDown = false; if (!drag && deleteModels) { DeleteWallItems(hoveredDeletableWallItem, setWallItems, wallItems, socket); } } }; const onMouseMove = () => { if (isLeftMouseDown) { drag = true; } }; const onDrop = (event: any) => { if (!event.dataTransfer?.files[0]) return pointer.x = (event.clientX / window.innerWidth) * 2 - 1; pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; raycaster.setFromCamera(pointer, camera); if (AssetConfigurations[(event.dataTransfer.files[0].name.split('.'))[0]]) { const selected = (event.dataTransfer.files[0].name.split('.'))[0]; if (AssetConfigurations[selected]?.type) { AddWallItems(selected, raycaster, CSGGroup, AssetConfigurations, setWallItems, socket); } event.preventDefault(); } } const onDragOver = (event: any) => { event.preventDefault(); }; canvasElement.addEventListener("mousedown", onMouseDown); canvasElement.addEventListener("mouseup", onMouseUp); canvasElement.addEventListener("mousemove", onMouseMove); canvasElement.addEventListener("drop", onDrop); canvasElement.addEventListener("dragover", onDragOver); return () => { canvasElement.removeEventListener("mousedown", onMouseDown); canvasElement.removeEventListener("mouseup", onMouseUp); canvasElement.removeEventListener("mousemove", onMouseMove); canvasElement.removeEventListener("drop", onDrop); canvasElement.removeEventListener("dragover", onDragOver); }; }, [deleteModels, wallItems]) useEffect(() => { if (deleteModels) { handleMeshMissed(currentWallItem, setSelectedWallItem, setSelectedItemsIndex); setSelectedWallItem(null); setSelectedItemsIndex(null); } }, [deleteModels]) return ( <> {wallItems.map((item: Types.WallItem, index: number) => ( ))} ) } export default WallItemsGroup;