import { useEffect, useRef, useState } from "react"; import { useThree, useFrame } from "@react-three/fiber"; import { Vector3 } from "three"; import { CameraControls } from '@react-three/drei'; import { useLimitDistance, useRenderDistance, useSelectedFloorItem } from '../../../../store/builder/store'; import { useSelectedAsset } from '../../../../store/simulation/useSimulationStore'; import { useSceneContext } from '../../../scene/sceneContext'; import Model from './model/model'; import { GLTFLoader } from "three/examples/jsm/Addons"; const distanceWorker = new Worker(new URL("../../../../services/factoryBuilder/webWorkers/distanceWorker.js", import.meta.url)); function Models({ loader }: { loader: GLTFLoader }) { const { controls, camera } = useThree(); const { assetStore } = useSceneContext(); const { assets } = assetStore(); const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem(); const { selectedAsset, clearSelectedAsset } = useSelectedAsset(); const { limitDistance } = useLimitDistance(); const { renderDistance } = useRenderDistance(); const [renderMap, setRenderMap] = useState>({}); const cameraPos = useRef(new Vector3()); useEffect(() => { distanceWorker.onmessage = (e) => { const { shouldRender, modelUuid } = e.data; setRenderMap((prev) => { if (prev[modelUuid] === shouldRender) return prev; return { ...prev, [modelUuid]: shouldRender }; }); }; }, []); useFrame(() => { camera.getWorldPosition(cameraPos.current); for (const asset of assets) { const isRendered = renderMap[asset.modelUuid] ?? false; distanceWorker.postMessage({ modelUuid: asset.modelUuid, assetPosition: { x: asset.position[0], y: asset.position[1], z: asset.position[2], }, cameraPosition: cameraPos.current, limitDistance, renderDistance, isRendered, }); } }); return ( { e.stopPropagation(); if (selectedFloorItem) { const target = (controls as CameraControls).getTarget(new Vector3()); (controls as CameraControls).setTarget(target.x, 0, target.z, true); setSelectedFloorItem(null); } if (selectedAsset) { clearSelectedAsset(); } }} > {assets.map((asset) => ( ))} ); } export default Models;