Files
Dwinzo_Demo/app/src/modules/builder/asset/models/models.tsx

67 lines
2.7 KiB
TypeScript
Raw Normal View History

import { useEffect, useRef, useState } from "react";
import { useThree, useFrame } from "@react-three/fiber";
import { Vector3 } from "three";
2025-06-10 15:28:23 +05:30
import { CameraControls } from '@react-three/drei';
import { useLimitDistance, useRenderDistance, useSelectedFloorItem } from '../../../../store/builder/store';
2025-06-10 15:28:23 +05:30
import { useSelectedAsset } from '../../../../store/simulation/useSimulationStore';
2025-06-23 09:37:53 +05:30
import { useSceneContext } from '../../../scene/sceneContext';
2025-06-10 15:28:23 +05:30
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();
2025-06-23 09:37:53 +05:30
const { assetStore } = useSceneContext();
const { assets } = assetStore();
2025-06-10 15:28:23 +05:30
const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem();
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
const { limitDistance } = useLimitDistance();
const { renderDistance } = useRenderDistance();
const [renderMap, setRenderMap] = useState<Record<string, boolean>>({});
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, });
}
});
2025-06-10 15:28:23 +05:30
return (
<group
name='Asset Group'
onPointerMissed={(e) => {
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) => (
<Model key={asset.modelUuid} asset={asset} isRendered={renderMap[asset.modelUuid] ?? false} loader={loader} />
))}
2025-06-10 15:28:23 +05:30
</group>
);
2025-06-10 15:28:23 +05:30
}
export default Models;