import { useEffect, useMemo, useRef, useState } from "react"; import { useFrame, useThree } from "@react-three/fiber"; import * as THREE from "three"; import { useSelectedZoneStore } from "../../../store/useZoneStore"; import { useEditPosition, usezonePosition, usezoneTarget } from "../../../store/store"; export default function ZoneCentreTarget() { const { selectedZone, setSelectedZone } = useSelectedZoneStore(); const [previousZoneCentre, setPreviousZoneCentre] = useState(null); const sphereRef = useRef(null); const { camera, controls }: any = useThree(); const { zonePosition, setZonePosition } = usezonePosition(); const { zoneTarget, setZoneTarget } = usezoneTarget(); const { Edit, setEdit } = useEditPosition(); useEffect(() => { if ( selectedZone.zoneViewPortTarget && JSON.stringify(previousZoneCentre) !== JSON.stringify(selectedZone.zoneViewPortTarget) ) { setPreviousZoneCentre(selectedZone.zoneViewPortTarget); } }, [selectedZone.zoneViewPortTarget, previousZoneCentre]); const centrePoint = useMemo(() => { if (!previousZoneCentre || !selectedZone.zoneViewPortTarget) return null; return previousZoneCentre.map((value, index) => (value + selectedZone.zoneViewPortTarget[index]) / 2 ); }, [previousZoneCentre, selectedZone.zoneViewPortTarget]); useEffect(() => { if (selectedZone.zoneName !== "") { if (sphereRef.current) { sphereRef.current.position.set(selectedZone.zoneViewPortTarget[0], selectedZone.zoneViewPortTarget[1], selectedZone.zoneViewPortTarget[2]); } if (centrePoint) { if (centrePoint.length > 0) { let camPosition = new THREE.Vector3(...selectedZone.zoneViewPortPosition); let CamTarget = new THREE.Vector3(...selectedZone.zoneViewPortTarget); const direction = new THREE.Vector3().subVectors(CamTarget, camPosition).normalize(); const worldUp = new THREE.Vector3(0, 0, 1); const right = new THREE.Vector3().crossVectors(worldUp, direction).normalize(); const up = new THREE.Vector3().crossVectors(direction, right).normalize(); const offsetPosition = up.clone().multiplyScalar(20); camPosition.add(offsetPosition); const setCam = async () => { controls.setLookAt(centrePoint[0], 100, centrePoint[2], ...centrePoint, true); setTimeout(() => { controls?.setLookAt( ...camPosition.toArray(), selectedZone.zoneViewPortTarget[0], selectedZone.zoneViewPortTarget[1], selectedZone.zoneViewPortTarget[2], true ); }, 400) }; setCam(); } else { let camPosition = new THREE.Vector3(...selectedZone.zoneViewPortPosition); let CamTarget = new THREE.Vector3(...selectedZone.zoneViewPortTarget); const direction = new THREE.Vector3().subVectors(CamTarget, camPosition).normalize(); const worldUp = new THREE.Vector3(0, 0, 1); const right = new THREE.Vector3().crossVectors(worldUp, direction).normalize(); const up = new THREE.Vector3().crossVectors(direction, right).normalize(); const offsetPosition = up.clone().multiplyScalar(20); camPosition.add(offsetPosition); const setCam = async () => { controls?.setLookAt( ...camPosition.toArray(), selectedZone.zoneViewPortTarget[0], selectedZone.zoneViewPortTarget[1], selectedZone.zoneViewPortTarget[2], true ); }; setCam(); } } } }, [selectedZone.zoneViewPortTarget]); useFrame(() => { if (Edit) { setZonePosition([controls.getPosition().x, controls.getPosition().y, controls.getPosition().z]) setZoneTarget([controls.getTarget().x, controls.getTarget().y, controls.getTarget().z]) } }) return ( <> ); }