import * as THREE from "three"; import * as CONSTANTS from '../../../../types/world/worldConstants'; import * as Types from "../../../../types/world/worldTypes"; function createAndMoveReferenceLine( point: Types.Vector3, cursorPosition: Types.Vector3, isSnapped: Types.RefBoolean, ispreSnapped: Types.RefBoolean, line: Types.RefLine, setRefTextUpdate: Types.NumberIncrementState, floorPlanGroup: Types.RefGroup, ReferenceLineMesh: Types.RefMesh, LineCreated: Types.RefBoolean, Tube: Types.RefTubeGeometry, anglesnappedPoint: Types.RefVector3, isAngleSnapped: Types.RefBoolean ): void { ////////// Creating new and maintaining the old reference line and also snap the reference line based on its angle ////////// const startPoint = point; const dx = cursorPosition.x - startPoint.x; const dz = cursorPosition.z - startPoint.z; let angle = Math.atan2(dz, dx); angle = (angle * 180) / Math.PI; angle = (angle + 360) % 360; const snapAngles = [0, 90, 180, 270, 360]; const snapThreshold = 2.5; const closestSnapAngle = snapAngles.reduce((prev, curr) => Math.abs(curr - angle) < Math.abs(prev - angle) ? curr : prev ); if (!isSnapped.current && !ispreSnapped.current && line.current.length > 0) { if (Math.abs(closestSnapAngle - angle) <= snapThreshold) { const snappedAngleRad = (closestSnapAngle * Math.PI) / 180; const distance = Math.sqrt(dx * dx + dz * dz); const snappedX = startPoint.x + distance * Math.cos(snappedAngleRad); const snappedZ = startPoint.z + distance * Math.sin(snappedAngleRad); if ( cursorPosition.distanceTo( new THREE.Vector3(snappedX, 0.01, snappedZ) ) < 2 ) { cursorPosition.set(snappedX, 0.01, snappedZ); isAngleSnapped.current = true; anglesnappedPoint.current = new THREE.Vector3( snappedX, 0.01, snappedZ ); } else { isAngleSnapped.current = false; anglesnappedPoint.current = null; } } else { isAngleSnapped.current = false; anglesnappedPoint.current = null; } } else { isAngleSnapped.current = false; anglesnappedPoint.current = null; } if (!LineCreated.current) { setRefTextUpdate((prevUpdate) => prevUpdate - 1); const path = new THREE.LineCurve3(startPoint, cursorPosition); Tube.current = new THREE.TubeGeometry(path, CONSTANTS.lineConfig.tubularSegments, CONSTANTS.lineConfig.radius, CONSTANTS.lineConfig.radialSegments, false); const material = new THREE.MeshBasicMaterial({ color: CONSTANTS.lineConfig.helperColor }); ReferenceLineMesh.current = new THREE.Mesh(Tube.current, material); ReferenceLineMesh.current.name = CONSTANTS.lineConfig.referenceName; ReferenceLineMesh.current.userData = { linePoints: { startPoint, cursorPosition }, }; floorPlanGroup.current?.add(ReferenceLineMesh.current); LineCreated.current = true; } else { if (ReferenceLineMesh.current) { const path = new THREE.LineCurve3(startPoint, new THREE.Vector3(cursorPosition.x, 0.01, cursorPosition.z)); Tube.current = new THREE.TubeGeometry(path, CONSTANTS.lineConfig.tubularSegments, CONSTANTS.lineConfig.radius, CONSTANTS.lineConfig.radialSegments, false); if (ReferenceLineMesh.current) { ReferenceLineMesh.current.userData = { linePoints: { startPoint, cursorPosition }, }; ReferenceLineMesh.current.geometry.dispose(); ReferenceLineMesh.current.geometry = Tube.current; } } } } export default createAndMoveReferenceLine;