feat: Integrate active tool management across builder components; add deletableWallAsset state and related functionality
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<GLTF["scene"] | null>(null);
|
||||
const [boundingBox, setBoundingBox] = useState<THREE.Box3 | null>(null);
|
||||
const groupRef = useRef<THREE.Group>(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 && (
|
||||
<mesh
|
||||
onPointerDown={(e) => {
|
||||
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}
|
||||
>
|
||||
<primitive userData={wallAsset} object={gltfScene} />
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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 (
|
||||
<>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 (
|
||||
<EffectComposer autoClear={false}>
|
||||
<N8AO
|
||||
@@ -78,6 +82,21 @@ export default function PostProcessing() {
|
||||
xRay={true}
|
||||
/>
|
||||
)}
|
||||
{deletableWallAsset && (
|
||||
<Outline
|
||||
selection={flattenChildren(deletableWallAsset.children)}
|
||||
selectionLayer={10}
|
||||
width={2000}
|
||||
blendFunction={BlendFunction.ALPHA}
|
||||
edgeStrength={5}
|
||||
resolutionScale={2}
|
||||
pulseSpeed={0}
|
||||
visibleEdgeColor={CONSTANTS.outlineConfig.assetDeleteColor}
|
||||
hiddenEdgeColor={CONSTANTS.outlineConfig.assetDeleteColor}
|
||||
blur={true}
|
||||
xRay={true}
|
||||
/>
|
||||
)}
|
||||
{selectedAisle && (
|
||||
<Outline
|
||||
selection={flattenChildren(selectedAisle.children)}
|
||||
|
||||
@@ -11,6 +11,7 @@ interface BuilderState {
|
||||
|
||||
// Wall Asset
|
||||
selectedWallAsset: Object3D | null;
|
||||
deletableWallAsset: Object3D | null;
|
||||
|
||||
// Floor Asset
|
||||
selectedFloorAsset: Object3D | null;
|
||||
@@ -59,6 +60,7 @@ interface BuilderState {
|
||||
|
||||
// Setters - Wall Asset
|
||||
setSelectedWallAsset: (asset: Object3D | null) => void;
|
||||
setDeletableWallAsset: (asset: Object3D | null) => void;
|
||||
|
||||
// Setters - Floor Asset
|
||||
setSelectedFloorAsset: (asset: Object3D | null) => void;
|
||||
@@ -113,6 +115,7 @@ export const useBuilderStore = create<BuilderState>()(
|
||||
hoveredLine: null,
|
||||
|
||||
selectedWallAsset: null,
|
||||
deletableWallAsset: null,
|
||||
|
||||
selectedFloorAsset: null,
|
||||
|
||||
@@ -180,6 +183,12 @@ export const useBuilderStore = create<BuilderState>()(
|
||||
});
|
||||
},
|
||||
|
||||
setDeletableWallAsset(asset: Object3D | null) {
|
||||
set((state) => {
|
||||
state.deletableWallAsset = asset;
|
||||
});
|
||||
},
|
||||
|
||||
// === Setters: Floor Asset ===
|
||||
|
||||
setSelectedFloorAsset(asset: Object3D | null) {
|
||||
|
||||
Reference in New Issue
Block a user