import React, { useEffect, useState, useRef } from "react"; import * as THREE from "three"; import { useFrame } from "@react-three/fiber"; import { NavMeshQuery } from "@recast-navigation/core"; import { Line } from "@react-three/drei"; // Define interface for props interface PathNavigatorProps { navMesh: any; selectedPoints: any; } export default function PathNavigator({ navMesh, selectedPoints, }: PathNavigatorProps) { const [path, setPath] = useState<[number, number, number][]>([]); const progressRef = useRef(0); const meshRef = useRef(null); useEffect(() => { if (selectedPoints.length === 2 && navMesh) { const [start, end] = selectedPoints; if (!start || !end) return; const navMeshQuery = new NavMeshQuery(navMesh); const { path: computedPath } = navMeshQuery.computePath(start, end); if (computedPath.length > 0) { setPath(computedPath.map(({ x, y, z }) => [x, y + 0.1, z])); progressRef.current = 0; } } }, [selectedPoints, navMesh]); useFrame((_, delta) => { if (path.length > 1 && meshRef.current) { const speed = 3; progressRef.current += delta * speed; let totalDistance = 0; const distances: number[] = []; for (let i = 0; i < path.length - 1; i++) { const start = new THREE.Vector3(...path[i]); const end = new THREE.Vector3(...path[i + 1]); const segmentDistance = start.distanceTo(end); distances.push(segmentDistance); totalDistance += segmentDistance; } let coveredDistance = progressRef.current; let accumulatedDistance = 0; let index = 0; while ( index < distances.length && coveredDistance > accumulatedDistance + distances[index] ) { accumulatedDistance += distances[index]; index++; } if (index < distances.length) { const start = new THREE.Vector3(...path[index]); const end = new THREE.Vector3(...path[index + 1]); const segmentDistance = distances[index]; const t = (coveredDistance - accumulatedDistance) / segmentDistance; const position = start.clone().lerp(end, t); // Use clone() to avoid mutating the original vector meshRef.current.position.copy(position); const direction = new THREE.Vector3() .subVectors(end, start) .normalize(); const targetQuaternion = new THREE.Quaternion().setFromUnitVectors( new THREE.Vector3(0, 0, 1), direction ); meshRef.current.quaternion.slerp(targetQuaternion, 0.1); } else { progressRef.current = totalDistance; } } }); return ( <> {/* {path.length > 0 && } */} {path.length > 0 && ( 0 ? path[0] : [0, 0.1, 0]}> )} ); }