From 7d29228541b5e4a407c1839f26c34122aba9b6e7 Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Mon, 28 Jul 2025 17:34:36 +0530 Subject: [PATCH] Refactor Model and Models components to streamline rendering logic; update distanceWorker for improved distance calculations and rendering conditions. --- .../builder/asset/models/model/model.tsx | 28 ++--------- .../modules/builder/asset/models/models.tsx | 48 +++++++++++++++---- .../webWorkers/distanceWorker.js | 14 ++++-- 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/app/src/modules/builder/asset/models/model/model.tsx b/app/src/modules/builder/asset/models/model/model.tsx index ffeffe0..1679b10 100644 --- a/app/src/modules/builder/asset/models/model/model.tsx +++ b/app/src/modules/builder/asset/models/model/model.tsx @@ -3,8 +3,8 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import { retrieveGLTF, storeGLTF } from '../../../../../utils/indexDB/idbUtils'; import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'; -import { ThreeEvent, useFrame, useThree } from '@react-three/fiber'; -import { useActiveTool, useDeletableFloorItem, useLimitDistance, useRenderDistance, useSelectedAssets, useSelectedFloorItem, useSocketStore, useToggleView, useToolMode } from '../../../../../store/builder/store'; +import { ThreeEvent, useThree } from '@react-three/fiber'; +import { useActiveTool, useDeletableFloorItem, useSelectedAssets, useSelectedFloorItem, useSocketStore, useToggleView, useToolMode } from '../../../../../store/builder/store'; import { AssetBoundingBox } from '../../functions/assetBoundingBox'; import { CameraControls } from '@react-three/drei'; import useModuleStore, { useSubModuleStore } from '../../../../../store/useModuleStore'; @@ -21,12 +21,11 @@ import { upsertProductOrEventApi } from '../../../../../services/simulation/prod import { getAssetIksApi } from '../../../../../services/simulation/ik/getAssetIKs'; import { ModelAnimator } from './animator/modelAnimator'; -const distanceWorker = new Worker(new URL("../../../../../services/factoryBuilder/webWorkers/distanceWorker.js", import.meta.url)); -function Model({ asset }: { readonly asset: Asset }) { +function Model({ asset, isRendered }: { readonly asset: Asset, isRendered: boolean }) { const url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`; const savedTheme: string = localStorage.getItem("theme") || "light"; - const { camera, controls, gl, scene } = useThree(); + const { controls, gl } = useThree(); const { activeTool } = useActiveTool(); const { toolMode } = useToolMode(); const { toggleView } = useToggleView(); @@ -44,13 +43,10 @@ function Model({ asset }: { readonly asset: Asset }) { const { socket } = useSocketStore(); const { deletableFloorItem, setDeletableFloorItem } = useDeletableFloorItem(); const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem(); - const { limitDistance } = useLimitDistance(); - const { renderDistance } = useRenderDistance(); const leftDrag = useRef(false); const isLeftMouseDown = useRef(false); const rightDrag = useRef(false); const isRightMouseDown = useRef(false); - const [isRendered, setIsRendered] = useState(false); const [gltfScene, setGltfScene] = useState(null); const [boundingBox, setBoundingBox] = useState(null); const [isSelected, setIsSelected] = useState(false); @@ -61,7 +57,6 @@ function Model({ asset }: { readonly asset: Asset }) { const { userId, organization } = getUserData(); const { projectId } = useParams(); const { selectedAssets } = useSelectedAssets(); - const intervalRef = useRef(null); const updateBackend = ( productName: string, @@ -189,21 +184,6 @@ function Model({ asset }: { readonly asset: Asset }) { }, []); - useFrame(() => { - const assetPosition = scene.getObjectByProperty("uuid", asset.modelUuid)?.position; - if (limitDistance && assetPosition) { - if (!isRendered && assetPosition.distanceTo(camera.position) <= renderDistance) { - setIsRendered(true); - } else if (isRendered && assetPosition.distanceTo(camera.position) > renderDistance) { - setIsRendered(false); - } - } else { - if (!isRendered) { - setIsRendered(true); - } - } - }) - const handleDblClick = (asset: Asset) => { if (asset) { if (activeTool === "cursor" && boundingBox && groupRef.current && activeModule === 'builder') { diff --git a/app/src/modules/builder/asset/models/models.tsx b/app/src/modules/builder/asset/models/models.tsx index a7bd752..cdfa21b 100644 --- a/app/src/modules/builder/asset/models/models.tsx +++ b/app/src/modules/builder/asset/models/models.tsx @@ -1,17 +1,45 @@ -import Model from './model/model'; -import { useThree } from '@react-three/fiber'; +import { useEffect, useRef, useState } from "react"; +import { useThree, useFrame } from "@react-three/fiber"; +import { Vector3 } from "three"; import { CameraControls } from '@react-three/drei'; -import { Vector3 } from 'three'; -import { useSelectedFloorItem } from '../../../../store/builder/store'; +import { useLimitDistance, useRenderDistance, useSelectedFloorItem } from '../../../../store/builder/store'; import { useSelectedAsset } from '../../../../store/simulation/useSimulationStore'; import { useSceneContext } from '../../../scene/sceneContext'; +import Model from './model/model'; + +const distanceWorker = new Worker(new URL("../../../../services/factoryBuilder/webWorkers/distanceWorker.js", import.meta.url)); + function Models() { - const { controls } = useThree(); + 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 ( - {assets.map((asset) => - - )} + {assets.map((asset) => ( + + ))} - ) + ); } -export default Models \ No newline at end of file +export default Models; \ No newline at end of file diff --git a/app/src/services/factoryBuilder/webWorkers/distanceWorker.js b/app/src/services/factoryBuilder/webWorkers/distanceWorker.js index 84ba747..44111c5 100644 --- a/app/src/services/factoryBuilder/webWorkers/distanceWorker.js +++ b/app/src/services/factoryBuilder/webWorkers/distanceWorker.js @@ -1,12 +1,16 @@ import { Vector3 } from "three"; onmessage = function (e) { - const { modelUuid, assetPosition, cameraPosition, limitDistance, renderDistance, isRendered } = e.data; + const { modelUuid, assetPosition, cameraPosition, limitDistance, renderDistance, isRendered, } = e.data; - if (limitDistance && assetPosition) { - if (!isRendered && new Vector3(assetPosition.x, assetPosition.y, assetPosition.z).distanceTo(cameraPosition) <= renderDistance) { + const assetVec = new Vector3(assetPosition.x, assetPosition.y, assetPosition.z); + const cameraVec = new Vector3(cameraPosition.x, cameraPosition.y, cameraPosition.z); + const distance = assetVec.distanceTo(cameraVec); + + if (limitDistance) { + if (!isRendered && distance <= renderDistance) { postMessage({ shouldRender: true, modelUuid }); - } else if (isRendered && new Vector3(assetPosition.x, assetPosition.y, assetPosition.z).distanceTo(cameraPosition) > renderDistance) { + } else if (isRendered && distance > renderDistance) { postMessage({ shouldRender: false, modelUuid }); } } else { @@ -14,4 +18,4 @@ onmessage = function (e) { postMessage({ shouldRender: true, modelUuid }); } } -}; \ No newline at end of file +};