Dwinzo_dev/app/src/modules/builder/groups/wallItemsGroup.tsx

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;