Refactor asset loading and distance calculation logic for improved performance and clarity
This commit is contained in:
@@ -16,12 +16,7 @@ import { getUserData } from "../../../functions/getUserData";
|
|||||||
import { useSceneContext } from "../../scene/sceneContext";
|
import { useSceneContext } from "../../scene/sceneContext";
|
||||||
import { useVersionContext } from "../version/versionContext";
|
import { useVersionContext } from "../version/versionContext";
|
||||||
|
|
||||||
const gltfLoaderWorker = new Worker(
|
const gltfLoaderWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js", import.meta.url));
|
||||||
new URL(
|
|
||||||
"../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js",
|
|
||||||
import.meta.url
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
function AssetsGroup({ plane }: { readonly plane: RefMesh }) {
|
function AssetsGroup({ plane }: { readonly plane: RefMesh }) {
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
|
|||||||
@@ -17,13 +17,16 @@ import { useSceneContext } from '../../../../scene/sceneContext';
|
|||||||
import { useVersionContext } from '../../../version/versionContext';
|
import { useVersionContext } from '../../../version/versionContext';
|
||||||
import { SkeletonUtils } from 'three-stdlib';
|
import { SkeletonUtils } from 'three-stdlib';
|
||||||
import { useAnimationPlaySpeed, usePauseButtonStore } from '../../../../../store/usePlayButtonStore';
|
import { useAnimationPlaySpeed, usePauseButtonStore } from '../../../../../store/usePlayButtonStore';
|
||||||
|
|
||||||
import { upsertProductOrEventApi } from '../../../../../services/simulation/products/UpsertProductOrEventApi';
|
import { upsertProductOrEventApi } from '../../../../../services/simulation/products/UpsertProductOrEventApi';
|
||||||
import { getAssetIksApi } from '../../../../../services/simulation/ik/getAssetIKs';
|
import { getAssetIksApi } from '../../../../../services/simulation/ik/getAssetIKs';
|
||||||
|
|
||||||
|
const distanceWorker = new Worker(new URL("../../../../../services/factoryBuilder/webWorkers/distanceWorker.js", import.meta.url));
|
||||||
|
|
||||||
function Model({ asset }: { readonly asset: Asset }) {
|
function Model({ asset }: { readonly asset: Asset }) {
|
||||||
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 } = useThree();
|
const { camera, controls, gl, scene } = useThree();
|
||||||
const { activeTool } = useActiveTool();
|
const { activeTool } = useActiveTool();
|
||||||
const { toolMode } = useToolMode();
|
const { toolMode } = useToolMode();
|
||||||
const { toggleView } = useToggleView();
|
const { toggleView } = useToggleView();
|
||||||
@@ -116,6 +119,12 @@ function Model({ asset }: { readonly asset: Asset }) {
|
|||||||
}
|
}
|
||||||
}, [isRendered, selectedFloorItem])
|
}, [isRendered, selectedFloorItem])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
distanceWorker.onmessage = (e) => {
|
||||||
|
setIsRendered(e.data.shouldRender);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loader = new GLTFLoader();
|
const loader = new GLTFLoader();
|
||||||
const dracoLoader = new DRACOLoader();
|
const dracoLoader = new DRACOLoader();
|
||||||
@@ -202,21 +211,6 @@ function Model({ asset }: { readonly asset: Asset }) {
|
|||||||
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useFrame(() => {
|
|
||||||
const assetPosition = new THREE.Vector3(...asset.position);
|
|
||||||
if (limitDistance) {
|
|
||||||
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') {
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ const DuplicationControls3D = ({
|
|||||||
right: false,
|
right: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const calculateDragOffset = useCallback((point: THREE.Vector3, hitPoint: THREE.Vector3) => {
|
const calculateDragOffset = useCallback((point: THREE.Object3D, hitPoint: THREE.Vector3) => {
|
||||||
const pointPosition = new THREE.Vector3().copy(point);
|
const pointPosition = new THREE.Vector3().copy(point.position);
|
||||||
return new THREE.Vector3().subVectors(pointPosition, hitPoint);
|
return new THREE.Vector3().subVectors(pointPosition, hitPoint);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -120,11 +120,9 @@ const DuplicationControls3D = ({
|
|||||||
|
|
||||||
if (hit) {
|
if (hit) {
|
||||||
if (mouseButtonsDown.current.left || mouseButtonsDown.current.right) {
|
if (mouseButtonsDown.current.left || mouseButtonsDown.current.right) {
|
||||||
const assetUuid = duplicatedObjects[0].userData.modelUuid;
|
const model = scene.getObjectByProperty("uuid", duplicatedObjects[0].userData.modelUuid);
|
||||||
const asset = getAssetById(assetUuid);
|
if (model) {
|
||||||
if (!asset) return;
|
const newOffset = calculateDragOffset(model, intersectionPoint);
|
||||||
if (duplicatedObjects[0]) {
|
|
||||||
const newOffset = calculateDragOffset(new THREE.Vector3(...asset.position), intersectionPoint);
|
|
||||||
setDragOffset(newOffset);
|
setDragOffset(newOffset);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -177,7 +175,7 @@ const DuplicationControls3D = ({
|
|||||||
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||||
|
|
||||||
if (hit) {
|
if (hit) {
|
||||||
const offset = calculateDragOffset(selectedAssets[0].position, hit);
|
const offset = calculateDragOffset(selectedAssets[0], hit);
|
||||||
setDragOffset(offset);
|
setDragOffset(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ function MoveControls3D({
|
|||||||
const initialBasePosition = initialPositions[movedObjects[0].uuid];
|
const initialBasePosition = initialPositions[movedObjects[0].uuid];
|
||||||
const positionDifference = new THREE.Vector3().subVectors(rawBasePosition, initialBasePosition);
|
const positionDifference = new THREE.Vector3().subVectors(rawBasePosition, initialBasePosition);
|
||||||
|
|
||||||
const adjustedDifference = positionDifference.multiplyScalar(moveDistance);
|
let adjustedDifference = positionDifference.multiplyScalar(moveDistance);
|
||||||
|
|
||||||
const baseNewPosition = new THREE.Vector3().addVectors(initialBasePosition, adjustedDifference);
|
const baseNewPosition = new THREE.Vector3().addVectors(initialBasePosition, adjustedDifference);
|
||||||
|
|
||||||
|
|||||||
21
app/src/services/factoryBuilder/webWorkers/distanceWorker.js
Normal file
21
app/src/services/factoryBuilder/webWorkers/distanceWorker.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
onmessage = function (e) {
|
||||||
|
const { assetPosition, cameraPosition, limitDistance, renderDistance, isRendered } = e.data;
|
||||||
|
|
||||||
|
if (limitDistance && assetPosition) {
|
||||||
|
const distance = Math.sqrt(
|
||||||
|
Math.pow(assetPosition.x - cameraPosition.x, 2) +
|
||||||
|
Math.pow(assetPosition.y - cameraPosition.y, 2) +
|
||||||
|
Math.pow(assetPosition.z - cameraPosition.z, 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isRendered && distance <= renderDistance) {
|
||||||
|
postMessage({ shouldRender: true });
|
||||||
|
} else if (isRendered && distance > renderDistance) {
|
||||||
|
postMessage({ shouldRender: false });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!isRendered) {
|
||||||
|
postMessage({ shouldRender: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,12 +1,5 @@
|
|||||||
import * as THREE from 'three';
|
|
||||||
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
|
||||||
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
|
|
||||||
import { retrieveGLTF, storeGLTF } from '../../../utils/indexDB/idbUtils';
|
import { retrieveGLTF, storeGLTF } from '../../../utils/indexDB/idbUtils';
|
||||||
|
|
||||||
const loader = new GLTFLoader();
|
|
||||||
const dracoLoader = new DRACOLoader();
|
|
||||||
dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/');
|
|
||||||
loader.setDRACOLoader(dracoLoader);
|
|
||||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||||
|
|
||||||
onmessage = async (event) => {
|
onmessage = async (event) => {
|
||||||
@@ -17,8 +10,8 @@ onmessage = async (event) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
for (const item of uniqueItems) {
|
for (const item of uniqueItems) {
|
||||||
if(item.assetId === null || item.assetId === undefined) {
|
if (item.assetId === null || item.assetId === undefined) {
|
||||||
continue; // Skip items without a valid assetId
|
continue;
|
||||||
}
|
}
|
||||||
const modelID = item.assetId;
|
const modelID = item.assetId;
|
||||||
const indexedDBModel = await retrieveGLTF(modelID);
|
const indexedDBModel = await retrieveGLTF(modelID);
|
||||||
@@ -37,5 +30,5 @@ onmessage = async (event) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
postMessage({ message: 'done' })
|
postMessage({ message: 'done' });
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user