Refactor version management: Replace useSaveVersion with useIsComparing across components
- Updated MainScene, SideBarLeft, SideBarRight, Simulations, and CompareLayOut to utilize isComparing state instead of isVersionSaved. - Adjusted conditional rendering and logic to reflect the new comparison state. - Introduced SyncCam component to synchronize camera state during comparisons. - Created useSceneStore to manage camera state with position and target vectors. - Cleaned up imports and ensured consistent formatting across affected files.
This commit is contained in:
@@ -10,7 +10,6 @@ import ForgotPassword from "./pages/ForgotPassword";
|
|||||||
import PageNotFound from "./pages/PageNotFound";
|
import PageNotFound from "./pages/PageNotFound";
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Cache.clear();
|
Cache.clear();
|
||||||
Cache.enabled = true;
|
Cache.enabled = true;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { useCompareProductDataStore, useLoadingProgress, useSaveVersion } from "../../../store/builder/store";
|
import { useCompareProductDataStore, useLoadingProgress, useIsComparing } from "../../../store/builder/store";
|
||||||
import { useComparisonProduct, useMainProduct } from "../../../store/simulation/useSimulationStore";
|
import { useComparisonProduct, useMainProduct } from "../../../store/simulation/useSimulationStore";
|
||||||
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
@@ -9,21 +9,18 @@ import CompareLayOut from "../../ui/compareVersion/CompareLayOut";
|
|||||||
import ComparisonResult from "../../ui/compareVersion/ComparisonResult";
|
import ComparisonResult from "../../ui/compareVersion/ComparisonResult";
|
||||||
import RegularDropDown from "../../ui/inputs/RegularDropDown";
|
import RegularDropDown from "../../ui/inputs/RegularDropDown";
|
||||||
|
|
||||||
import { getVersionHistoryApi } from "../../../services/factoryBuilder/versionControl/getVersionHistoryApi";
|
|
||||||
|
|
||||||
function ComparisonScene() {
|
function ComparisonScene() {
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
const { productStore, versionStore } = useSceneContext();
|
const { productStore, versionStore } = useSceneContext();
|
||||||
const { versionHistory, selectedVersion, setSelectedVersion, setVersions } = versionStore();
|
const { versionHistory, selectedVersion, setSelectedVersion } = versionStore();
|
||||||
const { products, selectedProduct } = productStore();
|
const { products, selectedProduct } = productStore();
|
||||||
const { isVersionSaved } = useSaveVersion();
|
const { isComparing } = useIsComparing();
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
const { comparisonProduct, setComparisonProduct } = useComparisonProduct();
|
const { comparisonProduct, setComparisonProduct } = useComparisonProduct();
|
||||||
const { mainProduct } = useMainProduct();
|
const { mainProduct } = useMainProduct();
|
||||||
const { loadingProgress } = useLoadingProgress();
|
const { loadingProgress } = useLoadingProgress();
|
||||||
const { compareProductsData } = useCompareProductDataStore();
|
const { compareProductsData } = useCompareProductDataStore();
|
||||||
const [shouldShowComparisonResult, setShouldShowComparisonResult] = useState(false);
|
const [shouldShowComparisonResult, setShouldShowComparisonResult] = useState(false);
|
||||||
const { projectId } = useParams();
|
|
||||||
|
|
||||||
const handleSelectVersion = (option: string) => {
|
const handleSelectVersion = (option: string) => {
|
||||||
const version = versionHistory.find((version) => version.versionName === option);
|
const version = versionHistory.find((version) => version.versionName === option);
|
||||||
@@ -39,30 +36,6 @@ function ComparisonScene() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!projectId) return;
|
|
||||||
|
|
||||||
getVersionHistoryApi(projectId)
|
|
||||||
.then((data) => {
|
|
||||||
const versions: VersionHistory = [];
|
|
||||||
data.versions.forEach((version: any) => {
|
|
||||||
versions.push({
|
|
||||||
version: version.version,
|
|
||||||
versionId: version.versionId,
|
|
||||||
versionName: version.versionName,
|
|
||||||
versionDescription: version.description,
|
|
||||||
timeStamp: version.createdAt,
|
|
||||||
createdBy: version.createdBy.userName,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
setVersions(versions);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
console.error("Error fetching version history");
|
|
||||||
});
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [projectId]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (mainProduct && comparisonProduct && compareProductsData.length > 1) {
|
if (mainProduct && comparisonProduct && compareProductsData.length > 1) {
|
||||||
const hasMain = compareProductsData.some((val) => val.productUuid === mainProduct.productUuid);
|
const hasMain = compareProductsData.some((val) => val.productUuid === mainProduct.productUuid);
|
||||||
@@ -79,7 +52,7 @@ function ComparisonScene() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isVersionSaved && activeModule === "simulation" && selectedProduct && (
|
{isComparing && activeModule === "simulation" && selectedProduct && (
|
||||||
<>
|
<>
|
||||||
{selectedVersion && !isPlaying && (
|
{selectedVersion && !isPlaying && (
|
||||||
<div className="initial-selectLayout-wrapper">
|
<div className="initial-selectLayout-wrapper">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { useLoadingProgress, useRenameModeStore, useSaveVersion, useSelectedComment, useSocketStore, useWidgetSubOption } from "../../../store/builder/store";
|
import { useLoadingProgress, useRenameModeStore, useIsComparing, useSelectedComment, useSocketStore, useWidgetSubOption } from "../../../store/builder/store";
|
||||||
import useModuleStore, { useThreeDStore } from "../../../store/ui/useModuleStore";
|
import useModuleStore, { useThreeDStore } from "../../../store/ui/useModuleStore";
|
||||||
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
||||||
import { useSelectedZoneStore } from "../../../store/visualization/useZoneStore";
|
import { useSelectedZoneStore } from "../../../store/visualization/useZoneStore";
|
||||||
@@ -36,7 +36,7 @@ import { getVersionHistoryApi } from "../../../services/factoryBuilder/versionCo
|
|||||||
|
|
||||||
function MainScene() {
|
function MainScene() {
|
||||||
const { setMainProduct } = useMainProduct();
|
const { setMainProduct } = useMainProduct();
|
||||||
const { isVersionSaved, setIsVersionSaved } = useSaveVersion();
|
const { isComparing, setIsComparing } = useIsComparing();
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
const { selectedUser } = useSelectedUserStore();
|
const { selectedUser } = useSelectedUserStore();
|
||||||
const { loadingProgress } = useLoadingProgress();
|
const { loadingProgress } = useLoadingProgress();
|
||||||
@@ -67,9 +67,9 @@ function MainScene() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (activeModule !== "simulation") {
|
if (activeModule !== "simulation") {
|
||||||
clearComparisonProduct();
|
clearComparisonProduct();
|
||||||
setIsVersionSaved(false);
|
setIsComparing(false);
|
||||||
}
|
}
|
||||||
}, [activeModule, clearComparisonProduct, setIsVersionSaved]);
|
}, [activeModule, clearComparisonProduct, setIsComparing]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!projectId) return;
|
if (!projectId) return;
|
||||||
@@ -162,14 +162,14 @@ function MainScene() {
|
|||||||
{loadingProgress > 0 && <LoadingPage progress={loadingProgress} />}
|
{loadingProgress > 0 && <LoadingPage progress={loadingProgress} />}
|
||||||
{!isPlaying && (
|
{!isPlaying && (
|
||||||
<>
|
<>
|
||||||
{toggleThreeD && !isVersionSaved && <ModuleToggle />}
|
{toggleThreeD && !isComparing && <ModuleToggle />}
|
||||||
<SideBarLeft />
|
<SideBarLeft />
|
||||||
<SideBarRight />
|
<SideBarRight />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<RealTimeVisulization />
|
<RealTimeVisulization />
|
||||||
{activeModule === "market" && <MarketPlace />}
|
{activeModule === "market" && <MarketPlace />}
|
||||||
{activeModule !== "market" && !isPlaying && !isVersionSaved && <Tools />}
|
{activeModule !== "market" && !isPlaying && !isComparing && <Tools />}
|
||||||
{isPlaying && activeModule === "simulation" && loadingProgress === 0 && <SimulationPlayer />}
|
{isPlaying && activeModule === "simulation" && loadingProgress === 0 && <SimulationPlayer />}
|
||||||
{isPlaying && activeModule !== "simulation" && <ControlsPlayer />}
|
{isPlaying && activeModule !== "simulation" && <ControlsPlayer />}
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ function MainScene() {
|
|||||||
<Scene layout="Main Layout" />
|
<Scene layout="Main Layout" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{selectedProduct && selectedVersion && isVersionSaved && !isPlaying && activeModule === "simulation" && (
|
{selectedProduct && selectedVersion && isComparing && !isPlaying && activeModule === "simulation" && (
|
||||||
<div className="selectLayout-wrapper">
|
<div className="selectLayout-wrapper">
|
||||||
<RegularDropDown
|
<RegularDropDown
|
||||||
header={selectedVersion.versionName}
|
header={selectedVersion.versionName}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import useModuleStore from "../../../store/ui/useModuleStore";
|
|||||||
import Widgets from "./visualization/widgets/Widgets";
|
import Widgets from "./visualization/widgets/Widgets";
|
||||||
import Templates from "../../../modules/visualization/template/Templates";
|
import Templates from "../../../modules/visualization/template/Templates";
|
||||||
import Search from "../../ui/inputs/Search";
|
import Search from "../../ui/inputs/Search";
|
||||||
import { useSaveVersion } from "../../../store/builder/store";
|
import { useIsComparing } from "../../../store/builder/store";
|
||||||
|
|
||||||
const SideBarLeft: React.FC = () => {
|
const SideBarLeft: React.FC = () => {
|
||||||
const [activeOption, setActiveOption] = useState("Widgets");
|
const [activeOption, setActiveOption] = useState("Widgets");
|
||||||
@@ -16,7 +16,7 @@ const SideBarLeft: React.FC = () => {
|
|||||||
const { toggleUILeft } = useToggleStore();
|
const { toggleUILeft } = useToggleStore();
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
|
|
||||||
const { isVersionSaved } = useSaveVersion();
|
const { isComparing } = useIsComparing();
|
||||||
|
|
||||||
// Reset activeOption whenever activeModule changes
|
// Reset activeOption whenever activeModule changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -35,7 +35,7 @@ const SideBarLeft: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`sidebar-left-wrapper ${toggleUILeft && (!isVersionSaved || activeModule !== "simulation") ? "open" : "closed"
|
className={`sidebar-left-wrapper ${toggleUILeft && (!isComparing || activeModule !== "simulation") ? "open" : "closed"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<Header />
|
<Header />
|
||||||
@@ -74,7 +74,7 @@ const SideBarLeft: React.FC = () => {
|
|||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!isVersionSaved && (
|
{!isComparing && (
|
||||||
<>
|
<>
|
||||||
<ToggleHeader
|
<ToggleHeader
|
||||||
options={["Outline"]}
|
options={["Outline"]}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { useToggleStore } from "../../../store/ui/useUIToggleStore";
|
|||||||
import Visualization from "./visualization/Visualization";
|
import Visualization from "./visualization/Visualization";
|
||||||
import Analysis from "./analysis/Analysis";
|
import Analysis from "./analysis/Analysis";
|
||||||
import Simulations from "./simulation/Simulations";
|
import Simulations from "./simulation/Simulations";
|
||||||
import useVersionHistoryVisibleStore, { useSaveVersion, useToolMode } from "../../../store/builder/store";
|
import useVersionHistoryVisibleStore, { useIsComparing, useToolMode } from "../../../store/builder/store";
|
||||||
import { useSelectedEventData, useSelectedEventSphere, } from "../../../store/simulation/useSimulationStore";
|
import { useSelectedEventData, useSelectedEventSphere, } from "../../../store/simulation/useSimulationStore";
|
||||||
import { useBuilderStore } from "../../../store/builder/useBuilderStore";
|
import { useBuilderStore } from "../../../store/builder/useBuilderStore";
|
||||||
import GlobalProperties from "./properties/GlobalProperties";
|
import GlobalProperties from "./properties/GlobalProperties";
|
||||||
@@ -52,7 +52,7 @@ const SideBarRight: React.FC = () => {
|
|||||||
const { selectedEventData } = useSelectedEventData();
|
const { selectedEventData } = useSelectedEventData();
|
||||||
const { selectedEventSphere } = useSelectedEventSphere();
|
const { selectedEventSphere } = useSelectedEventSphere();
|
||||||
const { viewVersionHistory, setVersionHistoryVisible } = useVersionHistoryVisibleStore();
|
const { viewVersionHistory, setVersionHistoryVisible } = useVersionHistoryVisibleStore();
|
||||||
const { isVersionSaved } = useSaveVersion();
|
const { isComparing } = useIsComparing();
|
||||||
|
|
||||||
const [displayComponent, setDisplayComponent] = useState<DisplayComponent>("none");
|
const [displayComponent, setDisplayComponent] = useState<DisplayComponent>("none");
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ const SideBarRight: React.FC = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isVersionSaved && activeModule === "simulation") {
|
if (!isComparing && activeModule === "simulation") {
|
||||||
if (subModule === "simulations") {
|
if (subModule === "simulations") {
|
||||||
setDisplayComponent("simulations");
|
setDisplayComponent("simulations");
|
||||||
return;
|
return;
|
||||||
@@ -155,7 +155,7 @@ const SideBarRight: React.FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setDisplayComponent("none");
|
setDisplayComponent("none");
|
||||||
}, [viewVersionHistory, activeModule, subModule, isVersionSaved, selectedFloorAsset, selectedWall, selectedFloor, selectedAisle, toolMode, selectedDecal]);
|
}, [viewVersionHistory, activeModule, subModule, isComparing, selectedFloorAsset, selectedWall, selectedFloor, selectedAisle, toolMode, selectedDecal]);
|
||||||
|
|
||||||
const renderComponent = () => {
|
const renderComponent = () => {
|
||||||
switch (displayComponent) {
|
switch (displayComponent) {
|
||||||
@@ -197,11 +197,11 @@ const SideBarRight: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`sidebar-right-wrapper ${toggleUIRight && (!isVersionSaved || activeModule !== "simulation") ? "open" : "closed"}`} onPointerDown={(e) => e.stopPropagation()}>
|
<div className={`sidebar-right-wrapper ${toggleUIRight && (!isComparing || activeModule !== "simulation") ? "open" : "closed"}`} onPointerDown={(e) => e.stopPropagation()}>
|
||||||
<Header />
|
<Header />
|
||||||
{toggleUIRight && (
|
{toggleUIRight && (
|
||||||
<>
|
<>
|
||||||
{(!isVersionSaved || activeModule !== "simulation") && (
|
{(!isComparing || activeModule !== "simulation") && (
|
||||||
<div className="sidebar-actions-container">
|
<div className="sidebar-actions-container">
|
||||||
{activeModule !== "simulation" && (
|
{activeModule !== "simulation" && (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { deleteProductApi } from "../../../../services/simulation/products/delet
|
|||||||
import { renameProductApi } from "../../../../services/simulation/products/renameProductApi";
|
import { renameProductApi } from "../../../../services/simulation/products/renameProductApi";
|
||||||
import { determineExecutionMachineSequences } from "../../../../modules/simulation/simulator/functions/determineExecutionMachineSequences";
|
import { determineExecutionMachineSequences } from "../../../../modules/simulation/simulator/functions/determineExecutionMachineSequences";
|
||||||
import ComparePopUp from "../../../ui/compareVersion/Compare";
|
import ComparePopUp from "../../../ui/compareVersion/Compare";
|
||||||
import { useCompareStore, useSaveVersion } from "../../../../store/builder/store";
|
import { useCompareStore, useIsComparing } from "../../../../store/builder/store";
|
||||||
import { useToggleStore } from "../../../../store/ui/useUIToggleStore";
|
import { useToggleStore } from "../../../../store/ui/useUIToggleStore";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { useSceneContext } from "../../../../modules/scene/sceneContext";
|
import { useSceneContext } from "../../../../modules/scene/sceneContext";
|
||||||
@@ -36,10 +36,10 @@ const Simulations: React.FC = () => {
|
|||||||
const { setMainProduct } = useMainProduct();
|
const { setMainProduct } = useMainProduct();
|
||||||
const { selectedVersion } = versionStore();
|
const { selectedVersion } = versionStore();
|
||||||
const { comparePopUp, setComparePopUp } = useCompareStore();
|
const { comparePopUp, setComparePopUp } = useCompareStore();
|
||||||
const { setIsVersionSaved } = useSaveVersion();
|
const { setIsComparing } = useIsComparing();
|
||||||
|
|
||||||
const handleSaveVersion = () => {
|
const handleSaveVersion = () => {
|
||||||
setIsVersionSaved(true);
|
setIsComparing(true);
|
||||||
setComparePopUp(false);
|
setComparePopUp(false);
|
||||||
setToggleUI(false, false);
|
setToggleUI(false, false);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
|
import { useParams } from "react-router-dom";
|
||||||
import React, { useState, useRef, useEffect, Suspense } from "react";
|
import React, { useState, useRef, useEffect, Suspense } from "react";
|
||||||
import { CompareLayoutIcon, LayoutIcon, ResizerIcon } from "../../icons/SimulationIcons";
|
import { CompareLayoutIcon, LayoutIcon, ResizerIcon } from "../../icons/SimulationIcons";
|
||||||
import { useLoadingProgress, useSaveVersion } from "../../../store/builder/store";
|
import { useLoadingProgress, useIsComparing } from "../../../store/builder/store";
|
||||||
import Search from "../inputs/Search";
|
|
||||||
import OuterClick from "../../../utils/outerClick";
|
|
||||||
import Scene from "../../../modules/scene/scene";
|
|
||||||
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore";
|
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore";
|
||||||
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
import { usePlayButtonStore } from "../../../store/ui/usePlayButtonStore";
|
||||||
import { useSceneContext } from "../../../modules/scene/sceneContext";
|
import { useSceneContext } from "../../../modules/scene/sceneContext";
|
||||||
import { getAllProductsApi } from "../../../services/simulation/products/getallProductsApi";
|
import { getAllProductsApi } from "../../../services/simulation/products/getallProductsApi";
|
||||||
import { useParams } from "react-router-dom";
|
import Search from "../inputs/Search";
|
||||||
|
import OuterClick from "../../../utils/outerClick";
|
||||||
|
import Scene from "../../../modules/scene/scene";
|
||||||
|
import useRestStates from "../../../hooks/useResetStates";
|
||||||
|
|
||||||
|
import { getVersionHistoryApi } from "../../../services/factoryBuilder/versionControl/getVersionHistoryApi";
|
||||||
|
|
||||||
const CompareLayOut = () => {
|
const CompareLayOut = () => {
|
||||||
const { clearComparisonProduct, comparisonProduct, setComparisonProduct } = useComparisonProduct();
|
const { clearComparisonProduct, comparisonProduct, setComparisonProduct } = useComparisonProduct();
|
||||||
const { versionStore } = useSceneContext();
|
const { versionStore } = useSceneContext();
|
||||||
const { versionHistory, selectedVersion, setSelectedVersion, clearSelectedVersion } = versionStore();
|
const { versionHistory, selectedVersion, setSelectedVersion, clearSelectedVersion, setVersions } = versionStore();
|
||||||
const { setLoadingProgress } = useLoadingProgress();
|
const { setLoadingProgress } = useLoadingProgress();
|
||||||
const [width, setWidth] = useState("50vw");
|
const [width, setWidth] = useState("50vw");
|
||||||
const [isResizing, setIsResizing] = useState(false);
|
const [isResizing, setIsResizing] = useState(false);
|
||||||
@@ -21,10 +24,43 @@ const CompareLayOut = () => {
|
|||||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||||
const startWidthRef = useRef<number>(0);
|
const startWidthRef = useRef<number>(0);
|
||||||
const startXRef = useRef<number>(0);
|
const startXRef = useRef<number>(0);
|
||||||
const { setIsVersionSaved } = useSaveVersion();
|
const { setIsComparing } = useIsComparing();
|
||||||
const { loadingProgress } = useLoadingProgress();
|
const { loadingProgress } = useLoadingProgress();
|
||||||
const { setIsPlaying } = usePlayButtonStore();
|
const { setIsPlaying } = usePlayButtonStore();
|
||||||
const { projectId } = useParams();
|
const { projectId } = useParams();
|
||||||
|
const { resetStates } = useRestStates();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
if (selectedVersion?.versionId) {
|
||||||
|
resetStates();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [selectedVersion?.versionId]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!projectId) return;
|
||||||
|
|
||||||
|
getVersionHistoryApi(projectId)
|
||||||
|
.then((data) => {
|
||||||
|
const versions: VersionHistory = [];
|
||||||
|
data.versions.forEach((version: any) => {
|
||||||
|
versions.push({
|
||||||
|
version: version.version,
|
||||||
|
versionId: version.versionId,
|
||||||
|
versionName: version.versionName,
|
||||||
|
versionDescription: version.description,
|
||||||
|
timeStamp: version.createdAt,
|
||||||
|
createdBy: version.createdBy.userName,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
setVersions(versions);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
console.error("Error fetching version history");
|
||||||
|
});
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [projectId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!comparisonProduct) {
|
if (!comparisonProduct) {
|
||||||
@@ -71,7 +107,7 @@ const CompareLayOut = () => {
|
|||||||
|
|
||||||
if (finalWidthVw <= 10) {
|
if (finalWidthVw <= 10) {
|
||||||
setWidth("0px");
|
setWidth("0px");
|
||||||
setIsVersionSaved(false);
|
setIsComparing(false);
|
||||||
clearComparisonProduct();
|
clearComparisonProduct();
|
||||||
setIsPlaying(false);
|
setIsPlaying(false);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import * as THREE from 'three';
|
import * as THREE from "three";
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { 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 { useToggleView, useToolMode } from '../../../../../store/builder/store';
|
import { useToggleView, useToolMode } from "../../../../../store/builder/store";
|
||||||
import { AssetBoundingBox } from '../../functions/assetBoundingBox';
|
import { AssetBoundingBox } from "../../functions/assetBoundingBox";
|
||||||
import { useBuilderStore } from '../../../../../store/builder/useBuilderStore';
|
import { useBuilderStore } from "../../../../../store/builder/useBuilderStore";
|
||||||
import useModuleStore from '../../../../../store/ui/useModuleStore';
|
import useModuleStore from "../../../../../store/ui/useModuleStore";
|
||||||
import { useSceneContext } from '../../../../scene/sceneContext';
|
import { useSceneContext } from "../../../../scene/sceneContext";
|
||||||
import { SkeletonUtils } from 'three-stdlib';
|
import { SkeletonUtils } from "three-stdlib";
|
||||||
|
|
||||||
import { getAssetFieldApi } from '../../../../../services/factoryBuilder/asset/floorAsset/getAssetField';
|
import { getAssetFieldApi } from "../../../../../services/factoryBuilder/asset/floorAsset/getAssetField";
|
||||||
import { ModelAnimator } from './animator/modelAnimator';
|
import { ModelAnimator } from "./animator/modelAnimator";
|
||||||
import { useModelEventHandlers } from './eventHandlers/useModelEventHandlers';
|
import { useModelEventHandlers } from "./eventHandlers/useModelEventHandlers";
|
||||||
|
|
||||||
function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendered: boolean; loader: GLTFLoader }>) {
|
function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendered: boolean; loader: GLTFLoader }>) {
|
||||||
const url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
const url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
|
||||||
@@ -31,33 +31,33 @@ function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendere
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!fieldData && asset.eventData) {
|
if (!fieldData && asset.eventData) {
|
||||||
getAssetFieldApi(asset.assetId).then((data) => {
|
getAssetFieldApi(asset.assetId).then((data) => {
|
||||||
if (data.type === 'ArmBot') {
|
if (data.type === "ArmBot") {
|
||||||
if (data.data) {
|
if (data.data) {
|
||||||
const fieldData: IK[] = data.data;
|
const fieldData: IK[] = data.data;
|
||||||
setFieldData(fieldData);
|
setFieldData(fieldData);
|
||||||
}
|
}
|
||||||
} else if (data.type === 'Conveyor' || data.type === 'Crane') {
|
} else if (data.type === "Conveyor" || data.type === "Crane") {
|
||||||
if (data.data) {
|
if (data.data) {
|
||||||
const fieldData = data.data;
|
const fieldData = data.data;
|
||||||
setFieldData(fieldData);
|
setFieldData(fieldData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}, [asset.modelUuid, fieldData])
|
}, [asset.modelUuid, fieldData]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setDeletableFloorAsset(null);
|
setDeletableFloorAsset(null);
|
||||||
if (selectedFloorAsset === null || selectedFloorAsset.userData.modelUuid !== asset.modelUuid) {
|
if (selectedFloorAsset === null || selectedFloorAsset.userData.modelUuid !== asset.modelUuid) {
|
||||||
resetAnimation(asset.modelUuid);
|
resetAnimation(asset.modelUuid);
|
||||||
}
|
}
|
||||||
}, [activeModule, toolMode, selectedFloorAsset])
|
}, [activeModule, toolMode, selectedFloorAsset]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedFloorAsset && selectedFloorAsset.userData.modelUuid === asset.modelUuid) {
|
if (selectedFloorAsset && selectedFloorAsset.userData.modelUuid === asset.modelUuid) {
|
||||||
setSelectedFloorAsset(groupRef.current);
|
setSelectedFloorAsset(groupRef.current);
|
||||||
}
|
}
|
||||||
}, [isRendered, selectedFloorAsset])
|
}, [isRendered, selectedFloorAsset]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedAssets.length > 0) {
|
if (selectedAssets.length > 0) {
|
||||||
@@ -69,7 +69,7 @@ function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendere
|
|||||||
} else {
|
} else {
|
||||||
setIsSelected(false);
|
setIsSelected(false);
|
||||||
}
|
}
|
||||||
}, [selectedAssets])
|
}, [selectedAssets]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (gltfScene) {
|
if (gltfScene) {
|
||||||
@@ -78,13 +78,13 @@ function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendere
|
|||||||
child.castShadow = true;
|
child.castShadow = true;
|
||||||
child.receiveShadow = true;
|
child.receiveShadow = true;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}, [gltfScene]);
|
}, [gltfScene]);
|
||||||
|
|
||||||
const logModelStatus = (modelId: string, status: string) => {
|
const logModelStatus = (modelId: string, status: string) => {
|
||||||
// console.log(modelId, status);
|
// console.log(modelId, status);
|
||||||
}
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Calculate Bounding Box
|
// Calculate Bounding Box
|
||||||
@@ -101,12 +101,13 @@ function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendere
|
|||||||
clone.animations = cachedModel.animations || [];
|
clone.animations = cachedModel.animations || [];
|
||||||
setGltfScene(clone);
|
setGltfScene(clone);
|
||||||
calculateBoundingBox(clone);
|
calculateBoundingBox(clone);
|
||||||
logModelStatus(assetId, 'cache-loaded');
|
logModelStatus(assetId, "cache-loaded");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check IndexedDB
|
// Check IndexedDB
|
||||||
retrieveGLTF(assetId).then((indexedDBModel) => {
|
retrieveGLTF(assetId)
|
||||||
|
.then((indexedDBModel) => {
|
||||||
if (indexedDBModel) {
|
if (indexedDBModel) {
|
||||||
const blobUrl = URL.createObjectURL(indexedDBModel);
|
const blobUrl = URL.createObjectURL(indexedDBModel);
|
||||||
loader.load(
|
loader.load(
|
||||||
@@ -117,10 +118,10 @@ function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendere
|
|||||||
THREE.Cache.add(assetId, gltf);
|
THREE.Cache.add(assetId, gltf);
|
||||||
setGltfScene(gltf.scene.clone());
|
setGltfScene(gltf.scene.clone());
|
||||||
calculateBoundingBox(gltf.scene);
|
calculateBoundingBox(gltf.scene);
|
||||||
logModelStatus(assetId, 'indexedDB-loaded');
|
logModelStatus(assetId, "indexedDB-loaded");
|
||||||
},
|
},
|
||||||
undefined,
|
undefined,
|
||||||
(error) => {
|
() => {
|
||||||
echo.error(`[IndexedDB] Error loading ${asset.modelName}:`);
|
echo.error(`[IndexedDB] Error loading ${asset.modelName}:`);
|
||||||
URL.revokeObjectURL(blobUrl);
|
URL.revokeObjectURL(blobUrl);
|
||||||
}
|
}
|
||||||
@@ -140,21 +141,19 @@ function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendere
|
|||||||
THREE.Cache.add(assetId, gltf);
|
THREE.Cache.add(assetId, gltf);
|
||||||
setGltfScene(gltf.scene.clone());
|
setGltfScene(gltf.scene.clone());
|
||||||
calculateBoundingBox(gltf.scene);
|
calculateBoundingBox(gltf.scene);
|
||||||
logModelStatus(assetId, 'backend-loaded');
|
logModelStatus(assetId, "backend-loaded");
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(
|
console.error(`[Backend] Error storing/loading ${asset.modelName}:`, error);
|
||||||
`[Backend] Error storing/loading ${asset.modelName}:`,
|
|
||||||
error
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
undefined,
|
undefined,
|
||||||
(error) => {
|
() => {
|
||||||
echo.error(`[Backend] Error loading ${asset.modelName}:`);
|
echo.error(`[Backend] Error loading ${asset.modelName}:`);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}).catch((err) => {
|
})
|
||||||
|
.catch((err) => {
|
||||||
console.error("Failed to load model:", asset.assetId, err);
|
console.error("Failed to load model:", asset.assetId, err);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
@@ -164,7 +163,7 @@ function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendere
|
|||||||
return (
|
return (
|
||||||
<group
|
<group
|
||||||
key={asset.modelUuid}
|
key={asset.modelUuid}
|
||||||
name='Asset Model'
|
name="Asset Model"
|
||||||
ref={groupRef}
|
ref={groupRef}
|
||||||
uuid={asset.modelUuid}
|
uuid={asset.modelUuid}
|
||||||
position={asset.position}
|
position={asset.position}
|
||||||
@@ -206,22 +205,14 @@ function Model({ asset, isRendered, loader }: Readonly<{ asset: Asset; isRendere
|
|||||||
<>
|
<>
|
||||||
{isRendered ? (
|
{isRendered ? (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
<primitive object={gltfScene} />
|
<primitive object={gltfScene} />
|
||||||
|
|
||||||
<ModelAnimator asset={asset} gltfScene={gltfScene} />
|
<ModelAnimator asset={asset} gltfScene={gltfScene} />
|
||||||
|
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>{!isSelected && <AssetBoundingBox name="Asset Fallback" boundingBox={boundingBox} color="gray" lineWidth={2.5} />}</>
|
||||||
{!isSelected &&
|
|
||||||
<AssetBoundingBox name='Asset Fallback' boundingBox={boundingBox} color='gray' lineWidth={2.5} />
|
|
||||||
}
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
{isSelected &&
|
{isSelected && <AssetBoundingBox name="Asset BBox" boundingBox={boundingBox} color={savedTheme === "dark" ? "#c4abf1" : "#6f42c1"} lineWidth={2.7} />}
|
||||||
<AssetBoundingBox name='Asset BBox' boundingBox={boundingBox} color={savedTheme === "dark" ? "#c4abf1" : "#6f42c1"} lineWidth={2.7} />
|
|
||||||
}
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</group>
|
</group>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { useThree, useFrame } from "@react-three/fiber";
|
import { useThree, useFrame } from "@react-three/fiber";
|
||||||
import { Group, Vector3 } from "three";
|
import { Group, Vector3 } from "three";
|
||||||
import { CameraControls } from '@react-three/drei';
|
import { CameraControls } from "@react-three/drei";
|
||||||
import { useLimitDistance, useRenderDistance } from '../../../../store/builder/store';
|
import { useLimitDistance, useRenderDistance } 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 { useBuilderStore } from "../../../../store/builder/useBuilderStore";
|
import { useBuilderStore } from "../../../../store/builder/useBuilderStore";
|
||||||
|
|
||||||
import Model from './model/model';
|
import Model from "./model/model";
|
||||||
import { GLTFLoader } from "three/examples/jsm/Addons";
|
import { GLTFLoader } from "three/examples/jsm/Addons";
|
||||||
|
|
||||||
const distanceWorker = new Worker(new URL("../../../../services/factoryBuilder/webWorkers/distanceWorker.js", import.meta.url));
|
const distanceWorker = new Worker(new URL("../../../../services/factoryBuilder/webWorkers/distanceWorker.js", import.meta.url));
|
||||||
@@ -15,7 +15,7 @@ const distanceWorker = new Worker(new URL("../../../../services/factoryBuilder/w
|
|||||||
function Models({ loader }: { readonly loader: GLTFLoader }) {
|
function Models({ loader }: { readonly loader: GLTFLoader }) {
|
||||||
const { controls, camera } = useThree();
|
const { controls, camera } = useThree();
|
||||||
const assetGroupRef = useRef<Group>(null);
|
const assetGroupRef = useRef<Group>(null);
|
||||||
const { assetStore } = useSceneContext();
|
const { assetStore, layout } = useSceneContext();
|
||||||
const { assets } = assetStore();
|
const { assets } = assetStore();
|
||||||
const { selectedFloorAsset, setSelectedFloorAsset } = useBuilderStore();
|
const { selectedFloorAsset, setSelectedFloorAsset } = useBuilderStore();
|
||||||
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
|
const { selectedAsset, clearSelectedAsset } = useSelectedAsset();
|
||||||
@@ -40,13 +40,13 @@ function Models({ loader }: { readonly loader: GLTFLoader }) {
|
|||||||
camera.getWorldPosition(cameraPos.current);
|
camera.getWorldPosition(cameraPos.current);
|
||||||
for (const asset of assets) {
|
for (const asset of assets) {
|
||||||
const isRendered = renderMap[asset.modelUuid] ?? false;
|
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, });
|
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
|
||||||
name='Asset Group'
|
name="Asset Group"
|
||||||
ref={assetGroupRef}
|
ref={assetGroupRef}
|
||||||
onPointerMissed={(e) => {
|
onPointerMissed={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|||||||
32
app/src/modules/scene/camera/syncCam.tsx
Normal file
32
app/src/modules/scene/camera/syncCam.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { useFrame, useThree } from "@react-three/fiber";
|
||||||
|
import { useSceneContext } from "../sceneContext";
|
||||||
|
import { CameraControls } from "@react-three/drei";
|
||||||
|
import { useIsComparing } from "../../../store/builder/store";
|
||||||
|
import useModuleStore from "../../../store/ui/useModuleStore";
|
||||||
|
import { useComparisonProduct } from "../../../store/simulation/useSimulationStore";
|
||||||
|
import { useSceneStore } from "../../../store/scene/useSceneStore";
|
||||||
|
import { Vector3 } from "three";
|
||||||
|
|
||||||
|
function SyncCam() {
|
||||||
|
const { layout } = useSceneContext();
|
||||||
|
const { controls } = useThree();
|
||||||
|
const { isComparing } = useIsComparing();
|
||||||
|
const { activeModule } = useModuleStore();
|
||||||
|
const { comparisonProduct } = useComparisonProduct();
|
||||||
|
const { setCamera, camState } = useSceneStore();
|
||||||
|
|
||||||
|
useFrame(() => {
|
||||||
|
if (layout === "Comparison Layout" && controls && camState) {
|
||||||
|
(controls as CameraControls).setLookAt(camState.position.x, camState.position.y, camState.position.z, camState.target.x, camState.target.y, camState.target.z, true);
|
||||||
|
}
|
||||||
|
if (layout === "Main Layout" && controls && isComparing && activeModule === "simulation" && comparisonProduct) {
|
||||||
|
const position = (controls as CameraControls).getPosition(new Vector3());
|
||||||
|
const target = (controls as CameraControls).getTarget(new Vector3());
|
||||||
|
setCamera(position, target);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SyncCam;
|
||||||
@@ -2,7 +2,7 @@ import { CameraControls } from "@react-three/drei";
|
|||||||
import { useRef, useEffect } from "react";
|
import { useRef, useEffect } from "react";
|
||||||
import { useThree } from "@react-three/fiber";
|
import { useThree } from "@react-three/fiber";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import * as CONSTANTS from '../../../types/world/worldConstants';
|
import * as CONSTANTS from "../../../types/world/worldConstants";
|
||||||
import { useSocketStore, useToggleView, useResetCamera } from "../../../store/builder/store";
|
import { useSocketStore, useToggleView, useResetCamera } from "../../../store/builder/store";
|
||||||
|
|
||||||
import CamMode from "../camera/camMode";
|
import CamMode from "../camera/camMode";
|
||||||
@@ -20,6 +20,7 @@ import { getUserData } from "../../../functions/getUserData";
|
|||||||
import { getCameraApi } from "../../../services/factoryBuilder/camera/getCameraApi";
|
import { getCameraApi } from "../../../services/factoryBuilder/camera/getCameraApi";
|
||||||
import { setCameraApi } from "../../../services/factoryBuilder/camera/setCameraApi";
|
import { setCameraApi } from "../../../services/factoryBuilder/camera/setCameraApi";
|
||||||
import updateCamPosition from "../camera/functions/updateCameraPosition";
|
import updateCamPosition from "../camera/functions/updateCameraPosition";
|
||||||
|
import SyncCam from "../camera/syncCam";
|
||||||
|
|
||||||
export default function Controls() {
|
export default function Controls() {
|
||||||
const controlsRef = useRef<CameraControls>(null);
|
const controlsRef = useRef<CameraControls>(null);
|
||||||
@@ -38,7 +39,8 @@ export default function Controls() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!projectId) return;
|
if (!projectId) return;
|
||||||
getCameraApi(projectId).then((data) => {
|
getCameraApi(projectId)
|
||||||
|
.then((data) => {
|
||||||
if (data?.position && data?.target) {
|
if (data?.position && data?.target) {
|
||||||
controlsRef.current?.setPosition(data.position.x, data.position.y, data.position.z);
|
controlsRef.current?.setPosition(data.position.x, data.position.y, data.position.z);
|
||||||
controlsRef.current?.setTarget(data.target.x, data.target.y, data.target.z);
|
controlsRef.current?.setTarget(data.target.x, data.target.y, data.target.z);
|
||||||
@@ -46,7 +48,8 @@ export default function Controls() {
|
|||||||
controlsRef.current?.setPosition(...CONSTANTS.threeDimension.defaultPosition);
|
controlsRef.current?.setPosition(...CONSTANTS.threeDimension.defaultPosition);
|
||||||
controlsRef.current?.setTarget(...CONSTANTS.threeDimension.defaultTarget);
|
controlsRef.current?.setTarget(...CONSTANTS.threeDimension.defaultTarget);
|
||||||
}
|
}
|
||||||
}).catch((error) => console.error("Failed to fetch camera data:", error));
|
})
|
||||||
|
.catch((error) => console.error("Failed to fetch camera data:", error));
|
||||||
}, [projectId]);
|
}, [projectId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -56,12 +59,7 @@ export default function Controls() {
|
|||||||
controlsRef.current?.rotateAzimuthTo(CONSTANTS.threeDimension.defaultAzimuth);
|
controlsRef.current?.rotateAzimuthTo(CONSTANTS.threeDimension.defaultAzimuth);
|
||||||
|
|
||||||
if (!socket?.connected) {
|
if (!socket?.connected) {
|
||||||
setCameraApi(
|
setCameraApi(projectId, new THREE.Vector3(...CONSTANTS.threeDimension.defaultPosition), new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget), new THREE.Vector3(...CONSTANTS.threeDimension.defaultRotation));
|
||||||
projectId,
|
|
||||||
new THREE.Vector3(...CONSTANTS.threeDimension.defaultPosition),
|
|
||||||
new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget),
|
|
||||||
new THREE.Vector3(...CONSTANTS.threeDimension.defaultRotation),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
const camData = {
|
const camData = {
|
||||||
organization,
|
organization,
|
||||||
@@ -70,9 +68,9 @@ export default function Controls() {
|
|||||||
target: new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget),
|
target: new THREE.Vector3(...CONSTANTS.threeDimension.defaultTarget),
|
||||||
rotation: new THREE.Vector3(...CONSTANTS.threeDimension.defaultRotation),
|
rotation: new THREE.Vector3(...CONSTANTS.threeDimension.defaultRotation),
|
||||||
socketId: socket.id,
|
socketId: socket.id,
|
||||||
projectId
|
projectId,
|
||||||
};
|
};
|
||||||
socket.emit('v1:Camera:set', camData)
|
socket.emit("v1:Camera:set", camData);
|
||||||
}
|
}
|
||||||
|
|
||||||
setResetCamera(false);
|
setResetCamera(false);
|
||||||
@@ -152,6 +150,7 @@ export default function Controls() {
|
|||||||
|
|
||||||
<CameraShortcutsControls />
|
<CameraShortcutsControls />
|
||||||
|
|
||||||
|
<SyncCam />
|
||||||
</CameraControls>
|
</CameraControls>
|
||||||
|
|
||||||
<SelectionControls3D />
|
<SelectionControls3D />
|
||||||
@@ -165,7 +164,6 @@ export default function Controls() {
|
|||||||
<TransformControl />
|
<TransformControl />
|
||||||
|
|
||||||
<ContextControls />
|
<ContextControls />
|
||||||
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,7 @@
|
|||||||
import { useRef, useEffect } from "react";
|
import { useRef, useEffect } from "react";
|
||||||
import { useThree } from "@react-three/fiber";
|
import { useThree } from "@react-three/fiber";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import {
|
import { useAzimuth, useElevation, useShadows, useSunPosition, useTileDistance } from "../../../store/builder/store";
|
||||||
useAzimuth,
|
|
||||||
useElevation,
|
|
||||||
useShadows,
|
|
||||||
useSunPosition,
|
|
||||||
useTileDistance,
|
|
||||||
} from "../../../store/builder/store";
|
|
||||||
import * as CONSTANTS from "../../../types/world/worldConstants";
|
import * as CONSTANTS from "../../../types/world/worldConstants";
|
||||||
|
|
||||||
const shadowWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/shadowWorker", import.meta.url));
|
const shadowWorker = new Worker(new URL("../../../services/factoryBuilder/webWorkers/shadowWorker", import.meta.url));
|
||||||
@@ -67,31 +61,11 @@ export default function Shadows() {
|
|||||||
{/* {(lightRef.current?.shadow) &&
|
{/* {(lightRef.current?.shadow) &&
|
||||||
<cameraHelper visible={shadows} args={[lightRef.current.shadow.camera]} />
|
<cameraHelper visible={shadows} args={[lightRef.current.shadow.camera]} />
|
||||||
} */}
|
} */}
|
||||||
<directionalLight
|
<directionalLight ref={lightRef} castShadow={shadows} shadow-mapSize-width={CONSTANTS.shadowConfig.shadowmapSizewidth} shadow-mapSize-height={CONSTANTS.shadowConfig.shadowmapSizeheight} shadow-camera-far={CONSTANTS.shadowConfig.shadowcamerafar} shadow-camera-near={CONSTANTS.shadowConfig.shadowcameranear} shadow-camera-top={CONSTANTS.shadowConfig.shadowcameratop} shadow-camera-bottom={CONSTANTS.shadowConfig.shadowcamerabottom} shadow-camera-left={CONSTANTS.shadowConfig.shadowcameraleft} shadow-camera-right={CONSTANTS.shadowConfig.shadowcameraright} shadow-bias={CONSTANTS.shadowConfig.shadowbias} shadow-normalBias={CONSTANTS.shadowConfig.shadownormalBias} />
|
||||||
ref={lightRef}
|
|
||||||
castShadow={shadows}
|
|
||||||
shadow-mapSize-width={CONSTANTS.shadowConfig.shadowmapSizewidth}
|
|
||||||
shadow-mapSize-height={CONSTANTS.shadowConfig.shadowmapSizeheight}
|
|
||||||
shadow-camera-far={CONSTANTS.shadowConfig.shadowcamerafar}
|
|
||||||
shadow-camera-near={CONSTANTS.shadowConfig.shadowcameranear}
|
|
||||||
shadow-camera-top={CONSTANTS.shadowConfig.shadowcameratop}
|
|
||||||
shadow-camera-bottom={CONSTANTS.shadowConfig.shadowcamerabottom}
|
|
||||||
shadow-camera-left={CONSTANTS.shadowConfig.shadowcameraleft}
|
|
||||||
shadow-camera-right={CONSTANTS.shadowConfig.shadowcameraright}
|
|
||||||
shadow-bias={CONSTANTS.shadowConfig.shadowbias}
|
|
||||||
shadow-normalBias={CONSTANTS.shadowConfig.shadownormalBias}
|
|
||||||
/>
|
|
||||||
<object3D ref={targetRef} />
|
<object3D ref={targetRef} />
|
||||||
<mesh
|
<mesh position={CONSTANTS.shadowConfig.shadowMaterialPosition} rotation={CONSTANTS.shadowConfig.shadowMaterialRotation} receiveShadow>
|
||||||
position={CONSTANTS.shadowConfig.shadowMaterialPosition}
|
|
||||||
rotation={CONSTANTS.shadowConfig.shadowMaterialRotation}
|
|
||||||
receiveShadow
|
|
||||||
>
|
|
||||||
<planeGeometry args={[planeValue.width, planeValue.height]} />
|
<planeGeometry args={[planeValue.width, planeValue.height]} />
|
||||||
<shadowMaterial
|
<shadowMaterial opacity={CONSTANTS.shadowConfig.shadowMaterialOpacity} transparent />
|
||||||
opacity={CONSTANTS.shadowConfig.shadowMaterialOpacity}
|
|
||||||
transparent
|
|
||||||
/>
|
|
||||||
</mesh>
|
</mesh>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -8,12 +8,7 @@ type SocketStore = {
|
|||||||
dashBoardSocket?: ReturnType<typeof io> | null;
|
dashBoardSocket?: ReturnType<typeof io> | null;
|
||||||
projectSocket?: ReturnType<typeof io> | null;
|
projectSocket?: ReturnType<typeof io> | null;
|
||||||
threadSocket?: ReturnType<typeof io> | null;
|
threadSocket?: ReturnType<typeof io> | null;
|
||||||
initializeSocket: (
|
initializeSocket: (email?: string, organization?: string, token?: string, refreshToken?: string) => void;
|
||||||
email?: string,
|
|
||||||
organization?: string,
|
|
||||||
token?: string,
|
|
||||||
refreshToken?: string
|
|
||||||
) => void;
|
|
||||||
disconnectSocket: () => void;
|
disconnectSocket: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -23,54 +18,34 @@ export const useSocketStore = create<SocketStore>((set, get) => ({
|
|||||||
dashBoardSocket: null,
|
dashBoardSocket: null,
|
||||||
projectSocket: null,
|
projectSocket: null,
|
||||||
threadSocket: null,
|
threadSocket: null,
|
||||||
initializeSocket: (
|
initializeSocket: (email?: string, organization?: string, token?: string, refreshToken?: string) => {
|
||||||
email?: string,
|
|
||||||
organization?: string,
|
|
||||||
token?: string,
|
|
||||||
refreshToken?: string
|
|
||||||
) => {
|
|
||||||
const existingSocket = get().socket;
|
const existingSocket = get().socket;
|
||||||
if (existingSocket) {
|
if (existingSocket) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const socket = io(
|
const socket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder_v1`, {
|
||||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder_v1`,
|
|
||||||
{
|
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
auth: { token, refreshToken },
|
auth: { token, refreshToken },
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
const visualizationSocket = io(
|
const visualizationSocket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization_v1`, {
|
||||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization_v1`,
|
|
||||||
{
|
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
auth: { token, refreshToken },
|
auth: { token, refreshToken },
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
const dashBoardSocket = io(
|
const dashBoardSocket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/dashboard`, {
|
||||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/dashboard`,
|
|
||||||
{
|
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
auth: { token, refreshToken },
|
auth: { token, refreshToken },
|
||||||
}
|
});
|
||||||
);
|
const projectSocket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/project`, {
|
||||||
const projectSocket = io(
|
|
||||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/project`,
|
|
||||||
{
|
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
auth: { token, refreshToken },
|
auth: { token, refreshToken },
|
||||||
}
|
});
|
||||||
);
|
const threadSocket = io(`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/thread`, {
|
||||||
const threadSocket = io(
|
|
||||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/thread`,
|
|
||||||
{
|
|
||||||
reconnection: true,
|
reconnection: true,
|
||||||
auth: { token, refreshToken },
|
auth: { token, refreshToken },
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
set({
|
set({
|
||||||
socket,
|
socket,
|
||||||
@@ -154,8 +129,7 @@ export const useShadows = create<any>((set: any) => ({
|
|||||||
|
|
||||||
export const useSunPosition = create<any>((set: any) => ({
|
export const useSunPosition = create<any>((set: any) => ({
|
||||||
sunPosition: { x: undefined, y: undefined, z: undefined },
|
sunPosition: { x: undefined, y: undefined, z: undefined },
|
||||||
setSunPosition: (newSuntPosition: any) =>
|
setSunPosition: (newSuntPosition: any) => set({ sunPosition: newSuntPosition }),
|
||||||
set({ sunPosition: newSuntPosition }),
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useProjectName = create<any>((set: any) => ({
|
export const useProjectName = create<any>((set: any) => ({
|
||||||
@@ -215,14 +189,12 @@ export const useRenameModeStore = create<any>((set: any) => ({
|
|||||||
|
|
||||||
export const useObjectPosition = create<any>((set: any) => ({
|
export const useObjectPosition = create<any>((set: any) => ({
|
||||||
objectPosition: { x: undefined, y: undefined, z: undefined },
|
objectPosition: { x: undefined, y: undefined, z: undefined },
|
||||||
setObjectPosition: (newObjectPosition: any) =>
|
setObjectPosition: (newObjectPosition: any) => set({ objectPosition: newObjectPosition }),
|
||||||
set({ objectPosition: newObjectPosition }),
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useObjectRotation = create<any>((set: any) => ({
|
export const useObjectRotation = create<any>((set: any) => ({
|
||||||
objectRotation: { x: undefined, y: undefined, z: undefined },
|
objectRotation: { x: undefined, y: undefined, z: undefined },
|
||||||
setObjectRotation: (newObjectRotation: any) =>
|
setObjectRotation: (newObjectRotation: any) => set({ objectRotation: newObjectRotation }),
|
||||||
set({ objectRotation: newObjectRotation }),
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useDrieTemp = create<any>((set: any) => ({
|
export const useDrieTemp = create<any>((set: any) => ({
|
||||||
@@ -234,16 +206,14 @@ export const useActiveUsers = create<any>((set: any) => ({
|
|||||||
activeUsers: [],
|
activeUsers: [],
|
||||||
setActiveUsers: (callback: (prev: any[]) => any[] | any[]) =>
|
setActiveUsers: (callback: (prev: any[]) => any[] | any[]) =>
|
||||||
set((state: { activeUsers: any[] }) => ({
|
set((state: { activeUsers: any[] }) => ({
|
||||||
activeUsers:
|
activeUsers: typeof callback === "function" ? callback(state.activeUsers) : callback,
|
||||||
typeof callback === "function" ? callback(state.activeUsers) : callback,
|
|
||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useDrieUIValue = create<any>((set: any) => ({
|
export const useDrieUIValue = create<any>((set: any) => ({
|
||||||
drieUIValue: { touch: null, temperature: null, humidity: null },
|
drieUIValue: { touch: null, temperature: null, humidity: null },
|
||||||
|
|
||||||
setDrieUIValue: (x: any) =>
|
setDrieUIValue: (x: any) => set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })),
|
||||||
set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })),
|
|
||||||
|
|
||||||
setTouch: (value: any) =>
|
setTouch: (value: any) =>
|
||||||
set((state: any) => ({
|
set((state: any) => ({
|
||||||
@@ -367,8 +337,7 @@ interface ShortcutStore {
|
|||||||
export const useShortcutStore = create<ShortcutStore>((set) => ({
|
export const useShortcutStore = create<ShortcutStore>((set) => ({
|
||||||
showShortcuts: false,
|
showShortcuts: false,
|
||||||
setShowShortcuts: (value) => set({ showShortcuts: value }),
|
setShowShortcuts: (value) => set({ showShortcuts: value }),
|
||||||
toggleShortcuts: () =>
|
toggleShortcuts: () => set((state) => ({ showShortcuts: !state.showShortcuts })),
|
||||||
set((state) => ({ showShortcuts: !state.showShortcuts })),
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useMachineCount = create<any>((set: any) => ({
|
export const useMachineCount = create<any>((set: any) => ({
|
||||||
@@ -470,19 +439,18 @@ interface CompareStore {
|
|||||||
export const useCompareStore = create<CompareStore>((set) => ({
|
export const useCompareStore = create<CompareStore>((set) => ({
|
||||||
comparePopUp: false,
|
comparePopUp: false,
|
||||||
setComparePopUp: (value) => set({ comparePopUp: value }),
|
setComparePopUp: (value) => set({ comparePopUp: value }),
|
||||||
toggleComparePopUp: () =>
|
toggleComparePopUp: () => set((state) => ({ comparePopUp: !state.comparePopUp })),
|
||||||
set((state) => ({ comparePopUp: !state.comparePopUp })),
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Save state store
|
// Save state store
|
||||||
interface SaveVersionStore {
|
interface IsComparingStore {
|
||||||
isVersionSaved: boolean;
|
isComparing: boolean;
|
||||||
setIsVersionSaved: (value: boolean) => void;
|
setIsComparing: (value: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useSaveVersion = create<SaveVersionStore>((set) => ({
|
export const useIsComparing = create<IsComparingStore>((set) => ({
|
||||||
isVersionSaved: false,
|
isComparing: false,
|
||||||
setIsVersionSaved: (value: boolean) => set({ isVersionSaved: value }),
|
setIsComparing: (value: boolean) => set({ isComparing: value }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
interface ViewSceneState {
|
interface ViewSceneState {
|
||||||
@@ -494,8 +462,7 @@ export const useViewSceneStore = create<ViewSceneState>((set) => ({
|
|||||||
viewSceneLabels: getInitialViewSceneLabels(),
|
viewSceneLabels: getInitialViewSceneLabels(),
|
||||||
setViewSceneLabels: (value) => {
|
setViewSceneLabels: (value) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const newValue =
|
const newValue = typeof value === "function" ? value(state.viewSceneLabels) : value;
|
||||||
typeof value === "function" ? value(state.viewSceneLabels) : value;
|
|
||||||
|
|
||||||
// Store in localStorage manually
|
// Store in localStorage manually
|
||||||
localStorage.setItem("viewSceneLabels", JSON.stringify(newValue));
|
localStorage.setItem("viewSceneLabels", JSON.stringify(newValue));
|
||||||
|
|||||||
27
app/src/store/scene/useSceneStore.ts
Normal file
27
app/src/store/scene/useSceneStore.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { create } from "zustand";
|
||||||
|
import { immer } from "zustand/middleware/immer";
|
||||||
|
import * as THREE from "three";
|
||||||
|
|
||||||
|
type SceneStore = {
|
||||||
|
camState: {
|
||||||
|
position: THREE.Vector3;
|
||||||
|
target: THREE.Vector3;
|
||||||
|
};
|
||||||
|
setCamera: (pos: THREE.Vector3, target: THREE.Vector3) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useSceneStore = create<SceneStore>()(
|
||||||
|
immer((set) => ({
|
||||||
|
camState: {
|
||||||
|
position: new THREE.Vector3(0, 5, 10),
|
||||||
|
target: new THREE.Vector3(0, 0, 0),
|
||||||
|
},
|
||||||
|
|
||||||
|
setCamera: (pos, target) =>
|
||||||
|
set((state) => {
|
||||||
|
state.camState.position.copy(pos);
|
||||||
|
|
||||||
|
state.camState.target.copy(target);
|
||||||
|
}),
|
||||||
|
}))
|
||||||
|
);
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import useModuleStore, { useSubModuleStore, useThreeDStore } from "../../store/ui/useModuleStore";
|
import useModuleStore, { useSubModuleStore, useThreeDStore } from "../../store/ui/useModuleStore";
|
||||||
import { usePlayerStore, useToggleStore } from "../../store/ui/useUIToggleStore";
|
import { usePlayerStore, useToggleStore } from "../../store/ui/useUIToggleStore";
|
||||||
import useVersionHistoryVisibleStore, { useActiveSubTool, useActiveTool, useAddAction, useDfxUpload, useRenameModeStore, useSaveVersion, useSelectedComment, useShortcutStore, useToggleView, useToolMode, useViewSceneStore } from "../../store/builder/store";
|
import useVersionHistoryVisibleStore, { useActiveSubTool, useActiveTool, useAddAction, useDfxUpload, useRenameModeStore, useIsComparing, useSelectedComment, useShortcutStore, useToggleView, useToolMode, useViewSceneStore } from "../../store/builder/store";
|
||||||
import useCameraModeStore, { usePlayButtonStore } from "../../store/ui/usePlayButtonStore";
|
import useCameraModeStore, { usePlayButtonStore } from "../../store/ui/usePlayButtonStore";
|
||||||
import { detectModifierKeys } from "./detectModifierKeys";
|
import { detectModifierKeys } from "./detectModifierKeys";
|
||||||
import { useSelectedZoneStore } from "../../store/visualization/useZoneStore";
|
import { useSelectedZoneStore } from "../../store/visualization/useZoneStore";
|
||||||
@@ -27,7 +27,7 @@ const KeyPressListener: React.FC = () => {
|
|||||||
const { clearSelectedZone } = useSelectedZoneStore();
|
const { clearSelectedZone } = useSelectedZoneStore();
|
||||||
const { showShortcuts, setShowShortcuts } = useShortcutStore();
|
const { showShortcuts, setShowShortcuts } = useShortcutStore();
|
||||||
const { setWalkMode } = useCameraModeStore();
|
const { setWalkMode } = useCameraModeStore();
|
||||||
const { setIsVersionSaved } = useSaveVersion();
|
const { setIsComparing } = useIsComparing();
|
||||||
const { isLogListVisible, setIsLogListVisible } = useLogger();
|
const { isLogListVisible, setIsLogListVisible } = useLogger();
|
||||||
const { hidePlayer, setHidePlayer } = usePlayerStore();
|
const { hidePlayer, setHidePlayer } = usePlayerStore();
|
||||||
const { setViewSceneLabels } = useViewSceneStore();
|
const { setViewSceneLabels } = useViewSceneStore();
|
||||||
@@ -177,7 +177,7 @@ const KeyPressListener: React.FC = () => {
|
|||||||
setIsPlaying(false);
|
setIsPlaying(false);
|
||||||
clearSelectedZone();
|
clearSelectedZone();
|
||||||
setShowShortcuts(false);
|
setShowShortcuts(false);
|
||||||
setIsVersionSaved(false);
|
setIsComparing(false);
|
||||||
clearComparisonProduct();
|
clearComparisonProduct();
|
||||||
setIsLogListVisible(false);
|
setIsLogListVisible(false);
|
||||||
setIsRenameMode(false);
|
setIsRenameMode(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user