added event handler for wall asset
This commit is contained in:
@@ -0,0 +1,213 @@
|
|||||||
|
import * as THREE from 'three';
|
||||||
|
import { useCallback, useEffect, useRef } from 'react';
|
||||||
|
import { ThreeEvent, useThree } from '@react-three/fiber';
|
||||||
|
import { useParams } from 'react-router-dom';
|
||||||
|
import { useActiveTool, useSocketStore, useToggleView } from '../../../../../../store/builder/store';
|
||||||
|
import useModuleStore from '../../../../../../store/useModuleStore';
|
||||||
|
import { useSceneContext } from '../../../../../scene/sceneContext';
|
||||||
|
import { useBuilderStore } from '../../../../../../store/builder/useBuilderStore';
|
||||||
|
import { useVersionContext } from '../../../../version/versionContext';
|
||||||
|
import { getUserData } from '../../../../../../functions/getUserData';
|
||||||
|
import closestPointOnLineSegment from '../../../../line/helpers/getClosestPointOnLineSegment';
|
||||||
|
import { upsertWallAssetApi } from '../../../../../../services/factoryBuilder/asset/wallAsset/upsertWallAssetApi';
|
||||||
|
import { deleteWallAssetApi } from '../../../../../../services/factoryBuilder/asset/wallAsset/deleteWallAssetApi';
|
||||||
|
|
||||||
|
export function useWallAssetEventHandler({
|
||||||
|
wallAsset,
|
||||||
|
groupRef,
|
||||||
|
wall,
|
||||||
|
}: {
|
||||||
|
wallAsset: WallAsset;
|
||||||
|
groupRef: React.RefObject<THREE.Group>;
|
||||||
|
wall: Wall | undefined;
|
||||||
|
}) {
|
||||||
|
const { socket } = useSocketStore();
|
||||||
|
const { raycaster, pointer, camera, scene, controls, gl } = useThree();
|
||||||
|
const { wallAssetStore } = useSceneContext();
|
||||||
|
const { updateWallAsset, removeWallAsset, getWallAssetById } = wallAssetStore();
|
||||||
|
const { toggleView } = useToggleView();
|
||||||
|
const { activeTool } = useActiveTool();
|
||||||
|
const { activeModule } = useModuleStore();
|
||||||
|
const { selectedWallAsset, setSelectedWallAsset, setDeletableWallAsset, deletableWallAsset } = useBuilderStore();
|
||||||
|
const { selectedVersionStore } = useVersionContext();
|
||||||
|
const { selectedVersion } = selectedVersionStore();
|
||||||
|
const { userId, organization } = getUserData();
|
||||||
|
const { projectId } = useParams();
|
||||||
|
|
||||||
|
const draggingRef = useRef(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const canvasElement = gl.domElement;
|
||||||
|
|
||||||
|
const onPointerUp = (e: PointerEvent) => {
|
||||||
|
if (draggingRef.current) {
|
||||||
|
draggingRef.current = false;
|
||||||
|
if (controls) {
|
||||||
|
(controls as any).enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedWallAsset) {
|
||||||
|
const updatedWallAsset = getWallAssetById(wallAsset.modelUuid);
|
||||||
|
|
||||||
|
if (projectId && updatedWallAsset) {
|
||||||
|
if (!socket?.connected) {
|
||||||
|
|
||||||
|
// API
|
||||||
|
|
||||||
|
upsertWallAssetApi(projectId, selectedVersion?.versionId || '', updatedWallAsset);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// SOCKET
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
wallAssetData: updatedWallAsset,
|
||||||
|
projectId: projectId,
|
||||||
|
versionId: selectedVersion?.versionId || '',
|
||||||
|
userId: userId,
|
||||||
|
organization: organization
|
||||||
|
}
|
||||||
|
socket.emit('v1:wall-asset:add', data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPointerMove = (e: any) => {
|
||||||
|
if (!draggingRef.current || !wall || !selectedWallAsset) return;
|
||||||
|
if (controls) {
|
||||||
|
(controls as any).enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer.x = (e.clientX / window.innerWidth) * 2 - 1;
|
||||||
|
pointer.y = -(e.clientY / window.innerHeight) * 2 + 1;
|
||||||
|
|
||||||
|
raycaster.setFromCamera(pointer, camera);
|
||||||
|
const intersects = raycaster.intersectObjects(scene.children, true);
|
||||||
|
const intersect = intersects.find((i: any) => i.object.name.includes('WallReference'));
|
||||||
|
|
||||||
|
if (intersect?.object.userData.wallUuid) {
|
||||||
|
const newPoint = closestPointOnLineSegment(
|
||||||
|
new THREE.Vector3(intersect.point.x, 0, intersect.point.z),
|
||||||
|
new THREE.Vector3(...intersect.object.userData.points[0].position),
|
||||||
|
new THREE.Vector3(...intersect.object.userData.points[1].position)
|
||||||
|
);
|
||||||
|
|
||||||
|
const wallRotation = intersect.object.rotation.clone();
|
||||||
|
|
||||||
|
updateWallAsset(wallAsset.modelUuid, {
|
||||||
|
wallUuid: intersect.object.userData.wallUuid,
|
||||||
|
position: [newPoint.x, wallAsset.wallAssetType === 'fixedMove' ? 0 : intersect.point.y, newPoint.z],
|
||||||
|
rotation: [wallRotation.x, wallRotation.y, wallRotation.z],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (selectedWallAsset && !toggleView && activeModule === 'builder') {
|
||||||
|
canvasElement.addEventListener('mousemove', onPointerMove);
|
||||||
|
canvasElement.addEventListener('pointerup', onPointerUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
canvasElement.removeEventListener('mousemove', onPointerMove);
|
||||||
|
canvasElement.removeEventListener('pointerup', onPointerUp);
|
||||||
|
};
|
||||||
|
}, [gl, camera, toggleView, activeModule, selectedWallAsset, socket, wall, wallAsset]);
|
||||||
|
|
||||||
|
const handlePointerEnter = useCallback((evt: ThreeEvent<MouseEvent>) => {
|
||||||
|
if (!toggleView) {
|
||||||
|
evt.stopPropagation();
|
||||||
|
let currentObject = evt.object;
|
||||||
|
while (currentObject) {
|
||||||
|
if (currentObject.userData.wallUuid) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentObject = currentObject.parent as THREE.Object3D;
|
||||||
|
}
|
||||||
|
if (activeTool === "delete" && activeModule === 'builder') {
|
||||||
|
if (deletableWallAsset && deletableWallAsset.userData.modelUuid === wallAsset.modelUuid) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
setDeletableWallAsset(currentObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [activeTool, activeModule, deletableWallAsset, toggleView]);
|
||||||
|
|
||||||
|
const handlePointerLeave = useCallback((evt: ThreeEvent<MouseEvent>) => {
|
||||||
|
if (!toggleView) {
|
||||||
|
evt.stopPropagation();
|
||||||
|
if (evt.intersections.length === 0 && activeTool === "delete" && deletableWallAsset && deletableWallAsset.userData.modelUuid === wallAsset.modelUuid) {
|
||||||
|
setDeletableWallAsset(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [activeTool, deletableWallAsset, toggleView]);
|
||||||
|
|
||||||
|
const handlePointerDown = useCallback((e: ThreeEvent<MouseEvent>) => {
|
||||||
|
if (!toggleView && activeModule === 'builder' && selectedWallAsset && selectedWallAsset.userData.modelUuid === wallAsset.modelUuid) {
|
||||||
|
draggingRef.current = true;
|
||||||
|
e.stopPropagation();
|
||||||
|
setSelectedWallAsset(groupRef.current);
|
||||||
|
if (controls) {
|
||||||
|
(controls as any).enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [toggleView, activeModule, selectedWallAsset, wallAsset]);
|
||||||
|
|
||||||
|
const handleClick = useCallback((e: ThreeEvent<MouseEvent>) => {
|
||||||
|
if (!toggleView && activeModule === 'builder' && activeTool !== 'delete') {
|
||||||
|
if (e.object) {
|
||||||
|
e.stopPropagation();
|
||||||
|
let currentObject = e.object;
|
||||||
|
while (currentObject) {
|
||||||
|
if (currentObject.userData.wallUuid) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentObject = currentObject.parent as THREE.Object3D;
|
||||||
|
}
|
||||||
|
setSelectedWallAsset(currentObject);
|
||||||
|
}
|
||||||
|
} else if (!toggleView && activeModule === 'builder' && activeTool === 'delete') {
|
||||||
|
if (activeTool === 'delete' && deletableWallAsset && deletableWallAsset.userData.modelUuid === wallAsset.modelUuid) {
|
||||||
|
const removedWallAsset = removeWallAsset(wallAsset.modelUuid);
|
||||||
|
|
||||||
|
if (projectId && removedWallAsset) {
|
||||||
|
if (!socket?.connected) {
|
||||||
|
|
||||||
|
// API
|
||||||
|
|
||||||
|
deleteWallAssetApi(projectId, selectedVersion?.versionId || '', removedWallAsset.modelUuid, removedWallAsset.wallUuid);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// SOCKET
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
projectId: projectId,
|
||||||
|
versionId: selectedVersion?.versionId || '',
|
||||||
|
userId: userId,
|
||||||
|
organization: organization,
|
||||||
|
modelUuid: removedWallAsset.modelUuid,
|
||||||
|
wallUuid: removedWallAsset.wallUuid
|
||||||
|
}
|
||||||
|
socket.emit('v1:wall-asset:delete', data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [toggleView, activeModule, activeTool, wallAsset, deletableWallAsset, socket]);
|
||||||
|
|
||||||
|
const handlePointerMissed = useCallback(() => {
|
||||||
|
if (selectedWallAsset && selectedWallAsset.userData.modelUuid === wallAsset.modelUuid) {
|
||||||
|
setSelectedWallAsset(null);
|
||||||
|
}
|
||||||
|
}, [selectedWallAsset, wallAsset]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
handlePointerDown,
|
||||||
|
handleClick,
|
||||||
|
handlePointerMissed,
|
||||||
|
handlePointerEnter,
|
||||||
|
handlePointerLeave,
|
||||||
|
draggingRef
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,42 +1,22 @@
|
|||||||
import * as THREE from 'three';
|
import * as THREE from 'three';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { ThreeEvent, useThree } from '@react-three/fiber';
|
|
||||||
import { Base, Geometry, Subtraction } from '@react-three/csg';
|
import { Base, Geometry, Subtraction } from '@react-three/csg';
|
||||||
import { retrieveGLTF, storeGLTF } from '../../../../../utils/indexDB/idbUtils';
|
|
||||||
import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
||||||
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
|
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
|
||||||
import useModuleStore from '../../../../../store/useModuleStore';
|
import { retrieveGLTF, storeGLTF } from '../../../../../utils/indexDB/idbUtils';
|
||||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||||
import { useBuilderStore } from '../../../../../store/builder/useBuilderStore';
|
|
||||||
import { useActiveTool, useSocketStore, useToggleView } from '../../../../../store/builder/store';
|
|
||||||
import { useParams } from 'react-router-dom';
|
|
||||||
import { useVersionContext } from '../../../version/versionContext';
|
|
||||||
import { getUserData } from '../../../../../functions/getUserData';
|
|
||||||
import closestPointOnLineSegment from '../../../line/helpers/getClosestPointOnLineSegment';
|
|
||||||
|
|
||||||
import { upsertWallAssetApi } from '../../../../../services/factoryBuilder/asset/wallAsset/upsertWallAssetApi';
|
import { useWallAssetEventHandler } from './eventHandler/useWallAssetEventHandler';
|
||||||
import { deleteWallAssetApi } from '../../../../../services/factoryBuilder/asset/wallAsset/deleteWallAssetApi';
|
|
||||||
|
|
||||||
function WallAssetInstance({ wallAsset }: { readonly wallAsset: WallAsset }) {
|
function WallAssetInstance({ wallAsset }: { readonly wallAsset: WallAsset }) {
|
||||||
const url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
const url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||||
const { socket } = useSocketStore();
|
const { wallStore } = useSceneContext();
|
||||||
const { raycaster, pointer, camera, scene, controls, gl } = useThree();
|
|
||||||
const { wallStore, wallAssetStore } = useSceneContext();
|
|
||||||
const { walls, getWallById } = wallStore();
|
const { walls, getWallById } = wallStore();
|
||||||
const { updateWallAsset, removeWallAsset, getWallAssetById } = wallAssetStore();
|
|
||||||
const { toggleView } = useToggleView();
|
|
||||||
const { activeTool } = useActiveTool();
|
|
||||||
const { activeModule } = useModuleStore();
|
|
||||||
const { selectedWallAsset, setSelectedWallAsset, setDeletableWallAsset, deletableWallAsset } = useBuilderStore();
|
|
||||||
const [gltfScene, setGltfScene] = useState<GLTF["scene"] | null>(null);
|
const [gltfScene, setGltfScene] = useState<GLTF["scene"] | null>(null);
|
||||||
const [boundingBox, setBoundingBox] = useState<THREE.Box3 | null>(null);
|
const [boundingBox, setBoundingBox] = useState<THREE.Box3 | null>(null);
|
||||||
const groupRef = useRef<THREE.Group>(null);
|
const groupRef = useRef<THREE.Group>(null);
|
||||||
const wall = useMemo(() => getWallById(wallAsset.wallUuid), [getWallById, wallAsset.wallUuid, walls]);
|
const wall = useMemo(() => getWallById(wallAsset.wallUuid), [getWallById, wallAsset.wallUuid, walls]);
|
||||||
const draggingRef = useRef(false);
|
const { handlePointerDown, handleClick, handlePointerMissed, handlePointerEnter, handlePointerLeave } = useWallAssetEventHandler({ wallAsset, groupRef, wall });
|
||||||
const { selectedVersionStore } = useVersionContext();
|
|
||||||
const { selectedVersion } = selectedVersionStore();
|
|
||||||
const { userId, organization } = getUserData();
|
|
||||||
const { projectId } = useParams();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loader = new GLTFLoader();
|
const loader = new GLTFLoader();
|
||||||
@@ -112,130 +92,6 @@ function WallAssetInstance({ wallAsset }: { readonly wallAsset: WallAsset }) {
|
|||||||
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const canvasElement = gl.domElement;
|
|
||||||
|
|
||||||
const onPointerUp = (e: PointerEvent) => {
|
|
||||||
if (draggingRef.current) {
|
|
||||||
draggingRef.current = false;
|
|
||||||
if (controls) {
|
|
||||||
(controls as any).enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedWallAsset) {
|
|
||||||
const updatedWallAsset = getWallAssetById(wallAsset.modelUuid);
|
|
||||||
|
|
||||||
if (projectId && updatedWallAsset) {
|
|
||||||
if (!socket?.connected) {
|
|
||||||
|
|
||||||
// API
|
|
||||||
|
|
||||||
upsertWallAssetApi(projectId, selectedVersion?.versionId || '', updatedWallAsset);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// SOCKET
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
wallAssetData: updatedWallAsset,
|
|
||||||
projectId: projectId,
|
|
||||||
versionId: selectedVersion?.versionId || '',
|
|
||||||
userId: userId,
|
|
||||||
organization: organization
|
|
||||||
}
|
|
||||||
|
|
||||||
socket.emit('v1:wall-asset:add', data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onPointerMove = (e: any) => {
|
|
||||||
if (!draggingRef.current || !wall || !selectedWallAsset) return;
|
|
||||||
if (controls) {
|
|
||||||
(controls as any).enabled = false;
|
|
||||||
}
|
|
||||||
pointer.x = (e.clientX / window.innerWidth) * 2 - 1;
|
|
||||||
pointer.y = -(e.clientY / window.innerHeight) * 2 + 1;
|
|
||||||
|
|
||||||
raycaster.setFromCamera(pointer, camera);
|
|
||||||
const intersects = raycaster.intersectObjects(scene.children, true);
|
|
||||||
const intersect = intersects.find((i: any) => i.object.name.includes('WallReference'));
|
|
||||||
|
|
||||||
if (intersect?.object.userData.wallUuid) {
|
|
||||||
const newPoint = closestPointOnLineSegment(
|
|
||||||
new THREE.Vector3(intersect.point.x, 0, intersect.point.z),
|
|
||||||
new THREE.Vector3(...intersect.object.userData.points[0].position),
|
|
||||||
new THREE.Vector3(...intersect.object.userData.points[1].position)
|
|
||||||
);
|
|
||||||
|
|
||||||
const wallRotation = intersect.object.rotation.clone();
|
|
||||||
|
|
||||||
updateWallAsset(wallAsset.modelUuid, {
|
|
||||||
wallUuid: intersect.object.userData.wallUuid,
|
|
||||||
position: [newPoint.x, wallAsset.wallAssetType === 'fixedMove' ? 0 : intersect.point.y, newPoint.z],
|
|
||||||
rotation: [wallRotation.x, wallRotation.y, wallRotation.z],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (selectedWallAsset && !toggleView && activeModule === 'builder') {
|
|
||||||
canvasElement.addEventListener('mousemove', onPointerMove);
|
|
||||||
canvasElement.addEventListener('pointerup', onPointerUp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
canvasElement.removeEventListener('mousemove', onPointerMove);
|
|
||||||
canvasElement.removeEventListener('pointerup', onPointerUp);
|
|
||||||
};
|
|
||||||
|
|
||||||
}, [gl, camera, toggleView, activeModule, selectedWallAsset, socket])
|
|
||||||
|
|
||||||
const handlePointerClick = useCallback((wallAsset: WallAsset) => {
|
|
||||||
if (activeTool === 'delete' && deletableWallAsset && deletableWallAsset.userData.modelUuid === wallAsset.modelUuid) {
|
|
||||||
const removedWallAsset = removeWallAsset(wallAsset.modelUuid);
|
|
||||||
|
|
||||||
if (projectId && removedWallAsset) {
|
|
||||||
if (!socket?.connected) {
|
|
||||||
|
|
||||||
// API
|
|
||||||
|
|
||||||
deleteWallAssetApi(projectId, selectedVersion?.versionId || '', removedWallAsset.modelUuid, removedWallAsset.wallUuid);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// SOCKET
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
projectId: projectId,
|
|
||||||
versionId: selectedVersion?.versionId || '',
|
|
||||||
userId: userId,
|
|
||||||
organization: organization,
|
|
||||||
modelUuid: removedWallAsset.modelUuid,
|
|
||||||
wallUuid: removedWallAsset.wallUuid
|
|
||||||
}
|
|
||||||
|
|
||||||
socket.emit('v1:wall-asset:delete', data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [activeTool, activeModule, deletableWallAsset, socket])
|
|
||||||
|
|
||||||
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((evt: ThreeEvent<MouseEvent>, wallAsset: WallAsset) => {
|
|
||||||
if (evt.intersections.length === 0 && activeTool === "delete" && deletableWallAsset && deletableWallAsset.userData.modelUuid === wallAsset.modelUuid) {
|
|
||||||
setDeletableWallAsset(null);
|
|
||||||
}
|
|
||||||
}, [activeTool, deletableWallAsset]);
|
|
||||||
|
|
||||||
if (!gltfScene || !boundingBox) { return null }
|
if (!gltfScene || !boundingBox) { return null }
|
||||||
const size = new THREE.Vector3();
|
const size = new THREE.Vector3();
|
||||||
boundingBox.getSize(size);
|
boundingBox.getSize(size);
|
||||||
@@ -259,57 +115,11 @@ function WallAssetInstance({ wallAsset }: { readonly wallAsset: WallAsset }) {
|
|||||||
</Subtraction>
|
</Subtraction>
|
||||||
{gltfScene && (
|
{gltfScene && (
|
||||||
<mesh
|
<mesh
|
||||||
onPointerDown={(e) => {
|
onPointerDown={handlePointerDown}
|
||||||
if (!toggleView && activeModule === 'builder' && selectedWallAsset && selectedWallAsset.userData.modelUuid === wallAsset.modelUuid) {
|
onClick={handleClick}
|
||||||
draggingRef.current = true;
|
onPointerMissed={handlePointerMissed}
|
||||||
e.stopPropagation();
|
onPointerEnter={handlePointerEnter}
|
||||||
setSelectedWallAsset(groupRef.current);
|
onPointerLeave={handlePointerLeave}
|
||||||
if (controls) {
|
|
||||||
(controls as any).enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onClick={(e) => {
|
|
||||||
if (!toggleView && activeModule === 'builder' && activeTool !== 'delete') {
|
|
||||||
if (e.object) {
|
|
||||||
e.stopPropagation();
|
|
||||||
let currentObject = e.object as THREE.Object3D;
|
|
||||||
while (currentObject) {
|
|
||||||
if (currentObject.userData.wallUuid) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
currentObject = currentObject.parent as THREE.Object3D;
|
|
||||||
}
|
|
||||||
setSelectedWallAsset(currentObject);
|
|
||||||
}
|
|
||||||
} else if (!toggleView && activeModule === 'builder' && activeTool === 'delete') {
|
|
||||||
handlePointerClick(wallAsset);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onPointerMissed={() => {
|
|
||||||
if (selectedWallAsset && selectedWallAsset.userData.modelUuid === wallAsset.modelUuid) {
|
|
||||||
setSelectedWallAsset(null);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onPointerEnter={(e) => {
|
|
||||||
if (!toggleView) {
|
|
||||||
e.stopPropagation();
|
|
||||||
let currentObject = e.object as THREE.Object3D;
|
|
||||||
while (currentObject) {
|
|
||||||
if (currentObject.userData.wallUuid) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
currentObject = currentObject.parent as THREE.Object3D;
|
|
||||||
}
|
|
||||||
handlePointerOver(wallAsset, currentObject);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onPointerLeave={(e) => {
|
|
||||||
if (!toggleView) {
|
|
||||||
e.stopPropagation();
|
|
||||||
handlePointerOut(e, wallAsset);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
userData={wallAsset}
|
userData={wallAsset}
|
||||||
>
|
>
|
||||||
<primitive userData={wallAsset} object={gltfScene} />
|
<primitive userData={wallAsset} object={gltfScene} />
|
||||||
|
|||||||
Reference in New Issue
Block a user