diff --git a/app/src/modules/builder/floor/floorGroup.tsx b/app/src/modules/builder/floor/floorGroup.tsx index e0da8e5..47ea3b5 100644 --- a/app/src/modules/builder/floor/floorGroup.tsx +++ b/app/src/modules/builder/floor/floorGroup.tsx @@ -1,5 +1,5 @@ import { useEffect } from 'react'; -import { useToggleView } from '../../../store/builder/store' +import { useActiveTool, useToggleView } from '../../../store/builder/store' import { useBuilderStore } from '../../../store/builder/useBuilderStore'; import { useVersionContext } from '../version/versionContext'; import { useSceneContext } from '../../scene/sceneContext'; @@ -13,6 +13,7 @@ function FloorGroup() { const { togglView } = useToggleView(); const { setSelectedFloor, setSelectedDecal } = useBuilderStore(); const { activeModule } = useModuleStore(); + const { activeTool } = useActiveTool(); const { selectedVersionStore } = useVersionContext(); const { selectedVersion } = selectedVersionStore(); const { floorStore } = useSceneContext(); @@ -24,7 +25,7 @@ function FloorGroup() { setSelectedFloor(null); setSelectedDecal(null); } - }, [togglView, activeModule]) + }, [togglView, activeModule, activeTool]) useEffect(() => { if (projectId && selectedVersion) { diff --git a/app/src/modules/builder/wall/wallGroup.tsx b/app/src/modules/builder/wall/wallGroup.tsx index bd8bad1..084b969 100644 --- a/app/src/modules/builder/wall/wallGroup.tsx +++ b/app/src/modules/builder/wall/wallGroup.tsx @@ -1,5 +1,5 @@ import { useEffect } from 'react'; -import { useToggleView } from '../../../store/builder/store'; +import { useActiveTool, useToggleView } from '../../../store/builder/store'; import { useBuilderStore } from '../../../store/builder/useBuilderStore'; import { useVersionContext } from '../version/versionContext'; import { useSceneContext } from '../../scene/sceneContext'; @@ -14,6 +14,7 @@ function WallGroup() { const { togglView } = useToggleView(); const { setSelectedWall, setSelectedDecal } = useBuilderStore(); const { activeModule } = useModuleStore(); + const { activeTool } = useActiveTool(); const { selectedVersionStore } = useVersionContext(); const { selectedVersion } = selectedVersionStore(); const { wallStore } = useSceneContext(); @@ -25,7 +26,7 @@ function WallGroup() { setSelectedWall(null); setSelectedDecal(null); } - }, [togglView, activeModule]) + }, [togglView, activeModule, activeTool]) useEffect(() => { if (projectId && selectedVersion) { diff --git a/app/src/modules/builder/wallAsset/Instances/Instances/wallAssetInstance.tsx b/app/src/modules/builder/wallAsset/Instances/Instances/wallAssetInstance.tsx index 90b93ad..d9f8df0 100644 --- a/app/src/modules/builder/wallAsset/Instances/Instances/wallAssetInstance.tsx +++ b/app/src/modules/builder/wallAsset/Instances/Instances/wallAssetInstance.tsx @@ -1,5 +1,5 @@ import * as THREE from 'three'; -import { useEffect, useMemo, useRef, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { retrieveGLTF, storeGLTF } from '../../../../../utils/indexDB/idbUtils'; import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; @@ -7,7 +7,7 @@ import { Base, Geometry, Subtraction } from '@react-three/csg'; import useModuleStore from '../../../../../store/useModuleStore'; import { useSceneContext } from '../../../../scene/sceneContext'; import { useBuilderStore } from '../../../../../store/builder/useBuilderStore'; -import { useToggleView } from '../../../../../store/builder/store'; +import { useActiveTool, useToggleView } from '../../../../../store/builder/store'; import closestPointOnLineSegment from '../../../line/helpers/getClosestPointOnLineSegment'; import { useThree } from '@react-three/fiber'; @@ -16,10 +16,11 @@ function WallAssetInstance({ wallAsset }: { wallAsset: WallAsset }) { const { raycaster, pointer, camera, scene, controls, gl } = useThree(); const { wallStore, wallAssetStore } = useSceneContext(); const { walls, getWallById } = wallStore(); - const { updateWallAsset } = wallAssetStore(); - const { togglView } = useToggleView(); + const { updateWallAsset, removeWallAsset } = wallAssetStore(); + const { toggleView } = useToggleView(); + const { activeTool } = useActiveTool(); const { activeModule } = useModuleStore(); - const { selectedWallAsset, setSelectedWallAsset } = useBuilderStore(); + const { selectedWallAsset, setSelectedWallAsset, setDeletableWallAsset, deletableWallAsset } = useBuilderStore(); const [gltfScene, setGltfScene] = useState(null); const [boundingBox, setBoundingBox] = useState(null); const groupRef = useRef(null); @@ -138,7 +139,7 @@ function WallAssetInstance({ wallAsset }: { wallAsset: WallAsset }) { } }; - if (selectedWallAsset && !togglView && activeModule === 'builder') { + if (selectedWallAsset && !toggleView && activeModule === 'builder') { canvasElement.addEventListener('mousemove', onPointerMove); canvasElement.addEventListener('pointerup', onPointerUp); } @@ -148,7 +149,29 @@ function WallAssetInstance({ wallAsset }: { wallAsset: WallAsset }) { canvasElement.removeEventListener('pointerup', onPointerUp); }; - }, [gl, camera, togglView, activeModule, selectedWallAsset]) + }, [gl, camera, toggleView, activeModule, selectedWallAsset]) + + const handlePointerClick = useCallback((wallAsset: WallAsset) => { + if (activeTool === 'delete' && deletableWallAsset && deletableWallAsset.userData.modelUuid === wallAsset.modelUuid) { + removeWallAsset(wallAsset.modelUuid); + } + }, [activeTool, activeModule, deletableWallAsset]) + + const handlePointerOver = useCallback((wallAsset: WallAsset, currentObject: THREE.Object3D) => { + if (activeTool === "delete" && activeModule === 'builder') { + if (deletableWallAsset && deletableWallAsset.userData.modelUuid === wallAsset.modelUuid) { + return; + } else { + setDeletableWallAsset(currentObject); + } + } + }, [activeTool, activeModule, deletableWallAsset]); + + const handlePointerOut = useCallback((wallAsset: WallAsset) => { + if (activeTool === "delete" && deletableWallAsset && deletableWallAsset.userData.modelUuid === wallAsset.modelUuid) { + setDeletableWallAsset(null); + } + }, [activeTool, deletableWallAsset]); if (!gltfScene || !boundingBox || !wall) { return null } const size = new THREE.Vector3(); @@ -175,7 +198,7 @@ function WallAssetInstance({ wallAsset }: { wallAsset: WallAsset }) { {gltfScene && ( { - if (!togglView && activeModule === 'builder' && selectedWallAsset && selectedWallAsset.userData.modelUuid === wallAsset.modelUuid) { + if (!toggleView && activeModule === 'builder' && selectedWallAsset && selectedWallAsset.userData.modelUuid === wallAsset.modelUuid) { draggingRef.current = true; e.stopPropagation(); setSelectedWallAsset(groupRef.current); @@ -185,7 +208,7 @@ function WallAssetInstance({ wallAsset }: { wallAsset: WallAsset }) { } }} onClick={(e) => { - if (!togglView && activeModule === 'builder') { + if (!toggleView && activeModule === 'builder' && activeTool !== 'delete') { if (e.object) { e.stopPropagation(); let currentObject = e.object as THREE.Object3D; @@ -197,6 +220,8 @@ function WallAssetInstance({ wallAsset }: { wallAsset: WallAsset }) { } setSelectedWallAsset(currentObject); } + } else if (!toggleView && activeModule === 'builder' && activeTool === 'delete') { + handlePointerClick(wallAsset); } }} onPointerMissed={() => { @@ -204,6 +229,25 @@ function WallAssetInstance({ wallAsset }: { wallAsset: WallAsset }) { setSelectedWallAsset(null); } }} + onPointerEnter={(e) => { + if (!toggleView) { + e.stopPropagation(); + let currentObject = e.object as THREE.Object3D; + while (currentObject) { + if (currentObject.name === "Scene") { + break; + } + currentObject = currentObject.parent as THREE.Object3D; + } + handlePointerOver(wallAsset, currentObject); + } + }} + onPointerOut={(e) => { + if (!toggleView) { + e.stopPropagation(); + handlePointerOut(wallAsset); + } + }} userData={wallAsset} > diff --git a/app/src/modules/builder/wallAsset/Instances/wallAssetInstances.tsx b/app/src/modules/builder/wallAsset/Instances/wallAssetInstances.tsx index 3c5fbdd..581dfe7 100644 --- a/app/src/modules/builder/wallAsset/Instances/wallAssetInstances.tsx +++ b/app/src/modules/builder/wallAsset/Instances/wallAssetInstances.tsx @@ -5,54 +5,9 @@ import WallAssetInstance from './Instances/wallAssetInstance'; function WallAssetInstances() { const { wallAssetStore } = useSceneContext(); - const { wallAssets, setWallAssets } = wallAssetStore(); + const { wallAssets } = wallAssetStore(); const { toggleView } = useToggleView(); - useEffect(() => { - setWallAssets([ - { - "modelName": "shutter_open", - "modelUuid": "23bf68d5-10c9-4cd0-807f-80e5016707b5", - "wallUuid": "7fc7984d-6d62-4cec-afaa-289673dcce43", - "wallAssetType": "fixed-move", - "assetId": "274f6c32aa861255c2947bea", - "position": [ - -13.748701534598418, - 0, - 20.112805679001355 - ], - "rotation": [ - 0, - -3.141592653589793, - 0 - ], - "isLocked": false, - "isVisible": true, - "opacity": 1 - }, - { - "modelName": "window", - "modelUuid": "5d73f98e-6f17-42b0-a53c-9a2c4472f2be", - "wallUuid": "7fc7984d-6d62-4cec-afaa-289673dcce43", - "wallAssetType": "free-move", - "assetId": "e44a85ff2021392f4c4a03f4", - "position": [ - -4.522713460474861, - 4.189202463272018, - 20.112805679001355 - ], - "rotation": [ - 0, - -3.141592653589793, - 0 - ], - "isLocked": false, - "isVisible": true, - "opacity": 1 - } - ]) - }, []) - useEffect(() => { // console.log('wallAssets: ', wallAssets); }, [wallAssets]) diff --git a/app/src/modules/builder/wallAsset/wallAssetGroup.tsx b/app/src/modules/builder/wallAsset/wallAssetGroup.tsx index ac55d01..f9d1290 100644 --- a/app/src/modules/builder/wallAsset/wallAssetGroup.tsx +++ b/app/src/modules/builder/wallAsset/wallAssetGroup.tsx @@ -1,5 +1,5 @@ import { useEffect } from 'react'; -import { useToggleView } from '../../../store/builder/store'; +import { useActiveTool, useToggleView } from '../../../store/builder/store'; import { useBuilderStore } from '../../../store/builder/useBuilderStore'; import { useVersionContext } from '../version/versionContext'; import { useSceneContext } from '../../scene/sceneContext'; @@ -10,8 +10,9 @@ import WallAssetInstances from './Instances/wallAssetInstances' function WallAssetGroup() { const { togglView } = useToggleView(); - const { setSelectedFloorAsset } = useBuilderStore(); + const { setSelectedFloorAsset, setDeletableWallAsset } = useBuilderStore(); const { activeModule } = useModuleStore(); + const { activeTool } = useActiveTool(); const { selectedVersionStore } = useVersionContext(); const { selectedVersion } = selectedVersionStore(); const { wallAssetStore } = useSceneContext(); @@ -22,7 +23,8 @@ function WallAssetGroup() { if (togglView || activeModule !== 'builder') { setSelectedFloorAsset(null); } - }, [togglView, activeModule]) + setDeletableWallAsset(null); + }, [togglView, activeModule, activeTool]) return ( <> diff --git a/app/src/modules/builder/zone/zoneGroup.tsx b/app/src/modules/builder/zone/zoneGroup.tsx index 46bddb7..c44bf09 100644 --- a/app/src/modules/builder/zone/zoneGroup.tsx +++ b/app/src/modules/builder/zone/zoneGroup.tsx @@ -1,5 +1,5 @@ import { useEffect } from 'react'; -import { useToggleView } from '../../../store/builder/store'; +import { useActiveTool, useToggleView } from '../../../store/builder/store'; import { useBuilderStore } from '../../../store/builder/useBuilderStore'; import { useVersionContext } from '../version/versionContext'; import { useSceneContext } from '../../scene/sceneContext'; @@ -14,6 +14,7 @@ function ZoneGroup() { const { togglView } = useToggleView(); const { setSelectedZone } = useBuilderStore(); const { activeModule } = useModuleStore(); + const { activeTool } = useActiveTool(); const { selectedVersionStore } = useVersionContext(); const { selectedVersion } = selectedVersionStore(); const { zoneStore } = useSceneContext(); @@ -24,7 +25,7 @@ function ZoneGroup() { if (togglView || activeModule !== 'builder') { setSelectedZone(null); } - }, [togglView, activeModule]) + }, [togglView, activeModule, activeTool]) useEffect(() => { if (projectId && selectedVersion) { diff --git a/app/src/modules/scene/postProcessing/postProcessing.tsx b/app/src/modules/scene/postProcessing/postProcessing.tsx index e6ec6a2..6c2f8d6 100644 --- a/app/src/modules/scene/postProcessing/postProcessing.tsx +++ b/app/src/modules/scene/postProcessing/postProcessing.tsx @@ -15,7 +15,7 @@ export default function PostProcessing() { const { selectedWallItem } = useSelectedWallItem(); const { selectedFloorItem } = useSelectedFloorItem(); const { selectedEventSphere } = useSelectedEventSphere(); - const { selectedAisle, selectedWall, selectedDecal, selectedFloor, selectedWallAsset } = useBuilderStore(); + const { selectedAisle, selectedWall, selectedDecal, selectedFloor, selectedWallAsset, deletableWallAsset } = useBuilderStore(); function flattenChildren(children: any[]) { const allChildren: any[] = []; @@ -52,6 +52,10 @@ export default function PostProcessing() { // console.log('selectedWallAsset: ', selectedWallAsset); }, [selectedWallAsset]) + useEffect(() => { + // console.log('deletableWallAsset: ', deletableWallAsset); + }, [deletableWallAsset]) + return ( )} + {deletableWallAsset && ( + + )} {selectedAisle && ( void; + setDeletableWallAsset: (asset: Object3D | null) => void; // Setters - Floor Asset setSelectedFloorAsset: (asset: Object3D | null) => void; @@ -113,6 +115,7 @@ export const useBuilderStore = create()( hoveredLine: null, selectedWallAsset: null, + deletableWallAsset: null, selectedFloorAsset: null, @@ -180,6 +183,12 @@ export const useBuilderStore = create()( }); }, + setDeletableWallAsset(asset: Object3D | null) { + set((state) => { + state.deletableWallAsset = asset; + }); + }, + // === Setters: Floor Asset === setSelectedFloorAsset(asset: Object3D | null) {