import { useEffect, useMemo, useRef, useState } from "react"; import { Html } from "@react-three/drei"; import * as THREE from "three"; import { useToggleView, useZonePoints, } from "../../../../store/builder/store"; import { getZonesApi } from "../../../../services/factoryBuilder/zones/getZonesApi"; import * as CONSTANTS from "../../../../types/world/worldConstants"; import * as turf from "@turf/turf"; import { useSelectedZoneStore } from "../../../../store/visualization/useZoneStore"; const ZoneDuplicate = ({ projectId }: { projectId: string }) => { const [zones, setZones] = useState([]); const { setZonePoints } = useZonePoints(); const { selectedZone } = useSelectedZoneStore(); const { toggleView } = useToggleView(); const groupsRef = useRef(); const zoneMaterial = useMemo( () => new THREE.ShaderMaterial({ side: THREE.DoubleSide, vertexShader: ` varying vec2 vUv; void main(){ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); vUv = uv; } `, fragmentShader: ` varying vec2 vUv; uniform vec3 uOuterColor; void main(){ float alpha = 1.0 - vUv.y; gl_FragColor = vec4(uOuterColor, alpha); } `, uniforms: { uOuterColor: { value: new THREE.Color(CONSTANTS.zoneConfig.color) }, }, transparent: true, depthWrite: false, }), [] ); useEffect(() => { const fetchZones = async () => { const email = localStorage.getItem("email"); if (!email) return; const organization = email.split("@")[1].split(".")[0]; const data = await getZonesApi(organization, projectId); if (data.length > 0) { const fetchedZones = data.map((zone: any) => ({ zoneUuid: zone.zoneUuid, zoneName: zone.zoneName, points: zone.points, viewPortCenter: zone.viewPortCenter, viewPortposition: zone.viewPortposition, layer: zone.layer, })); setZones(fetchedZones); const fetchedPoints = data.flatMap((zone: any) => zone.points.slice(0, 4).map((point: [number, number, number]) => new THREE.Vector3(...point)) ); setZonePoints(fetchedPoints); } }; fetchZones(); }, []); return ( {zones.map((zone: any) => ( {zone.points .slice(0, -1) .map((point: [number, number, number], index: number) => { const nextPoint = zone.points[index + 1]; const point1 = new THREE.Vector3(point[0], point[1], point[2]); const point2 = new THREE.Vector3( nextPoint[0], nextPoint[1], nextPoint[2] ); const planeWidth = point1.distanceTo(point2); const planeHeight = CONSTANTS.zoneConfig.height; const midpoint = new THREE.Vector3( (point1.x + point2.x) / 2, CONSTANTS.zoneConfig.height / 2 + (zone.layer - 1) * CONSTANTS.zoneConfig.height, (point1.z + point2.z) / 2 ); const angle = Math.atan2( point2.z - point1.z, point2.x - point1.x ); return ( ); })} {!toggleView && (() => { const points3D = zone.points || []; const coords2D = points3D.map((p: any) => [p[0], p[2]]); // Ensure the polygon is closed if ( coords2D.length >= 4 && (coords2D[0][0] !== coords2D[coords2D.length - 1][0] || coords2D[0][1] !== coords2D[coords2D.length - 1][1]) ) { coords2D.push(coords2D[0]); } if (coords2D.length < 4) return null; const polygon = turf.polygon([coords2D]); const center2D = turf.center(polygon).geometry.coordinates; // Calculate the average Y value const sumY = points3D.reduce( (sum: number, p: any) => sum + p[1], 0 ); const avgY = points3D.length > 0 ? sumY / points3D.length : 0; const htmlPosition: [number, number, number] = [ center2D[0], avgY + (CONSTANTS.zoneConfig.height || 0) + 1.5, center2D[1], ]; return (
{zone.zoneName}
); })()}
))}
); }; export default ZoneDuplicate;