import { useEffect, useRef, useState } from 'react'; import * as THREE from 'three'; import { useFrame, useThree } from '@react-three/fiber'; import { Html } from '@react-three/drei'; import { useBuilderStore } from '../../../../store/builder/useBuilderStore'; import { useActiveLayer, useToolMode, useToggleView } from '../../../../store/builder/store'; import { useDirectionalSnapping } from '../../point/helpers/useDirectionalSnapping'; import { usePointSnapping } from '../../point/helpers/usePointSnapping'; import * as Constants from '../../../../types/world/worldConstants'; import ReferenceLine from '../../line/reference/referenceLine'; interface ReferenceWallProps { tempPoints: Point[]; } function ReferenceWall({ tempPoints }: Readonly) { const { wallHeight, wallThickness, setSnappedPosition, setSnappedPoint } = useBuilderStore(); const { pointer, raycaster, camera } = useThree(); const { toolMode } = useToolMode(); const { toggleView } = useToggleView(); const { activeLayer } = useActiveLayer(); const plane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0); const finalPosition = useRef<[number, number, number] | null>(null); const [tempWall, setTempWall] = useState(null); const [currentPosition, setCurrentPosition] = useState<[number, number, number]>(tempPoints[0]?.position); const directionalSnap = useDirectionalSnapping(currentPosition, tempPoints[0]?.position || null); const { checkSnapForWall } = usePointSnapping({ uuid: 'temp-wall', pointType: 'Wall', position: directionalSnap.position || [0, 0, 0] }); useFrame(() => { if (toolMode === 'Wall' && toggleView && tempPoints.length === 1) { raycaster.setFromCamera(pointer, camera); const intersectionPoint = new THREE.Vector3(); raycaster.ray.intersectPlane(plane, intersectionPoint); setCurrentPosition([intersectionPoint.x, intersectionPoint.y, intersectionPoint.z]); if (intersectionPoint) { const snapped = checkSnapForWall([intersectionPoint.x, intersectionPoint.y, intersectionPoint.z]); if (snapped.isSnapped && snapped.snappedPoint) { finalPosition.current = snapped.position; setSnappedPosition(snapped.position); setSnappedPoint(snapped.snappedPoint); } else if (directionalSnap.isSnapped) { finalPosition.current = directionalSnap.position; setSnappedPosition(directionalSnap.position); setSnappedPoint(null); } else { finalPosition.current = [intersectionPoint.x, intersectionPoint.y, intersectionPoint.z]; setSnappedPosition(null); setSnappedPoint(null); } if (!finalPosition.current) return; const wallPoints: [Point, Point] = [ tempPoints[0], { pointUuid: 'temp-point', pointType: 'Wall', position: finalPosition.current, layer: activeLayer, } ]; setTempWall({ wallUuid: 'temp-wall', points: wallPoints, outSideMaterial: 'default', inSideMaterial: 'default', wallThickness: wallThickness, wallHeight: wallHeight, }) } } else if (tempWall !== null) { setTempWall(null); } }); useEffect(() => { setTempWall(null); }, [toolMode, toggleView, tempPoints.length, wallHeight, wallThickness]); if (!tempWall) return null; const renderWall = () => { return ( ) }; const textPosition = new THREE.Vector3().addVectors(new THREE.Vector3(...tempWall.points[0].position), new THREE.Vector3(...tempWall.points[1].position)).divideScalar(2); const distance = new THREE.Vector3(...tempWall.points[0].position).distanceTo(new THREE.Vector3(...tempWall.points[1].position)); const rendertext = () => { return ( <> {toggleView && (
{distance.toFixed(2)} m
)} ) } return ( {renderWall()} {rendertext()} ); } export default ReferenceWall;