289 lines
12 KiB
TypeScript
289 lines
12 KiB
TypeScript
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) => (
|
|
<group
|
|
key={index}
|
|
position={item.position}
|
|
quaternion={item.quaternion}
|
|
scale={item.scale}
|
|
>
|
|
<Csg
|
|
position={item.csgposition!}
|
|
scale={item.csgscale!}
|
|
model={item.model!}
|
|
hoveredDeletableWallItem={hoveredDeletableWallItem}
|
|
/>
|
|
</group>
|
|
))}
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default WallItemsGroup; |