2025-03-26 12:58:14 +00:00
|
|
|
// import React, { useEffect, useState } from "react";
|
|
|
|
// import { init as initRecastNavigation } from "@recast-navigation/core";
|
|
|
|
// import { generateSoloNavMesh } from "@recast-navigation/generators";
|
|
|
|
// import { DebugDrawer, getPositionsAndIndices } from "@recast-navigation/three";
|
|
|
|
// import { useThree } from "@react-three/fiber";
|
|
|
|
// import * as THREE from "three";
|
|
|
|
// interface RawNavMesh {
|
|
|
|
// ptr: number; // Replace `number` with the actual type if known
|
|
|
|
// }
|
|
|
|
|
|
|
|
// interface NavMesh {
|
|
|
|
// raw: RawNavMesh;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // Update the MeshState interface to use the correct type
|
|
|
|
// interface MeshState {
|
|
|
|
// setNavMesh: React.Dispatch<React.SetStateAction<NavMesh | null>>;
|
|
|
|
// }
|
|
|
|
// export default function NavMeshDetails({ setNavMesh }: MeshState) {
|
|
|
|
// const { scene } = useThree();
|
|
|
|
// useEffect(() => {
|
|
|
|
// const initializeNavMesh = async () => {
|
|
|
|
// try {
|
|
|
|
// // Initialize Recast Navigation
|
|
|
|
// await initRecastNavigation();
|
|
|
|
|
|
|
|
// // Extract meshes from the scene
|
|
|
|
// // Extract meshes from the scene
|
|
|
|
// const meshes = scene?.children
|
|
|
|
// .filter((child) => child.name === "Meshes")
|
|
|
|
// .flatMap((mesh) => mesh.children);
|
|
|
|
|
|
|
|
// if (!meshes || meshes.length === 0) {
|
|
|
|
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // Filter and process only Mesh objects
|
|
|
|
// const meshObjects = meshes.filter(
|
|
|
|
// (
|
|
|
|
// child
|
|
|
|
// ): child is THREE.Mesh<
|
|
|
|
// THREE.BufferGeometry,
|
|
|
|
// THREE.Material | THREE.Material[]
|
|
|
|
// > => child instanceof THREE.Mesh
|
|
|
|
// );
|
|
|
|
|
|
|
|
// if (meshObjects.length === 0) {
|
|
|
|
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // Get positions and indices from the meshes
|
|
|
|
// const [positions, indices] = getPositionsAndIndices(meshObjects);
|
|
|
|
|
|
|
|
// // Generate navigation mesh
|
|
|
|
// const cs = 0.05;
|
|
|
|
// const ch = 0.05;
|
|
|
|
// const walkableRadius = 0.87;
|
|
|
|
// const { success, navMesh } = generateSoloNavMesh(positions, indices, {
|
|
|
|
// cs,
|
|
|
|
// ch,
|
|
|
|
// walkableRadius: Math.round(walkableRadius / ch),
|
|
|
|
// });
|
|
|
|
|
|
|
|
// if (!success || !navMesh) {
|
|
|
|
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // Log and update the navigation mesh
|
|
|
|
|
|
|
|
//
|
|
|
|
// setNavMesh(navMesh);
|
|
|
|
|
|
|
|
// // Draw the debug visualization
|
|
|
|
// const debugDrawer = new DebugDrawer();
|
|
|
|
// debugDrawer.drawNavMesh(navMesh);
|
|
|
|
// // scene.add(debugDrawer); // Uncomment if you want to add the debug drawer to the scene
|
|
|
|
// } catch (error) {
|
|
|
|
|
|
|
|
// }
|
|
|
|
// };
|
|
|
|
|
|
|
|
// initializeNavMesh();
|
|
|
|
// }, [setNavMesh, scene]);
|
|
|
|
|
|
|
|
// return null;
|
|
|
|
// }
|
|
|
|
import React, { useEffect } from "react";
|
|
|
|
import { init as initRecastNavigation } from "@recast-navigation/core";
|
|
|
|
import { generateSoloNavMesh } from "@recast-navigation/generators";
|
|
|
|
import { DebugDrawer, getPositionsAndIndices } from "@recast-navigation/three";
|
|
|
|
import { useThree } from "@react-three/fiber";
|
|
|
|
import * as THREE from "three";
|
|
|
|
|
|
|
|
// Import the NavMesh type from the library
|
|
|
|
import { NavMesh as RecastNavMesh } from "@recast-navigation/core";
|
|
|
|
|
|
|
|
// Define the state type based on the library's NavMesh type
|
|
|
|
interface MeshState {
|
|
|
|
setNavMesh: React.Dispatch<React.SetStateAction<RecastNavMesh | null>>;
|
|
|
|
}
|
|
|
|
|
|
|
|
export default function NavMeshDetails({ setNavMesh }: MeshState) {
|
|
|
|
const { scene } = useThree();
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
const initializeNavMesh = async () => {
|
|
|
|
try {
|
|
|
|
// Initialize Recast Navigation
|
|
|
|
await initRecastNavigation();
|
|
|
|
|
|
|
|
// Extract meshes from the scene
|
|
|
|
const meshes = scene?.children
|
|
|
|
.filter((child) => child.name === "Meshes")
|
|
|
|
.flatMap((mesh) => mesh.children);
|
|
|
|
|
|
|
|
if (!meshes || meshes.length === 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Filter and process only Mesh objects
|
|
|
|
const meshObjects = meshes.filter(
|
|
|
|
(
|
|
|
|
child
|
|
|
|
): child is THREE.Mesh<
|
|
|
|
THREE.BufferGeometry,
|
|
|
|
THREE.Material | THREE.Material[]
|
|
|
|
> => child instanceof THREE.Mesh
|
|
|
|
);
|
|
|
|
|
|
|
|
if (meshObjects.length === 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get positions and indices from the meshes
|
|
|
|
const [positions, indices] = getPositionsAndIndices(meshObjects);
|
|
|
|
|
|
|
|
// Generate navigation mesh
|
|
|
|
const cs = 0.05;
|
|
|
|
const ch = 0.05;
|
|
|
|
const walkableRadius = 0.95;
|
|
|
|
const { success, navMesh } = generateSoloNavMesh(positions, indices, {
|
|
|
|
cs,
|
|
|
|
ch,
|
|
|
|
walkableRadius: Math.round(walkableRadius / ch),
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!success || !navMesh) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Log and update the navigation mesh
|
|
|
|
setNavMesh(navMesh); // Now compatible with the library's NavMesh type
|
|
|
|
// Draw the debug visualization
|
|
|
|
const debugDrawer = new DebugDrawer();
|
|
|
|
debugDrawer.drawNavMesh(navMesh);
|
2025-03-26 13:10:28 +00:00
|
|
|
// scene.add(debugDrawer); // Uncomment if you want to add the debug drawer to the scene
|
2025-03-26 12:58:14 +00:00
|
|
|
} catch (error) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
initializeNavMesh();
|
|
|
|
}, [setNavMesh, scene]);
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|