added decal dropping to scene, decal movement from one wall to another wall, one floor to another floor, one wall to floor and one floor to wall
This commit is contained in:
@@ -0,0 +1,301 @@
|
||||
import * as THREE from 'three';
|
||||
import { CameraControls } from '@react-three/drei';
|
||||
import { ThreeEvent, useFrame, useThree } from '@react-three/fiber';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useSocketStore, useToggleView, useToolMode } from '../../../../store/builder/store';
|
||||
import { useBuilderStore } from '../../../../store/builder/useBuilderStore';
|
||||
import useModuleStore from '../../../../store/useModuleStore';
|
||||
import { getUserData } from '../../../../functions/getUserData';
|
||||
import { useVersionContext } from '../../version/versionContext';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useSceneContext } from '../../../scene/sceneContext';
|
||||
|
||||
// import { upsertWallApi } from '../../../../services/factoryBuilder/wall/upsertWallApi';
|
||||
// import { upsertFloorApi } from '../../../../services/factoryBuilder/floor/upsertFloorApi';
|
||||
|
||||
export function useDecalEventHandlers({
|
||||
parent,
|
||||
decal,
|
||||
visible,
|
||||
}: {
|
||||
parent: Wall | Floor;
|
||||
decal: Decal;
|
||||
visible: boolean;
|
||||
}) {
|
||||
const { wallStore, floorStore } = useSceneContext();
|
||||
const { removeDecal: removeDecalInWall, updateDecalPosition: updateDecalPositionInWall, getWallById, addDecal: addDecalToWall } = wallStore();
|
||||
const { removeDecal: removeDecalInFloor, updateDecalPosition: updateDecalPositionInFloor, getFloorById, addDecal: addDecalToFloor } = floorStore();
|
||||
const { setSelectedWall, setSelectedFloor, setSelectedDecal, setDeletableDecal, deletableDecal, selectedDecal, setDecalDragState, decalDragState } = useBuilderStore();
|
||||
const { toolMode } = useToolMode();
|
||||
const { toggleView } = useToggleView();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { userId, organization } = getUserData();
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { projectId } = useParams();
|
||||
const { socket } = useSocketStore();
|
||||
const { raycaster, pointer, camera, scene, gl, controls } = useThree();
|
||||
|
||||
useFrame(() => {
|
||||
if (activeModule !== 'builder' || toggleView || !decalDragState.isDragging || !selectedDecal || selectedDecal.decalData.decalUuid !== decal.decalUuid) return;
|
||||
|
||||
raycaster.setFromCamera(pointer, camera);
|
||||
const intersects = raycaster.intersectObjects(scene.children, true);
|
||||
|
||||
const wallIntersect = intersects.find(i => i.object.userData?.wallUuid);
|
||||
const floorIntersect = intersects.find(i => i.object.userData?.floorUuid);
|
||||
|
||||
let offset = decalDragState.dragOffset || new THREE.Vector3(0, 0, 0);
|
||||
|
||||
if (wallIntersect) {
|
||||
const wallUuid = wallIntersect.object.userData.wallUuid;
|
||||
const point = wallIntersect.object.worldToLocal(wallIntersect.point.clone());
|
||||
|
||||
if ("wallUuid" in parent && parent.wallUuid === wallUuid && decal.decalType.type === 'Wall') {
|
||||
updateDecalPositionInWall(decal.decalUuid, [point.x + offset.x, point.y + offset.y, decal.decalPosition[2]]);
|
||||
} else if (decal.decalType.type === 'Wall' && wallUuid) {
|
||||
deleteDecal(decal.decalUuid, parent);
|
||||
|
||||
const addedDecal = addDecalToWall(wallUuid, {
|
||||
...decal,
|
||||
decalPosition: [point.x + offset.x, point.y + offset.y, decal.decalPosition[2]],
|
||||
decalType: { type: 'Wall', wallUuid: wallUuid }
|
||||
});
|
||||
|
||||
if (addedDecal) {
|
||||
setSelectedDecal({ decalMesh: null, decalData: addedDecal })
|
||||
}
|
||||
} else if (decal.decalType.type === 'Floor' && wallUuid) {
|
||||
deleteDecal(decal.decalUuid, parent);
|
||||
const wall = getWallById(wallUuid);
|
||||
if (!wall) return;
|
||||
|
||||
const addedDecal = addDecalToWall(wallUuid, {
|
||||
...decal,
|
||||
decalPosition: [point.x + offset.x, point.y + offset.y, wall.wallThickness / 2 + 0.001],
|
||||
decalType: { type: 'Wall', wallUuid: wallUuid }
|
||||
});
|
||||
|
||||
if (addedDecal) {
|
||||
setSelectedDecal({ decalMesh: null, decalData: addedDecal })
|
||||
}
|
||||
}
|
||||
} else if (floorIntersect) {
|
||||
const floorUuid = floorIntersect.object.userData.floorUuid;
|
||||
const point = floorIntersect.object.worldToLocal(floorIntersect.point.clone());
|
||||
|
||||
if ("floorUuid" in parent && parent.floorUuid === floorUuid && decal.decalType.type === 'Floor') {
|
||||
updateDecalPositionInFloor(decal.decalUuid, [point.x + offset.x, point.y + offset.y, decal.decalPosition[2]]);
|
||||
} else if (decal.decalType.type === 'Floor' && floorUuid) {
|
||||
deleteDecal(decal.decalUuid, parent);
|
||||
|
||||
const addedDecal = addDecalToFloor(floorUuid, {
|
||||
...decal,
|
||||
decalPosition: [point.x + offset.x, point.y + offset.y, decal.decalPosition[2]],
|
||||
decalType: { type: 'Floor', floorUuid: floorUuid }
|
||||
});
|
||||
|
||||
if (addedDecal) {
|
||||
setSelectedDecal({ decalMesh: null, decalData: addedDecal })
|
||||
}
|
||||
} else if (decal.decalType.type === 'Wall' && floorUuid) {
|
||||
deleteDecal(decal.decalUuid, parent);
|
||||
const floor = getFloorById(floorUuid);
|
||||
if (!floor) return;
|
||||
|
||||
const addedDecal = addDecalToFloor(floorUuid, {
|
||||
...decal,
|
||||
decalPosition: [point.x + offset.x, point.y + offset.y, -0.001],
|
||||
decalType: { type: 'Floor', floorUuid: floorUuid }
|
||||
});
|
||||
|
||||
if (addedDecal) {
|
||||
setSelectedDecal({ decalMesh: null, decalData: addedDecal })
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const handlePointerUp = (e: PointerEvent) => {
|
||||
if (controls) {
|
||||
(controls as CameraControls).enabled = true;
|
||||
}
|
||||
if (decalDragState.isDragging) {
|
||||
setDecalDragState(false, null, null);
|
||||
|
||||
if ('wallUuid' in parent) {
|
||||
setTimeout(() => {
|
||||
const updatedWall = getWallById(parent.wallUuid);
|
||||
if (updatedWall) {
|
||||
if (projectId && updatedWall) {
|
||||
// API
|
||||
|
||||
// upsertWallApi(projectId, selectedVersion?.versionId || '', updatedWall);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
wallData: updatedWall,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Wall:add', data);
|
||||
}
|
||||
}
|
||||
}, 0)
|
||||
} else if ('floorUuid' in parent) {
|
||||
setTimeout(() => {
|
||||
const updatedFloor = parent;
|
||||
|
||||
if (projectId && updatedFloor) {
|
||||
// API
|
||||
|
||||
// upsertFloorApi(projectId, selectedVersion?.versionId || '', updatedFloor);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
floorData: updatedFloor,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Floor:add', data);
|
||||
}
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const deleteDecal = (decalUuid: string, parent: Wall | Floor) => {
|
||||
if ('wallUuid' in parent) {
|
||||
const updatedWall = removeDecalInWall(decalUuid);
|
||||
|
||||
if (projectId && updatedWall) {
|
||||
// API
|
||||
|
||||
// upsertWallApi(projectId, selectedVersion?.versionId || '', updatedWall);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
wallData: updatedWall,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Wall:add', data);
|
||||
}
|
||||
} else if ('floorUuid' in parent) {
|
||||
const updatedFloor = removeDecalInFloor(decalUuid);
|
||||
|
||||
if (projectId && updatedFloor) {
|
||||
// API
|
||||
|
||||
// upsertFloorApi(projectId, selectedVersion?.versionId || '', updatedFloor);
|
||||
|
||||
// SOCKET
|
||||
|
||||
const data = {
|
||||
floorData: updatedFloor,
|
||||
projectId: projectId,
|
||||
versionId: selectedVersion?.versionId || '',
|
||||
userId: userId,
|
||||
organization: organization
|
||||
}
|
||||
|
||||
socket.emit('v1:model-Floor:add', data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handlePointerDown = (e: ThreeEvent<MouseEvent>) => {
|
||||
if (visible && !toggleView && activeModule === 'builder') {
|
||||
if (e.object.userData.decalUuid && toolMode === 'cursor') {
|
||||
e.stopPropagation();
|
||||
setDecalDragState(true, decal.decalUuid, null);
|
||||
if (controls) {
|
||||
(controls as CameraControls).enabled = false;
|
||||
}
|
||||
setSelectedDecal({ decalMesh: e.object, decalData: decal });
|
||||
setSelectedWall(null);
|
||||
setSelectedFloor(null);
|
||||
|
||||
const localIntersect = e.object.worldToLocal(e.point.clone());
|
||||
let dragOffset = new THREE.Vector3(decal.decalPosition[0] - localIntersect.x, decal.decalPosition[1] - localIntersect.y, 0);
|
||||
setDecalDragState(true, decal.decalUuid, dragOffset);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleClick = (e: ThreeEvent<MouseEvent>) => {
|
||||
if (visible && !toggleView && activeModule === 'builder') {
|
||||
if (e.object.userData.decalUuid) {
|
||||
e.stopPropagation();
|
||||
if (toolMode === 'cursor') {
|
||||
setSelectedDecal({ decalMesh: e.object, decalData: decal });
|
||||
setSelectedWall(null);
|
||||
setSelectedFloor(null);
|
||||
} else if (toolMode === '3D-Delete') {
|
||||
deleteDecal(e.object.userData.decalUuid, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handlePointerEnter = (e: ThreeEvent<MouseEvent>) => {
|
||||
if (visible && !toggleView && activeModule === 'builder') {
|
||||
if (e.object.userData.decalUuid) {
|
||||
e.stopPropagation();
|
||||
if (toolMode === '3D-Delete') {
|
||||
setDeletableDecal(e.object);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handlePointerLeave = (e: ThreeEvent<MouseEvent>) => {
|
||||
if (visible && !toggleView && activeModule === 'builder') {
|
||||
if (e.object.userData.decalUuid) {
|
||||
e.stopPropagation();
|
||||
if (toolMode === '3D-Delete' && deletableDecal && deletableDecal?.userData.decalUuid === e.object.userData.decalUuid) {
|
||||
setDeletableDecal(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handlePointerMissed = () => {
|
||||
if (selectedDecal && selectedDecal.decalMesh && selectedDecal.decalMesh.userData.decalUuid === decal.decalUuid) {
|
||||
setSelectedDecal(null);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const canvasElement = gl.domElement;
|
||||
|
||||
if (activeModule === 'builder' && !toggleView && selectedDecal && selectedDecal.decalData.decalUuid === decal.decalUuid) {
|
||||
canvasElement.addEventListener('pointerup', handlePointerUp);
|
||||
}
|
||||
|
||||
return () => {
|
||||
canvasElement.removeEventListener('pointerup', handlePointerUp);
|
||||
};
|
||||
}, [gl, activeModule, toggleView, selectedDecal, camera, controls, visible, parent, decal, decalDragState]);
|
||||
|
||||
return {
|
||||
handlePointerDown,
|
||||
handleClick,
|
||||
handlePointerEnter,
|
||||
handlePointerLeave,
|
||||
handlePointerMissed,
|
||||
deleteDecal
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user