Refactor Model and Models components to streamline rendering logic; update distanceWorker for improved distance calculations and rendering conditions.
This commit is contained in:
@@ -3,8 +3,8 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
|||||||
import { retrieveGLTF, storeGLTF } from '../../../../../utils/indexDB/idbUtils';
|
import { retrieveGLTF, storeGLTF } from '../../../../../utils/indexDB/idbUtils';
|
||||||
import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
||||||
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
|
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
|
||||||
import { ThreeEvent, useFrame, useThree } from '@react-three/fiber';
|
import { ThreeEvent, useThree } from '@react-three/fiber';
|
||||||
import { useActiveTool, useDeletableFloorItem, useLimitDistance, useRenderDistance, useSelectedAssets, useSelectedFloorItem, useSocketStore, useToggleView, useToolMode } from '../../../../../store/builder/store';
|
import { useActiveTool, useDeletableFloorItem, useSelectedAssets, useSelectedFloorItem, useSocketStore, useToggleView, useToolMode } from '../../../../../store/builder/store';
|
||||||
import { AssetBoundingBox } from '../../functions/assetBoundingBox';
|
import { AssetBoundingBox } from '../../functions/assetBoundingBox';
|
||||||
import { CameraControls } from '@react-three/drei';
|
import { CameraControls } from '@react-three/drei';
|
||||||
import useModuleStore, { useSubModuleStore } from '../../../../../store/useModuleStore';
|
import useModuleStore, { useSubModuleStore } from '../../../../../store/useModuleStore';
|
||||||
@@ -21,12 +21,11 @@ import { upsertProductOrEventApi } from '../../../../../services/simulation/prod
|
|||||||
import { getAssetIksApi } from '../../../../../services/simulation/ik/getAssetIKs';
|
import { getAssetIksApi } from '../../../../../services/simulation/ik/getAssetIKs';
|
||||||
import { ModelAnimator } from './animator/modelAnimator';
|
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 url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||||
const savedTheme: string = localStorage.getItem("theme") || "light";
|
const savedTheme: string = localStorage.getItem("theme") || "light";
|
||||||
const { camera, controls, gl, scene } = useThree();
|
const { controls, gl } = useThree();
|
||||||
const { activeTool } = useActiveTool();
|
const { activeTool } = useActiveTool();
|
||||||
const { toolMode } = useToolMode();
|
const { toolMode } = useToolMode();
|
||||||
const { toggleView } = useToggleView();
|
const { toggleView } = useToggleView();
|
||||||
@@ -44,13 +43,10 @@ function Model({ asset }: { readonly asset: Asset }) {
|
|||||||
const { socket } = useSocketStore();
|
const { socket } = useSocketStore();
|
||||||
const { deletableFloorItem, setDeletableFloorItem } = useDeletableFloorItem();
|
const { deletableFloorItem, setDeletableFloorItem } = useDeletableFloorItem();
|
||||||
const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem();
|
const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem();
|
||||||
const { limitDistance } = useLimitDistance();
|
|
||||||
const { renderDistance } = useRenderDistance();
|
|
||||||
const leftDrag = useRef(false);
|
const leftDrag = useRef(false);
|
||||||
const isLeftMouseDown = useRef(false);
|
const isLeftMouseDown = useRef(false);
|
||||||
const rightDrag = useRef(false);
|
const rightDrag = useRef(false);
|
||||||
const isRightMouseDown = useRef(false);
|
const isRightMouseDown = useRef(false);
|
||||||
const [isRendered, setIsRendered] = useState(false);
|
|
||||||
const [gltfScene, setGltfScene] = useState<GLTF["scene"] | null>(null);
|
const [gltfScene, setGltfScene] = useState<GLTF["scene"] | null>(null);
|
||||||
const [boundingBox, setBoundingBox] = useState<THREE.Box3 | null>(null);
|
const [boundingBox, setBoundingBox] = useState<THREE.Box3 | null>(null);
|
||||||
const [isSelected, setIsSelected] = useState(false);
|
const [isSelected, setIsSelected] = useState(false);
|
||||||
@@ -61,7 +57,6 @@ function Model({ asset }: { readonly asset: Asset }) {
|
|||||||
const { userId, organization } = getUserData();
|
const { userId, organization } = getUserData();
|
||||||
const { projectId } = useParams();
|
const { projectId } = useParams();
|
||||||
const { selectedAssets } = useSelectedAssets();
|
const { selectedAssets } = useSelectedAssets();
|
||||||
const intervalRef = useRef<NodeJS.Timeout | null>(null);
|
|
||||||
|
|
||||||
const updateBackend = (
|
const updateBackend = (
|
||||||
productName: string,
|
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) => {
|
const handleDblClick = (asset: Asset) => {
|
||||||
if (asset) {
|
if (asset) {
|
||||||
if (activeTool === "cursor" && boundingBox && groupRef.current && activeModule === 'builder') {
|
if (activeTool === "cursor" && boundingBox && groupRef.current && activeModule === 'builder') {
|
||||||
|
|||||||
@@ -1,17 +1,45 @@
|
|||||||
import Model from './model/model';
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { useThree } from '@react-three/fiber';
|
import { useThree, useFrame } from "@react-three/fiber";
|
||||||
|
import { Vector3 } from "three";
|
||||||
import { CameraControls } from '@react-three/drei';
|
import { CameraControls } from '@react-three/drei';
|
||||||
import { Vector3 } from 'three';
|
import { useLimitDistance, useRenderDistance, useSelectedFloorItem } from '../../../../store/builder/store';
|
||||||
import { useSelectedFloorItem } from '../../../../store/builder/store';
|
|
||||||
import { useSelectedAsset } from '../../../../store/simulation/useSimulationStore';
|
import { useSelectedAsset } from '../../../../store/simulation/useSimulationStore';
|
||||||
import { useSceneContext } from '../../../scene/sceneContext';
|
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() {
|
function Models() {
|
||||||
const { controls } = useThree();
|
const { controls, camera } = useThree();
|
||||||
const { assetStore } = useSceneContext();
|
const { assetStore } = useSceneContext();
|
||||||
const { assets } = assetStore();
|
const { assets } = assetStore();
|
||||||
const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem();
|
const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem();
|
||||||
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
|
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, });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<group
|
<group
|
||||||
@@ -28,11 +56,11 @@ function Models() {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{assets.map((asset) =>
|
{assets.map((asset) => (
|
||||||
<Model key={asset.modelUuid} asset={asset} />
|
<Model key={asset.modelUuid} asset={asset} isRendered={renderMap[asset.modelUuid] ?? false} />
|
||||||
)}
|
))}
|
||||||
</group>
|
</group>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Models
|
export default Models;
|
||||||
@@ -1,12 +1,16 @@
|
|||||||
import { Vector3 } from "three";
|
import { Vector3 } from "three";
|
||||||
|
|
||||||
onmessage = function (e) {
|
onmessage = function (e) {
|
||||||
const { modelUuid, assetPosition, cameraPosition, limitDistance, renderDistance, isRendered } = e.data;
|
const { modelUuid, assetPosition, cameraPosition, limitDistance, renderDistance, isRendered, } = e.data;
|
||||||
|
|
||||||
if (limitDistance && assetPosition) {
|
const assetVec = new Vector3(assetPosition.x, assetPosition.y, assetPosition.z);
|
||||||
if (!isRendered && new Vector3(assetPosition.x, assetPosition.y, assetPosition.z).distanceTo(cameraPosition) <= renderDistance) {
|
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 });
|
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 });
|
postMessage({ shouldRender: false, modelUuid });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -14,4 +18,4 @@ onmessage = function (e) {
|
|||||||
postMessage({ shouldRender: true, modelUuid });
|
postMessage({ shouldRender: true, modelUuid });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user