Merge remote-tracking branch 'origin/main-dev' into main-demo
This commit is contained in:
@@ -16,12 +16,7 @@ import { getUserData } from "../../../functions/getUserData";
|
||||
import { useSceneContext } from "../../scene/sceneContext";
|
||||
import { useVersionContext } from "../version/versionContext";
|
||||
|
||||
const gltfLoaderWorker = new Worker(
|
||||
new URL(
|
||||
"../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js",
|
||||
import.meta.url
|
||||
)
|
||||
);
|
||||
const gltfLoaderWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js", import.meta.url));
|
||||
|
||||
function AssetsGroup({ plane }: { readonly plane: RefMesh }) {
|
||||
const { activeModule } = useModuleStore();
|
||||
|
||||
@@ -1,47 +1,67 @@
|
||||
import { Line } from "@react-three/drei";
|
||||
import { Box3, Vector3 } from "three";
|
||||
import { Box3, Vector3, Quaternion } from "three";
|
||||
import { useMemo } from "react";
|
||||
import { Cylinder } from "@react-three/drei";
|
||||
|
||||
export const AssetBoundingBox = ({ name, boundingBox, color, lineWidth }: { name: string; boundingBox: Box3 | null; color: string; lineWidth: number; }) => {
|
||||
const { points, size, center } = useMemo(() => {
|
||||
if (!boundingBox) { return { points: [], center: new Vector3(), size: new Vector3(), }; }
|
||||
export const AssetBoundingBox = ({ name, boundingBox, color, lineWidth, }: { name: string; boundingBox: Box3 | null; color: string; lineWidth: number; }) => {
|
||||
const { edgeCylinders, center, size } = useMemo(() => {
|
||||
if (!boundingBox) return { edgeCylinders: [], center: new Vector3(), size: new Vector3() };
|
||||
|
||||
const min = boundingBox.min;
|
||||
const max = boundingBox.max;
|
||||
const center = boundingBox.getCenter(new Vector3());
|
||||
const size = boundingBox.getSize(new Vector3());
|
||||
|
||||
const edges: Array<[number, number, number]> = [
|
||||
[min.x, min.y, min.z], [max.x, min.y, min.z],
|
||||
[max.x, min.y, min.z], [max.x, max.y, min.z],
|
||||
[max.x, max.y, min.z], [min.x, max.y, min.z],
|
||||
[min.x, max.y, min.z], [min.x, min.y, min.z],
|
||||
|
||||
[min.x, min.y, max.z], [max.x, min.y, max.z],
|
||||
[max.x, min.y, max.z], [max.x, max.y, max.z],
|
||||
[max.x, max.y, max.z], [min.x, max.y, max.z],
|
||||
[min.x, max.y, max.z], [min.x, min.y, max.z],
|
||||
|
||||
[min.x, min.y, min.z], [min.x, min.y, max.z],
|
||||
[max.x, min.y, min.z], [max.x, min.y, max.z],
|
||||
[max.x, max.y, min.z], [max.x, max.y, max.z],
|
||||
[min.x, max.y, min.z], [min.x, max.y, max.z],
|
||||
const corners = [
|
||||
new Vector3(min.x, min.y, min.z),
|
||||
new Vector3(max.x, min.y, min.z),
|
||||
new Vector3(max.x, max.y, min.z),
|
||||
new Vector3(min.x, max.y, min.z),
|
||||
new Vector3(min.x, min.y, max.z),
|
||||
new Vector3(max.x, min.y, max.z),
|
||||
new Vector3(max.x, max.y, max.z),
|
||||
new Vector3(min.x, max.y, max.z),
|
||||
];
|
||||
|
||||
return { points: edges, center, size };
|
||||
}, [boundingBox]);
|
||||
const edgeIndices: [number, number][] = [
|
||||
[0, 1], [1, 2], [2, 3], [3, 0],
|
||||
[4, 5], [5, 6], [6, 7], [7, 4],
|
||||
[0, 4], [1, 5], [2, 6], [3, 7],
|
||||
];
|
||||
|
||||
const radius = 0.005 * lineWidth;
|
||||
|
||||
const edgeCylinders = edgeIndices.map(([startIdx, endIdx], i) => {
|
||||
const start = corners[startIdx];
|
||||
const end = corners[endIdx];
|
||||
const direction = new Vector3().subVectors(end, start);
|
||||
const length = direction.length();
|
||||
const midPoint = new Vector3().addVectors(start, end).multiplyScalar(0.5);
|
||||
const quaternion = new Quaternion().setFromUnitVectors(
|
||||
new Vector3(0, 1, 0),
|
||||
direction.clone().normalize()
|
||||
);
|
||||
|
||||
return {
|
||||
key: `edge-cylinder-${i}`,
|
||||
position: midPoint,
|
||||
rotation: quaternion,
|
||||
length,
|
||||
radius,
|
||||
};
|
||||
});
|
||||
|
||||
return { edgeCylinders, center, size };
|
||||
}, [boundingBox, lineWidth]);
|
||||
|
||||
if (!boundingBox) return null;
|
||||
|
||||
return (
|
||||
<group name={name}>
|
||||
<Line
|
||||
segments
|
||||
depthWrite={false}
|
||||
points={points}
|
||||
color={color}
|
||||
lineWidth={lineWidth}
|
||||
/>
|
||||
{edgeCylinders.map(({ key, position, rotation, length, radius }) => (
|
||||
<Cylinder key={key} args={[radius, radius, length, 6]} position={position} quaternion={rotation} >
|
||||
<meshBasicMaterial color={color} depthWrite={false} />
|
||||
</Cylinder>
|
||||
))}
|
||||
|
||||
<mesh visible={false} position={center}>
|
||||
<boxGeometry args={[size.x, size.y, size.z]} />
|
||||
|
||||
@@ -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';
|
||||
@@ -16,23 +16,23 @@ import { getUserData } from '../../../../../functions/getUserData';
|
||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
||||
import { useVersionContext } from '../../../version/versionContext';
|
||||
import { SkeletonUtils } from 'three-stdlib';
|
||||
import { useAnimationPlaySpeed, usePauseButtonStore } from '../../../../../store/usePlayButtonStore';
|
||||
|
||||
import { upsertProductOrEventApi } from '../../../../../services/simulation/products/UpsertProductOrEventApi';
|
||||
import { getAssetIksApi } from '../../../../../services/simulation/ik/getAssetIKs';
|
||||
import { ModelAnimator } from './animator/modelAnimator';
|
||||
|
||||
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 } = useThree();
|
||||
const { controls, gl } = useThree();
|
||||
const { activeTool } = useActiveTool();
|
||||
const { toolMode } = useToolMode();
|
||||
const { toggleView } = useToggleView();
|
||||
const { subModule } = useSubModuleStore();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { speed } = useAnimationPlaySpeed();
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
const { assetStore, eventStore, productStore } = useSceneContext();
|
||||
const { removeAsset, setAnimations, resetAnimation, setAnimationComplete } = assetStore();
|
||||
const { removeAsset, resetAnimation } = assetStore();
|
||||
const { setTop } = useTopData();
|
||||
const { setLeft } = useLeftData();
|
||||
const { getIsEventInProduct, addPoint } = productStore();
|
||||
@@ -43,23 +43,15 @@ 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<GLTF["scene"] | null>(null);
|
||||
const [boundingBox, setBoundingBox] = useState<THREE.Box3 | null>(null);
|
||||
const [isSelected, setIsSelected] = useState(false);
|
||||
const groupRef = useRef<THREE.Group>(null);
|
||||
const mixerRef = useRef<THREE.AnimationMixer>();
|
||||
const actions = useRef<{ [name: string]: THREE.AnimationAction }>({});
|
||||
const [previousAnimation, setPreviousAnimation] = useState<string | null>(null);
|
||||
const [ikData, setIkData] = useState<any>();
|
||||
const blendFactor = useRef(0);
|
||||
const blendDuration = 0.5;
|
||||
const { selectedVersionStore } = useVersionContext();
|
||||
const { selectedVersion } = selectedVersionStore();
|
||||
const { userId, organization } = getUserData();
|
||||
@@ -133,16 +125,6 @@ function Model({ asset }: { readonly asset: Asset }) {
|
||||
clone.animations = cachedModel.animations || [];
|
||||
setGltfScene(clone);
|
||||
calculateBoundingBox(clone);
|
||||
if (cachedModel.animations && clone.animations.length > 0) {
|
||||
const animationName = clone.animations.map((clip: any) => clip.name);
|
||||
setAnimations(asset.modelUuid, animationName)
|
||||
mixerRef.current = new THREE.AnimationMixer(clone);
|
||||
|
||||
clone.animations.forEach((animation: any) => {
|
||||
const action = mixerRef.current!.clipAction(animation);
|
||||
actions.current[animation.name] = action;
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -202,21 +184,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) => {
|
||||
if (asset) {
|
||||
if (activeTool === "cursor" && boundingBox && groupRef.current && activeModule === 'builder') {
|
||||
@@ -382,50 +349,6 @@ function Model({ asset }: { readonly asset: Asset }) {
|
||||
}
|
||||
}
|
||||
|
||||
const handleAnimationComplete = useCallback(() => {
|
||||
if (asset.animationState) {
|
||||
setAnimationComplete(asset.modelUuid, true);
|
||||
}
|
||||
}, [asset.animationState]);
|
||||
|
||||
useFrame((_, delta) => {
|
||||
if (mixerRef.current) {
|
||||
mixerRef.current.update(delta * (activeModule === 'simulation' ? speed : 1));
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!asset.animationState || !mixerRef.current) return;
|
||||
|
||||
const { current, loopAnimation, isPlaying } = asset.animationState;
|
||||
const currentAction = actions.current[current];
|
||||
const previousAction = previousAnimation ? actions.current[previousAnimation] : null;
|
||||
|
||||
if (isPlaying && currentAction && activeModule === 'simulation' && !isPaused) {
|
||||
blendFactor.current = 0;
|
||||
|
||||
currentAction.reset();
|
||||
currentAction.setLoop(loopAnimation ? THREE.LoopRepeat : THREE.LoopOnce, loopAnimation ? Infinity : 1);
|
||||
currentAction.clampWhenFinished = true;
|
||||
|
||||
if (previousAction && previousAction !== currentAction) {
|
||||
previousAction.crossFadeTo(currentAction, blendDuration, false);
|
||||
}
|
||||
|
||||
currentAction.play();
|
||||
mixerRef.current.addEventListener('finished', handleAnimationComplete);
|
||||
setPreviousAnimation(current);
|
||||
} else {
|
||||
Object.values(actions.current).forEach((action) => action.stop());
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (mixerRef.current) {
|
||||
mixerRef.current.removeEventListener('finished', handleAnimationComplete);
|
||||
}
|
||||
};
|
||||
}, [asset.animationState?.current, asset.animationState?.isCompleted, asset.animationState?.isPlaying, isPaused, activeModule]);
|
||||
|
||||
useEffect(() => {
|
||||
const canvasElement = gl.domElement;
|
||||
|
||||
@@ -526,9 +449,15 @@ function Model({ asset }: { readonly asset: Asset }) {
|
||||
{gltfScene && (
|
||||
<>
|
||||
{isRendered ? (
|
||||
<primitive object={gltfScene} />
|
||||
<>
|
||||
|
||||
<primitive object={gltfScene} />
|
||||
|
||||
<ModelAnimator asset={asset} gltfScene={gltfScene} />
|
||||
|
||||
</>
|
||||
) : (
|
||||
<AssetBoundingBox name='Asset Fallback' boundingBox={boundingBox} color='gray' lineWidth={1} />
|
||||
<AssetBoundingBox name='Asset Fallback' boundingBox={boundingBox} color='gray' lineWidth={2.5} />
|
||||
)}
|
||||
{isSelected &&
|
||||
<AssetBoundingBox name='Asset BBox' boundingBox={boundingBox} color={savedTheme === "dark" ? "#c4abf1" : "#6f42c1"} lineWidth={2.7} />
|
||||
|
||||
@@ -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<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 (
|
||||
<group
|
||||
@@ -28,11 +56,11 @@ function Models() {
|
||||
}
|
||||
}}
|
||||
>
|
||||
{assets.map((asset) =>
|
||||
<Model key={asset.modelUuid} asset={asset} />
|
||||
)}
|
||||
{assets.map((asset) => (
|
||||
<Model key={asset.modelUuid} asset={asset} isRendered={renderMap[asset.modelUuid] ?? false} />
|
||||
))}
|
||||
</group>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default Models
|
||||
export default Models;
|
||||
@@ -164,7 +164,7 @@ function MoveControls2D({
|
||||
return new THREE.Vector3().subVectors(pointPosition, hitPoint);
|
||||
}, []);
|
||||
|
||||
const movePoints = useCallback(() => {
|
||||
const movePoints = (() => {
|
||||
if (selectedPoints.length === 0) return;
|
||||
|
||||
const states: Record<string, { position: THREE.Vector3; rotation?: THREE.Euler; }> = {};
|
||||
@@ -192,9 +192,9 @@ function MoveControls2D({
|
||||
|
||||
setMovedObjects(selectedPoints);
|
||||
setIsMoving(true);
|
||||
}, [selectedPoints, camera, pointer, plane, raycaster, calculateDragOffset]);
|
||||
});
|
||||
|
||||
const resetToInitialPositions = useCallback(() => {
|
||||
const resetToInitialPositions = () => {
|
||||
setTimeout(() => {
|
||||
movedObjects.forEach((movedPoint: THREE.Object3D) => {
|
||||
if (movedPoint.userData.pointUuid && initialStates[movedPoint.uuid]) {
|
||||
@@ -218,7 +218,7 @@ function MoveControls2D({
|
||||
}
|
||||
});
|
||||
}, 0)
|
||||
}, [movedObjects, initialStates, setAislePosition, setWallPosition, setFloorPosition, setZonePosition]);
|
||||
};
|
||||
|
||||
const placeMovedAssets = () => {
|
||||
if (movedObjects.length === 0) return;
|
||||
|
||||
@@ -42,8 +42,8 @@ const DuplicationControls3D = ({
|
||||
right: false,
|
||||
});
|
||||
|
||||
const calculateDragOffset = useCallback((point: THREE.Vector3, hitPoint: THREE.Vector3) => {
|
||||
const pointPosition = new THREE.Vector3().copy(point);
|
||||
const calculateDragOffset = useCallback((point: THREE.Object3D, hitPoint: THREE.Vector3) => {
|
||||
const pointPosition = new THREE.Vector3().copy(point.position);
|
||||
return new THREE.Vector3().subVectors(pointPosition, hitPoint);
|
||||
}, []);
|
||||
|
||||
@@ -120,11 +120,9 @@ const DuplicationControls3D = ({
|
||||
|
||||
if (hit) {
|
||||
if (mouseButtonsDown.current.left || mouseButtonsDown.current.right) {
|
||||
const assetUuid = duplicatedObjects[0].userData.modelUuid;
|
||||
const asset = getAssetById(assetUuid);
|
||||
if (!asset) return;
|
||||
if (duplicatedObjects[0]) {
|
||||
const newOffset = calculateDragOffset(new THREE.Vector3(...asset.position), intersectionPoint);
|
||||
const model = scene.getObjectByProperty("uuid", duplicatedObjects[0].userData.modelUuid);
|
||||
if (model) {
|
||||
const newOffset = calculateDragOffset(model, intersectionPoint);
|
||||
setDragOffset(newOffset);
|
||||
}
|
||||
return;
|
||||
@@ -177,7 +175,7 @@ const DuplicationControls3D = ({
|
||||
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||
|
||||
if (hit) {
|
||||
const offset = calculateDragOffset(selectedAssets[0].position, hit);
|
||||
const offset = calculateDragOffset(selectedAssets[0], hit);
|
||||
setDragOffset(offset);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,10 +46,7 @@ function MoveControls3D({
|
||||
const [initialPositions, setInitialPositions] = useState<Record<string, THREE.Vector3>>({});
|
||||
const [initialStates, setInitialStates] = useState<Record<string, { position: THREE.Vector3; rotation?: THREE.Euler; }>>({});
|
||||
const [isMoving, setIsMoving] = useState(false);
|
||||
const mouseButtonsDown = useRef<{ left: boolean; right: boolean }>({
|
||||
left: false,
|
||||
right: false,
|
||||
});
|
||||
const mouseButtonsDown = useRef<{ left: boolean; right: boolean }>({ left: false, right: false, });
|
||||
|
||||
const updateBackend = (
|
||||
productName: string,
|
||||
@@ -79,9 +76,9 @@ function MoveControls3D({
|
||||
};
|
||||
|
||||
const onKeyUp = (event: KeyboardEvent) => {
|
||||
const isModifierKey = event.key === "Control" || event.key === "Shift";
|
||||
const isModifierKey = (!event.shiftKey && !event.ctrlKey);
|
||||
|
||||
if (isModifierKey) {
|
||||
if (isModifierKey && keyEvent !== "") {
|
||||
setKeyEvent("");
|
||||
}
|
||||
};
|
||||
@@ -196,7 +193,6 @@ function MoveControls3D({
|
||||
raycaster.setFromCamera(pointer, camera);
|
||||
const hit = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||
|
||||
|
||||
if (hit) {
|
||||
if (mouseButtonsDown.current.left || mouseButtonsDown.current.right) {
|
||||
if (movedObjects[0]) {
|
||||
@@ -209,18 +205,18 @@ function MoveControls3D({
|
||||
if (dragOffset) {
|
||||
const rawBasePosition = new THREE.Vector3().addVectors(intersectionPoint, dragOffset);
|
||||
|
||||
let moveSpeed = keyEvent.includes("Shift") ? 0.05 : 1;
|
||||
let moveDistance = keyEvent.includes("Shift") ? 0.05 : 1;
|
||||
|
||||
const initialBasePosition = initialPositions[movedObjects[0].uuid];
|
||||
const positionDifference = new THREE.Vector3().subVectors(rawBasePosition, initialBasePosition);
|
||||
|
||||
const adjustedDifference = positionDifference.multiplyScalar(moveSpeed);
|
||||
let adjustedDifference = positionDifference.multiplyScalar(moveDistance);
|
||||
|
||||
const baseNewPosition = new THREE.Vector3().addVectors(initialBasePosition, adjustedDifference);
|
||||
|
||||
if (keyEvent.includes("Ctrl")) {
|
||||
baseNewPosition.x = snapControls(baseNewPosition.x, "Ctrl");
|
||||
baseNewPosition.z = snapControls(baseNewPosition.z, "Ctrl");
|
||||
baseNewPosition.x = snapControls(baseNewPosition.x, keyEvent);
|
||||
baseNewPosition.z = snapControls(baseNewPosition.z, keyEvent);
|
||||
}
|
||||
|
||||
movedObjects.forEach((movedAsset: THREE.Object3D) => {
|
||||
|
||||
@@ -3,17 +3,15 @@ import { useFrame } from "@react-three/fiber";
|
||||
import { usePlayButtonStore, usePauseButtonStore, useResetButtonStore, useAnimationPlaySpeed } from "../../../../../store/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||
import { useProductContext } from "../../../products/productContext";
|
||||
import { useHumanEventManager } from "../../../human/eventManager/useHumanEventManager";
|
||||
|
||||
export function useRetrieveHandler() {
|
||||
const { materialStore, armBotStore, vehicleStore, storageUnitStore, productStore, humanStore, assetStore, humanEventManagerRef } = useSceneContext();
|
||||
const { materialStore, armBotStore, vehicleStore, storageUnitStore, productStore, humanStore, assetStore } = useSceneContext();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { addMaterial } = materialStore();
|
||||
const { getModelUuidByActionUuid, getPointUuidByActionUuid, getEventByModelUuid, getActionByUuid } = productStore();
|
||||
const { getStorageUnitById, getLastMaterial, updateCurrentLoad, removeLastMaterial } = storageUnitStore();
|
||||
const { getVehicleById, incrementVehicleLoad, addCurrentMaterial } = vehicleStore();
|
||||
const { getHumanById, incrementHumanLoad, addCurrentMaterial: addCurrentMaterialToHuman } = humanStore();
|
||||
const { addHumanToMonitor } = useHumanEventManager();
|
||||
const { getAssetById, setCurrentAnimation } = assetStore();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
const { getArmBotById, addCurrentAction } = armBotStore();
|
||||
@@ -303,19 +301,10 @@ export function useRetrieveHandler() {
|
||||
const humanAsset = getAssetById(triggeredModel.modelUuid);
|
||||
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || '');
|
||||
|
||||
if (!action || action.actionType !== 'worker' || !humanEventManagerRef.current) return;
|
||||
if (!action || action.actionType !== 'worker') return;
|
||||
|
||||
let state = humanEventManagerRef.current.humanStates.find(h => h.humanId === triggeredModel.modelUuid);
|
||||
console.log('state: ', state);
|
||||
console.log('human: ', human);
|
||||
const currentCount = retrievalCountRef.current.get(actionUuid) ?? 0;
|
||||
|
||||
let conditionMet = false;
|
||||
if (state) {
|
||||
console.log('state.actionQueue: ', state.actionQueue);
|
||||
// state.actionQueue[0].count
|
||||
}
|
||||
|
||||
if (currentCount >= action.loadCount) {
|
||||
completedActions.push(actionUuid);
|
||||
hasChanges = true;
|
||||
@@ -337,12 +326,10 @@ export function useRetrieveHandler() {
|
||||
removeLastMaterial(storageUnit.modelUuid);
|
||||
updateCurrentLoad(storageUnit.modelUuid, -1);
|
||||
incrementHumanLoad(human.modelUuid, 1);
|
||||
addHumanToMonitor(human.modelUuid, () => {
|
||||
addCurrentMaterialToHuman(human.modelUuid, material.materialType, material.materialId);
|
||||
retrieveLogStatus(material.materialName, `is picked by ${human.modelName}`);
|
||||
addCurrentMaterialToHuman(human.modelUuid, material.materialType, material.materialId);
|
||||
retrieveLogStatus(material.materialName, `is picked by ${human.modelName}`);
|
||||
|
||||
retrievalCountRef.current.set(actionUuid, currentCount + 1);
|
||||
}, actionUuid)
|
||||
retrievalCountRef.current.set(actionUuid, currentCount + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
21
app/src/services/factoryBuilder/webWorkers/distanceWorker.js
Normal file
21
app/src/services/factoryBuilder/webWorkers/distanceWorker.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import { Vector3 } from "three";
|
||||
|
||||
onmessage = function (e) {
|
||||
const { modelUuid, assetPosition, cameraPosition, limitDistance, renderDistance, isRendered, } = e.data;
|
||||
|
||||
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 && distance > renderDistance) {
|
||||
postMessage({ shouldRender: false, modelUuid });
|
||||
}
|
||||
} else {
|
||||
if (!isRendered) {
|
||||
postMessage({ shouldRender: true, modelUuid });
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -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';
|
||||
|
||||
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}`;
|
||||
|
||||
onmessage = async (event) => {
|
||||
@@ -17,8 +10,8 @@ onmessage = async (event) => {
|
||||
);
|
||||
|
||||
for (const item of uniqueItems) {
|
||||
if(item.assetId === null || item.assetId === undefined) {
|
||||
continue; // Skip items without a valid assetId
|
||||
if (item.assetId === null || item.assetId === undefined) {
|
||||
continue;
|
||||
}
|
||||
const modelID = item.assetId;
|
||||
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