Throughput Summary
diff --git a/app/src/components/ui/log/LoggerContext.tsx b/app/src/components/ui/log/LoggerContext.tsx
index 71bd467..721ef41 100644
--- a/app/src/components/ui/log/LoggerContext.tsx
+++ b/app/src/components/ui/log/LoggerContext.tsx
@@ -1,4 +1,10 @@
-import React, { createContext, useContext, useState, useCallback, useMemo } from "react";
+import React, {
+ createContext,
+ useContext,
+ useState,
+ useCallback,
+ useMemo,
+} from "react";
export type LogType = "log" | "info" | "warning" | "error" | "success";
@@ -48,18 +54,21 @@ export const LoggerProvider: React.FC<{ children: React.ReactNode }> = ({
[generateId]
);
- const loggerMethods: LoggerContextValue = useMemo(() => ({
- logs,
- setLogs,
- isLogListVisible,
- setIsLogListVisible,
- log: (message: string) => addLog("log", message),
- info: (message: string) => addLog("info", message),
- warn: (message: string) => addLog("warning", message),
- error: (message: string) => addLog("error", message),
- success: (message: string) => addLog("success", message),
- clear: () => setLogs([]),
- }), [logs, setLogs, isLogListVisible, setIsLogListVisible, addLog]);
+ const loggerMethods: LoggerContextValue = useMemo(
+ () => ({
+ logs,
+ setLogs,
+ isLogListVisible,
+ setIsLogListVisible,
+ log: (message: string) => addLog("log", message),
+ info: (message: string) => addLog("info", message),
+ warn: (message: string) => addLog("warning", message),
+ error: (message: string) => addLog("error", message),
+ success: (message: string) => addLog("success", message),
+ clear: () => setLogs([]),
+ }),
+ [logs, setLogs, isLogListVisible, setIsLogListVisible, addLog]
+ );
return (
diff --git a/app/src/components/ui/simulation/simulationPlayer.tsx b/app/src/components/ui/simulation/simulationPlayer.tsx
index 525dc0f..334f2e1 100644
--- a/app/src/components/ui/simulation/simulationPlayer.tsx
+++ b/app/src/components/ui/simulation/simulationPlayer.tsx
@@ -368,7 +368,7 @@ const SimulationPlayer: React.FC = () => {
)}
- {subModule === "analysis" && (
+ {/* {subModule === "analysis" && ( */}
@@ -376,7 +376,7 @@ const SimulationPlayer: React.FC = () => {
- )}
+ {/* )} */}
>
);
};
diff --git a/app/src/modules/builder/groups/floorItemsGroup.tsx b/app/src/modules/builder/groups/floorItemsGroup.tsx
index f3f5050..d5ca04f 100644
--- a/app/src/modules/builder/groups/floorItemsGroup.tsx
+++ b/app/src/modules/builder/groups/floorItemsGroup.tsx
@@ -1,11 +1,25 @@
import { useFrame, useThree } from "@react-three/fiber";
-import { useActiveTool, useAsset3dWidget, useCamMode, useDeletableFloorItem, useDeleteTool, useFloorItems, useLoadingProgress, useRenderDistance, useSelectedFloorItem, useSelectedItem, useSocketStore, useToggleView, useTransformMode, } from "../../../store/store";
+import {
+ useActiveTool,
+ useAsset3dWidget,
+ useCamMode,
+ useDeletableFloorItem,
+ useDeleteTool,
+ useFloorItems,
+ useLoadingProgress,
+ useRenderDistance,
+ useSelectedFloorItem,
+ useSelectedItem,
+ useSocketStore,
+ useToggleView,
+ useTransformMode,
+} from "../../../store/store";
import assetVisibility from "../geomentries/assets/assetVisibility";
import { useEffect } from "react";
import * as THREE from "three";
import * as Types from "../../../types/world/worldTypes";
import assetManager, {
- cancelOngoingTasks,
+ cancelOngoingTasks,
} from "../geomentries/assets/assetManager";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
@@ -18,313 +32,422 @@ import useModuleStore from "../../../store/useModuleStore";
// import { retrieveGLTF } from "../../../utils/indexDB/idbUtils";
import { useEventsStore } from "../../../store/simulation/useEventsStore";
-const assetManagerWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/assetManagerWorker.js", import.meta.url));
-const gltfLoaderWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js", import.meta.url));
+const assetManagerWorker = new Worker(
+ new URL(
+ "../../../services/factoryBuilder/webWorkers/assetManagerWorker.js",
+ import.meta.url
+ )
+);
+const gltfLoaderWorker = new Worker(
+ new URL(
+ "../../../services/factoryBuilder/webWorkers/gltfLoaderWorker.js",
+ import.meta.url
+ )
+);
-const FloorItemsGroup = ({ itemsGroup, hoveredDeletableFloorItem, AttachedObject, floorGroup, tempLoader, isTempLoader, plane, }: any) => {
- const state: Types.ThreeState = useThree();
- const { raycaster, controls }: any = state;
- const { renderDistance } = useRenderDistance();
- const { toggleView } = useToggleView();
- const { floorItems, setFloorItems } = useFloorItems();
- const { camMode } = useCamMode();
- const { deleteTool } = useDeleteTool();
- const { setDeletableFloorItem } = useDeletableFloorItem();
- const { transformMode } = useTransformMode();
- const { setSelectedFloorItem } = useSelectedFloorItem();
- const { activeTool } = useActiveTool();
- const { selectedItem, setSelectedItem } = useSelectedItem();
- const { setLoadingProgress } = useLoadingProgress();
- const { activeModule } = useModuleStore();
- const { socket } = useSocketStore();
- const loader = new GLTFLoader();
- const dracoLoader = new DRACOLoader();
- const { addEvent } = useEventsStore();
+const FloorItemsGroup = ({
+ itemsGroup,
+ hoveredDeletableFloorItem,
+ AttachedObject,
+ floorGroup,
+ tempLoader,
+ isTempLoader,
+ plane,
+}: any) => {
+ const state: Types.ThreeState = useThree();
+ const { raycaster, controls }: any = state;
+ const { renderDistance } = useRenderDistance();
+ const { toggleView } = useToggleView();
+ const { floorItems, setFloorItems } = useFloorItems();
+ const { camMode } = useCamMode();
+ const { deleteTool } = useDeleteTool();
+ const { setDeletableFloorItem } = useDeletableFloorItem();
+ const { transformMode } = useTransformMode();
+ const { setSelectedFloorItem } = useSelectedFloorItem();
+ const { activeTool } = useActiveTool();
+ const { selectedItem, setSelectedItem } = useSelectedItem();
+ const { setLoadingProgress } = useLoadingProgress();
+ const { activeModule } = useModuleStore();
+ const { socket } = useSocketStore();
+ const loader = new GLTFLoader();
+ const dracoLoader = new DRACOLoader();
+ const { addEvent } = useEventsStore();
- dracoLoader.setDecoderPath("https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/");
- loader.setDRACOLoader(dracoLoader);
+ dracoLoader.setDecoderPath(
+ "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/"
+ );
+ loader.setDRACOLoader(dracoLoader);
- useEffect(() => {
- const email = localStorage.getItem("email");
- const organization = email!.split("@")[1].split(".")[0];
+ useEffect(() => {
+ const email = localStorage.getItem("email");
+ const organization = email!.split("@")[1].split(".")[0];
- let totalAssets = 0;
- let loadedAssets = 0;
+ let totalAssets = 0;
+ let loadedAssets = 0;
- const updateLoadingProgress = (progress: number) => {
- if (progress < 100) {
- setLoadingProgress(progress);
- } else if (progress === 100) {
- setTimeout(() => {
- setLoadingProgress(100);
- setTimeout(() => {
- setLoadingProgress(0);
- }, 1500);
- }, 1000);
- }
- };
+ const updateLoadingProgress = (progress: number) => {
+ if (progress < 100) {
+ setLoadingProgress(progress);
+ } else if (progress === 100) {
+ setTimeout(() => {
+ setLoadingProgress(100);
+ setTimeout(() => {
+ setLoadingProgress(0);
+ }, 1500);
+ }, 1000);
+ }
+ };
- getFloorAssets(organization).then((data) => {
- if (data.length > 0) {
- const uniqueItems = (data as Types.FloorItems).filter((item, index, self) => index === self.findIndex((t) => t.modelfileID === item.modelfileID));
- totalAssets = uniqueItems.length;
- if (totalAssets === 0) {
- updateLoadingProgress(100);
- return;
- }
- gltfLoaderWorker.postMessage({ floorItems: data });
- } else {
- gltfLoaderWorker.postMessage({ floorItems: [] });
- loadInitialFloorItems(itemsGroup, setFloorItems, addEvent, renderDistance);
- updateLoadingProgress(100);
- }
+ getFloorAssets(organization).then((data) => {
+ if (data.length > 0) {
+ const uniqueItems = (data as Types.FloorItems).filter(
+ (item, index, self) =>
+ index === self.findIndex((t) => t.modelfileID === item.modelfileID)
+ );
+ totalAssets = uniqueItems.length;
+ if (totalAssets === 0) {
+ updateLoadingProgress(100);
+ return;
+ }
+ gltfLoaderWorker.postMessage({ floorItems: data });
+ } else {
+ gltfLoaderWorker.postMessage({ floorItems: [] });
+ loadInitialFloorItems(
+ itemsGroup,
+ setFloorItems,
+ addEvent,
+ renderDistance
+ );
+ updateLoadingProgress(100);
+ }
+ });
+
+ gltfLoaderWorker.onmessage = async (event) => {
+ if (event.data.message === "gltfLoaded" && event.data.modelBlob) {
+ const blobUrl = URL.createObjectURL(event.data.modelBlob);
+
+ loader.load(blobUrl, (gltf) => {
+ URL.revokeObjectURL(blobUrl);
+ THREE.Cache.remove(blobUrl);
+ THREE.Cache.add(event.data.modelID, gltf);
+
+ loadedAssets++;
+ const progress = Math.round((loadedAssets / totalAssets) * 100);
+ updateLoadingProgress(progress);
+
+ if (loadedAssets === totalAssets) {
+ loadInitialFloorItems(
+ itemsGroup,
+ setFloorItems,
+ addEvent,
+ renderDistance
+ );
+ updateLoadingProgress(100);
+ }
});
+ }
+ };
+ }, []);
- gltfLoaderWorker.onmessage = async (event) => {
- if (event.data.message === "gltfLoaded" && event.data.modelBlob) {
- const blobUrl = URL.createObjectURL(event.data.modelBlob);
+ useEffect(() => {
+ assetManagerWorker.onmessage = async (event) => {
+ cancelOngoingTasks(); // Cancel the ongoing process
+ await assetManager(event.data, itemsGroup, loader);
+ };
+ }, [assetManagerWorker]);
- loader.load(blobUrl, (gltf) => {
- URL.revokeObjectURL(blobUrl);
- THREE.Cache.remove(blobUrl);
- THREE.Cache.add(event.data.modelID, gltf);
+ useEffect(() => {
+ if (toggleView) return;
- loadedAssets++;
- const progress = Math.round((loadedAssets / totalAssets) * 100);
- updateLoadingProgress(progress);
+ const uuids: string[] = [];
+ itemsGroup.current?.children.forEach((child: any) => {
+ uuids.push(child.uuid);
+ });
+ const cameraPosition = state.camera.position;
- if (loadedAssets === totalAssets) {
- loadInitialFloorItems(itemsGroup, setFloorItems, addEvent, renderDistance);
- updateLoadingProgress(100);
- }
- });
- }
- };
- }, []);
+ assetManagerWorker.postMessage({
+ floorItems,
+ cameraPosition,
+ uuids,
+ renderDistance,
+ });
+ }, [camMode, renderDistance]);
- useEffect(() => {
- assetManagerWorker.onmessage = async (event) => {
- cancelOngoingTasks(); // Cancel the ongoing process
- await assetManager(event.data, itemsGroup, loader);
- };
- }, [assetManagerWorker]);
+ useEffect(() => {
+ const controls: any = state.controls;
+ const camera: any = state.camera;
- useEffect(() => {
+ if (controls) {
+ let intervalId: NodeJS.Timeout | null = null;
+
+ const handleChange = () => {
if (toggleView) return;
const uuids: string[] = [];
- itemsGroup.current?.children.forEach((child: any) => { uuids.push(child.uuid); });
- const cameraPosition = state.camera.position;
+ itemsGroup.current?.children.forEach((child: any) => {
+ uuids.push(child.uuid);
+ });
+ const cameraPosition = camera.position;
- assetManagerWorker.postMessage({ floorItems, cameraPosition, uuids, renderDistance, });
- }, [camMode, renderDistance]);
+ assetManagerWorker.postMessage({
+ floorItems,
+ cameraPosition,
+ uuids,
+ renderDistance,
+ });
+ };
- useEffect(() => {
- const controls: any = state.controls;
- const camera: any = state.camera;
-
- if (controls) {
- let intervalId: NodeJS.Timeout | null = null;
-
- const handleChange = () => {
- if (toggleView) return;
-
- const uuids: string[] = [];
- itemsGroup.current?.children.forEach((child: any) => { uuids.push(child.uuid); });
- const cameraPosition = camera.position;
-
- assetManagerWorker.postMessage({ floorItems, cameraPosition, uuids, renderDistance, });
- };
-
- const startInterval = () => {
- if (!intervalId) {
- intervalId = setInterval(handleChange, 50);
- }
- };
-
- const stopInterval = () => {
- handleChange();
- if (intervalId) {
- clearInterval(intervalId);
- intervalId = null;
- }
- };
-
- controls.addEventListener("rest", handleChange);
- controls.addEventListener("rest", stopInterval);
- controls.addEventListener("control", startInterval);
- controls.addEventListener("controlend", stopInterval);
-
- return () => {
- controls.removeEventListener("rest", handleChange);
- controls.removeEventListener("rest", stopInterval);
- controls.removeEventListener("control", startInterval);
- controls.removeEventListener("controlend", stopInterval);
- if (intervalId) {
- clearInterval(intervalId);
- }
- };
+ const startInterval = () => {
+ if (!intervalId) {
+ intervalId = setInterval(handleChange, 50);
}
- }, [state.controls, floorItems, toggleView, renderDistance]);
+ };
- useEffect(() => {
- const canvasElement = state.gl.domElement;
- let drag = false;
- let isLeftMouseDown = false;
-
- const onMouseDown = (evt: any) => {
- if (evt.button === 0) {
- isLeftMouseDown = true;
- drag = false;
- }
- };
-
- const onMouseMove = () => {
- if (isLeftMouseDown) {
- drag = true;
- }
- };
-
- const onMouseUp = async (evt: any) => {
- if (controls) {
- (controls as any).enabled = true;
- }
- if (evt.button === 0) {
- isLeftMouseDown = false;
- if (drag) return;
-
- if (deleteTool) {
- DeleteFloorItems(itemsGroup, hoveredDeletableFloorItem, setFloorItems, socket);
- }
- const Mode = transformMode;
-
- if (Mode !== null || activeTool === "cursor") {
- if (!itemsGroup.current) return;
- let intersects = raycaster.intersectObjects(
- itemsGroup.current.children,
- true
- );
- if (intersects.length > 0 && intersects[0]?.object?.parent?.parent?.position && intersects[0]?.object?.parent?.parent?.scale && intersects[0]?.object?.parent?.parent?.rotation) {
- // let currentObject = intersects[0].object;
- // while (currentObject) {
- // if (currentObject.name === "Scene") {
- // break;
- // }
- // currentObject = currentObject.parent as THREE.Object3D;
- // }
- // if (currentObject) {
- // AttachedObject.current = currentObject as any;
- // setSelectedFloorItem(AttachedObject.current!);
- // }
- } else {
- const target = controls.getTarget(new THREE.Vector3());
- await controls.setTarget(target.x, 0, target.z, true);
- setSelectedFloorItem(null);
- }
- }
- }
- };
-
- const onDblClick = async (evt: any) => {
- if (evt.button === 0) {
- isLeftMouseDown = false;
- if (drag) return;
-
- const Mode = transformMode;
-
- if (Mode !== null || activeTool === "cursor") {
- if (!itemsGroup.current) return;
- let intersects = raycaster.intersectObjects(itemsGroup.current.children, true);
- if (intersects.length > 0 && intersects[0]?.object?.parent?.parent?.position && intersects[0]?.object?.parent?.parent?.scale && intersects[0]?.object?.parent?.parent?.rotation) {
- let currentObject = intersects[0].object;
-
- while (currentObject) {
- if (currentObject.name === "Scene") {
- break;
- }
- currentObject = currentObject.parent as THREE.Object3D;
- }
- if (currentObject) {
- AttachedObject.current = currentObject as any;
- // controls.fitToSphere(AttachedObject.current!, true);
-
- const bbox = new THREE.Box3().setFromObject(AttachedObject.current);
- const size = bbox.getSize(new THREE.Vector3());
- const center = bbox.getCenter(new THREE.Vector3());
-
- const front = new THREE.Vector3(0, 0, 1);
- AttachedObject.current.localToWorld(front);
- front.sub(AttachedObject.current.position).normalize();
-
- const distance = Math.max(size.x, size.y, size.z) * 2;
- const newPosition = center.clone().addScaledVector(front, distance);
-
- controls.setPosition(newPosition.x, newPosition.y, newPosition.z, true);
- controls.setTarget(center.x, center.y, center.z, true);
- controls.fitToBox(AttachedObject.current!, true, { cover: true, paddingTop: 5, paddingLeft: 5, paddingBottom: 5, paddingRight: 5, });
-
- setSelectedFloorItem(AttachedObject.current!);
- }
- } else {
- const target = controls.getTarget(new THREE.Vector3());
- await controls.setTarget(target.x, 0, target.z, true);
- setSelectedFloorItem(null);
- }
- }
- }
- };
-
- const onDrop = (event: any) => {
- if (!event.dataTransfer?.files[0]) return;
-
- if (selectedItem.id !== "" && event.dataTransfer?.files[0]) {
- addAssetModel(raycaster, state.camera, state.pointer, floorGroup, setFloorItems, itemsGroup, isTempLoader, tempLoader, socket, selectedItem, setSelectedItem, addEvent, plane);
- }
- };
-
- const onDragOver = (event: any) => {
- event.preventDefault();
- };
-
- if (activeModule === "builder") {
- canvasElement.addEventListener("mousedown", onMouseDown);
- canvasElement.addEventListener("mouseup", onMouseUp);
- canvasElement.addEventListener("mousemove", onMouseMove);
- canvasElement.addEventListener("dblclick", onDblClick);
- canvasElement.addEventListener("drop", onDrop);
- canvasElement.addEventListener("dragover", onDragOver);
- } else {
- if (controls) {
- const target = controls.getTarget(new THREE.Vector3());
- controls.setTarget(target.x, 0, target.z, true);
- setSelectedFloorItem(null);
- }
+ const stopInterval = () => {
+ handleChange();
+ if (intervalId) {
+ clearInterval(intervalId);
+ intervalId = null;
}
+ };
- return () => {
- canvasElement.removeEventListener("mousedown", onMouseDown);
- canvasElement.removeEventListener("mouseup", onMouseUp);
- canvasElement.removeEventListener("mousemove", onMouseMove);
- canvasElement.removeEventListener("dblclick", onDblClick);
- canvasElement.removeEventListener("drop", onDrop);
- canvasElement.removeEventListener("dragover", onDragOver);
- };
- }, [deleteTool, transformMode, controls, selectedItem, state.camera, state.pointer, activeTool, activeModule,]);
+ controls.addEventListener("rest", handleChange);
+ controls.addEventListener("rest", stopInterval);
+ controls.addEventListener("control", startInterval);
+ controls.addEventListener("controlend", stopInterval);
- useFrame(() => {
- if (controls)
- // assetVisibility(itemsGroup, state.camera.position, renderDistance);
- if (deleteTool && activeModule === "builder") {
- DeletableHoveredFloorItems(state, itemsGroup, hoveredDeletableFloorItem, setDeletableFloorItem);
- } else if (!deleteTool) {
- if (hoveredDeletableFloorItem.current) {
- hoveredDeletableFloorItem.current = undefined;
- setDeletableFloorItem(null);
- }
+ return () => {
+ controls.removeEventListener("rest", handleChange);
+ controls.removeEventListener("rest", stopInterval);
+ controls.removeEventListener("control", startInterval);
+ controls.removeEventListener("controlend", stopInterval);
+ if (intervalId) {
+ clearInterval(intervalId);
+ }
+ };
+ }
+ }, [state.controls, floorItems, toggleView, renderDistance]);
+
+ useEffect(() => {
+ const canvasElement = state.gl.domElement;
+ let drag = false;
+ let isLeftMouseDown = false;
+
+ const onMouseDown = (evt: any) => {
+ if (evt.button === 0) {
+ isLeftMouseDown = true;
+ drag = false;
+ }
+ };
+
+ const onMouseMove = () => {
+ console.log('isLeftMouseDown: ', isLeftMouseDown);
+ if (isLeftMouseDown) {
+ drag = true;
+ }
+ };
+
+ const onMouseUp = async (evt: any) => {
+ if (controls) {
+ (controls as any).enabled = true;
+ }
+ if (evt.button === 0) {
+ isLeftMouseDown = false;
+ if (drag) return;
+
+ if (deleteTool) {
+ DeleteFloorItems(
+ itemsGroup,
+ hoveredDeletableFloorItem,
+ setFloorItems,
+ socket
+ );
+ }
+ const Mode = transformMode;
+
+ if (Mode !== null || activeTool === "cursor") {
+ if (!itemsGroup.current) return;
+ let intersects = raycaster.intersectObjects(
+ itemsGroup.current.children,
+ true
+ );
+ if (
+ intersects.length > 0 &&
+ intersects[0]?.object?.parent?.parent?.position &&
+ intersects[0]?.object?.parent?.parent?.scale &&
+ intersects[0]?.object?.parent?.parent?.rotation
+ ) {
+ // let currentObject = intersects[0].object;
+ // while (currentObject) {
+ // if (currentObject.name === "Scene") {
+ // break;
+ // }
+ // currentObject = currentObject.parent as THREE.Object3D;
+ // }
+ // if (currentObject) {
+ // AttachedObject.current = currentObject as any;
+ // setSelectedFloorItem(AttachedObject.current!);
+ // }
+ } else {
+ const target = controls.getTarget(new THREE.Vector3());
+ await controls.setTarget(target.x, 0, target.z, true);
+ setSelectedFloorItem(null);
+ }
+ }
+ }
+ };
+
+ const onDblClick = async (evt: any) => {
+ if (evt.button === 0) {
+ isLeftMouseDown = false;
+ if (drag) return;
+
+ const Mode = transformMode;
+
+ if (Mode !== null || activeTool === "cursor") {
+ if (!itemsGroup.current) return;
+ let intersects = raycaster.intersectObjects(
+ itemsGroup.current.children,
+ true
+ );
+ if (
+ intersects.length > 0 &&
+ intersects[0]?.object?.parent?.parent?.position &&
+ intersects[0]?.object?.parent?.parent?.scale &&
+ intersects[0]?.object?.parent?.parent?.rotation
+ ) {
+ let currentObject = intersects[0].object;
+
+ while (currentObject) {
+ if (currentObject.name === "Scene") {
+ break;
+ }
+ currentObject = currentObject.parent as THREE.Object3D;
}
- });
+ if (currentObject) {
+ AttachedObject.current = currentObject as any;
+ // controls.fitToSphere(AttachedObject.current!, true);
- return
;
+ const bbox = new THREE.Box3().setFromObject(
+ AttachedObject.current
+ );
+ const size = bbox.getSize(new THREE.Vector3());
+ const center = bbox.getCenter(new THREE.Vector3());
+
+ const front = new THREE.Vector3(0, 0, 1);
+ AttachedObject.current.localToWorld(front);
+ front.sub(AttachedObject.current.position).normalize();
+
+ const distance = Math.max(size.x, size.y, size.z) * 2;
+ const newPosition = center
+ .clone()
+ .addScaledVector(front, distance);
+
+ controls.setPosition(
+ newPosition.x,
+ newPosition.y,
+ newPosition.z,
+ true
+ );
+ controls.setTarget(center.x, center.y, center.z, true);
+ controls.fitToBox(AttachedObject.current!, true, {
+ cover: true,
+ paddingTop: 5,
+ paddingLeft: 5,
+ paddingBottom: 5,
+ paddingRight: 5,
+ });
+
+ setSelectedFloorItem(AttachedObject.current!);
+ }
+ } else {
+ const target = controls.getTarget(new THREE.Vector3());
+ await controls.setTarget(target.x, 0, target.z, true);
+ setSelectedFloorItem(null);
+ }
+ }
+ }
+ };
+
+ const onDrop = (event: any) => {
+ if (!event.dataTransfer?.files[0]) return;
+
+ if (selectedItem.id !== "" && event.dataTransfer?.files[0]) {
+ addAssetModel(
+ raycaster,
+ state.camera,
+ state.pointer,
+ floorGroup,
+ setFloorItems,
+ itemsGroup,
+ isTempLoader,
+ tempLoader,
+ socket,
+ selectedItem,
+ setSelectedItem,
+ addEvent,
+ plane
+ );
+ }
+ };
+
+ const onDragOver = (event: any) => {
+ event.preventDefault();
+ };
+
+ if (activeModule === "builder") {
+ canvasElement.addEventListener("mousedown", onMouseDown);
+ canvasElement.addEventListener("mouseup", onMouseUp);
+ canvasElement.addEventListener("mousemove", onMouseMove);
+ canvasElement.addEventListener("dblclick", onDblClick);
+ canvasElement.addEventListener("drop", onDrop);
+ canvasElement.addEventListener("dragover", onDragOver);
+ } else {
+ if (controls) {
+ const target = controls.getTarget(new THREE.Vector3());
+ controls.setTarget(target.x, 0, target.z, true);
+ setSelectedFloorItem(null);
+ }
+ }
+
+ return () => {
+ canvasElement.removeEventListener("mousedown", onMouseDown);
+ canvasElement.removeEventListener("mouseup", onMouseUp);
+ canvasElement.removeEventListener("mousemove", onMouseMove);
+ canvasElement.removeEventListener("dblclick", onDblClick);
+ canvasElement.removeEventListener("drop", onDrop);
+ canvasElement.removeEventListener("dragover", onDragOver);
+ };
+ }, [
+ deleteTool,
+ transformMode,
+ controls,
+ selectedItem,
+ state.camera,
+ state.pointer,
+ activeTool,
+ activeModule,
+ ]);
+
+ useFrame(() => {
+ if (controls)
+ if (deleteTool && activeModule === "builder") {
+ // assetVisibility(itemsGroup, state.camera.position, renderDistance);
+ DeletableHoveredFloorItems(
+ state,
+ itemsGroup,
+ hoveredDeletableFloorItem,
+ setDeletableFloorItem
+ );
+ } else if (!deleteTool) {
+ if (hoveredDeletableFloorItem.current) {
+ hoveredDeletableFloorItem.current = undefined;
+ setDeletableFloorItem(null);
+ }
+ }
+ });
+
+ return
;
};
export default FloorItemsGroup;
diff --git a/app/src/styles/components/simulation/analysis.scss b/app/src/styles/components/simulation/analysis.scss
index 44d4ba0..9456dc8 100644
--- a/app/src/styles/components/simulation/analysis.scss
+++ b/app/src/styles/components/simulation/analysis.scss
@@ -104,7 +104,6 @@
.metrics-section {
padding-top: 16px;
- border-top: 1px solid var(--background-color-gray);
.metric {
display: flex;
@@ -124,7 +123,7 @@
}
}
- .throughoutSummary-wrapper {
+ .production-wrapper {
.process-container {
display: flex;
flex-direction: row;
@@ -172,6 +171,8 @@
.footer-card {
width: 100%;
background: var(--background-color-gray);
+
+ border: 1px solid var(--border-color);
border-radius: 6px;
padding: 8px;
display: flex;
@@ -303,15 +304,19 @@
border: 1px solid var(--border-color);
.info {
+ opacity: 0.8;
+
span {
font-size: var(--font-size-xlarge);
&:first-child {
color: #31c756;
+ opacity: 1;
}
&:last-child {
color: var(--text-color);
+ opacity: 1;
}
}
}
@@ -361,6 +366,8 @@
&:last-child {
align-items: center;
+
+
}
.metric-label {
@@ -378,6 +385,15 @@
}
}
+ .metric-item.net-profit {
+ .metric-label {
+
+ span {
+ color: #21ad50;
+ }
+ }
+ }
+
.metric-wrapper {
display: flex;
gap: 6px;
@@ -446,6 +462,7 @@
padding: 8px;
text-align: left;
border: 1px solid var(--border-color);
+ font-size: var(--font-size-small);
}
th {
@@ -486,6 +503,24 @@
color: #488ef6;
}
}
+
+ .placeHolder-wrapper {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ padding-top: 6px;
+
+ .placeHolder {
+ height: 11px;
+ width: 100%;
+ background: #EAEAEA;
+ border-radius: 4px;
+
+ &:nth-child(2) {
+ width: 50%;
+ }
+ }
+ }
}
}