import * as THREE from 'three'; import * as Constants from '../../../types/world/worldConstants'; import { useRef, useState, useEffect, useMemo } from 'react'; import { useDeletePointOrLine, useToolMode } from '../../../store/builder/store'; import { DragControls } from '@react-three/drei'; import { useAisleStore } from '../../../store/builder/useAisleStore'; import { useThree } from '@react-three/fiber'; import { useBuilderStore } from '../../../store/builder/useBuilderStore'; function Point({ point, userData }: { readonly point: Point, readonly userData: any }) { const materialRef = useRef(null); const { raycaster, camera, pointer } = useThree(); const plane = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 1, 0), 0), []); const [isHovered, setIsHovered] = useState(false); const { toolMode } = useToolMode(); const { setPosition, removePoint } = useAisleStore(); const { hoveredPoint, setHoveredPoint } = useBuilderStore(); const { deletePointOrLine } = useDeletePointOrLine(); const boxScale: [number, number, number] = Constants.pointConfig.boxScale; const defaultInnerColor = Constants.pointConfig.defaultInnerColor; const defaultOuterColor = Constants.pointConfig.aisleOuterColor; const defaultDeleteColor = Constants.pointConfig.deleteColor; useEffect(() => { if (materialRef.current && (toolMode === 'move' || deletePointOrLine)) { let innerColor; let outerColor; if (isHovered) { innerColor = deletePointOrLine ? defaultDeleteColor : defaultOuterColor; outerColor = deletePointOrLine ? defaultDeleteColor : defaultOuterColor; } else { innerColor = defaultInnerColor; outerColor = defaultOuterColor; } materialRef.current.uniforms.uInnerColor.value.set(innerColor); materialRef.current.uniforms.uOuterColor.value.set(outerColor); materialRef.current.uniformsNeedUpdate = true; } else if (materialRef.current && toolMode !== 'move') { materialRef.current.uniforms.uInnerColor.value.set(defaultInnerColor); materialRef.current.uniforms.uOuterColor.value.set(defaultOuterColor); materialRef.current.uniformsNeedUpdate = true; } }, [isHovered, defaultInnerColor, defaultOuterColor, toolMode, deletePointOrLine, defaultDeleteColor]); const uniforms = useMemo(() => ({ uOuterColor: { value: new THREE.Color(defaultOuterColor) }, uInnerColor: { value: new THREE.Color(defaultInnerColor) }, }), [defaultInnerColor, defaultInnerColor]); const handleDrag = (point: Point) => { if (toolMode === 'move' && isHovered) { raycaster.setFromCamera(pointer, camera); const intersectionPoint = new THREE.Vector3(); const position = raycaster.ray.intersectPlane(plane, intersectionPoint); if (userData.pointType === 'Aisle') { if (position) { setPosition(point.uuid, [position.x, position.y, position.z]); } } } } const handleDragEnd = (point: Point) => { if (deletePointOrLine) return; console.log('point: ', point); } const handlePointClick = (point: Point) => { if (deletePointOrLine) { const removedAisles = removePoint(point.uuid); if (removedAisles.length > 0) { setHoveredPoint(null); console.log(removedAisles); } } } useEffect(() => { if (hoveredPoint && hoveredPoint.uuid !== point.uuid) { setIsHovered(false); } }, [hoveredPoint]) if (!point) { return null; } return ( { handleDrag(point) }} onDragEnd={() => { handleDragEnd(point) }} > { handlePointClick(point); }} onPointerOver={() => { if (!hoveredPoint) { setHoveredPoint(point); setIsHovered(true) } }} onPointerOut={() => { if (hoveredPoint && hoveredPoint.uuid === point.uuid) { setHoveredPoint(null); } setIsHovered(false) }} userData={userData} > borderThickness && vUv.x < 1.0 - borderThickness && vUv.y > borderThickness && vUv.y < 1.0 - borderThickness) { gl_FragColor = vec4(uInnerColor, 1.0); // Inner square } else { gl_FragColor = vec4(uOuterColor, 1.0); // Border } } ` } /> ); } export default Point;